Skip to content

Commit

Permalink
PMICDRV-178: Allow crcEnable in driver init to control comms CRC
Browse files Browse the repository at this point in the history
In the previous implementation the crcEnable field passed to Pmic_init()
was only used to indicate to the driver whether CRC should be calculated
when performing I/O, but had not effect on whether CRC was enabled in
the HW. It was only used to match the configuration of the HW.

In this implementation, this bit now controls whether comms CRC is
enabled or not, allowing users to dynamically control CRC enablement.
Additionally, 3 new APIs are added to allow users to control CRC outside
of the context of driver initialization, these functions are:

- Pmic_ioGetCrcEnableState(Pmic_CoreHandle_t *, bool *)
- Pmic_ioCrcEnableControl(Pmic_CoreHandle_t *, bool)
- Pmic_ioCrcEnable(Pmic_CoreHandle_t *)
- Pmic_ioCrcDisable(Pmic_CoreHandle_t *)

Signed-off-by: Michael Leonard <m-leonard@ti.com>
  • Loading branch information
LeonardMH committed Jun 27, 2024
1 parent b295a33 commit a5502e0
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/pmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,12 @@ extern "C" {
* values, see @ref Pmic_I2CSpeedSel. Valid only when
* `PMIC_CFG_I2C2_SPEED_VALID` bit is set. Only necessary for I2C interfaces.
*
* @param crcEnable Controls whether communications layer CRC is enabled or
* disabled. If enabled the driver will enable the CRC feature in HW and perform
* the necessary CRC calculations when communication with the PMIC. If disabled,
* the CRC feature will be disabled in HW and no calculations will be performed
* by the driver.
*
* @param pFnPmicCommIoRd Pointer to I2C/SPI Comm LLD Read Function. Valid
* only when `PMIC_CFG_COMM_IO_RD_VALID` bit of `validParams` is set.
*
Expand Down
52 changes: 52 additions & 0 deletions include/pmic_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,58 @@ int32_t Pmic_ioTxByte(Pmic_CoreHandle_t *handle, uint16_t regAddr, uint8_t txDat
*/
int32_t Pmic_ioRxByte(Pmic_CoreHandle_t *handle, uint16_t regAddr, uint8_t *rxBuffer);

/**
* @ingroup DRV_PMIC_IO_MODULE
* @brief Determine whether I2C CRC is enabled or disabled.
*
* @param handle [IN] PMIC Interface Handle
* @param isEnabled [OUT] Set to true (PMIC_ENABLE) if comms CRC is enabled,
* false (PMIC_DISABLE) if disabled. See @ref Pmic_EnableDisable.
*
* @return Returns PMIC_ST_SUCCESS if the operation is successful; otherwise,
* it returns an appropriate error code. For possible values, see @ref
* Pmic_ErrorCodes.
*/
int32_t Pmic_ioGetCrcEnableState(Pmic_CoreHandle_t *handle, bool *isEnabled);

/**
* @ingroup DRV_PMIC_IO_MODULE
* @brief Control whether I2C CRC is enabled or disabled.
*
* @param handle [IN] PMIC Interface Handle
* @param enable [IN] Set to true (PMIC_ENABLE) to enable comms CRC, false
* (PMIC_DISABLE) to disable. See @ref Pmic_EnableDisable.
*
* @return Returns PMIC_ST_SUCCESS if the operation is successful; otherwise,
* it returns an appropriate error code. For possible values, see @ref
* Pmic_ErrorCodes.
*/
int32_t Pmic_ioSetCrcEnableState(Pmic_CoreHandle_t *handle, bool enable);

/**
* @ingroup DRV_PMIC_IO_MODULE
* @brief Enable I2C CRC.
*
* @param handle [IN] PMIC Interface Handle
*
* @return Returns PMIC_ST_SUCCESS if the operation is successful; otherwise,
* it returns an appropriate error code. For possible values, see @ref
* Pmic_ErrorCodes.
*/
int32_t Pmic_ioCrcEnable(Pmic_CoreHandle_t *handle);

/**
* @ingroup DRV_PMIC_IO_MODULE
* @brief Disable I2C CRC.
*
* @param handle [IN] PMIC Interface Handle
*
* @return Returns PMIC_ST_SUCCESS if the operation is successful; otherwise,
* it returns an appropriate error code. For possible values, see @ref
* Pmic_ErrorCodes.
*/
int32_t Pmic_ioCrcDisable(Pmic_CoreHandle_t *handle);

#ifdef __cplusplus
}
#endif /* __cplusplus */
Expand Down
56 changes: 56 additions & 0 deletions include/regmap/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/******************************************************************************
* Copyright (c) 2024 Texas Instruments Incorporated - http://www.ti.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __PMIC_REGMAP_IO_H__
#define __PMIC_REGMAP_IO_H__

#ifdef __cplusplus
extern "C" {
#endif

/** @brief PMIC I/O Related Register Offset */
#define PMIC_IO_INTERFACE_CONF (0x1DU)

/** @brief PMIC Interface Configuration Register (INTERFACE_CONF) */
#define PMIC_INTF_CONF_NINT_GPO_PU_EN_SHIFT (0U)
#define PMIC_INTF_CONF_NINT_GPO_POL_SHIFT (1U)
#define PMIC_INTF_CONF_NINT_GPO_OD_SHIFT (2U)
#define PMIC_INTF_CONF_NRSTOUT_PU_EN_SHIFT (3U)
#define PMIC_INTF_CONF_NRSTOUT_POL_SHIFT (4U)
#define PMIC_INTF_CONF_NRSTOUT_OD_SHIFT (5U)
#define PMIC_INTF_CONF_NERR_PU_DIS_SHIFT (6U)
#define PMIC_INTF_CONF_I2C_CRC_EN_SHIFT (7U)

#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __PMIC_REGMAP_IO_H__ */
8 changes: 8 additions & 0 deletions src/pmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ int32_t Pmic_init(Pmic_CoreHandle_t *handle, const Pmic_CoreCfg_t *config) {
handle->drvInitStatus |= DRV_INIT_SUCCESS;
}

// Update PMIC Comms CRC status, note that this performs communications with
// the device to ensure handle `crcEnable` property and HW status are in
// sync, and this relies on the handle being fully initialized so it must
// come after DRV_INIT_SUCCESS.
if (Pmic_validParamStatusCheck(config->validParams, PMIC_CFG_CRC_ENABLE_VALID, status)) {
status = Pmic_ioSetCrcEnableState(handle, config->crcEnable);
}

return status;
}

