/** ****************************************************************************** * @file tae32f53xx_ll_adc.c * @author MCD Application Team * @brief ADC LL module driver. * ****************************************************************************** @verbatim * ============================================================================== * ##### ADC peripheral features ##### * ============================================================================== * [..] * (+) Interrupt generation at the end of regular conversion and in case of * analog watchdog or overrun events. * * (+) Single and continuous conversion modes. * * (+) Scan mode for conversion of several channels sequentially. * * (+) Data alignment with in-built data coherency. * * (+) Programmable sampling time (channel wise) * * (+) External trigger (timer or EXTI) with configurable polarity * * (+) DMA request generation for transfer of conversions data of regular group. * * (+) Configurable delay between conversions in Dual interleaved mode. * * (+) ADC channels selectable single/differential input. * * (+) ADC calibration shared on 4 group offset & gain compensation instances. * * (+) ADC conversion of regular group. * * (+) ADC supply requirements: 1.62 V to 3.6 V. * * (+) ADC single input range: 0 to Vref. Vref is 3V * * (+) ADC Differential input range: from Vref- (connected to IN-) to Vref+ (connected to * IN+ or to an external voltage reference). @endverbatim * ****************************************************************************** * @attention * *

© Copyright (c) 2020 Tai-Action. * All rights reserved.

* * This software is licensed by Tai-Action under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "tae32f53xx_ll.h" #include "string.h" #include "stdlib.h" #define DBG_TAG "ADC LL" #define DBG_LVL DBG_ERROR #include "dbg/tae32f53xx_dbg.h" /** @addtogroup TAE32F53xx_LL_Driver * @{ */ /** @defgroup ADC_LL ADC LL * @brief ADC LL module driver * @{ */ #ifdef LL_ADC_MODULE_ENABLED /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /** @defgroup ADC_LL_Private_Variables ADC LL Private Variables * @brief ADC LL Private Variables * @{ */ /** * @brief ADC Calibration temp offset param */ volatile static int16_t temp_offset = 0; /** * @brief ADC Calibration temp gain param */ volatile static uint16_t temp_gain = 0; /** * @brief ADC Calibration Data struct param */ volatile ADC_CalibrationDataTypeDef pCoef = {0}; /** * @brief ADC Calibration Data static param */ static const uint32_t Calib_check_data[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; /** * @brief ADC Calibration read data array */ static uint32_t Calib_read_data[3] = {0}; /** * @} */ /* Private function prototypes -----------------------------------------------*/ /** @defgroup ADC_LL_Private_Functions ADC LL Private Functions * @brief ADC LL Private Functions * @{ */ static void LL_ADC_ReadCoef(void); static void LL_ADC_OverSamp_Mode(ADC_TypeDef *Instance, int16_t offset); /** * @} */ /* Exported functions --------------------------------------------------------*/ /** @defgroup ADC_LL_Exported_Functions ADC LL Exported Functions * @brief ADC LL Exported Functions * @{ */ /** @defgroup ADC_LL_Exported_Functions_Group1 Initialization and de-initialization functions * @brief Initialization and Configuration functions * @{ */ /** * @brief Initialize some features of ADC instance. * @note These parameters have an impact on ADC scope: ADC instance. * Affects both group regular and group injected * Refer to corresponding unitary functions into * @ref ADC_LL_EF_Configuration_ADC_Instance . * @note The setting of these parameters by function @ref LL_ADC_Init() * is conditioned to ADC state: * ADC instance must be disabled. * @param Instance ADC instance * @param ADC_InitStruct Pointer to a @ref ADC_REG_InitTypeDef structure * @retval An LL_StatusETypeDef enumeration value: * - SUCCESS: ADC registers are initialized * - ERROR: ADC registers are not initialized */ LL_StatusETypeDef LL_ADC_Init(ADC_TypeDef *Instance, ADC_InitTypeDef *ADC_InitStruct) { LL_StatusETypeDef status = LL_OK; /*hardware level Initialize*/ LL_ADC_MspInit(Instance); /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_SYNCHRONIZATION(ADC_InitStruct->Synchronization)); assert_param(IS_ADC_ANOLOGSET(ADC_InitStruct->AnologCfg)); assert_param(IS_ADC_OVR_DATA_BEHAVIOR(ADC_InitStruct->Overrun)); /*Check whether the SOC has been calibrated*/ LL_ADC_ReadCoef(); /* Note: Hardware constraint (refer to description of this function): */ /* ADC instance must be disabled. */ if (__LL_ADC_REG_IsConversionOngoing(Instance) == 0UL) { /* Configuration of ADC hierarchical scope: */ /* - ADC instance */ /* - Set ADC Synchronization */ MODIFY_REG(Instance->CR1, ADC_CR1_SYNCEN, ADC_InitStruct->Synchronization); //WRITE_REG(Instance->CR2, ADC_InitStruct->AnologCfg); /*only ADC0 valid paramter*/ //WRITE_REG(ADC0->CR2, ADC_InitStruct->AnologCfg); if (Instance == ADC0) { WRITE_REG(Instance->CR2, ADC_InitStruct->AnologCfg); } else if (Instance == ADC1) { /*only ADC0 valid paramter*/ WRITE_REG(Instance->CR2, ADC_InitStruct->AnologCfg); WRITE_REG(ADC0->CR2, ADC_InitStruct->AnologCfg); } while (!(Instance->ISR & BIT(8))); /* Configuration of Oversampler: */ /* - Oversampling Ratio */ /* - Right bit shift */ /* - Triggered mode */ /* - Oversampling mode (continued/resumed) */ if (ADC_InitStruct->RegOversampMode && !(ADC_InitStruct->InjOversampMode)) { SET_BIT(Instance->CR1, ADC_CR1_ROVSE); } else if (ADC_InitStruct->InjOversampMode && !(ADC_InitStruct->RegOversampMode)) { SET_BIT(Instance->CR1, ADC_CR1_JOVSE); } else { SET_BIT(Instance->CR1, ADC_CR1_ROVSE | ADC_CR1_JOVSE); } assert_param(IS_ADC_OVERSAMPMODE_SET(ADC_InitStruct->OverSampling.OverSampResetMode)); assert_param(IS_ADC_TRIGOVERSAMP(ADC_InitStruct->OverSampling.TrigOverSamp)); assert_param(IS_ADC_OVERSAMPSHIFT(ADC_InitStruct->OverSampling.OverSampShiftBit)); assert_param(IS_ADC_OVERSAMPRATIO(ADC_InitStruct->OverSampling.OverSampRatio)); MODIFY_REG(Instance->CR1, ADC_CR1_ROVSM | ADC_CR1_TROVS | ADC_CR1_OVSS | ADC_CR1_OVSR | ADC_CR1_OVRMOD , ADC_InitStruct->OverSampling.OverSampResetMode | ADC_InitStruct->OverSampling.TrigOverSamp | ADC_InitStruct->OverSampling.OverSampShiftBit | ADC_InitStruct->OverSampling.OverSampRatio | ADC_InitStruct->Overrun ); /*Normal interrupt config*/ WRITE_REG(Instance->IER, ADC_InitStruct->NormInterrupt); } else { /* Initialization error: ADC instance is not disabled. */ status = LL_ERROR; } return status; } /** * @brief De-initialize registers of the selected ADC instance * to their default reset values. * @note To reset all ADC instances quickly (perform a hard reset), * @note If this functions returns error status, it means that ADC instance * is in an unknown state. * In this case, perform a hard reset using high level * clock source RCC ADC reset. * @param Instance ADC instance * @retval An LL_StatusETypeDef enumeration value: * - SUCCESS: ADC registers are de-initialized * - ERROR: ADC registers are not de-initialized */ LL_StatusETypeDef LL_ADC_DeInit(ADC_TypeDef *Instance) { LL_StatusETypeDef status = LL_OK; assert_param(IS_ADC_ALL_INSTANCE(Instance)); /* Disable ADC instance if not already disabled. */ /* Set ADC group regular trigger source to SW start to ensure to not */ /* have an external trigger event occurring during the conversion stop */ /* ADC disable process. */ __LL_ADC_REG_SetTriggerSource(Instance, ADC_REG_TRIG_SOFTWARE); /* Stop potential ADC conversion on going on ADC group regular. */ if (__LL_ADC_REG_IsConversionOngoing(Instance) != 0UL) { if (__LL_ADC_REG_IsStopConversionOngoing(Instance) == 0UL) { __LL_ADC_REG_StopConversion(Instance); } } /* Set ADC group injected trigger source to SW start to ensure to not */ /* have an external trigger event occurring during the conversion stop */ /* ADC disable process. */ __LL_ADC_INJ_SetTriggerSource(Instance, ADC_INJ_TRIG_SOFTWARE); /* Stop potential ADC conversion on going on ADC group injected. */ if (__LL_ADC_INJ_IsConversionOngoing(Instance) != 0UL) { if (__LL_ADC_INJ_IsStopConversionOngoing(Instance) == 0UL) { __LL_ADC_INJ_StopConversion(Instance); } } /* Check whether ADC state is compliant with expected state */ if (READ_BIT(Instance->CR0, (ADC_CR0_JADSTP | ADC_CR0_ADSTP | ADC_CR0_JADSTART | ADC_CR0_ADSTART)) == 0UL) { /* ========== Reset ADC registers ========== */ /* Reset register IER */ CLEAR_BIT(Instance->IER, (ADC_IER_ADRDYIE | ADC_IER_EOCIE | ADC_IER_EOSIE | ADC_IER_OVRIE | ADC_IER_EOSMPIE | ADC_IER_JEOCIE | ADC_IER_JEOSIE | ADC_IER_AWD0IE | ADC_IER_AWD1IE | ADC_IER_AWD2IE ) ); /* Reset register ISR */ SET_BIT(Instance->ISR, (ADC_ISR_ADRDY | ADC_ISR_EOC | ADC_ISR_EOS | ADC_ISR_OVR | ADC_ISR_EOSMP | ADC_ISR_JEOC | ADC_ISR_JEOS | ADC_ISR_AWD0 | ADC_ISR_AWD1 | ADC_ISR_AWD2 ) ); /* Reset register SIER */ CLEAR_BIT(Instance->SIER, (ADC_SIER_CHANNEL)); /* Reset register SISR */ SET_BIT(Instance->SISR, (ADC_SISR_CHANNEL)); /* Reset register HIER */ CLEAR_BIT(Instance->HIER, (ADC_HIER_CHANNEL)); /* Reset register SISR */ SET_BIT(Instance->HISR, (ADC_HISR_CHANNEL)); /* Reset register SIER */ CLEAR_BIT(Instance->FIER, (ADC_FIER_CHANNEL)); /* Reset register SISR */ SET_BIT(Instance->FISR, (ADC_FISR_CHANNEL)); /* Reset register CR1 */ CLEAR_BIT(Instance->CR1, (ADC_CR1_SYNCEN | ADC_CR1_JAUTO | ADC_CR1_JDISCEN | ADC_CR1_DISCNUM | ADC_CR1_DISCEN | ADC_CR1_CONT | ADC_CR1_OVRMOD | ADC_CR1_ROVSM | ADC_CR1_TROVS | ADC_CR1_OVSS | ADC_CR1_OVSR | ADC_CR1_JOVSE | ADC_CR1_ROVSE) ); /* Reset register CR2 */ CLEAR_BIT(Instance->CR2, (ADC_CR2_ISEL | ADC_CR2_TBOMOD | ADC_CR2_TBIMOD | ADC_CR2_TB_EN | ADC_CR2_CH_EN | ADC_CR2_FADC_EN | ADC_CR2_REF_EN | ADC_CR2_BIAS_EN) ); /* Reset register DIFSEL */ CLEAR_BIT(Instance->DIFSEL, (ADC_DIFSEL_DIFSEL)); /* Reset register SMPR0 */ CLEAR_BIT(Instance->SMPR0, (ADC_SMPR0_SMP7 | ADC_SMPR0_SMP6 | ADC_SMPR0_SMP5 | ADC_SMPR0_SMP4 | ADC_SMPR0_SMP3 | ADC_SMPR0_SMP2 | ADC_SMPR0_SMP1 | ADC_SMPR0_SMP0) ); /* Reset register SMPR1 */ CLEAR_BIT(Instance->SMPR1, (ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10 | ADC_SMPR1_SMP9 | ADC_SMPR1_SMP8)); /* Reset register CALR0 */ CLEAR_BIT(Instance->SMPR0, (ADC_CALR0_CAL7 | ADC_CALR0_CAL6 | ADC_CALR0_CAL5 | ADC_CALR0_CAL4 | ADC_CALR0_CAL3 | ADC_CALR0_CAL2 | ADC_CALR0_CAL1 | ADC_CALR0_CAL0) ); /* Reset register CALR1 */ CLEAR_BIT(Instance->SMPR1, (ADC_CALR1_CAL11 | ADC_CALR1_CAL10 | ADC_CALR1_CAL9 | ADC_CALR1_CAL8)); /* Reset register AWD0CR TR0 */ CLEAR_BIT(Instance->AWDCR[0], ADC_AWD0CR_AWD0FILT | ADC_AWD0CR_AWD0CH); CLEAR_BIT(Instance->TR[0], ADC_TR0_HT0 | ADC_TR0_LT0); /* Reset register AWD1CR TR1 */ CLEAR_BIT(Instance->AWDCR[1], ADC_AWD1CR_AWD1FILT | ADC_AWD1CR_AWD1CH); CLEAR_BIT(Instance->TR[1], ADC_TR1_HT1 | ADC_TR1_LT1); /* Reset register AWD2CR TR2 */ CLEAR_BIT(Instance->AWDCR[2], ADC_AWD2CR_AWD2FILT | ADC_AWD2CR_AWD2CH); CLEAR_BIT(Instance->TR[2], ADC_TR2_HT2 | ADC_TR2_LT2); /* Reset register SQR0*/ CLEAR_BIT(Instance->SQR0, (ADC_SQR0_SQ8 | ADC_SQR0_SQ7 | ADC_SQR0_SQ6 | ADC_SQR0_SQ5 | ADC_SQR0_SQ4 | ADC_SQR0_SQ3 | ADC_SQR0_SQ2 | ADC_SQR0_SQ1) ); /* Reset register SQR1 */ CLEAR_BIT(Instance->SQR1, (ADC_SQR1_SQ16 | ADC_SQR1_SQ15 | ADC_SQR1_SQ14 | ADC_SQR1_SQ13 | ADC_SQR1_SQ12 | ADC_SQR1_SQ11 | ADC_SQR1_SQ10 | ADC_SQR1_SQ9) ); /* Reset register LR */ CLEAR_BIT(Instance->LR, (ADC_LR_LEN | ADC_LR_EXTEN | ADC_LR_EXTSEL)); /* Reset register JSQR */ CLEAR_BIT(Instance->JSQR, ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1); /* Reset register JLR */ CLEAR_BIT(Instance->JLR, (ADC_JLR_JLEN | ADC_JLR_JEXTSEL | ADC_JLR_JEXTEN)); /* Reset register DR */ /* Note: bits in access mode read only, no direct reset applicable */ /* Reset register OFR0 */ CLEAR_BIT(Instance->OFR[0], ADC_OFR0_OFFSET); /* Reset register OFR1 */ CLEAR_BIT(Instance->OFR[1], ADC_OFR1_OFFSET); /* Reset register OFR2 */ CLEAR_BIT(Instance->OFR[2], ADC_OFR2_OFFSET); /* Reset register OFR3 */ CLEAR_BIT(Instance->OFR[3], ADC_OFR3_OFFSET); /* Reset register GCR0 */ CLEAR_BIT(Instance->GCR[0], ADC_GCR0_GAIN); /* Reset register GCR1 */ CLEAR_BIT(Instance->GCR[1], ADC_GCR1_GAIN); /* Reset register GCR2 */ CLEAR_BIT(Instance->GCR[2], ADC_GCR2_GAIN); /* Reset register GCR3 */ CLEAR_BIT(Instance->GCR[3], ADC_GCR3_GAIN); /* Reset register DOFR0 */ CLEAR_BIT(Instance->DOFR[0], ADC_DOFR0_OFFSET); /* Reset register DOFR1 */ CLEAR_BIT(Instance->DOFR[1], ADC_DOFR1_OFFSET); /* Reset register DOFR2 */ CLEAR_BIT(Instance->DOFR[2], ADC_DOFR2_OFFSET); /* Reset register DOFR3 */ CLEAR_BIT(Instance->DOFR[3], ADC_DOFR3_OFFSET); /* Reset register DGCR0 */ CLEAR_BIT(Instance->DGCR[0], ADC_DGCR0_GAIN); /* Reset register DGCR1 */ CLEAR_BIT(Instance->DGCR[1], ADC_DGCR1_GAIN); /* Reset register DGCR2 */ CLEAR_BIT(Instance->DGCR[2], ADC_DGCR2_GAIN); /* Reset register DGCR3 */ CLEAR_BIT(Instance->DGCR[3], ADC_DGCR3_GAIN); /* Reset registers JDR1, JDR2, JDR3, JDR4 */ /* Note: bits in access mode read only, no direct reset applicable */ /* Reset register ECR0 */ CLEAR_BIT(Instance->ECR[0], ADC_ECR0_ADSRC | ADC_ECR0_PSRCU | ADC_ECR0_PSRCD | ADC_ECR0_AWD2SEL | ADC_ECR0_AWD1SEL | ADC_ECR0_AWD0SEL); /* Reset register ECR1 */ CLEAR_BIT(Instance->ECR[1], ADC_ECR1_ADSRC | ADC_ECR1_PSRCU | ADC_ECR1_PSRCD | ADC_ECR1_AWD2SEL | ADC_ECR1_AWD1SEL | ADC_ECR1_AWD0SEL); /* Reset register ECR2 */ CLEAR_BIT(Instance->ECR[2], ADC_ECR2_ADSRC | ADC_ECR2_PSRCU | ADC_ECR2_PSRCD | ADC_ECR2_AWD2SEL | ADC_ECR2_AWD1SEL | ADC_ECR2_AWD0SEL); /* Reset register ECR3 */ CLEAR_BIT(Instance->ECR[3], ADC_ECR3_ADSRC | ADC_ECR3_PSRCU | ADC_ECR3_PSRCD | ADC_ECR3_AWD2SEL | ADC_ECR3_AWD1SEL | ADC_ECR3_AWD0SEL); /* Reset register DMA_CR */ for (uint8_t i = 0; i < 12; i++) { CLEAR_BIT(Instance->DMA_CR[i].TCR, ADC_DMA_TCR_CIRC | ADC_DMA_TCR_STP | ADC_DMA_TCR_START); CLEAR_BIT(Instance->DMA_CR[i].TAR, ADC_DMA_TAR_ADDR); CLEAR_BIT(Instance->DMA_CR[i].TLR, ADC_DMA_TLR_LENG); } } else { /* ADC instance is in an unknown state */ /* Need to performing a hard reset of ADC instance, using high level */ /* clock source RCC ADC reset. */ status = LL_ERROR; } return status; } /** * @brief Initialize some features of ADC group regular. * @note These parameters have an impact on ADC scope: ADC group regular. * @note The setting of these parameters by function @ref LL_ADC_Init() * is conditioned to ADC state: * ADC instance must be disabled. * Each feature can be updated afterwards with a unitary function * and potentially with ADC in a different state than disabled, * refer to description of each function for setting * conditioned to ADC state. * @param Instance ADC instance * @param ADC_REG_InitStruct Pointer to a @ref ADC_REG_InitTypeDef structure * @retval An StatusETypeDef enumeration value: * - SUCCESS: ADC registers are initialized * - ERROR: ADC registers are not initialized */ LL_StatusETypeDef LL_ADC_REG_Init(ADC_TypeDef *Instance, ADC_REG_InitTypeDef *ADC_REG_InitStruct) { LL_StatusETypeDef status = LL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_CHANNEL(ADC_REG_InitStruct->Channel)); assert_param(IS_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource)); assert_param(IS_ADC_REG_SEQ_LENGTH(ADC_REG_InitStruct->SequencerLength)); assert_param(IS_ADC_REG_SEQ_POS(ADC_REG_InitStruct->SequencerPos)); if (ADC_REG_InitStruct->SequencerLength != ADC_REG_SEQ_LENGTH_1) { assert_param(IS_ADC_REG_SEQ_DISCONT(ADC_REG_InitStruct->SequencerDiscont)); } if (ADC_REG_InitStruct->Channel == ADC_CHANNEL_TEMPSENSOR) { /*Enable temperature sensor detection*/ __LL_SYSCTRL_CTRLReg_Unlock(SYSCTRL); __LL_SYSCTRL_ADCBuf_En(SYSCTRL); __LL_SYSCTRL_Reg_Lock(SYSCTRL); } assert_param(IS_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode)); assert_param(IS_ADC_REG_DIFFERSEL(ADC_REG_InitStruct->DifferSel)); assert_param(IS_ADC_REG_SAMPTIMCLK(ADC_REG_InitStruct->SampTimClk)); if (__LL_ADC_REG_IsConversionOngoing(Instance) == 0UL) { /* Configuration of ADC hierarchical scope: */ /* - ADC group regular */ /* - Set ADC group regular trigger source */ /* - Set ADC group regular sequencer length */ /* - Set ADC group regular sequencer discontinuous mode */ /* - Set ADC group regular continuous mode */ /* - Set ADC group regular overrun behavior */ /* Note: ADC trigger edge is set to value 0x0 by */ /* setting of trigger source to SW start. */ /* Set ADC group regular sequencer length */ if (ADC_REG_InitStruct->SequencerLength == ADC_REG_SEQ_LENGTH_1) { MODIFY_REG(Instance->LR, ADC_LR_EXTSEL | ADC_LR_EXTEN | ADC_LR_LEN , ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->SequencerLength ); MODIFY_REG(Instance->SQR0, ADC_SQR0_SQ1, ADC_REG_InitStruct->Channel ); } else { MODIFY_REG(Instance->LR, ADC_LR_EXTSEL | ADC_LR_EXTEN | ADC_LR_LEN , ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->SequencerLength ); if (ADC_REG_InitStruct->SequencerPos > 7) { MODIFY_REG(Instance->SQR1, (ADC_SQR1_SQ9 << ((ADC_REG_InitStruct->SequencerPos - 8U) << 2U)), (ADC_REG_InitStruct->Channel << ((ADC_REG_InitStruct->SequencerPos - 8U) << 2U)) ); } else { MODIFY_REG(Instance->SQR0, ADC_SQR0_SQ1 << (ADC_REG_InitStruct->SequencerPos << 2U), (ADC_REG_InitStruct->Channel << (ADC_REG_InitStruct->SequencerPos << 2U)) ); } } /*Continuous mode and discontinuous mode cannot be set to 1 at the same time*/ CLEAR_BIT(Instance->CR1, ADC_CR1_CONT | ADC_CR1_DISCEN); if (ADC_REG_InitStruct->ContinuousMode == ADC_REG_CONV_CONTINUOUS) { SET_BIT(Instance->CR1, ADC_CR1_CONT); } else { MODIFY_REG(Instance->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM | ADC_CR1_CONT , ADC_REG_InitStruct->SequencerDiscont | ADC_REG_InitStruct->ContinuousMode ); } /*Sampling time and calibration parameter set selection*/ if (ADC_REG_InitStruct->Channel > 7) { MODIFY_REG(Instance->SMPR1, ADC_SMPR1_SMP8 << ((ADC_REG_InitStruct->Channel - 8U) << 2U), ADC_REG_InitStruct->SampTimClk << ((ADC_REG_InitStruct->Channel - 8U) << 2U) ); } else { MODIFY_REG(Instance->SMPR0, ADC_SMPR0_SMP0 << (ADC_REG_InitStruct->Channel << 2U), ADC_REG_InitStruct->SampTimClk << (ADC_REG_InitStruct->Channel << 2U) ); } /*configure the channel sample interrupt*/ if (ADC_REG_InitStruct->SampInterrupt == ENABLE) { __LL_ADC_ENABLE_IT_DONE(Instance, ADC_REG_InitStruct->Channel); } else { __LL_ADC_DISABLE_IT_DONE(Instance, ADC_REG_InitStruct->Channel); } /*Differential single-end Offset/Gain setting*/ SET_BIT(Instance->DIFSEL, (ADC_DIFSEL_DIFSEL & (ADC_REG_InitStruct->DifferSel << ADC_REG_InitStruct->Channel))); } else { /* Initialization error: ADC instance is not disabled. */ status = LL_ERROR; } return status; } /** * @brief Initialize some features of ADC group injected. * @note These parameters have an impact on ADC scope: ADC group injected. * @note The setting of these parameters by function @ref LL_ADC_Init() * is conditioned to ADC state: * ADC instance must be disabled. * @note After using this function, other features must be configured * using LL unitary functions. * The minimum configuration remaining to be done is: * - Set ADC group injected sequencer: * map channel on the selected sequencer rank. * Refer to function @ref LL_ADC_INJ_SetSequencerRanks(). * @param Instance ADC instance * @param ADC_INJ_InitStruct Pointer to a @ref ADC_INJ_InitTypeDef structure * @retval An LL_StatusETypeDef enumeration value: * - SUCCESS: ADC registers are initialized * - ERROR: ADC registers are not initialized */ LL_StatusETypeDef LL_ADC_INJ_Init(ADC_TypeDef *Instance, ADC_INJ_InitTypeDef *ADC_INJ_InitStruct) { LL_StatusETypeDef status = LL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_CHANNEL(ADC_INJ_InitStruct->Channel)); assert_param(IS_ADC_INJ_JSEQ_POS(ADC_INJ_InitStruct->SequencerPos)); assert_param(IS_ADC_INJ_TRIG_SOURCE(ADC_INJ_InitStruct->TriggerSource)); assert_param(IS_ADC_INJ_SEQ_SCAN_LENGTH(ADC_INJ_InitStruct->SequencerLength)); assert_param(IS_ADC_INJ_SEQ_SCAN_DISCONT_MODE(ADC_INJ_InitStruct->SequencerDiscont)); assert_param(IS_ADC_INJ_TRIG_AUTO(ADC_INJ_InitStruct->TrigAuto)); /* Note: Hardware constraint (refer to description of this function): */ /* ADC instance must be disabled. */ if (__LL_ADC_INJ_IsConversionOngoing(Instance) == 0UL) { if (ADC_INJ_InitStruct->Channel == ADC_CHANNEL_TEMPSENSOR) { /*Enable temperature sensor detection*/ __LL_SYSCTRL_CTRLReg_Unlock(SYSCTRL); __LL_SYSCTRL_ADCBuf_En(SYSCTRL); __LL_SYSCTRL_Reg_Lock(SYSCTRL); } /* Configuration of ADC hierarchical scope: */ /* - ADC group injected */ /* - Set ADC group injected trigger source */ /* - Set ADC group injected sequencer length */ /* - Set ADC group injected sequencer discontinuous mode */ /* - Set ADC group injected conversion trigger: independent or */ /* from ADC group regular (injected auto ) */ MODIFY_REG(Instance->CR1, ADC_CR1_JDISCEN | ADC_CR1_JAUTO , ADC_INJ_InitStruct->SequencerDiscont | ADC_INJ_InitStruct->TrigAuto ); MODIFY_REG(Instance->JLR, ADC_JLR_JEXTSEL | ADC_JLR_JEXTEN | ADC_JLR_JLEN , ADC_INJ_InitStruct->TriggerSource | ADC_INJ_InitStruct->SequencerLength ); /*JSQR sequence position*/ MODIFY_REG(Instance->JSQR, (ADC_JSQR_JSQ1 << ADC_INJ_InitStruct->SequencerPos), ADC_INJ_InitStruct->Channel << ADC_INJ_InitStruct->SequencerPos); } else { /* Initialization error: ADC instance is not disabled. */ status = LL_ERROR; } return status; } /** * @brief Initializes the ADC MSP. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_MspInit(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_MspInit could be implemented in the user file */ } /** * @brief DeInitializes the ADC MSP * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_MspDeInit(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_MspDeInit could be implemented in the user file */ } /** * @} */ /** @defgroup ADC_LL_Exported_Functions_Group2 ADC Config Functions * @brief ADC Config Functions * @verbatim =============================================================================== ##### Peripheral Control functions ##### =============================================================================== [..] This section provides functions allowing to: (+) Configure the adc to ecu paramter (+) Configure the analog watchdog (+) Configure the DMA Transfer (+) Configure the calibration paramter (+) Configure the oversamping @endverbatim * * @{ */ /** * @brief Initialize some features of ADC and ECU linkage related register. * @note These parameters have an impact on ADC scope: ADC to ECU register ECR0~3. * @note The setting of these parameters by function @ref LL_ADC_Init() * is conditioned to ADC state: * ADC instance must be disabled. * @param Instance ADC instance * @param ADC_ECU_Config Pointer to a @ref ADC_ECU_Config structure * @retval An LL_StatusETypeDef enumeration value: * - SUCCESS: ADC registers are initialized * - ERROR: ADC registers are not initialized */ LL_StatusETypeDef LL_ADC_ECU_Config(ADC_TypeDef *Instance, ADC_ECUConfTypeDef *ADC_ECU_Config) { LL_StatusETypeDef status = LL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_ECU_GROUPSEL(ADC_ECU_Config->GroupSel)); assert_param(IS_ADC_CHANNEL(ADC_ECU_Config->AddrDataSel)); assert_param(IS_ADC_CHANNEL(ADC_ECU_Config->AWD0SourceSel)); assert_param(IS_ADC_CHANNEL(ADC_ECU_Config->AWD1SourceSel)); assert_param(IS_ADC_CHANNEL(ADC_ECU_Config->AWD2SourceSel)); assert_param(IS_ADC_REG_AWD_SEL(ADC_ECU_Config->PingPongUpZero)); assert_param(IS_ADC_REG_AWD_SEL(ADC_ECU_Config->PingPongDownZero)); /* Note: Hardware constraint (refer to description of this function): */ /* ADC instance must be disabled. */ if (__LL_ADC_REG_IsConversionOngoing(Instance) == 0UL) { /* Configuration of ADC hierarchical scope: */ /* - ADC to ECU control paramter */ /* - Set ADC address data flag */ /* - Set ADC ping pong up zero anolog watchdog */ /* - Set ADC ping pong down zero anolog watchdog */ /* - Set ADC anolog watchdog x detected channel */ MODIFY_REG(Instance->ECR[ADC_ECU_Config->GroupSel], ADC_ECR0_ADSRC | ADC_ECR0_PSRCU | ADC_ECR0_PSRCD | ADC_ECR0_AWD2SEL | ADC_ECR0_AWD1SEL | ADC_ECR0_AWD0SEL , (ADC_ECU_Config->AddrDataSel << 16U) | (ADC_ECU_Config->PingPongUpZero << 14U) | (ADC_ECU_Config->PingPongDownZero << 12U) | (ADC_ECU_Config->AWD2SourceSel << 8U) | (ADC_ECU_Config->AWD1SourceSel << 4U) | ADC_ECU_Config->AWD0SourceSel ); } else { /* Initialization error: ADC instance is not disabled. */ status = LL_ERROR; } return status; } /** * @brief Configure the analog watchdog. * @note Possibility to update parameters on the fly: * This function initializes the selected analog watchdog, successive * calls to this function can be used to reconfigure some parameters * of structure "ADC_AnalogWDGCfgTypeDef" on the fly, without resetting * the ADC. * The same watchdog can monitor multiple channels simultaneously. * @param Instance ADC instance * @param AnalogWDGConfig Structure of ADC analog watchdog configuration * @retval LL status */ LL_StatusETypeDef LL_ADC_AnalogWDGConfig(ADC_TypeDef *Instance, ADC_AnalogWDGCfgTypeDef *AnalogWDGConfig) { LL_StatusETypeDef status = LL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_REG_AWD_SEL(AnalogWDGConfig->WatchdogNumber)); assert_param(IS_ADC_AWD_CHANNEL(AnalogWDGConfig->Channel)); assert_param(IS_ADC_REG_AWD_FILTER(AnalogWDGConfig->Filtering)); /* - Analog watchdog channels */ if ((__LL_ADC_REG_IsConversionOngoing(Instance) == 0UL) && (__LL_ADC_INJ_IsConversionOngoing(Instance) == 0UL)) { /* Configuration of analog watchdog:*/ /* Set the filtering \ channel configuration */ MODIFY_REG(Instance->AWDCR[AnalogWDGConfig->WatchdogNumber], ADC_AWD0CR_AWD0CH | ADC_AWD0CR_AWD0FILT, (AnalogWDGConfig->Channel) | (AnalogWDGConfig->Filtering) ); /* Set the watchdog high and low threshold */ MODIFY_REG(Instance->TR[AnalogWDGConfig->WatchdogNumber], ADC_TR0_HT0 | ADC_TR0_LT0, (AnalogWDGConfig->LowThreshold & ADC_TR0_LT0) | ((AnalogWDGConfig->HighThreshold & ADC_TR0_LT0) << ADC_TR0_HT0_Pos) ); } else { status = LL_ERROR; } return status; } /** * @brief Configure the DMA transfer. * @note Possibility to update parameters on the fly: * This function initializes the selected channel, * Only one channel can be configured at a time. * You cannot use the same address for different channels. * @param Instance ADC instance * @param DMATransferConfig Structure of ADC DMA transfer configuration * @retval LL status */ LL_StatusETypeDef LL_ADC_DMATransferConfig(ADC_TypeDef *Instance, ADC_DMATransferCfgTypeDef *DMATransferConfig) { LL_StatusETypeDef status = LL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_CHANNEL(DMATransferConfig->Channel)); assert_param(IS_ADC_REG_DMA_TRANSFER(DMATransferConfig->TransferMode)); /* - DMA Transfer channels */ if ((__LL_ADC_REG_IsConversionOngoing(Instance) == 0UL) && (__LL_ADC_INJ_IsConversionOngoing(Instance) == 0UL)) { MODIFY_REG(Instance->DMA_CR[DMATransferConfig->Channel].TAR, ADC_DMA_TAR_ADDR, (DMATransferConfig->Address) ); MODIFY_REG(Instance->DMA_CR[DMATransferConfig->Channel].TLR, ADC_DMA_TLR_LENG, (DMATransferConfig->Length) ); MODIFY_REG(Instance->DMA_CR[DMATransferConfig->Channel].TCR, ADC_DMA_TCR_START | ADC_DMA_TCR_CIRC, (DMATransferConfig->TransferMode) ); if (DMATransferConfig->HalfInterrupt == ENABLE) { __LL_ADC_ENABLE_IT_HALF(Instance, DMATransferConfig->Channel); } else { __LL_ADC_DISABLE_IT_HALF(Instance, DMATransferConfig->Channel); } if (DMATransferConfig->FullInterrupt == ENABLE) { __LL_ADC_ENABLE_IT_FULL(Instance, DMATransferConfig->Channel); } else { __LL_ADC_DISABLE_IT_FULL(Instance, DMATransferConfig->Channel); } } else { status = LL_ERROR; } return status; } /** * @brief Configure the calibration parameters. * @note Possibility to update parameters on the fly: * This function initializes the selected channel, * A total of four sets of calibration parameters can be selected for 12 channels. * @param Instance ADC instance * @param CalibrationConfig Structure of ADC DMA transfer configuration * @retval LL status */ LL_StatusETypeDef LL_ADC_CalibrationConfig(ADC_TypeDef *Instance, ADC_CalibrationTypeDef *CalibrationConfig) { LL_StatusETypeDef status = LL_OK; temp_offset = 0; temp_gain = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(Instance)); assert_param(IS_ADC_CHANNEL(CalibrationConfig->Channel)); assert_param(IS_LL_ADC_CALCOEFSEL(CalibrationConfig->CalibrationGroup)); /* Determine if the ADC is started */ if ((__LL_ADC_REG_IsConversionOngoing(Instance) == 0UL) && (__LL_ADC_INJ_IsConversionOngoing(Instance) == 0UL)) { __LL_ADC_SetCalGroup(Instance, CalibrationConfig->Channel, CalibrationConfig->CalibrationGroup); /*Determines whether the selected channel is single-ended or differential*/ if (__LL_ADC_GetChannelSingleDiff(Instance, CalibrationConfig->Channel)) { temp_offset = (int16_t)(pCoef.DiffOffset + (((int32_t)CalibrationConfig->Offset << 13) / pCoef.DiffGain)); temp_gain = (uint16_t)((uint32_t)(CalibrationConfig->Gain * pCoef.DiffGain) >> 13); LL_ADC_OverSamp_Mode(Instance, temp_offset); MODIFY_REG(Instance->DOFR[CalibrationConfig->CalibrationGroup], ADC_DOFR0_OFFSET, (temp_offset) ); MODIFY_REG(Instance->DGCR[CalibrationConfig->CalibrationGroup], ADC_DGCR0_GAIN, (temp_gain) ); } else { temp_offset = (int16_t)(pCoef.SingleOffset + (((int32_t)CalibrationConfig->Offset << 13) / pCoef.SingleGain)); temp_gain = (uint16_t)((uint32_t)(CalibrationConfig->Gain * pCoef.SingleGain) >> 13); LL_ADC_OverSamp_Mode(Instance, temp_offset); MODIFY_REG(Instance->OFR[CalibrationConfig->CalibrationGroup], ADC_OFR0_OFFSET, (temp_offset) ); MODIFY_REG(Instance->GCR[CalibrationConfig->CalibrationGroup], ADC_GCR0_GAIN, (temp_gain) ); } } else { status = LL_ERROR; } return status; } /** * @brief Convert to actual degrees Celsius * @note Temperature = (Vout - 1.34) / 0.005 * @retval LL status */ float LL_ADC_TemperatureCovert(uint16_t voltage_data) { float voltage_realvalue = 0; float temper_realvalue = 0; voltage_realvalue = (3.0 * voltage_data * 1000) / 8192.0; temper_realvalue = (voltage_realvalue - 1340) / 5; return temper_realvalue; } /** * @} */ /** @defgroup ADC_LL_Exported_Functions_Interrupt Interrupt handler and call back * @brief Interrupt handler and call back * @{ */ /** * @brief ADC Ready detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_AdRdyCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_AdRdyCallback could be implemented in the user file */ } /** * @brief ADC EoSmp detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_EosmpCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_EoSmpCallback could be implemented in the user file */ } /** * @brief ADC Anolog WatchDog 2 detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_AnologWD2Callback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_AnologWD2Callback could be implemented in the user file */ } /** * @brief ADC Anolog WatchDog 1 detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_AnologWD1Callback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_AnologWD1Callback could be implemented in the user file */ } /** * @brief ADC Anolog WatchDog 0 detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_AnologWD0Callback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_AnologWD0Callback could be implemented in the user file */ } /** * @brief ADC OverRun detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_OverRunCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_OverRunCallback could be implemented in the user file */ } /** * @brief ADC injected end of sequencer detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_JeosCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_JeosCallback could be implemented in the user file */ } /** * @brief ADC regular end of sequencer detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_EosCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_EosCallback could be implemented in the user file */ } /** * @brief ADC injected end of conversion detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_JeocCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_JeocCallback could be implemented in the user file */ } /** * @brief ADC regualr end of conversion detection callback. * @param Instance ADC instance * @return None */ __WEAK void LL_ADC_EocCallback(ADC_TypeDef *Instance) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_EocCallback could be implemented in the user file */ } /** * @brief ADC Sample done detection callback. * @param Instance ADC instance * @param Channel 0~11 * @return None */ __WEAK void LL_ADC_SampCallback(ADC_TypeDef *Instance, uint8_t Channel) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_SampCallback could be implemented in the user file */ } /** * @brief ADC DMA Half detection callback. * @param Instance ADC instance * @param Channel 0~11 * @return None */ __WEAK void LL_ADC_HalfCallback(ADC_TypeDef *Instance, uint8_t Channel) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_HalfCallback could be implemented in the user file */ } /** * @brief ADC DMA Full detection callback. * @param Instance ADC instance * @param Channel 0~11 * @return None */ __WEAK void LL_ADC_FullCallback(ADC_TypeDef *Instance, uint8_t Channel) { /* Prevent unused argument(s) compilation warning */ LL_UNUSED(Instance); /* NOTE: This function should not be modified, when the callback is needed, the LL_ADC_FullCallback could be implemented in the user file */ } /** * @brief This function handles ADC Normal interrupts requests. * @param Instance ADC instance * @return None */ void LL_ADC_NORM_IRQHandler(ADC_TypeDef *Instance) { if ((__LL_ADC_GET_IT_ADRDY(Instance)) && (__LL_ADC_GET_FLAG_ADRDY(Instance))) { __LL_ADC_CLEAR_FLAG_ADRDY(Instance); /*Handle something*/ LL_ADC_AdRdyCallback(Instance); } if ((__LL_ADC_GET_IT_EOSMP(Instance)) && (__LL_ADC_GET_FLAG_EOSMP(Instance))) { __LL_ADC_CLEAR_FLAG_EOSMP(Instance); /*Handle something*/ LL_ADC_EosmpCallback(Instance); } if ((__LL_ADC_GET_IT_AWD2(Instance)) && (__LL_ADC_GET_FLAG_AWD2(Instance))) { __LL_ADC_CLEAR_FLAG_AWD2(Instance); /*Handle something*/ LL_ADC_AnologWD2Callback(Instance); } if ((__LL_ADC_GET_IT_AWD1(Instance)) && (__LL_ADC_GET_FLAG_AWD1(Instance))) { __LL_ADC_CLEAR_FLAG_AWD1(Instance); /*Handle something*/ LL_ADC_AnologWD1Callback(Instance); } if ((__LL_ADC_GET_IT_AWD0(Instance)) && (__LL_ADC_GET_FLAG_AWD0(Instance))) { __LL_ADC_CLEAR_FLAG_AWD0(Instance); /*Handle something*/ LL_ADC_AnologWD0Callback(Instance); } if ((__LL_ADC_GET_IT_OVR(Instance)) && (__LL_ADC_GET_FLAG_OVR(Instance))) { __LL_ADC_CLEAR_FLAG_OVR(Instance); /*Handle something*/ LL_ADC_OverRunCallback(Instance); } if ((__LL_ADC_GET_IT_JEOS(Instance)) && (__LL_ADC_GET_FLAG_JEOS(Instance))) { __LL_ADC_CLEAR_FLAG_JEOS(Instance); /*Handle something*/ LL_ADC_JeosCallback(Instance); } if ((__LL_ADC_GET_IT_JEOC(Instance)) && (__LL_ADC_GET_FLAG_JEOC(Instance))) { __LL_ADC_CLEAR_FLAG_JEOC(Instance); /*Handle something*/ LL_ADC_JeocCallback(Instance); } if ((__LL_ADC_GET_IT_EOS(Instance)) && (__LL_ADC_GET_FLAG_EOS(Instance))) { __LL_ADC_CLEAR_FLAG_EOS(Instance); /*Handle something*/ LL_ADC_EosCallback(Instance); } if ((__LL_ADC_GET_IT_EOC(Instance)) && (__LL_ADC_GET_FLAG_EOC(Instance))) { __LL_ADC_CLEAR_FLAG_EOC(Instance); /*Handle something*/ LL_ADC_EocCallback(Instance); } } /** * @brief This function handles ADC Sample interrupts requests. * @param Instance ADC instance * @param Channel 0~11 * @return None */ void LL_ADC_SAMP_IRQHandler(ADC_TypeDef *Instance, uint8_t Channel) { if ((__LL_ADC_GET_IT_DONE(Instance, Channel)) && (__LL_ADC_GET_FLAG_DONE(Instance, Channel))) { __LL_ADC_CLEAR_FLAG_DONE(Instance, Channel); /*Handle something*/ LL_ADC_SampCallback(Instance, Channel); } } /** * @brief This function handles ADC Dma Half interrupts requests. * @param Instance ADC instance * @param Channel 0~11 * @return None */ void LL_ADC_HALF_IRQHandler(ADC_TypeDef *Instance, uint8_t Channel) { if ((__LL_ADC_GET_IT_HALF(Instance, Channel)) && (__LL_ADC_GET_FLAG_HALF(Instance, Channel))) { __LL_ADC_CLEAR_FLAG_HALF(Instance, Channel); /*Handle something*/ LL_ADC_HalfCallback(Instance, Channel); } } /** * @brief This function handles ADC Dma Full interrupts requests. * @param Instance ADC instance * @param Channel 0~11 * @return None */ void LL_ADC_FULL_IRQHandler(ADC_TypeDef *Instance, uint8_t Channel) { if ((__LL_ADC_GET_IT_FULL(Instance, Channel)) && (__LL_ADC_GET_FLAG_FULL(Instance, Channel))) { __LL_ADC_CLEAR_FLAG_FULL(Instance, Channel); /*Handle something*/ LL_ADC_FullCallback(Instance, Channel); } } /** * @} */ /** * @} */ /* Private functions ---------------------------------------------------------*/ /** @addtogroup ADC_LL_Private_Functions * @{ */ /** * @brief Read ADC single-ended self-calibration data * @note No external calls * @return None */ static void LL_ADC_ReadCoef(void) { Calib_read_data[0] = SYSCTRL->SINGLE; Calib_read_data[1] = SYSCTRL->DIFFER; Calib_read_data[2] = SYSCTRL->SINGLE_BUFF; /* Determinate whether the SoC has been calibrated. If it has not been calibrated, the standard register is written into the user configuration data; if the calibration criterion reads the calibration data*/ if (memcmp(&Calib_check_data, &Calib_read_data, sizeof(Calib_read_data)) == 0) { /* CALB_SE*/ pCoef.SingleGain = 8192; /* CALA_SE*/ pCoef.SingleOffset = 0; /* CALB_DF*/ pCoef.DiffGain = 8192; /* CALA_DF*/ pCoef.DiffOffset = 0; /* CALB_WB*/ pCoef.SingleBuffGain = 8192; /* CALA_WB*/ pCoef.SingleBuffOffset = 0; } else { /* CALB_SE*/ pCoef.SingleGain = (uint16_t)Calib_read_data[0]; /* CALA_SE*/ pCoef.SingleOffset = (int16_t)(Calib_read_data[0] >> 16); /* CALB_DF*/ pCoef.DiffGain = (uint16_t)Calib_read_data[1]; /* CALA_DF*/ pCoef.DiffOffset = (int16_t)(Calib_read_data[1] >> 16); /* CALB_WB*/ pCoef.SingleBuffGain = (uint16_t)Calib_read_data[2]; /* CALA_WB*/ pCoef.SingleBuffOffset = (int16_t)(Calib_read_data[2] >> 16); } } /** * @brief The calibration coefficient varies with the change of oversampling * @note No external calls * @param Instance ADC instance * @param offset ADC offset * @return None */ static void LL_ADC_OverSamp_Mode(ADC_TypeDef *Instance, int16_t offset) { int8_t temp_mode = 0; temp_mode = (__LL_ADC_GetOverSamplingShift(Instance) >> ADC_CR1_OVSS_Pos) - \ (__LL_ADC_GetOverSamplingRatio(Instance) >> ADC_CR1_OVSR_Pos); if ((temp_mode - 1) >= 0) { temp_offset = offset >> (temp_mode - 1); } else { temp_offset = offset << (abs(temp_mode) + 1); } } /** * @} */ #endif /* LL_ADC_MODULE_ENABLE */ /** * @} */ /** * @} */ /************************* (C) COPYRIGHT Tai-Action *****END OF FILE***********/