PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_tstmp.c

421 lines
14 KiB
C

/**
* @file fc7xxx_driver_tstmp.c
* @author Flagchip
* @brief FC7xxx TSTMP driver source code
* @version 0.1.0
* @date 2024-01-14
*
* @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd.
*
* @details
*/
/********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024-01-14 Flagchip0122 N/A FC7xxx internal release version
********************************************************************************/
#include "fc7xxx_driver_tstmp.h"
#include "interrupt_manager.h"
/** @brief Tstmp instance list */
static TSTMP_Type *s_pTstmpPtrs[TSTMP_INSTANCE_COUNT] = TSTMP_BASE_PTRS;
/** @brief Tstmp user defined interrupt function */
static TSTMP_InterruptCallBackType s_pTstmpModulateNotifyPtr[TSTMP_INSTANCE_COUNT][MAX_MOD_NUMBER] = {NULL};
/** @brief TSTMP0 interrupt entry */
void TSTMP0_IRQHandler(void);
/** @brief TSTMP1 interrupt entry */
void TSTMP1_IRQHandler(void);
/** @brief TSTMP common interrupt function */
static void Tstmp_CommonProcessInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eIntModulate);
/**
* @brief Initialize TSTMP instance
*
* @param eInstance TSTMP instance
* @param pInitStruct TSTMP initialization structure
* @return TSTMP_StatusType TSTMP return type
* @note TSTMP0 clock source is 1MHZ and TSTMP1,TSTMP2,TSTMP3 clock source is bus clock
*/
TSTMP_StatusType TSTMP_Init(const TSTMP_InstanceType eInstance, const TSTMP_InitType *const pInitStruct)
{
TSTMP_Type *pTstmp;
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
if ((NULL == pInitStruct) || (eInstance >= TSTMP_INSTANCE_MAX))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
/* clear MOD(n) match flag */
TSTMP_HWA_ClearMod0MatchFlag(pTstmp);
TSTMP_HWA_ClearAllMod123MatchFlag(pTstmp);
for(uint8_t i = 0; i < MAX_MOD_NUMBER; i++)
{
TSTMP_HWA_SelectClkSource(pTstmp, (TSTMP_ModulateType)i, pInitStruct->pClk[i]);
}
/* set MOD0 match value */
TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD0, pInitStruct->u32Modulate0Value);
/* set MOD1 match value */
TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD1, pInitStruct->u32Modulate1Value);
/* set MOD2 match value */
TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD2, pInitStruct->u32Modulate2Value);
/* set MOD3 match value */
TSTMP_HWA_SetModMatchValue(pTstmp, TSTMP_MOD3, pInitStruct->u32Modulate3Value);
}
return eRet;
}
/**
* @brief Set the Counting mode of modulate timer counter0,1,2,3
*
* @param eInstance TSTMP instance
* @param eCounter0Mode Counting mode of counter0
* @param eCounter1Mode Counting mode of counter1
* @param eCounter2Mode Counting mode of counter2
* @param eCounter3Mode Counting mode of counter3
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_SetCounterRunningMode(const TSTMP_InstanceType eInstance, const TSTMP_ModeCounterRunningMode eCounter0Mode,
const TSTMP_ModeCounterRunningMode eCounter1Mode,const TSTMP_ModeCounterRunningMode eCounter2Mode,
const TSTMP_ModeCounterRunningMode eCounter3Mode)
{
TSTMP_Type *pTstmp;
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
if (eInstance >= TSTMP_INSTANCE_MAX)
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
if( (eCounter0Mode > TSTMP_MODE_PERIOD_RUNNING) || (eCounter1Mode > TSTMP_MODE_PERIOD_RUNNING) ||
(eCounter2Mode > TSTMP_MODE_PERIOD_RUNNING) || (eCounter3Mode > TSTMP_MODE_PERIOD_RUNNING))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
if(eRet == TSTMP_STATUS_SUCCESS)
{
pTstmp = s_pTstmpPtrs[eInstance];
TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD0, eCounter0Mode);
TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD1, eCounter1Mode);
TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD2, eCounter2Mode);
TSTMP_HWA_SetModCounterMode(pTstmp,TSTMP_MOD3, eCounter3Mode);
}
return eRet;
}
/**
* @brief De-initialize TSTMP instance
*
* @param eInstance TSTMP instance
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_Deinit(const TSTMP_InstanceType eInstance)
{
TSTMP_Type *pTstmp;
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
uint8_t u8Index;
if (eInstance >= TSTMP_INSTANCE_MAX)
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
for (u8Index = 0U; u8Index < MAX_MOD_NUMBER; u8Index++)
{
/* Disable TSTMP MOD(n) match interrupt */
TSTMP_HWA_DisableModMatchInterrupt(pTstmp, (TSTMP_ModulateType)u8Index);
/* Disable TSTMP MOD(n) counter */
TSTMP_HWA_DisableModCounter(pTstmp, (TSTMP_ModulateType)u8Index);
/* Clear TSTMP MOD(n) match value set*/
TSTMP_HWA_SetModMatchValue(pTstmp, (TSTMP_ModulateType)u8Index, (uint32_t)0U);
s_pTstmpModulateNotifyPtr[eInstance][u8Index] = NULL;
}
/* clear MOD(n) match flag */
TSTMP_HWA_ClearMod0MatchFlag(pTstmp);
TSTMP_HWA_ClearAllMod123MatchFlag(pTstmp);
}
return eRet;
}
/**
* @brief Initialize TSTMP interrupt functionality
*
* @param eInstance TSTMP instance
* @param pIntStruct TSTMP interrupt structure
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_InitInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_IntType *const pIntStruct)
{
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
TSTMP_Type *pTstmp;
uint8_t u8Index;
if ((NULL == pIntStruct) || (eInstance >= TSTMP_INSTANCE_MAX))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
for (u8Index = 0U; u8Index < MAX_MOD_NUMBER; u8Index++)
{
if (pIntStruct->bModulateIntEn[u8Index] == true)
{
/* Enable TSTMP MOD(n) match interrupt */
TSTMP_HWA_EnableModMatchInterrupt(pTstmp, (TSTMP_ModulateType)u8Index);
s_pTstmpModulateNotifyPtr[eInstance][u8Index] = pIntStruct->pIsrModNotify[u8Index];
}
else
{
/* Disable TSTMP MOD(n) match interrupt */
TSTMP_HWA_DisableModMatchInterrupt(pTstmp, (TSTMP_ModulateType)u8Index);
s_pTstmpModulateNotifyPtr[eInstance][u8Index] = NULL;
}
}
}
return eRet;
}
/**
* @brief Enable TSTMP interrupt function
*
* @param eInstance TSTMP instance
* @param eMod TSTMP modulate enumeration
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_EnableInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eMod)
{
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
TSTMP_Type *pTstmp;
if (((uint8_t)eMod >= MAX_MOD_NUMBER) || (eInstance >= TSTMP_INSTANCE_MAX))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
/* Enable TSTMP MOD(n) match interrupt */
TSTMP_HWA_EnableModMatchInterrupt(pTstmp, eMod);
}
return eRet;
}
/**
* @brief Disable TSTMP interrupt function
*
* @param eInstance TSTMP instance
* @param eMod TSTMP modulate enumeration
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_DisableInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eMod)
{
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
TSTMP_Type *pTstmp;
if (((uint8_t)eMod >= MAX_MOD_NUMBER) || (eInstance >= TSTMP_INSTANCE_MAX))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
/* Disable TSTMP MOD(n) match interrupt */
TSTMP_HWA_DisableModMatchInterrupt(pTstmp, eMod);
}
return eRet;
}
/**
* @brief Get TSTMP count value
*
* @param eInstance TSTMP instance
* @param u64TstmpValue in/out value
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_GetTstmpValue(const TSTMP_InstanceType eInstance, uint64_t *const u64TstmpValue)
{
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
TSTMP_Type *pTstmp;
if ((NULL == u64TstmpValue) || (eInstance >= TSTMP_INSTANCE_MAX))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
*u64TstmpValue = TSTMP_HWA_ReadTstmpValue(pTstmp);
}
return eRet;
}
/**
* @brief Update Modulate configuration
*
* @param eInstance TSTMP instance
* @param pUpdateStruct TSTMP update structure pointer
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_UpdateMod(const TSTMP_InstanceType eInstance, const TSTMP_UpdateType *const pUpdateStruct)
{
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
TSTMP_Type *pTstmp;
bool bIntEnStatus;
if ((NULL == pUpdateStruct) || (eInstance >= TSTMP_INSTANCE_MAX))
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
/* Clear MOD(n) interrupt flag */
if (TSTMP_MOD0 == pUpdateStruct->eMod)
{
TSTMP_HWA_ClearMod0MatchFlag(pTstmp);
}
else
{
TSTMP_HWA_ClearSingleMod123MatchFlag(pTstmp, pUpdateStruct->eMod);
}
bIntEnStatus = (bool)(((uint32_t)0U == (TSTMP_HWA_ReadTstmpInterruptEnable(pTstmp) &
TSTMP_MOD_INTEN_MOD0_INTEN_MASK << (pUpdateStruct->eMod))) ? true : false);
if ((pUpdateStruct->bIntEn) == true)
{
if(bIntEnStatus == true)
{
/* Enable TSTMP MOD(n) match interrupt */
TSTMP_HWA_EnableModMatchInterrupt(pTstmp, pUpdateStruct->eMod);
if (NULL != pUpdateStruct->pIsrModNotify)
{
s_pTstmpModulateNotifyPtr[eInstance][pUpdateStruct->eMod] = pUpdateStruct->pIsrModNotify;
}
}
}else
{
if(bIntEnStatus == false)
{
/* Disable TSTMP MOD(n) match interrupt */
TSTMP_HWA_DisableModMatchInterrupt(pTstmp, pUpdateStruct->eMod);
}
}
/* set MOD(n) match value */
TSTMP_HWA_SetModMatchValue(pTstmp, pUpdateStruct->eMod, pUpdateStruct->u32ModValue);
}
return eRet;
}
/**
* @brief Set counter MOD(n) counting on or off
*
* @param eInstance TSTMP instance
* @param eMod MOD number
* @param bCounterEn Whether enable the selected Modulate Timer Counter
* @return TSTMP_StatusType TSTMP return type
*/
TSTMP_StatusType TSTMP_SetModCountConfig(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eMod, const bool bCounterEn)
{
TSTMP_StatusType eRet = TSTMP_STATUS_SUCCESS;
TSTMP_Type *pTstmp;
if (eInstance >= TSTMP_INSTANCE_MAX || eMod > TSTMP_MOD3)
{
eRet = TSTMP_STATUS_PARAM_INVALID;
}
else
{
pTstmp = s_pTstmpPtrs[eInstance];
if(bCounterEn)
{
TSTMP_HWA_EnableModCounter(pTstmp, eMod);
}else
{
TSTMP_HWA_DisableModCounter(pTstmp, eMod);
}
}
return eRet;
}
/**
* @brief TSTMP common interrupt function
*
* @param eInstance TSTMP instance
* @param eIntModulate TSTMP modulate
*/
static void Tstmp_CommonProcessInterrupt(const TSTMP_InstanceType eInstance, const TSTMP_ModulateType eIntModulate)
{
if (NULL != s_pTstmpModulateNotifyPtr[eInstance][eIntModulate])
{
s_pTstmpModulateNotifyPtr[eInstance][eIntModulate]();
}
}
/**
* @brief TSTMP0 interrupt handler entry
*
*/
void TSTMP0_IRQHandler(void)
{
uint32_t u32TstmpStatus = TSTMP_HWA_ReadModMatchFlag(TSTMP0);
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD0_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD0_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD0);
/* Clear MOD0 interrupt flag */
TSTMP_HWA_ClearMod0MatchFlag(TSTMP0);
}
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD1_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD1_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD1);
/* Clear MOD1 interrupt flag */
TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP0, TSTMP_MOD1);
}
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD2_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD2_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD2);
/* Clear MOD2 interrupt flag */
TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP0, TSTMP_MOD2);
}
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD3_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD3_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_0, TSTMP_MOD3);
/* Clear MOD3 interrupt flag */
TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP0, TSTMP_MOD3);
}
}
/**
* @brief TSTMP1 interrupt handler entry
*
*/
void TSTMP1_IRQHandler(void)
{
uint32_t u32TstmpStatus = TSTMP_HWA_ReadModMatchFlag(TSTMP1);
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD0_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD0_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD0);
/* Clear MOD0 interrupt flag */
TSTMP_HWA_ClearMod0MatchFlag(TSTMP1);
}
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD1_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD1_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD1);
/* Clear MOD1 interrupt flag */
TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP1, TSTMP_MOD1);
}
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD2_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD2_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD2);
/* Clear MOD2 interrupt flag */
TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP1, TSTMP_MOD2);
}
if ((u32TstmpStatus & TSTMP_MOD_STATUS_MOD3_MATCH_MASK)>>TSTMP_MOD_STATUS_MOD3_MATCH_SHIFT == 1U)
{
Tstmp_CommonProcessInterrupt(TSTMP_INSTANCE_1, TSTMP_MOD3);
/* Clear MOD3 interrupt flag */
TSTMP_HWA_ClearSingleMod123MatchFlag(TSTMP1, TSTMP_MOD3);
}
}