228 lines
8.0 KiB
C
228 lines
8.0 KiB
C
/**
|
|
* @file module_driver_erm.c
|
|
* @author Flagchip0100
|
|
* @brief ERM Module driver type definition and API
|
|
* @version 2.0.0
|
|
* @date 2024-08-20
|
|
*
|
|
* SDK Version: 2.6.0
|
|
*
|
|
|
|
* @copyright Copyright 2020-2024 Flagchip Semiconductors Co., Ltd.
|
|
*/
|
|
|
|
/********************************************************************************
|
|
* Revision History:
|
|
*
|
|
* Version Date Initials CR# Descriptions
|
|
* --------- ---------- ------------ ---------- ---------------
|
|
* 0.2.0 2023-02-15 Flagchip052 N/A First version for FC7300
|
|
* 2.0.0 2024-08-01 Flagchip0100 N/A SDK2.0 release version
|
|
********************************************************************************/
|
|
|
|
#include "module_driver_erm.h"
|
|
|
|
#if (ERM_INSTANCE_COUNT > 0U)
|
|
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
#ifndef ERM_DEV_ERROR_REPORT
|
|
#define ERM_DEV_ERROR_REPORT STD_OFF
|
|
#endif
|
|
|
|
#if ERM_DEV_ERROR_REPORT == STD_ON
|
|
#define ERM_ReportDevError(func, error) ReportDevError(ERM_MODULE_ID, func, error)
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
static ERM_Type *const s_apErmBase[ERM_INSTANCE_COUNT] = ERM_BASE_PTRS;
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* @brief Initializes the Error Reporting Module (ERM) for the specified instance
|
|
*
|
|
* This function initializes the ERM module with the provided configuration structure.
|
|
* It performs parameter validation, sets up the control register based on the configuration,
|
|
* and clears the status. If an error occurs or the handle is invalid, an error report will
|
|
* be generated, and the function will return a failure status.
|
|
*
|
|
* @param pHandle Pointer to an ERM handle structure containing the instance information
|
|
* @param pInitCfg Pointer to an ERM configuration structure with desired settings
|
|
*
|
|
* @return Status of the initialization operation
|
|
* - ERM_STATUS_SUCCESS: Initialization successful
|
|
* - ERM_STATUS_FAIL: Initialization failed due to an error
|
|
*
|
|
* @preconditions
|
|
* - A valid ERM handle and configuration structure pointers must be provided
|
|
* - The ERM instance number should be within the supported range
|
|
*
|
|
* @postconditions
|
|
* - The ERM will be configured according to the provided settings
|
|
* - The status will be cleared
|
|
* - The error callback function pointer in the handle will be set to the one from the configuration
|
|
*
|
|
* @note Error reporting is enabled when `ERM_DEV_ERROR_REPORT` is set to `STD_ON`.
|
|
*/
|
|
ERM_StatusType ERM_Init(ERM_HandleType *const pHandle, const ERM_CfgType *const pInitCfg)
|
|
{
|
|
ERM_StatusType eStatus = ERM_STATUS_SUCCESS;
|
|
#if ERM_DEV_ERROR_REPORT == STD_ON
|
|
if (pHandle == NULL)
|
|
{
|
|
ERM_ReportDevError(ERM_INIT_ID, ERM_E_PARAM_NULLPTR);
|
|
eStatus = ERM_STATUS_FAIL;
|
|
}
|
|
else if (pInitCfg == NULL)
|
|
{
|
|
ERM_ReportDevError(ERM_INIT_ID, ERM_E_PARAM_NULLPTR);
|
|
eStatus = ERM_STATUS_FAIL;
|
|
}
|
|
else if (pHandle->eInstance >= ERM_INSTANCE_COUNT)
|
|
{
|
|
ERM_ReportDevError(ERM_INIT_ID, ERM_E_PARAM_INSTANCE);
|
|
eStatus = ERM_STATUS_FAIL;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
ERM_Type *const pErm = s_apErmBase[pHandle->eInstance];
|
|
uint32_t u32CRnValue = 0U;
|
|
uint8_t u8CRnIdx = (pInitCfg->u8Channel >> 3U) & 0x1FU;
|
|
uint8_t u8CRnPos = (uint8_t)(30U - 4U * (pInitCfg->u8Channel & 0x7U));
|
|
|
|
ERM_HWA_SetSRn(pErm, u8CRnIdx, (uint32_t)0x03U << u8CRnPos);
|
|
u32CRnValue = ERM_HWA_GetCRn(pErm, u8CRnIdx);
|
|
/* Enable ERM Channel */
|
|
if(pInitCfg->u8ErmEnable != 0U)
|
|
{
|
|
u32CRnValue |= (uint32_t)pInitCfg->u8IntType << u8CRnPos;
|
|
}
|
|
/* Disable ERM Channel */
|
|
else
|
|
{
|
|
u32CRnValue &= ~((uint32_t)pInitCfg->u8IntType << u8CRnPos);
|
|
}
|
|
ERM_HWA_SetCRn(pErm, u8CRnIdx, u32CRnValue);
|
|
}
|
|
|
|
return eStatus;
|
|
}
|
|
|
|
/**
|
|
* @brief Deinitializes the ERM module.
|
|
*
|
|
* This function deinitializes the specified ERM module instance by clearing its control and status registers.
|
|
*
|
|
* @param pHandle Pointer to the ERM handle structure.
|
|
*
|
|
* @return ERM_StatusType Indicates the status of the operation (ERM_STATUS_SUCCESS or ERM_STATUS_FAIL).
|
|
*
|
|
* @note If the handle pointer is NULL or the instance index is out of range, a device error will be reported, and the function returns ERM_STATUS_FAIL.
|
|
*/
|
|
ERM_StatusType ERM_DeInit(ERM_HandleType *const pHandle)
|
|
{
|
|
ERM_StatusType eStatus = ERM_STATUS_SUCCESS;
|
|
|
|
#if ERM_DEV_ERROR_REPORT == STD_ON
|
|
if (pHandle == NULL)
|
|
{
|
|
ERM_ReportDevError(ERM_DEINIT_ID, ERM_E_PARAM_NULLPTR);
|
|
eStatus = ERM_STATUS_FAIL;
|
|
}
|
|
else if (pHandle->eInstance >= ERM_INSTANCE_COUNT)
|
|
{
|
|
ERM_ReportDevError(ERM_DEINIT_ID, ERM_E_PARAM_INSTANCE);
|
|
eStatus = ERM_STATUS_FAIL;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
ERM_Type *const pErm = s_apErmBase[pHandle->eInstance];
|
|
uint8_t u8loop;
|
|
|
|
for (u8loop = 0U; u8loop < ERM_CR_SR_COUNT_MAX; u8loop++)
|
|
{
|
|
ERM_HWA_SetCRn(pErm, u8loop, 0x0U);
|
|
ERM_HWA_SetSRn(pErm, u8loop, ERM_SR0_MASK);
|
|
}
|
|
}
|
|
|
|
return eStatus;
|
|
}
|
|
|
|
/**
|
|
* @brief Handles common Error Reporting Module (ERM) interrupts and invokes error callbacks
|
|
*
|
|
* This function serves as the common interrupt handler for the ERM, checking for errors in various channels
|
|
* (CTCM, DTCM, PFLASH, optionally DFLASH, and DMA) and invoking the error callback function when an error
|
|
* is detected. It also clears the status flags after processing the interrupts.
|
|
*
|
|
* @param pHandle Pointer to an ERM handle structure containing the instance information and error callback
|
|
*
|
|
* @preconditions
|
|
* - A valid ERM handle must be provided with a potentially registered error callback
|
|
*
|
|
* @postconditions
|
|
* - If an error is detected, the corresponding error callback will be called with details
|
|
* including the channel, error type, and the address where the error occurred
|
|
* - All ERM status flags will be cleared after handling the interrupts
|
|
*
|
|
* @note This function is designed to be used within an interrupt context.
|
|
* @note Support for DFLASH depends on the compile-time configuration `ERM_DFLASH_SUPPORT`.
|
|
*/
|
|
void ERM_CommonIRQHandler(ERM_HandleType *const pHandle)
|
|
{
|
|
#if ERM_DEV_ERROR_REPORT == STD_ON
|
|
if (pHandle == NULL)
|
|
{
|
|
ERM_ReportDevError(ERM_COMMONIRQHANDLER_ID, ERM_E_PARAM_NULLPTR);
|
|
}
|
|
else if (pHandle->eInstance >= ERM_INSTANCE_COUNT)
|
|
{
|
|
ERM_ReportDevError(ERM_COMMONIRQHANDLER_ID, ERM_E_PARAM_INSTANCE);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
ERM_Type *const pErm = s_apErmBase[pHandle->eInstance];
|
|
uint32_t u32SRnValue;
|
|
uint8_t u8LoopI, u8LoopJ, u8Channel, u8ErrorType;
|
|
|
|
for (u8LoopI = 0U; u8LoopI < ERM_CR_SR_COUNT_MAX; u8LoopI++)
|
|
{
|
|
u32SRnValue = ERM_HWA_GetSRn(pErm, u8LoopI);
|
|
if (u32SRnValue != 0U)
|
|
{
|
|
for (u8LoopJ = 0U; u8LoopJ < 8U; u8LoopJ++)
|
|
{
|
|
u8ErrorType = (u32SRnValue >> (30U - 4U * u8LoopJ)) & 0x3U;
|
|
if (u8ErrorType != 0)
|
|
{
|
|
u8Channel = (uint8_t)((u8LoopI << 3U) + u8LoopJ);
|
|
if (pHandle->tSettings.pErrorCallback[u8Channel] != NULL)
|
|
{
|
|
pHandle->tSettings.pErrorCallback[u8Channel](pHandle, u8ErrorType, ERM_HWA_GetEARn(pErm, u8Channel));
|
|
}
|
|
}
|
|
}
|
|
ERM_HWA_SetSRn(pErm, u8LoopI, u32SRnValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* (ERM_INSTANCE_COUNT > 0U) */
|