187 lines
4.8 KiB
C
187 lines
4.8 KiB
C
/**
|
|
* @file fc7xxx_driver_freqm.c
|
|
* @author Flagchip
|
|
* @brief FC7xxx FREQM driver type definition and API
|
|
* @version 0.1.0
|
|
* @date 2024-01-14
|
|
*
|
|
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
|
|
*
|
|
* @details
|
|
*/
|
|
/* ********************************************************************************
|
|
* Revision History:
|
|
*
|
|
* Version Date Initials CR# Descriptions
|
|
* --------- ---------- ------------ ---------- ---------------
|
|
* 0.1.0 2024-01-14 qxw0100 N/A First version for FC7240
|
|
******************************************************************************** */
|
|
|
|
#include "fc7xxx_driver_freqm.h"
|
|
#include "fc7xxx_driver_pcc.h"
|
|
#include "interrupt_manager.h"
|
|
|
|
/********* Local variable ************/
|
|
static FREQM_Type * const pFreqmPtrs = FREQM;
|
|
|
|
static FREQM_MesCntStartCallBackType s_pMesCntStartCallback = NULL;
|
|
static FREQM_MesCntStopCallBackType s_pMesCntStopCallback = NULL;
|
|
static FREQM_RefCntStopCallBackType s_pRefCntStopCallback = NULL;
|
|
static FREQM_FaultCallBackType s_pFaultCallback = NULL;
|
|
|
|
|
|
/********* Global Functions ************/
|
|
/**
|
|
* @brief Initialize FREQM configuration
|
|
*
|
|
* @param pInitStruct the basic configurations of the FREQM
|
|
* @return FREQM_StatusType whether the operation is successfully
|
|
*/
|
|
FREQM_StatusType FREQM_Init(const FREQM_InitType *const pInitStruct)
|
|
{
|
|
FREQM_StatusType eRet = FREQM_STATUS_SUCCESS;
|
|
if (NULL == pInitStruct)
|
|
{
|
|
eRet = FREQM_STATUS_PARAM_INVALID;
|
|
}
|
|
else
|
|
{
|
|
/* Configure the clock divider value */
|
|
FREQM_HWA_MesClk_PreDiv(pFreqmPtrs,pInitStruct->u8PredivVal);
|
|
/* Select the clock source to be measured */
|
|
FREQM_HWA_MesClkSel(pFreqmPtrs,pInitStruct->eClkSel);
|
|
/* Set and clear the S/W reset */
|
|
PCC_GenPeripheralReset(PCC_CLK_FREQM);
|
|
/* Configure the measure counter targer value */
|
|
FREQM_HWA_SetMesLength(pFreqmPtrs,pInitStruct->u32MesLen);
|
|
/* Configure the reference counter target value */
|
|
FREQM_HWA_SetRefTimeout(pFreqmPtrs,pInitStruct->u32RefTo);
|
|
}
|
|
return eRet;
|
|
}
|
|
|
|
/**
|
|
* @brief De-initialize the FREQM
|
|
*
|
|
* @param eInstance the selected FREQM
|
|
* @return FREQM_StatusType whether the operation is successfully
|
|
*/
|
|
FREQM_StatusType FREQM_DeInit()
|
|
{
|
|
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
|
|
/* Set register to reset value */
|
|
FREQM_HWA_MesClk_PreDiv(pFreqmPtrs,0U);
|
|
FREQM_HWA_MesClkSel(pFreqmPtrs,(FREQM_MesClkSelType)0);
|
|
FREQM_HWA_SetMesLength(pFreqmPtrs,0xFFFFFFFFU);
|
|
FREQM_HWA_SetRefTimeout(pFreqmPtrs,0xFFFFFFFFU);
|
|
|
|
FREQM_HWA_DisableCntEventInterrupt(pFreqmPtrs);
|
|
s_pMesCntStartCallback = NULL;
|
|
s_pMesCntStopCallback = NULL;
|
|
s_pRefCntStopCallback = NULL;
|
|
s_pFaultCallback = NULL;
|
|
|
|
return eStatus;
|
|
}
|
|
|
|
/**
|
|
* @brief Clear all FREQM status
|
|
*
|
|
* @return FREQM_StatusType whether the operation is successfully
|
|
*/
|
|
FREQM_StatusType FREQM_ClearStatus()
|
|
{
|
|
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
|
|
uint32_t u32TimeOutVal = 0xffff;
|
|
uint32_t u32CntStatus;
|
|
|
|
FREQM_HWA_SetRefCnt(pFreqmPtrs,0U);
|
|
|
|
do
|
|
{
|
|
u32CntStatus = FREQM_HWA_GetCntStatus(pFreqmPtrs);
|
|
u32TimeOutVal--;
|
|
}while(u32CntStatus!=0U);
|
|
|
|
if(u32TimeOutVal == 0U)
|
|
{
|
|
eStatus = FREQM_STATUS_TIMEOUT;
|
|
}
|
|
return eStatus;
|
|
}
|
|
|
|
/**
|
|
* @brief Start the reference/measure counter
|
|
*
|
|
*/
|
|
void FREQM_StartMeasureCnt()
|
|
{
|
|
FREQM_HWA_SetMesCnt(pFreqmPtrs,0U);
|
|
}
|
|
|
|
/**
|
|
* @brief Get saved reference counter value
|
|
*
|
|
* @return uint32_t saved reference counter value
|
|
*/
|
|
uint32_t FREQM_GetRefCntSave()
|
|
{
|
|
return FREQM_HWA_GetRefCntSave(pFreqmPtrs);
|
|
}
|
|
|
|
/**
|
|
* @brief FREQM initialize interrupt function
|
|
*
|
|
* @param pIntStruct FREQM interrupt structure
|
|
* @return FREQM_StatusType whether the operation is successfully
|
|
*/
|
|
FREQM_StatusType FREQM_InterruptInit(const FREQM_InterruptType *const pIntrStruct)
|
|
{
|
|
FREQM_StatusType eStatus = FREQM_STATUS_SUCCESS;
|
|
|
|
FREQM_HWA_EnableCntEventInterrupt(pFreqmPtrs);
|
|
/*register callback functions*/
|
|
s_pMesCntStartCallback = pIntrStruct->pMesCntStartCallback;
|
|
s_pMesCntStopCallback = pIntrStruct->pMesCntStopCallback;
|
|
s_pRefCntStopCallback = pIntrStruct->pRefCntStopCallback;
|
|
s_pFaultCallback = pIntrStruct->pFaultCallback;
|
|
|
|
return eStatus;
|
|
}
|
|
|
|
/**
|
|
* @brief Interrupt IRQ handle of FREQM
|
|
*
|
|
*/
|
|
void FREQM_IRQHandler(void)
|
|
{
|
|
uint32_t u32CntStatus;
|
|
bool bIntFlag;
|
|
|
|
bIntFlag = FREQM_HWA_GetInterruptFlag(pFreqmPtrs);
|
|
if(bIntFlag)
|
|
{
|
|
FREQM_HWA_ClearInterruptFlag(pFreqmPtrs);
|
|
}
|
|
|
|
u32CntStatus = FREQM_HWA_GetCntStatus(pFreqmPtrs);
|
|
|
|
if(u32CntStatus == FREQM_CNT_STATUS_MES_CNT_START_MASK)//0x4
|
|
{
|
|
s_pMesCntStartCallback();
|
|
}
|
|
else if(u32CntStatus == (FREQM_CNT_STATUS_MES_CNT_START_MASK|FREQM_CNT_STATUS_MES_CNT_STOP_MASK) )//0x6
|
|
{
|
|
|
|
s_pMesCntStopCallback();
|
|
}
|
|
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
|
|
{
|
|
s_pRefCntStopCallback();
|
|
}
|
|
else
|
|
{
|
|
s_pFaultCallback();
|
|
}
|
|
}
|