PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_cmp.c

325 lines
9.9 KiB
C

/**
* @file fc7xxx_driver_cmp.c
* @author Flagchip0126
* @brief FC7xxx CMP driver source code
* @version 0.1.0
* @date 2024-01-15
*
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
*
*/
/********************************************************************************
* Revision History:
*
* Version Date Author CR# Descriptions
* --------- ---------- ------------ ---------- ------------------------
* 0.1.0 2024-01-15 Flagchip0126 N/A First version for FC7240
**********************************************************************************/
#include "fc7xxx_driver_cmp.h"
#include "interrupt_manager.h"
/********* Local Variables ************/
static CMP_Type *const s_apCmpBase[CMP_INSTANCE_COUNT] = CMP_BASE_PTRS;
static CMP_CompleteIntCallback s_apCmpIntNotify[CMP_INSTANCE_COUNT] = {NULL};
/******* Local Function Prototype *********/
/**
* @brief set CMPn IRQHandler
*
* @param eInstance the CMP instance to use
*/
static void CMPn_IRQHandler(const CMP_InstanceType eInstance);
void CMP0_IRQHandler(void);
void CMP1_IRQHandler(void);
static void CMPn_IRQHandler(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
/*callback function*/
if (s_apCmpIntNotify[eInstance] != NULL)
{
s_apCmpIntNotify[eInstance]();
}
else
{
/*Noting to do*/
}
/*clear interrupter status regs*/
CMP_ClearIntFlag(eInstance);
}
void CMP0_IRQHandler(void)
{
CMPn_IRQHandler(CMP_INSTANCE_0);
}
void CMP1_IRQHandler(void)
{
CMPn_IRQHandler(CMP_INSTANCE_1);
}
/********* Local Functions ************/
void CMP_Enable(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_Enable(pCmp);
}
void CMP_Disable(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_Disable(pCmp);
}
void CMP_CSEnable(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_CSEnable(pCmp);
}
void CMP_CSDisable(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_CSDisable(pCmp);
}
bool CMP_GetCmpOut(const CMP_InstanceType eInstance)
{
bool CmpOut;
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CmpOut = CMP_HWA_GetCmpOut(pCmp);
return CmpOut;
}
void CMP_SetDacData(const CMP_InstanceType eInstance, uint8_t u8Data)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_SetDacData(pCmp, u8Data);
}
CMP_OutStatus CMP_GetOutFlagStatus(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
bool bCFF_Status = false;
bool bCFR_Status = false;
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_OutStatus eRetVal = CMP_OUT_NONE;
bCFF_Status = CMP_HWA_GetIntFlag_Falling(pCmp);
bCFR_Status = CMP_HWA_GetIntFlag_Rising(pCmp);
if ((bCFF_Status == true) && (bCFR_Status == false))
{
eRetVal = CMP_OUT_FALLING_EDGE;
}
else if ((bCFF_Status == false) && (bCFR_Status == true))
{
eRetVal = CMP_OUT_RISING_EDGE;
}
else
{
eRetVal = CMP_OUT_NONE;
}
return eRetVal;
}
bool CMP_GetChannelScanFlagStatus(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
bool bCSF_Status = false;
CMP_Type *const pCmp = s_apCmpBase[eInstance];
bCSF_Status = CMP_HWA_GetIntFlag_ChannelScan(pCmp);
return bCSF_Status;
}
void CMP_ClearIntFlag(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_ClearIntFlag_Rising(pCmp);
CMP_HWA_ClearIntFlag_Falling(pCmp);
CMP_HWA_ClearIntFlag_ChannelScan(pCmp);
}
void CMP_Init(const CMP_InstanceType eInstance, const CMP_InitType *const pInitCfg)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
DEV_ASSERT(pInitCfg != NULL);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
/* disable CMP module */
CMP_HWA_Disable(pCmp);
/* determine comparator function mode */
CMP_HWA_SetComparatorMod(pCmp, (pInitCfg->tComparatorConfig).eModSel, ((pInitCfg->tComparatorConfig).u8FilterPeriod), ((pInitCfg->tComparatorConfig).eFilterCnt));
/* configure CMP module */
/* CCR0 register */
CMP_HWA_SetEnStopMod(pCmp, (pInitCfg->tComparatorConfig).bStopModEn);
CMP_HWA_SetDacEnableSrc(pCmp, (pInitCfg->tDacConfig).eDacEnsrc);
/* CCR1 register */
CMP_HWA_SetCmpOutInvert(pCmp, (pInitCfg->tComparatorConfig).eInvert);
CMP_HWA_SetCmpOutSel(pCmp, (pInitCfg->tComparatorConfig).eOutSelect);
CMP_HWA_SetEnCmpOutPack(pCmp, (pInitCfg->tComparatorConfig).bOutToPackagePinEn);
CMP_HWA_SetCmpOutWinLevel(pCmp, (pInitCfg->tComparatorConfig).eOutWinLevel);
CMP_HWA_SetCmpOutWin(pCmp, (pInitCfg->tComparatorConfig).eOutWin);
CMP_HWA_SetEnWinSampleInvert(pCmp, (pInitCfg->tComparatorConfig).bWinSampleInvertEn);
CMP_HWA_SetEnEventCloseWin(pCmp, (pInitCfg->tComparatorConfig).bEventCloseWinEn);
CMP_HWA_SetEventCloseWin(pCmp, (pInitCfg->tComparatorConfig).eEventSelect);
/* CCR2 register */
CMP_HWA_SetSpeedMod(pCmp, (pInitCfg->tComparatorConfig).eSpeedMod);
CMP_HWA_SetHystCtrl(pCmp, (pInitCfg->tComparatorConfig).eHystCrtl);
CMP_HWA_SetPSelMux(pCmp, (pInitCfg->tMuxConfig).ePSelMux);
CMP_HWA_SetNSelMux(pCmp, (pInitCfg->tMuxConfig).eNSelMux);
CMP_HWA_SetINPSel(pCmp, (pInitCfg->tMuxConfig).eINPSel);
CMP_HWA_SetINNSel(pCmp, (pInitCfg->tMuxConfig).eINNSel);
/* CCR3 register */
CMP_HWA_SetAnalogConfTransByp(pCmp, (pInitCfg->tComparatorConfig).bAnalogConfTransByp);
CMP_HWA_SetAnalogConfTransBypCnt(pCmp, (pInitCfg->tComparatorConfig).u16AnalogConfTransBypCnt);
/* DCR register */
CMP_HWA_SetEnDac(pCmp, (pInitCfg->tDacConfig).bDacEn);
CMP_HWA_SetVinRefSel(pCmp, (pInitCfg->tDacConfig).eVinRefSel);
CMP_HWA_SetDacData(pCmp, (pInitCfg->tDacConfig).u8DacData);
if ((pInitCfg->tComparatorConfig).eModSel == CMP_MOD_CHANNEL_SCAN)
{
/* CSCR0 register */
CMP_HWA_SetCSInitModulus(pCmp, (pInitCfg->tChannelScanConfig).u8ChannelScanInitModulus);
CMP_HWA_SetCSNumOfSampleClocks(pCmp, (pInitCfg->tChannelScanConfig).u8ChannelScanNumOfSampleClocks);
/* CSCR1 register */
CMP_HWA_SetCSFixedChannel(pCmp, (pInitCfg->tMuxConfig).eChannelScanFixedChannel);
CMP_HWA_SetCSFixedPort(pCmp, (pInitCfg->tMuxConfig).eChannelScanFixedPort);
/* CSCSR register */
CMP_HWA_SetCSComparisonResultsAutoClearEn(pCmp, (pInitCfg->tChannelScanConfig).bComparisonResultAutoClear);
}
}
void CMP_InitInterrupt(const CMP_InstanceType eInstance, const CMP_InterruptType *const pInterruptCfg)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
DEV_ASSERT(pInterruptCfg != NULL);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
/*disable DMA*/
CMP_HWA_DmaDisable(pCmp);
/*clear interrupter flag*/
CMP_ClearIntFlag(eInstance);
/*configure interrupter */
CMP_SetIntEn(eInstance, pInterruptCfg);
s_apCmpIntNotify[eInstance] = pInterruptCfg->pInterrupterNotify;
}
void CMP_InitInterrupt_Dma(const CMP_InstanceType eInstance, const CMP_DmaType *const pInterruptDmaCfg)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
DEV_ASSERT(pInterruptDmaCfg != NULL);
CMP_InterruptType pInterruptCfg;
pInterruptCfg.bRisingIntEn = pInterruptDmaCfg->bRisingDmaEn;
pInterruptCfg.bFallingIntEn = pInterruptDmaCfg->bFallingDmaEn;
pInterruptCfg.bChannelScanFlagIntEn = false;
pInterruptCfg.pInterrupterNotify = NULL;
/* Set rising/falling edge interrupt to trigger Dma*/
CMP_SetIntEn(eInstance, &pInterruptCfg);
if ((pInterruptDmaCfg->bRisingDmaEn == true) || (pInterruptDmaCfg->bFallingDmaEn == true))
{
CMP_DmaEnable(eInstance);
}
else
{
CMP_DmaDisable(eInstance);
}
}
void CMP_SetIntEn(const CMP_InstanceType eInstance, const CMP_InterruptType *const pInterruptCfg)
{
CMP_Type *const pCmp = s_apCmpBase[eInstance];
/*set rising edges interrupter enable*/
CMP_HWA_SetIntEn_Rising(pCmp, pInterruptCfg->bRisingIntEn);
/*set falling edges interrupter enable*/
CMP_HWA_SetIntEn_Falling(pCmp, pInterruptCfg->bFallingIntEn);
/*set channel scan flag interrupter enable*/
CMP_HWA_SetIntEn_ChannelScan(pCmp, pInterruptCfg->bChannelScanFlagIntEn);
}
void CMP_DmaEnable(const CMP_InstanceType eInstance)
{
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_DmaEnable(pCmp);
}
void CMP_DmaDisable(const CMP_InstanceType eInstance)
{
CMP_Type *const pCmp = s_apCmpBase[eInstance];
CMP_HWA_DmaDisable(pCmp);
}
void CMP_SetCSChannls(const CMP_InstanceType eInstance, const CMP_ChannelScanChannelCfgType s_tChnCfg[], const uint8_t u8ChnCnt)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
uint8_t u8ChnIndex;
CMP_Type *const pCmp = s_apCmpBase[eInstance];
for (u8ChnIndex = 0U; u8ChnIndex < u8ChnCnt; u8ChnIndex++)
{
CMP_HWA_SetCSChannelEn(pCmp, s_tChnCfg[u8ChnIndex].eChannel, true);
CMP_HWA_SetCSChannelPresetstate(pCmp, s_tChnCfg[u8ChnIndex].eChannel, s_tChnCfg[u8ChnIndex].bPreSetState);
}
}
void CMP_GetCSChannlsOut(const CMP_InstanceType eInstance, CMP_ChannelScanChannelCfgType s_tChnCfg[], const uint8_t u8ChnCnt)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
uint8_t u8ChnIndex;
CMP_Type *const pCmp = s_apCmpBase[eInstance];
for (u8ChnIndex = 0U; u8ChnIndex < u8ChnCnt; u8ChnIndex++)
{
s_tChnCfg[u8ChnIndex].bCurState = CMP_HWA_GetCSChannelsOut(pCmp, s_tChnCfg[u8ChnIndex].eChannel);
}
}
bool CMP_GetCmpCSActive(const CMP_InstanceType eInstance)
{
DEV_ASSERT(eInstance < CMP_INSTANCE_COUNT);
CMP_Type *const pCmp = s_apCmpBase[eInstance];
return CMP_HWA_GetCSActive(pCmp);
}