/** * @file module_driver_adc.c * @author flagchip * @brief ADC driver source code * @version 2.0.0 * @date 2024-08-20 * * SDK Version: 2.6.0 * * @copyright Copyright (c) 2020-2024 Flagchip Semiconductors Co., Ltd. * */ /* ******************************************************************************** * Revision History: * * Version Date Initials CR# Descriptions * --------- ---------- ------------ ---------- --------------- * 0.1.0 2022-12-01 Flagchip030 N/A First version for FC7300 ******************************************************************************** */ #include "module_driver_adc.h" #if ADC_INSTANCE_COUNT > 0U #include "module_driver_scg.h" #include "module_driver_pcc.h" #ifndef ADC_DEV_ERROR_REPORT #define ADC_DEV_ERROR_REPORT STD_OFF #endif #if ADC_DEV_ERROR_REPORT == STD_ON #define ADC_ReportDevError(func, error) ReportDevError(ADC_MODULE_ID, func, error) #endif /** * @name ADC default values * @brief ADC default configuration parameters * * @{ */ #define ADC_DEFAULT_SAMPLE_TIME_OPTION_0 (0x04U) #define ADC_DEFAULT_SAMPLE_TIME_OPTION_1 (0x0AU) #define ADC_DEFAULT_SAMPLE_TIME_OPTION_2 (0x22U) #define ADC_DEFAULT_SAMPLE_TIME_OPTION_3 (0x82U) #define ADC_DEFAULT_WATER_MARK (0x10U) #define ADC_DEFAULT_CMP_HIGH_THRESHOLD (0x000U) #define ADC_DEFAULT_CMP_LOW_THRESHOLD (0x200U) /** @}*/ /********* Local Variables ************/ static ADC_Type *const s_apAdcBase[ADC_INSTANCE_COUNT] = ADC_BASE_PTRS; /******* Local Function Prototype *********/ /********* Local Functions ************/ /***************ADC IRQ Functions*****************/ void ADCn_IRQHandler(ADC_HandleType *pAdcHandle) { ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; uint8_t u8Index = 0; uint32_t u32UnusedFlags = 0; uint32_t u32RegVal = 0; bool bConvCompleted = false; #if ADC_SUPPORT_SG_MODE uint8_t u8SGIndex; uint8_t u8SGStart; uint8_t u8SGEnd; uint8_t u8BufferIndex; if (pAdcHandle->tSettings.eSeqMode == ADC_SEQMODE_GROUP) { for (u8SGIndex = 0U; u8SGIndex < ADC_GET_SUPPORTED_SEQUENCE_GROUP_CNT(pAdcHandle->eInstance); u8SGIndex++) { if (ADC_HWA_GetEndOfSGFlag(pAdc, u8SGIndex) && ADC_HWA_GetEndOfSGIntEnable(pAdc, u8SGIndex)) { ADC_HWA_ClearEndOfSGFlag(pAdc, u8SGIndex); u8SGStart = ADC_HWA_GetSGStartPoint(pAdc, u8SGIndex); u8SGEnd = ADC_HWA_GetSGEndPoint(pAdc, u8SGIndex); u8BufferIndex = 0; for (u8Index = u8SGStart; u8Index < u8SGEnd + 1U; u8Index++) { (pAdcHandle->tSettings).pSGResultBuffer[u8SGIndex][u8BufferIndex++] = ADC_HWA_GetChannelData(pAdc, u8Index); } if ((pAdcHandle->tSettings).SGConvCompleteNotify[u8SGIndex] != NULL) { (pAdcHandle->tSettings).SGConvCompleteNotify[u8SGIndex](pAdcHandle); } } } } else #endif if (pAdcHandle->tSettings.eSeqMode == ADC_SEQMODE_DISCONTINUOUS_1) { bConvCompleted = false; for (u8Index = 0U; u8Index < (pAdcHandle->tSettings).u8ChannelCnt; u8Index++) { if (ADC_HWA_GetChannelCoCoFlag(pAdc, u8Index) == false) { break; } else if (ADC_HWA_GetChannelCoCoIntEnable(pAdc, u8Index) == true) { bConvCompleted = true; } else {} } if (bConvCompleted) { for (u8Index = 0U; u8Index < (pAdcHandle->tSettings).u8ChannelCnt; u8Index++) { ((pAdcHandle->tSettings).pResultBuffer)[u8Index] = ADC_HWA_GetChannelData(pAdc, u8Index); } if ((pAdcHandle->tSettings).pConvCompleteNotify != NULL) { (pAdcHandle->tSettings).pConvCompleteNotify(pAdcHandle); } } } else { if (ADC_HWA_GetFIFOReadyFlag(pAdc) && ADC_HWA_GetFIFOReadyIntEnable(pAdc)) { for (u8Index = 0U; u8Index < (pAdcHandle->tSettings).u8ChannelCnt; u8Index++) { ((pAdcHandle->tSettings).pResultBuffer)[u8Index] = ADC_HWA_GetFIFOData(pAdc); } if ((pAdcHandle->tSettings).pConvCompleteNotify != NULL) { (pAdcHandle->tSettings).pConvCompleteNotify(pAdcHandle); } } } #if ADC_SUPPORT_ENHANCED_CMP_BLOCK if (ADC_IS_SUPPORT_ENHANCED_CMP_BLOCK(pAdcHandle->eInstance)) // Not all adc hardware support enhanced cmp interrupt, so this check is needed { for (u8Index = 0; u8Index < ADC_ENHANCED_CMP_BLOCK_CNT; u8Index++) { if (ADC_HWA_GetECMPHighFlag(pAdc, (ADC_ECMPIndex)u8Index) && ADC_HWA_GetECMPHighIntEnable(pAdc, (ADC_ECMPIndex)u8Index)) { ADC_HWA_ClearECMPHighFlag(pAdc, (ADC_ECMPIndex)u8Index); if ((pAdcHandle->tSettings).pECmpHighNotify[u8Index] != NULL) { (pAdcHandle->tSettings).pECmpHighNotify[u8Index](pAdcHandle); } } if (ADC_HWA_GetECMPLowFlag(pAdc, (ADC_ECMPIndex)u8Index) && ADC_HWA_GetECMPLowIntEnable(pAdc, (ADC_ECMPIndex)u8Index)) { ADC_HWA_ClearECMPLowFlag(pAdc, (ADC_ECMPIndex)u8Index); if ((pAdcHandle->tSettings).pECmpLowNotify[u8Index] != NULL) { (pAdcHandle->tSettings).pECmpLowNotify[u8Index](pAdcHandle); } } if (ADC_HWA_GetECMPWinFlag(pAdc, (ADC_ECMPIndex)u8Index) && ADC_HWA_GetECMPWinIntEnable(pAdc, (ADC_ECMPIndex)u8Index)) { ADC_HWA_ClearECMPWinFlag(pAdc, (ADC_ECMPIndex)u8Index); if ((pAdcHandle->tSettings).pECmpWinNotify[u8Index] != NULL) { (pAdcHandle->tSettings).pECmpWinNotify[u8Index](pAdcHandle); } } } } #endif #if ADC_SUPPORT_SG_CMP_BLOCK if (ADC_IS_SUPPORT_SG_CMP_BLOCK(pAdcHandle->eInstance)) // Not all adc hardware support sg cmp interrupt, so this check is needed { u8Index = pAdcHandle->eInstance - ADC_SUPPORT_SG_CMP_INSTANCE_START; if (SMC_HWA_ADCRES_GetSGCMP_FLAG(u8Index)) { u32RegVal = SMC_HWA_GetADCCFG0(u8Index); u32RegVal |= SMC_ADC_CFG0_SGCMP_FLAG_CLR_MASK; SMC_HWA_SetADCCFG0(u8Index, u32RegVal); if ((pAdcHandle->tSettings).pSGCmpNotify != NULL) { (pAdcHandle->tSettings).pSGCmpNotify(pAdcHandle); } } } #endif #if ADC_SUPPORT_FAST_CMP_BLOCK if (ADC_IS_SUPPORT_FAST_CMP_BLOCK(pAdcHandle->eInstance)) // Not all adc hardware support fast cmp interrupt, so this check is needed { if (ADC_HWA_GetFCRFFlag(pAdc) && ADC_HWA_GetFCRFIntEnable(pAdc)) { ADC_HWA_ClearFCRFFlag(pAdc); if ((pAdcHandle->tSettings).pFCmpFallingNotify != NULL) { (pAdcHandle->tSettings).pFCmpFallingNotify(pAdcHandle); } } if (ADC_HWA_GetFCRRFlag(pAdc) && ADC_HWA_GetFCRRIntEnable(pAdc)) { ADC_HWA_ClearFCRRFlag(pAdc); if ((pAdcHandle->tSettings).pFCmpRisingNotify != NULL) { (pAdcHandle->tSettings).pFCmpRisingNotify(pAdcHandle); } } } #endif if (ADC_HWA_GetOverrunFlag(pAdc) && ADC_HWA_GetOverrunIntEnable(pAdc)) { ADC_HWA_ClearOverrunFlag(pAdc); if ((pAdcHandle->tSettings).pOverrunNotify != NULL) { (pAdcHandle->tSettings).pOverrunNotify(pAdcHandle); } } if (ADC_HWA_GetCmpFlag(pAdc) && ADC_HWA_GetCmpIntEnable(pAdc)) { ADC_HWA_ClearCmpFlag(pAdc); if ((pAdcHandle->tSettings).pCmpNotify != NULL) { (pAdcHandle->tSettings).pCmpNotify(pAdcHandle); } } /* Clear unused flags */ u32UnusedFlags = ADC_INT_STATUS_ADRDY(1U) | ADC_INT_STATUS_EOSMP(1U) | \ ADC_INT_STATUS_EOC(1U); ADC_HWA_ClearFlags(pAdc, u32UnusedFlags); (void)u32RegVal; } /***************** Global Functions *********************/ void ADC_InitStructure(ADC_InitType *const pInitCfg) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pInitCfg == NULL) { ADC_ReportDevError(ADC_INIT_STRUCTURE_ID, ADC_E_PARAM_POINTER); } else { #endif pInitCfg->eResolution = ADC_RESOLUTION_12_BIT; /* 12 bit Resolution */ pInitCfg->eAlign = ADC_ALIGN_RIGHT; /* Align right */ pInitCfg->eTrgMode = ADC_TRGMODE_SW; /* Software trigger */ #if ADC_SUPPORT_PERIOD_TRIGGER pInitCfg->u16PeriodTrgInterval = 0U; /* Periodic trigger interval set to 0 */ #endif pInitCfg->bWaitEn = false; /* Enable wait conversion mode */ #if ADC_SUPPORT_SG_MODE pInitCfg->eTrgLatchUnitPri = ADC_TRG_LATCH_UNIT_PRI_ROUND_ROBIN; /* Round Robin priority */ #endif #if ADC_SUPPORT_GAIN_AND_OFFSET_CALIBRATION pInitCfg->bCalibrationEn = false; pInitCfg->s32CalibrationOffset = 0U; pInitCfg->s32CalibrationGain = 0U; #endif #if ADC_SUPPORT_INSTANCE_DIFFMODE_SET pInitCfg->bDifferentialModeEn = false; #endif pInitCfg->eClockDivider = ADC_CLOCK_DIV_1; pInitCfg->eSeqMode = ADC_SEQMODE_SINGLE; /* Single sequence mode */ pInitCfg->bAutoDis = false; /* Disable auto disable mode */ pInitCfg->eOverrunMode = ADC_OVERRUN_MODE_PRESERVE; /* Old conversion data preserved when overrun occured */ #if ADC_SUPPORT_INTERNAL_REFERENCE pInitCfg->eVoltageRef = ADC_REF_INTERNAL; /* Use internal reference */ #endif pInitCfg->bAverageEn = false; /* Disable averaging functionality */ pInitCfg->eAverageLen = ADC_AVERAGE_LEN_4; /* Average by 4 samples if average is enabled */ pInitCfg->aSampleTimes[0] = ADC_DEFAULT_SAMPLE_TIME_OPTION_0; /* Sample time option 0 is 4 ADC Clock */ pInitCfg->aSampleTimes[1] = ADC_DEFAULT_SAMPLE_TIME_OPTION_1; /* Sample time option 1 is 10 ADC Clock */ pInitCfg->aSampleTimes[2] = ADC_DEFAULT_SAMPLE_TIME_OPTION_2; /* Sample time option 2 is 34 ADC Clock */ pInitCfg->aSampleTimes[3] = ADC_DEFAULT_SAMPLE_TIME_OPTION_3; /* Sample time option 3 is 130 ADC Clock */ pInitCfg->bDmaEn = false; /* Disable DMA for the ADC */ #if ADC_SUPPORT_GROUP_INJECTION pInitCfg->bGroupInjectionEn = false; /* Disable group injection mode */ #endif pInitCfg->bConvCompleteIntEn = false; pInitCfg->bOverrunIntEn = false; pInitCfg->pConvCompleteNotify = NULL; pInitCfg->pOverrunNotify = NULL; pInitCfg->pResultBuffer = NULL; #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_Init(ADC_HandleType *pAdcHandle, const ADC_InitType *const pInitCfg) { #if ADC_DEV_ERROR_REPORT == STD_ON if ((pAdcHandle == NULL) || (pInitCfg == NULL)) { ADC_ReportDevError(ADC_INIT_ID, ADC_E_PARAM_POINTER); } else if (pAdcHandle->eInstance >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_INIT_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; uint8_t u8SmprIndex; uint32_t u32TimeOut; uint32_t u32Cfg1; uint32_t u32Cfg2; uint32_t u32IntCfg; #if ADC_SUPPORT_GAIN_AND_OFFSET_CALIBRATION uint32_t u32Cal; #endif #if ADC_SUPPORT_SG_MODE bool bSGEnable = false; #endif ADC_TrgSrcType eTrgSrc; ADC_TrgModeType eTrgMode; uint32_t u32ClkDiv; uint32_t u32StartupCnt; uint32_t u32ClkFreq; PCC_ClkSrcType eClkName; switch (pInitCfg->eSeqMode) { #if ADC_SUPPORT_SG_MODE case ADC_SEQMODE_GROUP: { bSGEnable = true; eTrgSrc = ADC_TRGSRC_TRG_LATCH_UNIT; eTrgMode = ADC_TRGMODE_RISING_EDGE; u32IntCfg = 0u; break; } #endif case ADC_SEQMODE_DISCONTINUOUS_1: { eTrgSrc = ADC_TRGSRC_PTIMER; eTrgMode = ADC_TRGMODE_RISING_EDGE; u32IntCfg = ADC_INT_ENABLE_OVRIE(pInitCfg->bOverrunIntEn); break; } case ADC_SEQMODE_SINGLE: case ADC_SEQMODE_CONTINUOUS: case ADC_SEQMODE_DISCONTINUOUS_0: { eTrgSrc = ADC_TRGSRC_TRGSEL; eTrgMode = pInitCfg->eTrgMode; u32IntCfg = ADC_INT_ENABLE_OVRIE(pInitCfg->bOverrunIntEn) | ADC_INT_ENABLE_FIFO_RDY_IE(pInitCfg->bConvCompleteIntEn); break; } default: { return; } } switch (pAdcHandle->eInstance) { case ADC_INSTANCE_0: { eClkName = PCC_CLK_ADC0; break; } case ADC_INSTANCE_1: { eClkName = PCC_CLK_ADC1; break; } #if ADC_INSTANCE_COUNT > 2u case ADC_INSTANCE_2: { eClkName = PCC_CLK_ADC2; break; } #endif #if ADC_INSTANCE_COUNT > 3u case ADC_INSTANCE_3: { eClkName = PCC_CLK_ADC3; break; } #endif #if ADC_INSTANCE_COUNT > 4u case ADC_INSTANCE_4: { eClkName = PCC_CLK_ADC4; break; } #endif #if ADC_INSTANCE_COUNT > 5u case ADC_INSTANCE_5: { eClkName = PCC_CLK_ADC5; break; } #endif default: { return; } } u32ClkDiv = 1U << pInitCfg->eClockDivider; u32ClkFreq = PCC_GetPccFunctionClock(eClkName); /* The start up count shall be around 5us */ u32StartupCnt = u32ClkFreq / u32ClkDiv / 1000000U * 5U + 1U; if (u32StartupCnt < 2U) { u32StartupCnt = 2U; } else if (u32StartupCnt > 255U) { u32StartupCnt = 255U; } else {} /* Deinitialize the ADC before config it's registers, ADC_DeInit function will reset the registers */ ADC_DeInit(pAdcHandle); u32Cfg1 = ADC_CFG1_OVRMOD(pInitCfg->eOverrunMode) | #if ADC_SUPPORT_SG_MODE ADC_CFG1_SEQGP_EN(bSGEnable) | #endif ADC_CFG1_SEQ_LEN(0) | ADC_CFG1_SEQ_MOD(pInitCfg->eSeqMode) | ADC_CFG1_AUTO_DIS(pInitCfg->bAutoDis) | ADC_CFG1_WAIT(pInitCfg->bWaitEn) | #if ADC_SUPPORT_INSTANCE_DIFFMODE_SET ADC_CFG1_DIFF(pInitCfg->bDifferentialModeEn) | #endif ADC_CFG1_TRIGSRC(eTrgSrc) | ADC_CFG1_TRIGMODE(eTrgMode) | ADC_CFG1_ALIGN(pInitCfg->eAlign) | ADC_CFG1_RES(pInitCfg->eResolution) | ADC_CFG1_DMAEN(pInitCfg->bDmaEn); ADC_HWA_SetConfig1(pAdc, u32Cfg1); u32Cfg2 = ADC_CFG2_FWMARK(ADC_DEFAULT_WATER_MARK) | #if ADC_SUPPORT_GROUP_INJECTION ADC_CFG2_SEQ_INJTEN(pInitCfg->bGroupInjectionEn) | #endif #if ADC_SUPPORT_SG_MODE ADC_CFG2_TRG_PRI(pInitCfg->eTrgLatchUnitPri) | ADC_CFG2_TRG_CLR(1U) | #endif ADC_CFG2_AVG_EN(pInitCfg->bAverageEn) | ADC_CFG2_AVG_LEN(pInitCfg->eAverageLen) | #if ADC_SUPPORT_INTERNAL_REFERENCE ADC_CFG2_REF_EXT(pInitCfg->eVoltageRef) | #endif ADC_CFG2_STCNT(u32StartupCnt); ADC_HWA_SetConfig2(pAdc, u32Cfg2); #if ADC_SUPPORT_PERIOD_TRIGGER ADC_HWA_SetPeriodTriggerInterval(pAdc, pInitCfg->u16PeriodTrgInterval); #endif #if ADC_SUPPORT_GAIN_AND_OFFSET_CALIBRATION u32Cal = ADC_CAL_CAL_EN(pInitCfg->bCalibrationEn) | ADC_CAL_OFFSET(pInitCfg->s32CalibrationOffset) | ADC_CAL_GAIN(pInitCfg->s32CalibrationGain); ADC_HWA_SetCal(pAdc, u32Cal); #endif u32TimeOut = 15000000U; ADC_HWA_SetClockGatingEnable(pAdc, true); while ((ADC_HWA_GetClockGatingAck(pAdc) != true) && (u32TimeOut != 0)) { u32TimeOut--; } if (ADC_HWA_GetClockGatingAck(pAdc) == true) { ADC_HWA_SetClockDivider(pAdc, pInitCfg->eClockDivider); } u32TimeOut = 15000000U; ADC_HWA_SetClockGatingEnable(pAdc, false); while ((ADC_HWA_GetClockGatingAck(pAdc) != false) && (u32TimeOut != 0)) { u32TimeOut--; } for (u8SmprIndex = 0U; u8SmprIndex < ADC_SAMPLE_TIME_OPTION_CNT; u8SmprIndex++) { ADC_HWA_SetSampleTime(pAdc, u8SmprIndex, (uint8_t)(pInitCfg->aSampleTimes[u8SmprIndex] - 2U)); } pAdcHandle->tSettings.eSeqMode = pInitCfg->eSeqMode; pAdcHandle->tSettings.bConvCompleteIntEn = pInitCfg->bConvCompleteIntEn; pAdcHandle->tSettings.pConvCompleteNotify = pInitCfg->pConvCompleteNotify; pAdcHandle->tSettings.pOverrunNotify = pInitCfg->pOverrunNotify; pAdcHandle->tSettings.pResultBuffer = pInitCfg->pResultBuffer; ADC_HWA_SetIntEnable(pAdc, u32IntCfg); #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_DeInit(ADC_HandleType *pAdcHandle) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL) { ADC_ReportDevError(ADC_DEINIT_ID, ADC_E_PARAM_POINTER); } else if (pAdcHandle->eInstance >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_DEINIT_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; uint32_t u32TimeOut = 15000000U; if (ADC_HWA_GetStart(pAdc) == true) { ADC_HWA_Stop(pAdc); while ((ADC_HWA_GetStop(pAdc) == true) && (u32TimeOut != 0U)) { u32TimeOut--; } } u32TimeOut = 15000000U; if (ADC_HWA_GetEnable(pAdc) == true) { ADC_HWA_Disable(pAdc); while ((ADC_HWA_GetEnable(pAdc) == true) && (u32TimeOut != 0U)) { u32TimeOut--; } } /* Reset all registers to default values */ ADC_HWA_Reset(pAdc); #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitChannel(ADC_HandleType *pAdcHandle, const ADC_ChannelCfgType aChannels[], const uint8_t u8ChannelCnt) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL || aChannels == NULL) { ADC_ReportDevError(ADC_INIT_CHANNEL_ID, ADC_E_PARAM_POINTER); } else if (pAdcHandle->eInstance >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_INIT_CHANNEL_ID, ADC_E_PARAM_INSTANCE); } else if (u8ChannelCnt >= ADC_SC_COUNT) { ADC_ReportDevError(ADC_INIT_CHANNEL_ID, ADC_E_PARAM_CHANNEL); } else if (u8ChannelCnt == 0u) { ADC_ReportDevError(ADC_INIT_CHANNEL_ID, ADC_E_PARAM_COUNT); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; uint8_t u8ChnIndex; pAdcHandle->tSettings.u8ChannelCnt = u8ChannelCnt; for (u8ChnIndex = 0U; u8ChnIndex < u8ChannelCnt; u8ChnIndex++) { #if ADC_SUPPORT_CHANNEL_DIFFMODE_SET ADC_HWA_SetChannelDiffModeEnable(pAdc, u8ChnIndex, aChannels[u8ChnIndex].bDiff); #endif ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8ChnIndex, aChannels[u8ChnIndex].eSampleTimeOption); ADC_HWA_SetChannelCoCoIntEnable(pAdc, u8ChnIndex, false); ADC_HWA_SetChannelInput(pAdc, u8ChnIndex, aChannels[u8ChnIndex].eChannel); } switch (pAdcHandle->tSettings.eSeqMode) { #if ADC_SUPPORT_SG_MODE case ADC_SEQMODE_GROUP: { /* TODO */ break; } #endif case ADC_SEQMODE_DISCONTINUOUS_1: { ADC_HWA_SetChannelCoCoIntEnable(pAdc, (uint8_t)(u8ChannelCnt - 1U), (pAdcHandle->tSettings).bConvCompleteIntEn); break; } case ADC_SEQMODE_SINGLE: case ADC_SEQMODE_CONTINUOUS: case ADC_SEQMODE_DISCONTINUOUS_0: { ADC_HWA_SetSequenceLength(pAdc, (uint8_t)(u8ChannelCnt - 1U)); ADC_HWA_SetFIFOWaterMark(pAdc, (uint8_t)(u8ChannelCnt - 1U)); break; } default: { break; } } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitCmpStructure(ADC_CmpType *const pCmpCfg) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pCmpCfg == NULL) { ADC_ReportDevError(ADC_INIT_CMP_STRUCTURE_ID, ADC_E_PARAM_POINTER); } else { #endif pCmpCfg->bCmpEn = false; pCmpCfg->bCmpIntEn = false; pCmpCfg->eCmpChannelType = ADC_CMP_CHANNEL_ALL; pCmpCfg->u8CmpChannelSel = 0U; pCmpCfg->u16CmpHighThres = ADC_DEFAULT_CMP_HIGH_THRESHOLD; pCmpCfg->u16CmpLowThres = ADC_DEFAULT_CMP_LOW_THRESHOLD; pCmpCfg->pCmpNotify = NULL; #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitCmp(ADC_HandleType *pAdcHandle, const ADC_CmpType *const pCmpCfg) { #if ADC_DEV_ERROR_REPORT == STD_ON if ((pCmpCfg == NULL) || (pAdcHandle == NULL)) { ADC_ReportDevError(ADC_INIT_CMP_ID, ADC_E_PARAM_POINTER); } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_INIT_CMP_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; if (pCmpCfg->bCmpEn) { ADC_HWA_SetCmpChannel(pAdc, pCmpCfg->eCmpChannelType, pCmpCfg->u8CmpChannelSel); ADC_HWA_SetCmpThreshold(pAdc, pCmpCfg->u16CmpLowThres, pCmpCfg->u16CmpHighThres); ADC_HWA_SetCmpIntEnable(pAdc, pCmpCfg->bCmpIntEn); pAdcHandle->tSettings.pCmpNotify = pCmpCfg->pCmpNotify; ADC_HWA_SetCmpEnable(pAdc, true); } else { ADC_HWA_SetCmpEnable(pAdc, false); } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } #if ADC_SUPPORT_SG_MODE void ADC_InitSGStrcuture(ADC_SGType *const pSGType) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pSGType == NULL) { ADC_ReportDevError(ADC_INIT_SG_STRUCTURE_ID, ADC_E_PARAM_POINTER); } else { #endif pSGType->bSG0En = false; pSGType->u8SG0Len = 0; pSGType->aSG0Channels = NULL; pSGType->bSG0ConvCompleteIntEn = false; pSGType->pSG0ResultBuffer = NULL; pSGType->pSG0ConvCompleteNotify = NULL; pSGType->bSG1En = false; pSGType->u8SG1Len = 0; pSGType->aSG1Channels = NULL; pSGType->bSG1ConvCompleteIntEn = false; pSGType->pSG1ResultBuffer = NULL; pSGType->pSG1ConvCompleteNotify = NULL; pSGType->bSG2En = false; pSGType->u8SG2Len = 0; pSGType->aSG2Channels = NULL; pSGType->bSG2ConvCompleteIntEn = false; pSGType->pSG2ResultBuffer = NULL; pSGType->pSG2ConvCompleteNotify = NULL; pSGType->bSG3En = false; pSGType->u8SG3Len = 0; pSGType->aSG3Channels = NULL; pSGType->bSG3ConvCompleteIntEn = false; pSGType->pSG3ResultBuffer = NULL; pSGType->pSG3ConvCompleteNotify = NULL; #if ADC_SUPPORT_SG_DMA_MODE pSGType->bSGDmaEn = false; pSGType->u8SGDMAIndex = 0; #endif #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitSG(ADC_HandleType *pAdcHandle, const ADC_SGType *const pSGType) { #if ADC_DEV_ERROR_REPORT == STD_ON if ((pSGType == NULL) || (pAdcHandle == NULL)) { ADC_ReportDevError(ADC_INIT_SG_ID, ADC_E_PARAM_POINTER); } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_INIT_SG_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; uint8_t u8ChnIndex; uint8_t u8SCnIndex; u8SCnIndex = 0; #if ADC_SUPPORT_SG_DMA_MODE uint32_t u32RegVal; if (pSGType->bSGDmaEn) { u32RegVal = ADC_HWA_GetConfig1(pAdc); u32RegVal &= ~ADC_CFG1_SGDMA_SEL_MASK; u32RegVal = ADC_CFG1_SGDMA_SEL(pSGType->u8SGDMAIndex) | ADC_CFG1_SGDMAEN(true); ADC_HWA_SetConfig1(pAdc, u32RegVal); } else { u32RegVal = ADC_HWA_GetConfig1(pAdc); u32RegVal &= ~(ADC_CFG1_SGDMA_SEL_MASK | ADC_CFG1_SGDMAEN_MASK); ADC_HWA_SetConfig1(pAdc, u32RegVal); } #endif if (pSGType->bSG0En) { ADC_HWA_SetSGStartEndPoint(pAdc, 0, 0, (uint8_t)(0 + pSGType->u8SG0Len - 1)); ADC_HWA_SetEndOfSGIntEnable(pAdc, 0, pSGType->bSG0ConvCompleteIntEn); pAdcHandle->tSettings.pSGResultBuffer[0] = pSGType->pSG0ResultBuffer; pAdcHandle->tSettings.SGConvCompleteNotify[0] = pSGType->pSG0ConvCompleteNotify; for (u8ChnIndex = 0U; u8ChnIndex < pSGType->u8SG0Len; u8ChnIndex++) { ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8SCnIndex, pSGType->aSG0Channels[u8ChnIndex].eSampleTimeOption); ADC_HWA_SetChannelCoCoIntEnable(pAdc, u8SCnIndex, false); ADC_HWA_SetChannelInput(pAdc, u8SCnIndex, pSGType->aSG0Channels[u8ChnIndex].eChannel); u8SCnIndex++; } } else { ADC_HWA_SetSGStartEndPoint(pAdc, 0, 0, 0); ADC_HWA_SetEndOfSGIntEnable(pAdc, 0, false); pAdcHandle->tSettings.pSGResultBuffer[0] = NULL; pAdcHandle->tSettings.SGConvCompleteNotify[0] = NULL; } if (pSGType->bSG1En) { ADC_HWA_SetSGStartEndPoint(pAdc, 1, u8SCnIndex, (uint8_t)(u8SCnIndex + pSGType->u8SG1Len - 1)); ADC_HWA_SetEndOfSGIntEnable(pAdc, 1, pSGType->bSG1ConvCompleteIntEn); pAdcHandle->tSettings.pSGResultBuffer[1] = pSGType->pSG1ResultBuffer; pAdcHandle->tSettings.SGConvCompleteNotify[1] = pSGType->pSG1ConvCompleteNotify; for (u8ChnIndex = 0U; u8ChnIndex < pSGType->u8SG1Len; u8ChnIndex++) { ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8SCnIndex, pSGType->aSG1Channels[u8ChnIndex].eSampleTimeOption); ADC_HWA_SetChannelCoCoIntEnable(pAdc, u8SCnIndex, false); ADC_HWA_SetChannelInput(pAdc, u8SCnIndex, pSGType->aSG1Channels[u8ChnIndex].eChannel); u8SCnIndex++; } } else { ADC_HWA_SetSGStartEndPoint(pAdc, 1, 0, 0); ADC_HWA_SetEndOfSGIntEnable(pAdc, 1, false); pAdcHandle->tSettings.pSGResultBuffer[1] = NULL; pAdcHandle->tSettings.SGConvCompleteNotify[1] = NULL; } if (ADC_GET_SUPPORTED_SEQUENCE_GROUP_CNT(pAdcHandle->eInstance) >= 2) { if (pSGType->bSG2En) { ADC_HWA_SetSGStartEndPoint(pAdc, 2, u8SCnIndex, (uint8_t)(u8SCnIndex + pSGType->u8SG2Len - 1)); ADC_HWA_SetEndOfSGIntEnable(pAdc, 2, pSGType->bSG2ConvCompleteIntEn); pAdcHandle->tSettings.pSGResultBuffer[2] = pSGType->pSG2ResultBuffer; pAdcHandle->tSettings.SGConvCompleteNotify[2] = pSGType->pSG2ConvCompleteNotify; for (u8ChnIndex = 0U; u8ChnIndex < pSGType->u8SG2Len; u8ChnIndex++) { ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8SCnIndex, pSGType->aSG2Channels[u8ChnIndex].eSampleTimeOption); ADC_HWA_SetChannelCoCoIntEnable(pAdc, u8SCnIndex, false); ADC_HWA_SetChannelInput(pAdc, u8SCnIndex, pSGType->aSG2Channels[u8ChnIndex].eChannel); u8SCnIndex++; } } else { ADC_HWA_SetSGStartEndPoint(pAdc, 2, 0, 0); ADC_HWA_SetEndOfSGIntEnable(pAdc, 2, false); pAdcHandle->tSettings.pSGResultBuffer[2] = NULL; pAdcHandle->tSettings.SGConvCompleteNotify[2] = NULL; } if (pSGType->bSG3En) { ADC_HWA_SetSGStartEndPoint(pAdc, 3, u8SCnIndex, (uint8_t)(u8SCnIndex + pSGType->u8SG3Len - 1)); ADC_HWA_SetEndOfSGIntEnable(pAdc, 3, pSGType->bSG3ConvCompleteIntEn); pAdcHandle->tSettings.pSGResultBuffer[3] = pSGType->pSG3ResultBuffer; pAdcHandle->tSettings.SGConvCompleteNotify[3] = pSGType->pSG3ConvCompleteNotify; for (u8ChnIndex = 0U; u8ChnIndex < pSGType->u8SG3Len; u8ChnIndex++) { ADC_HWA_SetChannelSampleTimeIndex(pAdc, u8SCnIndex, pSGType->aSG3Channels[u8ChnIndex].eSampleTimeOption); ADC_HWA_SetChannelCoCoIntEnable(pAdc, u8SCnIndex, false); ADC_HWA_SetChannelInput(pAdc, u8SCnIndex, pSGType->aSG3Channels[u8ChnIndex].eChannel); u8SCnIndex++; } } else { ADC_HWA_SetSGStartEndPoint(pAdc, 3, 0, 0); ADC_HWA_SetEndOfSGIntEnable(pAdc, 3, false); pAdcHandle->tSettings.pSGResultBuffer[3] = NULL; pAdcHandle->tSettings.SGConvCompleteNotify[3] = NULL; } } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } #endif ADC_StatusType ADC_Enable(const ADC_HandleType *pAdcHandle) { ADC_StatusType eRet = ADC_STATUS_SUCCESS; #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL) { ADC_ReportDevError(ADC_ENABLE_ID, ADC_E_PARAM_POINTER); eRet = ADC_STATUS_ERROR; } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_ENABLE_ID, ADC_E_PARAM_INSTANCE); eRet = ADC_STATUS_ERROR; } else { #endif uint32_t u32TimeOut = 15000000U; ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; ADC_HWA_Enable(pAdc); while ((ADC_HWA_GetADCReadyFlag(pAdc) != true) && (u32TimeOut != 0U)) { u32TimeOut--; } if (u32TimeOut != 0U) { ADC_HWA_ClearADCReadyFlag(pAdc); eRet = ADC_STATUS_SUCCESS; } else { eRet = ADC_STATUS_TIMEOUT; } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif return eRet; } ADC_StatusType ADC_Disable(ADC_HandleType *pAdcHandle) { ADC_StatusType eRet = ADC_STATUS_SUCCESS; #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL) { ADC_ReportDevError(ADC_DISABLE_ID, ADC_E_PARAM_POINTER); } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_DISABLE_ID, ADC_E_PARAM_INSTANCE); } else { #endif uint32_t u32TimeOut = 15000000U; ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; if (ADC_HWA_GetStart(pAdc) == true) { eRet = ADC_Stop(pAdcHandle); } if (eRet == ADC_STATUS_SUCCESS) { ADC_HWA_Disable(pAdc); while ((ADC_HWA_GetEnable(pAdc) == true) && (u32TimeOut != 0U)) { u32TimeOut--; } if (u32TimeOut != 0U) { eRet = ADC_STATUS_SUCCESS; } else { eRet = ADC_STATUS_TIMEOUT; } } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif return eRet; } void ADC_Start(const ADC_HandleType *pAdcHandle) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL) { ADC_ReportDevError(ADC_START_ID, ADC_E_PARAM_POINTER); } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_START_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; ADC_HWA_Start(pAdc); #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } ADC_StatusType ADC_Stop(const ADC_HandleType *pAdcHandle) { ADC_StatusType eRet = ADC_STATUS_ERROR; #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL) { ADC_ReportDevError(ADC_STOP_ID, ADC_E_PARAM_POINTER); } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_STOP_ID, ADC_E_PARAM_INSTANCE); } else { #endif uint32_t u32TimeOut = 15000000U; ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; ADC_HWA_Stop(pAdc); while ((ADC_HWA_GetStop(pAdc) == true) && (u32TimeOut != 0U)) { u32TimeOut--; } if (u32TimeOut != 0U) { eRet = ADC_STATUS_SUCCESS; } else { eRet = ADC_STATUS_TIMEOUT; } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif return eRet; } void ADC_Reset(const ADC_HandleType *pAdcHandle) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL) { ADC_ReportDevError(ADC_RESET_ID, ADC_E_PARAM_POINTER); } else if ((pAdcHandle->eInstance) >= ADC_INSTANCE_COUNT) { ADC_ReportDevError(ADC_RESET_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; ADC_HWA_Reset(pAdc); #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } #if ADC_SUPPORT_SG_CMP_BLOCK void ADC_InitSGCmpStructure(ADC_SGCmpType *const pConfig) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pConfig == NULL) { ADC_ReportDevError(ADC_SG_CMP_STRUCTURE_ID, ADC_E_PARAM_POINTER); } else { #endif pConfig->bSGCmpEn = false; pConfig->bSGCmpIntEn = false; pConfig->u32SGCmpREFSel = 0U; pConfig->u32SGCmpACTSel = 0U; pConfig->pSGCmpNotify = NULL; #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitSGCmp(ADC_HandleType *pAdcHandle, const ADC_SGCmpType *const pConfig) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL || pConfig == NULL) { ADC_ReportDevError(ADC_SG_CMP_ID, ADC_E_PARAM_POINTER); } else if (ADC_IS_SUPPORT_SG_CMP_BLOCK(pAdcHandle->eInstance)) { ADC_ReportDevError(ADC_SG_CMP_ID, ADC_E_PARAM_INSTANCE); } else { #endif uint32_t u32RegVal = 0U; uint8_t index; index = pAdcHandle->eInstance - ADC_SUPPORT_SG_CMP_INSTANCE_START; if (pConfig->bSGCmpEn) { u32RegVal = SMC_ADC_CFG0_SGCMP_EN(true) | \ SMC_ADC_CFG0_SGCMP_IEN(pConfig->bSGCmpIntEn) | \ SMC_ADC_CFG0_SGCMP_REF_SEL(pConfig->u32SGCmpREFSel & 0x0FFFFFFFU); SMC_HWA_SetADCCFG0(index, u32RegVal); u32RegVal = SMC_ADC_CFG1_SGCMP_ACT_SEL(pConfig->u32SGCmpACTSel & 0x0FFFFFFFU); SMC_HWA_SetADCCFG1(index, u32RegVal); pAdcHandle->tSettings.pSGCmpNotify = pConfig->pSGCmpNotify; } else { SMC_HWA_SetADCCFG0(index, 0x0); SMC_HWA_SetADCCFG1(index, 0x0); pAdcHandle->tSettings.pSGCmpNotify = NULL; } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } #endif /* #if ADC_SUPPORT_SG_CMP_BLOCK */ #if ADC_SUPPORT_ENHANCED_CMP_BLOCK void ADC_InitECmpStructure(ADC_ECmpType *const pConfig) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pConfig == NULL) { ADC_ReportDevError(ADC_INIT_ECMP_STRUCTURE_ID, ADC_E_PARAM_POINTER); } else { #endif pConfig->bECmpEn = false; pConfig->eECmpChannelType = ADC_ECMP_CHANNEL_ALL; pConfig->u8ECmpChannelSel = 0U; pConfig->u16ECmpHighThres = 0U; pConfig->u16ECmpLowThres = 0U; pConfig->bECmpHighIntEn = false; pConfig->bECmpLowIntEn = false; pConfig->bECmpWinIntEn = false; pConfig->pECmpHighNotify = NULL; pConfig->pECmpLowNotify = NULL; pConfig->pECmpWinNotify = NULL; #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitECmp(ADC_HandleType *pAdcHandle, const ADC_ECmpType *const pConfig, const ADC_ECMPIndex u8Index) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pAdcHandle == NULL || pConfig == NULL) { ADC_ReportDevError(ADC_INIT_ECMP_ID, ADC_E_PARAM_POINTER); } else if (ADC_IS_SUPPORT_ENHANCED_CMP_BLOCK(pAdcHandle->eInstance)) { ADC_ReportDevError(ADC_INIT_ECMP_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; if (pConfig->bECmpEn) { ADC_HWA_SetECMPOption(pAdc, u8Index, pConfig->eECmpOption); ADC_HWA_SetECMPSGL(pAdc, u8Index, pConfig->eECmpChannelType); ADC_HWA_SetECMPChannel(pAdc, u8Index, pConfig->u8ECmpChannelSel); ADC_HWA_SetECMPHighIntEnable(pAdc, u8Index, pConfig->bECmpHighIntEn); ADC_HWA_SetECMPLowIntEnable(pAdc, u8Index, pConfig->bECmpLowIntEn); ADC_HWA_SetECMPWinIntEnable(pAdc, u8Index, pConfig->bECmpWinIntEn); ADC_HWA_SetECMPThreshold(pAdc, u8Index, pConfig->u16ECmpLowThres, pConfig->u16ECmpHighThres); ADC_HWA_SetECMPEnable(pAdc, u8Index, true); pAdcHandle->tSettings.pECmpHighNotify[u8Index] = pConfig->pECmpHighNotify; pAdcHandle->tSettings.pECmpLowNotify[u8Index] = pConfig->pECmpLowNotify; pAdcHandle->tSettings.pECmpWinNotify[u8Index] = pConfig->pECmpWinNotify; } else { ADC_HWA_SetECMPEnable(pAdc, u8Index, false); } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } #endif /* #if ADC_SUPPORT_ENHANCED_CMP_BLOCK */ #if ADC_SUPPORT_FAST_CMP_BLOCK void ADC_InitFCmpStructure(ADC_FCmpType *const pFCmpCfg) { #if ADC_DEV_ERROR_REPORT == STD_ON if (pFCmpCfg == NULL) { ADC_ReportDevError(ADC_INIT_FCMP_STRUCTURE_ID, ADC_E_PARAM_POINTER); } else { #endif pFCmpCfg->bFCmpEn = false; pFCmpCfg->eFCmpChannel = ADC_CHANNEL_0; pFCmpCfg->eFCmpSampleTimeOption = ADC_SAMPLE_TIME_OPTION_0; pFCmpCfg->bFCmpPreSetResult = false; pFCmpCfg->u16FCmpRefValue = 0U; pFCmpCfg->u16FCmpUpperDelta = 0U; pFCmpCfg->u16FCmpLowerDelta = 0U; pFCmpCfg->eFCmpRefMode = ADC_FCMP_REFMODE_SW; pFCmpCfg->eFCmpRampDir = ADC_FCMP_RAMPDIR_UP; pFCmpCfg->eFCmpRampTrgMode = ADC_FCMP_RAMPTRGMODE_SW_AUTO; pFCmpCfg->eFCmpRampTrgPol = ADC_FCMP_RAMPTRGPOL_RISING_OR_HIGH; pFCmpCfg->u8FCmpRampStep = 0U; pFCmpCfg->u16FCmpRampRefA = 0U; pFCmpCfg->u16FCmpRampRefB = 0U; pFCmpCfg->bFCmpBFLEn = false; pFCmpCfg->eFCmpBFLAct = ADC_FCMP_BFA_A1B0; pFCmpCfg->bFCmpBFLInvert = false; pFCmpCfg->bFCmpFallingIntEn = false; pFCmpCfg->bFCmpRisingIntEn = false; pFCmpCfg->pFCmpRisingNotify = NULL; pFCmpCfg->pFCmpFallingNotify = NULL; #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } void ADC_InitFCmp(ADC_HandleType *pAdcHandle, const ADC_FCmpType *const pFCmpCfg) { #if ADC_DEV_ERROR_REPORT == STD_ON if ((pFCmpCfg == NULL) || (pAdcHandle == NULL)) { ADC_ReportDevError(ADC_INIT_FCMP_ID, ADC_E_PARAM_POINTER); } else if (ADC_IS_SUPPORT_FAST_CMP_BLOCK(pAdcHandle->eInstance)) { ADC_ReportDevError(ADC_INIT_FCMP_ID, ADC_E_PARAM_INSTANCE); } else { #endif ADC_Type *const pAdc = s_apAdcBase[pAdcHandle->eInstance]; uint32_t u32FCCTRL; uint32_t u32FCHyst; uint32_t u32FCRamp0; uint32_t u32FCRamp1; bool bFCModALT = false; bool bFCRampCntEn = false; if (pFCmpCfg->bFCmpEn == true) { if (pFCmpCfg->eFCmpRefMode == ADC_FCMP_REFMODE_SW) { bFCModALT = false; bFCRampCntEn = false; } else if(pFCmpCfg->eFCmpRefMode == ADC_FCMP_REFMODE_RAMP) { bFCModALT = false; bFCRampCntEn = true; } else if(pFCmpCfg->eFCmpRefMode == ADC_FCMP_REFMODE_ALT) { bFCModALT = true; bFCRampCntEn = false; } else { bFCModALT = false; bFCRampCntEn = false; } /* Config fast compare channel */ ADC_HWA_SetChannelSampleTimeIndex(pAdc, 0, pFCmpCfg->eFCmpSampleTimeOption); ADC_HWA_SetChannelCoCoIntEnable(pAdc, 0, false); ADC_HWA_SetChannelInput(pAdc, 0, pFCmpCfg->eFCmpChannel); ADC_HWA_SetSequenceLength(pAdc, 0U); ADC_HWA_SetFIFOWaterMark(pAdc, 0U); /* Disable fast compare function firstly. */ ADC_HWA_SetFCEnable(pAdc, false); ADC_HWA_SetFCRef(pAdc, pFCmpCfg->u16FCmpRefValue); u32FCRamp0 = ((pFCmpCfg->u16FCmpRampRefA << 16) | pFCmpCfg->u8FCmpRampStep); ADC_HWA_SetFCRamp0(pAdc, u32FCRamp0); u32FCRamp1 = ((pFCmpCfg->u16FCmpRampRefB << 16) | pFCmpCfg->eFCmpRampDir); ADC_HWA_SetFCRamp1(pAdc, u32FCRamp1); u32FCHyst = ((pFCmpCfg->u16FCmpUpperDelta << 16) | pFCmpCfg->u16FCmpLowerDelta); ADC_HWA_SetFCHysteresis(pAdc, u32FCHyst); /* Just write fast compare ctrl register after setting other fast compare function registers. */ u32FCCTRL = ADC_FCMP_CTRL_RPTRG_SEL(pFCmpCfg->eFCmpRampTrgMode) | ADC_FCMP_CTRL_RPCNT_EN(bFCRampCntEn) | ADC_FCMP_CTRL_ETRG_POL(pFCmpCfg->eFCmpRampTrgPol) | ADC_FCMP_CTRL_FCMOD_ALT(bFCModALT) | ADC_FCMP_CTRL_FC_EN(true); /* Enable fast compare function here. */ ADC_HWA_SetFCCtrl(pAdc, u32FCCTRL); if (pFCmpCfg->bFCmpFallingIntEn) { ADC_HWA_SetFCRFIntEnable(pAdc, true); pAdcHandle->tSettings.pFCmpFallingNotify = pFCmpCfg->pFCmpFallingNotify; } else { ADC_HWA_SetFCRFIntEnable(pAdc, false); pAdcHandle->tSettings.pFCmpFallingNotify = NULL; } if (pFCmpCfg->bFCmpRisingIntEn) { ADC_HWA_SetFCRRIntEnable(pAdc, true); pAdcHandle->tSettings.pFCmpRisingNotify = pFCmpCfg->pFCmpRisingNotify; } else { ADC_HWA_SetFCRRIntEnable(pAdc, false); pAdcHandle->tSettings.pFCmpRisingNotify = NULL; } } else { ADC_HWA_SetFCEnable(pAdc, false); pAdcHandle->tSettings.pFCmpFallingNotify = NULL; pAdcHandle->tSettings.pFCmpRisingNotify = NULL; } #if ADC_DEV_ERROR_REPORT == STD_ON } #endif } #endif /* #if ADC_SUPPORT_FAST_CMP_BLOCK */ #endif /* #if ADC_INSTANCE_COUNT > 0U */