Expand Down
53 changes: 53 additions & 0 deletions src/pmic_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#include "pmic.h"
#include "pmic_io.h"
#include "regmap/io.h"

/*========================================================================== */
/* Macros & Typedefs */
Expand Down Expand Up @@ -102,3 +103,55 @@ int32_t Pmic_ioTxByte(Pmic_CoreHandle_t *handle, uint16_t regAddr, uint8_t txDat

return handle->pFnPmicCommIoWr(handle, (uint8_t)PMIC_MAIN_INST, regAddr, &txBuf[0], frameSize);
}

int32_t Pmic_ioGetCrcEnableState(Pmic_CoreHandle_t *handle, bool *isEnabled) {
int32_t status = Pmic_checkPmicCoreHandle(handle);
uint8_t regData = 0U;

// Read the INTERFACE_CONF register
if (status == PMIC_ST_SUCCESS) {
Pmic_criticalSectionStart(handle);
status = Pmic_ioRxByte(handle, PMIC_IO_INTERFACE_CONF, &regData);
Pmic_criticalSectionStop(handle);
}

// Extract the relevant bit
if (status == PMIC_ST_SUCCESS) {
*isEnabled = Pmic_getBitField_b(regData, PMIC_INTF_CONF_I2C_CRC_EN_SHIFT);
}

return status;
}

int32_t Pmic_ioSetCrcEnableState(Pmic_CoreHandle_t *handle, bool enable) {
int32_t status = Pmic_checkPmicCoreHandle(handle);
uint8_t regData = 0U;

// Read the INTERFACE_CONF register
Pmic_criticalSectionStart(handle);
if (status == PMIC_ST_SUCCESS) {
status = Pmic_ioRxByte(handle, PMIC_IO_INTERFACE_CONF, &regData);
}

// Set the I2C_CRC_EN bit accordingly and then write back to the register
if (status == PMIC_ST_SUCCESS) {
Pmic_setBitField_b(&regData, PMIC_INTF_CONF_I2C_CRC_EN_SHIFT, enable);
status = Pmic_ioTxByte(handle, PMIC_IO_INTERFACE_CONF, regData);
}
Pmic_criticalSectionStop(handle);

// Update the handle crcEnable property to track with the HW status
if (status == PMIC_ST_SUCCESS) {
handle->crcEnable = enable;
}

return status;
}

int32_t Pmic_ioCrcEnable(Pmic_CoreHandle_t *handle) {
return Pmic_ioSetCrcEnableState(handle, PMIC_ENABLE);
}

int32_t Pmic_ioCrcDisable(Pmic_CoreHandle_t *handle) {
return Pmic_ioSetCrcEnableState(handle, PMIC_DISABLE);
}

0 comments on commit a5502e0

Please sign in to comment.