PeripheralDriver_Flagchip_F.../Src/module_driver_freqm.c

324 lines
11 KiB
C

/**
* @file module_driver_freqm.c
* @author Flagchip0100
* @brief FREQM 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.1.0 2023-01-09 Flagchip087 N/A First version for FC7300
* 2.0.0 2024-08-01 Flagchip0100 N/A SDK2.0 release version
*********************************************************************************/
#include "module_driver_freqm.h"
#if (FREQM_INSTANCE_COUNT > 0U)
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef FREQM_DEV_ERROR_REPORT
#define FREQM_DEV_ERROR_REPORT STD_OFF
#endif
#if FREQM_DEV_ERROR_REPORT == STD_ON
#define FREQM_ReportDevError(func, error) ReportDevError(FREQM_MODULE_ID, func, error)
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
static FREQM_Type *const s_apFreqmBase[FREQM_INSTANCE_COUNT] = FREQM_BASE_PTRS;
/*******************************************************************************
* Code
******************************************************************************/
/**
* @brief Initializes the FREQM module with the specified configuration.
*
* This function initializes the FREQM module with the given configuration settings, including the clock divider value,
* the clock source to be measured, the measurement length, and the reference timeout.
*
* @param pHandle Pointer to the FREQM handle structure.
* @param pInitStruct Pointer to the initialization structure containing the configuration settings.
*
* @return FREQM_StatusType Indicates the status of the initialization process (FREQM_STATUS_SUCCESS or FREQM_STATUS_FAIL).
*
* @note If any of the required pointers are NULL or the instance index is out of range, a device error will be reported,
* and the function returns FREQM_STATUS_FAIL.
*/
FREQM_StatusType FREQM_Init(FREQM_HandleType *const pHandle, const FREQM_CfgType *const pInitStruct)
{
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
#if FREQM_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FREQM_ReportDevError(FREQM_INIT_ID, FREQM_E_PARAM_NULLPTR);
eStatus = FREQM_STATUS_FAIL;
}
else if (pInitStruct == NULL)
{
FREQM_ReportDevError(FREQM_INIT_ID, FREQM_E_PARAM_NULLPTR);
eStatus = FREQM_STATUS_FAIL;
}
else if (pHandle->eInstance >= FREQM_INSTANCE_COUNT)
{
FREQM_ReportDevError(FREQM_INIT_ID, FREQM_E_PARAM_INSTANCE);
eStatus = FREQM_STATUS_FAIL;
}
else
#endif
{
FREQM_Type *const pFreqm = s_apFreqmBase[pHandle->eInstance];
uint32_t u32TimeOutVal = 0xFFFFU;
uint32_t u32CntStatus;
FREQM_HWA_DisableCntEventInterrupt(pFreqm);
/* Configure the clock divider value */
FREQM_HWA_MesClk_PreDiv(pFreqm, pInitStruct->u8PredivVal);
/* Select the clock source to be measured */
FREQM_HWA_MesClkSel(pFreqm, pInitStruct->u8ClkSel);
FREQM_HWA_EnableCntEventInterrupt(pFreqm);
/* Configure the measure counter targer value */
FREQM_HWA_SetMesLength(pFreqm, pInitStruct->u32MesLen);
/* Configure the reference counter target value */
FREQM_HWA_SetRefTimeout(pFreqm, pInitStruct->u32RefTo);
FREQM_HWA_SetRefCnt(pFreqm, 0U);
do
{
u32CntStatus = FREQM_HWA_GetCntStatus(pFreqm);
u32TimeOutVal--;
if (u32TimeOutVal == 0U)
{
FREQM_HWA_DisableCntEventInterrupt(pFreqm);
eStatus = FREQM_STATUS_TIMEOUT;
break;
}
} while(u32CntStatus != 0U);
}
return eStatus;
}
/**
* @brief Deinitializes the FREQM module.
*
* This function deinitializes the specified FREQM module instance by resetting its configuration settings to default
* values and disabling the counter event interrupt.
*
* @param pHandle Pointer to the FREQM handle structure.
*
* @return FREQM_StatusType Indicates the status of the deinitialization process (FREQM_STATUS_SUCCESS or FREQM_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 FREQM_STATUS_FAIL.
*/
FREQM_StatusType FREQM_DeInit(FREQM_HandleType *const pHandle)
{
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
#if FREQM_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FREQM_ReportDevError(FREQM_DEINIT_ID, FREQM_E_PARAM_NULLPTR);
eStatus = FREQM_STATUS_FAIL;
}
else if (pHandle->eInstance >= FREQM_INSTANCE_COUNT)
{
FREQM_ReportDevError(FREQM_DEINIT_ID, FREQM_E_PARAM_INSTANCE);
eStatus = FREQM_STATUS_FAIL;
}
else
#endif
{
FREQM_Type *const pFreqm = s_apFreqmBase[pHandle->eInstance];
/* Set register to reset value */
FREQM_HWA_MesClk_PreDiv(pFreqm, 0U);
FREQM_HWA_MesClkSel(pFreqm, 0U);
FREQM_HWA_SetMesLength(pFreqm, 0xFFFFFFFFU);
FREQM_HWA_SetRefTimeout(pFreqm, 0xFFFFFFFFU);
FREQM_HWA_DisableCntEventInterrupt(pFreqm);
}
return eStatus;
}
/**
* @brief Starts the frequency measurement process in the FREQM module.
*
* This function starts the frequency measurement process by resetting the measurement counter to zero.
*
* @param pHandle Pointer to the FREQM handle structure.
*
* @return FREQM_StatusType Indicates the status of the start measurement process (FREQM_STATUS_SUCCESS or FREQM_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 FREQM_STATUS_FAIL.
*/
FREQM_StatusType FREQM_StartMeasure(FREQM_HandleType *pHandle)
{
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
#if FREQM_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FREQM_ReportDevError(FREQM_STARTMEASURE_ID, FREQM_E_PARAM_NULLPTR);
eStatus = FREQM_STATUS_FAIL;
}
else if (pHandle->eInstance >= FREQM_INSTANCE_COUNT)
{
FREQM_ReportDevError(FREQM_STARTMEASURE_ID, FREQM_E_PARAM_INSTANCE);
eStatus = FREQM_STATUS_FAIL;
}
else
#endif
{
FREQM_Type *const pFreqm = s_apFreqmBase[pHandle->eInstance];
FREQM_HWA_SetMesCnt(pFreqm, 0U);
}
return eStatus;
}
/**
* @brief Clears the status of the FREQM module.
*
* This function clears the status of the specified FREQM module instance by resetting the reference counter and waiting for
* the counters to stop.
*
* @param pHandle Pointer to the FREQM handle structure.
*
* @return FREQM_StatusType Indicates the status of the clear status operation (FREQM_STATUS_SUCCESS or FREQM_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 FREQM_STATUS_FAIL.
*/
FREQM_StatusType FREQM_ClearStatus(FREQM_HandleType *pHandle)
{
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
#if FREQM_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FREQM_ReportDevError(FREQM_CLEARSTATUS_ID, FREQM_E_PARAM_NULLPTR);
eStatus = FREQM_STATUS_FAIL;
}
else if (pHandle->eInstance >= FREQM_INSTANCE_COUNT)
{
FREQM_ReportDevError(FREQM_CLEARSTATUS_ID, FREQM_E_PARAM_INSTANCE);
eStatus = FREQM_STATUS_FAIL;
}
else
#endif
{
FREQM_Type *const pFreqm = s_apFreqmBase[pHandle->eInstance];
uint32_t u32TimeOutVal = 0xFFFFU;
uint32_t u32CntStatus;
FREQM_HWA_SetRefCnt(pFreqm, 0U);
do
{
u32CntStatus = FREQM_HWA_GetCntStatus(pFreqm);
u32TimeOutVal--;
if (u32TimeOutVal == 0U)
{
eStatus = FREQM_STATUS_TIMEOUT;
break;
}
} while(u32CntStatus != 0U);
}
return eStatus;
}
/**
* @brief Handles common interrupts for the FREQM module.
*
* This function processes the common interrupts for the specified FREQM module instance. It checks the interrupt flags and calls
* the appropriate callback functions based on the interrupt status.
*
* @param pHandle Pointer to the FREQM handle structure.
*
* @note If the handle pointer is NULL or the instance index is out of range, a device error will be reported.
*/
void FREQM_CommonIRQHandler(FREQM_HandleType *const pHandle)
{
#if FREQM_DEV_ERROR_REPORT == STD_ON
if (pHandle == NULL)
{
FREQM_ReportDevError(FREQM_COMMONIRQHANDLER_ID, FREQM_E_PARAM_NULLPTR);
}
else if (pHandle->eInstance >= FREQM_INSTANCE_COUNT)
{
FREQM_ReportDevError(FREQM_COMMONIRQHANDLER_ID, FREQM_E_PARAM_INSTANCE);
}
else
#endif
{
FREQM_Type *const pFreqm = s_apFreqmBase[pHandle->eInstance];
uint32_t u32CntStatus;
if (FREQM_HWA_GetInterruptFlag(pFreqm) == true)
{
FREQM_HWA_ClearInterruptFlag(pFreqm);
}
u32CntStatus = FREQM_HWA_GetCntStatus(pFreqm);
if(u32CntStatus == FREQM_CNT_STATUS_MES_CNT_START_MASK)//0x4
{
if (pHandle->tSettings.pMesCntStartCallback != NULL)
{
pHandle->tSettings.pMesCntStartCallback(pHandle, FREQM_HWA_GetRefCntSave(pFreqm));
}
}
else if(u32CntStatus == (FREQM_CNT_STATUS_MES_CNT_START_MASK|FREQM_CNT_STATUS_MES_CNT_STOP_MASK) )//0x6
{
if (pHandle->tSettings.pMesCntStopCallback != NULL)
{
pHandle->tSettings.pMesCntStopCallback(pHandle, FREQM_HWA_GetRefCntSave(pFreqm));
}
}
else if(u32CntStatus == (FREQM_CNT_STATUS_MES_CNT_START_MASK|FREQM_CNT_STATUS_MES_CNT_STOP_MASK|FREQM_CNT_STATUS_REF_CNT_STOP_MASK) )//0x7
{
if (pHandle->tSettings.pRefCntStopCallback != NULL)
{
pHandle->tSettings.pRefCntStopCallback(pHandle);
}
}
else
{
if (pHandle->tSettings.pErrorCallback != NULL)
{
pHandle->tSettings.pErrorCallback(pHandle);
}
}
}
}
#endif /* (FREQM_INSTANCE_COUNT > 0U) */