mbed library sources
Dependents: Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more
Superseded
This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.
Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.
If you are looking for a stable and tested release, please import one of the official mbed library releases:
Import librarymbed
The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Diff: targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c
- Revision:
- 630:825f75ca301e
- Parent:
- 441:d2c15dda23c1
diff -r 1806c2edb763 -r 825f75ca301e targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c --- a/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c Mon Sep 28 10:30:09 2015 +0100 +++ b/targets/cmsis/TARGET_STM/TARGET_STM32F0/stm32f0xx_hal_adc.c Mon Sep 28 10:45:10 2015 +0100 @@ -2,53 +2,55 @@ ****************************************************************************** * @file stm32f0xx_hal_adc.c * @author MCD Application Team - * @version V1.2.0 - * @date 11-December-2014 + * @version V1.3.0 + * @date 26-June-2015 * @brief This file provides firmware functions to manage the following * functionalities of the Analog to Digital Convertor (ADC) * peripheral: * + Initialization and de-initialization functions * ++ Initialization and Configuration of ADC * + Operation functions - * ++ Start, stop, get result of conversions of regular group, - * using 3 possible modes: polling, interruption or DMA. + * ++ Start, stop, get result of conversions of regular + * group, using 3 possible modes: polling, interruption or DMA. * + Control functions + * ++ Channels configuration on regular group * ++ Analog Watchdog configuration - * ++ Channels configuration on regular group * + State functions * ++ ADC state machine management * ++ Interrupts and flags management - * + * Other functions (extended functions) are available in file + * "stm32f0xx_hal_adc_ex.c". + * @verbatim ============================================================================== - ##### ADC specific features ##### + ##### ADC peripheral features ##### ============================================================================== - [..] - (#) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution + [..] + (+) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution - (#) Interrupt generation at the end of regular conversion and in case of + (+) Interrupt generation at the end of regular conversion and in case of analog watchdog or overrun events. - (#) Single and continuous conversion modes. + (+) Single and continuous conversion modes. - (#) Scan mode for automatic conversion of channel 0 to channel 'n'. + (+) Scan mode for conversion of several channels sequentially. - (#) Data alignment with in-built data coherency. + (+) Data alignment with in-built data coherency. - (#) Programmable sampling time. + (+) Programmable sampling time (common for all channels) - (#) ADC conversion group Regular. + (+) ADC conversion of regular group. - (#) External trigger (timer or EXTI) with configurable polarity. + (+) External trigger (timer or EXTI) with configurable polarity - (#) DMA request generation for transfer of conversions data of regular group. + (+) DMA request generation for transfer of conversions data of regular group. - (#) ADC calibration + (+) ADC calibration - (#) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at + (+) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at slower speed. - (#) ADC input range: from Vref minus (connected to Vssa) to Vref plus (connected to + (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to Vdda or to an external voltage reference). @@ -56,64 +58,176 @@ ============================================================================== [..] - (#) Enable the ADC interface - (++) As prerequisite, into HAL_ADC_MspInit(), ADC clock must be configured - at RCC top level: clock source and clock prescaler. - (++)Two possible clock sources: synchronous clock derived from APB clock - or asynchronous clock derived from ADC dedicated HSI RC oscillator - 14MHz. - (++)Example: - __ADC1_CLK_ENABLE(); (mandatory) - - HI14 enable or let under control of ADC: (optional) + *** Configuration of top level parameters related to ADC *** + ============================================================ + [..] + + (#) Enable the ADC interface + (++) As prerequisite, ADC clock must be configured at RCC top level. + Caution: On STM32F0, ADC clock frequency max is 14MHz (refer + to device datasheet). + Therefore, ADC clock prescaler must be configured in + function of ADC clock source frequency to remain below + this maximum frequency. + + (++) Two clock settings are mandatory: + (+++) ADC clock (core clock, also possibly conversion clock). - RCC_OscInitTypeDef RCC_OscInitStructure; - RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI14; - RCC_OscInitStructure.HSI14CalibrationValue = RCC_HSI14CALIBRATION_DEFAULT; - RCC_OscInitStructure.HSI14State = RCC_HSI14_ADC_CONTROL; - RCC_OscInitStructure.PLL... (optional if used for system clock) - HAL_RCC_OscConfig(&RCC_OscInitStructure); - - Parameter "HSI14State" must be set either: - - to "...HSI14State = RCC_HSI14_ADC_CONTROL" to let the ADC control - the HSI14 oscillator enable/disable (if not used to supply the main - system clock): feature used if ADC mode LowPowerAutoPowerOff is - enabled. - - to "...HSI14State = RCC_HSI14_ON" to maintain the HSI14 oscillator - always enabled: can be used to supply the main system clock. + (+++) ADC clock (conversions clock). + Two possible clock sources: synchronous clock derived from APB clock + or asynchronous clock derived from ADC dedicated HSI RC oscillator + 14MHz. + If asynchronous clock is selected, parameter "HSI14State" must be set either: + - to "...HSI14State = RCC_HSI14_ADC_CONTROL" to let the ADC control + the HSI14 oscillator enable/disable (if not used to supply the main + system clock): feature used if ADC mode LowPowerAutoPowerOff is + enabled. + - to "...HSI14State = RCC_HSI14_ON" to maintain the HSI14 oscillator + always enabled: can be used to supply the main system clock. + + (+++) Example: + Into HAL_ADC_MspInit() (recommended code location) or with + other device clock parameters configuration: + (+++) __HAL_RCC_ADC1_CLK_ENABLE(); (mandatory) + + HI14 enable or let under control of ADC: (optional: if asynchronous clock selected) + (+++) RCC_OscInitTypeDef RCC_OscInitStructure; + (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI14; + (+++) RCC_OscInitStructure.HSI14CalibrationValue = RCC_HSI14CALIBRATION_DEFAULT; + (+++) RCC_OscInitStructure.HSI14State = RCC_HSI14_ADC_CONTROL; + (+++) RCC_OscInitStructure.PLL... (optional if used for system clock) + (+++) HAL_RCC_OscConfig(&RCC_OscInitStructure); + + (++) ADC clock source and clock prescaler are configured at ADC level with + parameter "ClockPrescaler" using function HAL_ADC_Init(). (#) ADC pins configuration - (++) Enable the clock for the ADC GPIOs using the following function: - __GPIOx_CLK_ENABLE(); - (++) Configure these ADC pins in analog mode using HAL_GPIO_Init(); - - (#) Configure the ADC parameters (conversion resolution, data alignment, - continuous mode, ...) using the HAL_ADC_Init() function. + (++) Enable the clock for the ADC GPIOs + using macro __HAL_RCC_GPIOx_CLK_ENABLE() + (++) Configure these ADC pins in analog mode + using function HAL_GPIO_Init() - (#) Activate the ADC peripheral using one of the start functions: - HAL_ADC_Start(), HAL_ADC_Start_IT(), HAL_ADC_Start_DMA(). + (#) Optionally, in case of usage of ADC with interruptions: + (++) Configure the NVIC for ADC + using function HAL_NVIC_EnableIRQ(ADCx_IRQn) + (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler() + into the function of corresponding ADC interruption vector + ADCx_IRQHandler(). + + (#) Optionally, in case of usage of DMA: + (++) Configure the DMA (DMA channel, mode normal or circular, ...) + using function HAL_DMA_Init(). + (++) Configure the NVIC for DMA + using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn) + (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler() + into the function of corresponding DMA interruption vector + DMAx_Channelx_IRQHandler(). - *** Channels configuration to regular group *** - ================================================ - [..] - (+) To configure the ADC regular group features, use - HAL_ADC_Init() and HAL_ADC_ConfigChannel() functions. - (+) To activate the continuous mode, use the HAL_ADC_Init() function. - (+) To read the ADC converted values, use the HAL_ADC_GetValue() function. - - *** DMA for regular configuration *** - ============================================================= + *** Configuration of ADC, group regular, channels parameters *** + ================================================================ + [..] + + (#) Configure the ADC parameters (resolution, data alignment, ...) + and regular group parameters (conversion trigger, sequencer, ...) + using function HAL_ADC_Init(). + + (#) Configure the channels for regular group parameters (channel number, + channel rank into sequencer, ..., into regular group) + using function HAL_ADC_ConfigChannel(). + + (#) Optionally, configure the analog watchdog parameters (channels + monitored, thresholds, ...) + using function HAL_ADC_AnalogWDGConfig(). + + *** Execution of ADC conversions *** + ==================================== [..] - (+) To enable the DMA mode for regular group, use the - HAL_ADC_Start_DMA() function. - (+) To enable the generation of DMA requests continuously at the end of - the last DMA transfer, use the HAL_ADC_Init() function. + + (#) Optionally, perform an automatic ADC calibration to improve the + conversion accuracy + using function HAL_ADCEx_Calibration_Start(). + + (#) ADC driver can be used among three modes: polling, interruption, + transfer by DMA. + + (++) ADC conversion by polling: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start() + (+++) Wait for ADC conversion completion + using function HAL_ADC_PollForConversion() + (+++) Retrieve conversion results + using function HAL_ADC_GetValue() + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop() + + (++) ADC conversion by interruption: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start_IT() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() + (this function must be implemented in user program) + (+++) Retrieve conversion results + using function HAL_ADC_GetValue() + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop_IT() + + (++) ADC conversion with transfer by DMA: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start_DMA() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback() + (these functions must be implemented in user program) + (+++) Conversion results are automatically transferred by DMA into + destination variable address. + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop_DMA() + + [..] + + (@) Callback functions must be implemented in user program: + (+@) HAL_ADC_ErrorCallback() + (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog) + (+@) HAL_ADC_ConvCpltCallback() + (+@) HAL_ADC_ConvHalfCpltCallback + + *** Deinitialization of ADC *** + ============================================================ + [..] + + (#) Disable the ADC interface + (++) ADC clock can be hard reset and disabled at RCC top level. + (++) Hard reset of ADC peripherals + using macro __ADCx_FORCE_RESET(), __ADCx_RELEASE_RESET(). + (++) ADC clock disable + using the equivalent macro/functions as configuration step. + (+++) Example: + Into HAL_ADC_MspDeInit() (recommended code location) or with + other device clock parameters configuration: + (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI14; + (+++) RCC_OscInitStructure.HSI14State = RCC_HSI14_OFF; (if not used for system clock) + (+++) HAL_RCC_OscConfig(&RCC_OscInitStructure); + + (#) ADC pins configuration + (++) Disable the clock for the ADC GPIOs + using macro __HAL_RCC_GPIOx_CLK_DISABLE() + + (#) Optionally, in case of usage of ADC with interruptions: + (++) Disable the NVIC for ADC + using function HAL_NVIC_EnableIRQ(ADCx_IRQn) + + (#) Optionally, in case of usage of DMA: + (++) Deinitialize the DMA + using function HAL_DMA_Init(). + (++) Disable the NVIC for DMA + using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn) + + [..] @endverbatim ****************************************************************************** * @attention * - * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -147,7 +261,7 @@ * @{ */ -/** @defgroup ADC ADC HAL module driver +/** @defgroup ADC ADC * @brief ADC HAL module driver * @{ */ @@ -171,17 +285,16 @@ #define ADC_DISABLE_TIMEOUT ((uint32_t) 2) #define ADC_STOP_CONVERSION_TIMEOUT ((uint32_t) 2) + /* Delay for ADC stabilization time. */ + /* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */ + /* Unit: us */ + #define ADC_STAB_DELAY_US ((uint32_t) 1) + /* Delay for temperature sensor stabilization time. */ /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */ - /* Delay in CPU cycles, fixed to worst case: maximum CPU frequency 48MHz to */ - /* have the minimum number of CPU cycles to fulfill this delay. */ - #define ADC_TEMPSENSOR_DELAY_CPU_CYCLES ((uint32_t) 480) + /* Unit: us */ + #define ADC_TEMPSENSOR_DELAY_US ((uint32_t) 10) - /* Delay for ADC stabilization time. */ - /* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */ - /* Delay in CPU cycles, fixed to worst case: maximum CPU frequency 48MHz to */ - /* have the minimum number of CPU cycles to fulfill this delay. */ - #define ADC_STAB_DELAY_CPU_CYCLES ((uint32_t)48) /** * @} */ @@ -247,7 +360,7 @@ */ HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; uint32_t tmpCFGR1 = 0; /* Check ADC handle */ @@ -282,9 +395,14 @@ /* - ADC voltage regulator enable */ if (hadc->State == HAL_ADC_STATE_RESET) { + /* Initialize ADC error code */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Allocate lock resource and initialize it */ + hadc->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ HAL_ADC_MspInit(hadc); - } /* Configuration of ADC parameters if previous preliminary actions are */ @@ -292,17 +410,21 @@ /* and if there is no conversion on going on regular group (ADC can be */ /* enabled anyway, in case of call of this function to update a parameter */ /* on the fly). */ - if ((hadc->State != HAL_ADC_STATE_ERROR) && - (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) ) + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL) && + (tmp_hal_status == HAL_OK) && + (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) ) { - /* Initialize the ADC state */ - hadc->State = HAL_ADC_STATE_BUSY; + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_BUSY_INTERNAL); /* Parameters update conditioned to ADC state: */ /* Parameters that can be updated only when ADC is disabled: */ /* - ADC clock mode */ /* - ADC clock prescaler */ - if (__HAL_ADC_IS_ENABLED(hadc) == RESET) + /* - ADC resolution */ + if (ADC_IS_ENABLE(hadc) == RESET) { /* Some parameters of this register are not reset, since they are set */ /* by other functions and must be kept in case of usage of this */ @@ -312,13 +434,16 @@ /* - internal measurement paths: Vbat, temperature sensor, Vref */ /* (set into HAL_ADC_ConfigChannel() ) */ - /* Reset configuration of ADC configuration register CFGR2: */ - /* - ADC clock mode: CKMODE */ - hadc->Instance->CFGR2 &= ~(ADC_CFGR2_CKMODE); + /* Configuration of ADC resolution */ + MODIFY_REG(hadc->Instance->CFGR1, + ADC_CFGR1_RES , + hadc->Init.Resolution ); /* Configuration of ADC clock mode: clock source AHB or HSI with */ /* selectable prescaler */ - hadc->Instance->CFGR2 |= hadc->Init.ClockPrescaler; + MODIFY_REG(hadc->Instance->CFGR2 , + ADC_CFGR2_CKMODE , + hadc->Init.ClockPrescaler ); } /* Configuration of ADC: */ @@ -341,18 +466,16 @@ ADC_CFGR1_EXTSEL | ADC_CFGR1_EXTEN | ADC_CFGR1_ALIGN | - ADC_CFGR1_RES | ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG ); - tmpCFGR1 |= (__HAL_ADC_CFGR1_AUTOWAIT(hadc->Init.LowPowerAutoWait) | - __HAL_ADC_CFGR1_AUTOOFF(hadc->Init.LowPowerAutoPowerOff) | - __HAL_ADC_CFGR1_CONTINUOUS(hadc->Init.ContinuousConvMode) | - __HAL_ADC_CFGR1_OVERRUN(hadc->Init.Overrun) | - hadc->Init.DataAlign | - hadc->Init.Resolution | - __HAL_ADC_CFGR1_SCANDIR(hadc->Init.ScanConvMode) | - __HAL_ADC_CFGR1_DMACONTREQ(hadc->Init.DMAContinuousRequests) ); + tmpCFGR1 |= (ADC_CFGR1_AUTOWAIT(hadc->Init.LowPowerAutoWait) | + ADC_CFGR1_AUTOOFF(hadc->Init.LowPowerAutoPowerOff) | + ADC_CFGR1_CONTINUOUS(hadc->Init.ContinuousConvMode) | + ADC_CFGR1_OVERRUN(hadc->Init.Overrun) | + hadc->Init.DataAlign | + ADC_SCANDIR(hadc->Init.ScanConvMode) | + ADC_CFGR1_DMACONTREQ(hadc->Init.DMAContinuousRequests) ); /* Enable discontinuous mode only if continuous mode is disabled */ if ((hadc->Init.DiscontinuousConvMode == ENABLE) && @@ -364,7 +487,7 @@ /* Enable external trigger if trigger selection is different of software */ /* start. */ - /* @Note: This configuration keeps the hardware feature of parameter */ + /* Note: This configuration keeps the hardware feature of parameter */ /* ExternalTrigConvEdge "trigger edge none" equivalent to */ /* software start. */ if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) @@ -376,41 +499,62 @@ /* Update ADC configuration register with previous settings */ hadc->Instance->CFGR1 |= tmpCFGR1; + /* Channel sampling time configuration */ + /* Management of parameters "SamplingTimeCommon" and "SamplingTime" */ + /* (obsolete): sampling time set in this function if parameter */ + /* "SamplingTimeCommon" has been set to a valid sampling time. */ + /* Otherwise, sampling time is set into ADC channel initialization */ + /* structure with parameter "SamplingTime" (obsolete). */ + if (IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon)) + { + /* Channel sampling time configuration */ + /* Clear the old sample time */ + hadc->Instance->SMPR &= ~(ADC_SMPR_SMP); + + /* Set the new sample time */ + hadc->Instance->SMPR |= ADC_SMPR_SET(hadc->Init.SamplingTimeCommon); + } + /* Check back that ADC registers have effectively been configured to */ /* ensure of no potential problem of ADC core IP clocking. */ /* Check through register CFGR1 (excluding analog watchdog configuration: */ - /* set into separate dedicated function). */ - if ((hadc->Instance->CFGR1 & ~(ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL)) + /* set into separate dedicated function, and bits of ADC resolution set */ + /* out of temporary variable 'tmpCFGR1'). */ + if ((hadc->Instance->CFGR1 & ~(ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_RES)) == tmpCFGR1) { /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); + ADC_CLEAR_ERRORCODE(hadc); - /* Initialize the ADC state */ - hadc->State = HAL_ADC_STATE_READY; + /* Set the ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_READY); } else { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_ERROR_INTERNAL); /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); - tmpHALStatus = HAL_ERROR; + tmp_hal_status = HAL_ERROR; } } else { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); - tmpHALStatus = HAL_ERROR; + tmp_hal_status = HAL_ERROR; } /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } @@ -428,7 +572,7 @@ */ HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check ADC handle */ if(hadc == NULL) @@ -439,20 +583,20 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY; + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL); /* Stop potential conversion on going, on regular group */ - tmpHALStatus = ADC_ConversionStop(hadc); + tmp_hal_status = ADC_ConversionStop(hadc); /* Disable ADC peripheral if conversions are effectively stopped */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { /* Disable the ADC peripheral */ - tmpHALStatus = ADC_Disable(hadc); + tmp_hal_status = ADC_Disable(hadc); /* Check if ADC is effectively disabled */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status != HAL_ERROR) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_READY; @@ -462,7 +606,7 @@ /* Configuration of ADC parameters if previous preliminary actions are */ /* correctly completed. */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status != HAL_ERROR) { /* ========== Reset ADC registers ========== */ @@ -487,7 +631,7 @@ ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN ); /* Reset register CFGR2 */ - /* @Note: Update of ADC clock mode is conditioned to ADC state disabled: */ + /* Note: Update of ADC clock mode is conditioned to ADC state disabled: */ /* already done above. */ hadc->Instance->CFGR2 &= ~ADC_CFGR2_CKMODE; @@ -508,9 +652,7 @@ /* bits in access mode read only, no direct reset applicable*/ /* Reset register CCR */ - ADC->CCR &= ~( ADC_CCR_VBATEN | - ADC_CCR_TSEN | - ADC_CCR_VREFEN ); + ADC->CCR &= ~(ADC_CCR_ALL); /* ========== Hard reset ADC peripheral ========== */ /* Performs a global reset of the entire ADC peripheral: ADC state is */ @@ -518,16 +660,16 @@ /* If needed, copy-paste and uncomment the following reset code into */ /* function "void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)": */ /* */ - /* __ADC1_FORCE_RESET() */ - /* __ADC1_RELEASE_RESET() */ + /* __HAL_RCC_ADC1_FORCE_RESET() */ + /* __HAL_RCC_ADC1_RELEASE_RESET() */ /* DeInit the low level hardware */ HAL_ADC_MspDeInit(hadc); /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); + ADC_CLEAR_ERRORCODE(hadc); - /* Change ADC state */ + /* Set ADC state */ hadc->State = HAL_ADC_STATE_RESET; } @@ -535,7 +677,7 @@ __HAL_UNLOCK(hadc); /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } @@ -597,13 +739,13 @@ */ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Perform ADC enable and conversion start if no conversion is on going */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { /* Process locked */ __HAL_LOCK(hadc); @@ -613,17 +755,26 @@ /* performed automatically by hardware. */ if (hadc->Init.LowPowerAutoPowerOff != ENABLE) { - tmpHALStatus = ADC_Enable(hadc); + tmp_hal_status = ADC_Enable(hadc); } /* Start conversion if ADC is effectively enabled */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { - /* State machine update: Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY_REG; - - /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP, + HAL_ADC_STATE_REG_BUSY); + + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); /* Clear regular group conversion flag and overrun flag */ /* (To ensure of no unknown state from potential previous ADC */ @@ -636,17 +787,14 @@ /* trigger event. */ hadc->Instance->CR |= ADC_CR_ADSTART; } - - /* Process unlocked */ - __HAL_UNLOCK(hadc); } else { - tmpHALStatus = HAL_BUSY; + tmp_hal_status = HAL_BUSY; } /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } /** @@ -656,7 +804,7 @@ */ HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -665,19 +813,21 @@ __HAL_LOCK(hadc); /* 1. Stop potential conversion on going, on regular group */ - tmpHALStatus = ADC_ConversionStop(hadc); + tmp_hal_status = ADC_ConversionStop(hadc); /* Disable ADC peripheral if conversions are effectively stopped */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { /* 2. Disable the ADC peripheral */ - tmpHALStatus = ADC_Disable(hadc); + tmp_hal_status = ADC_Disable(hadc); /* Check if ADC is effectively disabled */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_READY; + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_READY); } } @@ -685,11 +835,23 @@ __HAL_UNLOCK(hadc); /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } /** * @brief Wait for regular group conversion to be completed. + * @note ADC conversion flags EOS (end of sequence) and EOC (end of + * conversion) are cleared by this function, with an exception: + * if low power feature "LowPowerAutoWait" is enabled, flags are + * not cleared to not interfere with this feature until data register + * is read using function HAL_ADC_GetValue(). + * @note This function cannot be used in a particular setup: ADC configured + * in DMA mode and polling for end of each conversion (ADC init + * parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV). + * In this case, DMA resets the flag EOC and polling cannot be + * performed on each conversion. Nevertheless, polling can still + * be performed on the complete sequence (ADC init + * parameter "EOCSelection" set to ADC_EOC_SEQ_CONV). * @param hadc: ADC handle * @param Timeout: Timeout value in millisecond. * @retval HAL status @@ -703,19 +865,38 @@ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* If end of conversion selected to end of sequence */ - if (hadc->Init.EOCSelection == EOC_SEQ_CONV) + if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) { tmp_Flag_EOC = ADC_FLAG_EOS; } /* If end of conversion selected to end of each conversion */ - else /* EOC_SINGLE_CONV */ + else /* ADC_EOC_SINGLE_CONV */ { - tmp_Flag_EOC = (ADC_FLAG_EOC | ADC_FLAG_EOS); + /* Verification that ADC configuration is compliant with polling for */ + /* each conversion: */ + /* Particular case is ADC configured in DMA mode and ADC sequencer with */ + /* several ranks and polling for end of each conversion. */ + /* For code simplicity sake, this particular case is generalized to */ + /* ADC configured in DMA mode and and polling for end of each conversion. */ + if (HAL_IS_BIT_SET(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN)) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + else + { + tmp_Flag_EOC = (ADC_FLAG_EOC | ADC_FLAG_EOS); + } } - - /* Get timeout */ - tickstart = HAL_GetTick(); - + + /* Get tick count */ + tickstart = HAL_GetTick(); + /* Wait until End of Conversion flag is raised */ while(HAL_IS_BIT_CLR(hadc->Instance->ISR, tmp_Flag_EOC)) { @@ -725,12 +906,49 @@ if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { /* Update ADC state machine to timeout */ - hadc->State = HAL_ADC_STATE_TIMEOUT; + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); /* Process unlocked */ __HAL_UNLOCK(hadc); - return HAL_ERROR; + return HAL_TIMEOUT; + } + } + } + + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) + { + /* If End of Sequence is reached, disable interrupts */ + if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) ) + { + /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */ + /* ADSTART==0 (no conversion on going) */ + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + { + /* Disable ADC end of single conversion interrupt on group regular */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* HAL_Start_IT(), but is not disabled here because can be used */ + /* by overrun IRQ process below. */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_READY); + } + else + { + /* Change ADC state to error state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); } } } @@ -744,13 +962,6 @@ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS)); } - /* Update state machine on conversion status if not in error state */ - if(hadc->State != HAL_ADC_STATE_ERROR) - { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_EOC_REG; - } - /* Return ADC state */ return HAL_OK; } @@ -760,8 +971,8 @@ * @param hadc: ADC handle * @param EventType: the ADC event type. * This parameter can be one of the following values: - * @arg AWD_EVENT: ADC Analog watchdog event - * @arg OVR_EVENT: ADC Overrun event + * @arg ADC_AWD_EVENT: ADC Analog watchdog event + * @arg ADC_OVR_EVENT: ADC Overrun event * @param Timeout: Timeout value in millisecond. * @retval HAL status */ @@ -773,6 +984,7 @@ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_EVENT_TYPE(EventType)); + /* Get tick count */ tickstart = HAL_GetTick(); /* Check selected event flag */ @@ -784,7 +996,7 @@ if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { /* Update ADC state machine to timeout */ - hadc->State = HAL_ADC_STATE_TIMEOUT; + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); /* Process unlocked */ __HAL_UNLOCK(hadc); @@ -797,27 +1009,27 @@ switch(EventType) { /* Analog watchdog (level out of window) event */ - case AWD_EVENT: - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_AWD; + case ADC_AWD_EVENT: + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); /* Clear ADC analog watchdog flag */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); break; /* Overrun event */ - default: /* Case OVR_EVENT */ + default: /* Case ADC_OVR_EVENT */ /* If overrun is set to overwrite previous data, overrun event is not */ /* considered as an error. */ /* (cf ref manual "Managing conversions without using the DMA and without */ /* overrun ") */ - if (hadc->Init.Overrun == OVR_DATA_PRESERVED) + if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED) { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_ERROR; + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR); /* Set ADC error code to overrun */ - hadc->ErrorCode |= HAL_ADC_ERROR_OVR; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR); } /* Clear ADC Overrun flag */ @@ -842,13 +1054,13 @@ */ HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Perform ADC enable and conversion start if no conversion is on going */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { /* Process locked */ __HAL_LOCK(hadc); @@ -858,17 +1070,26 @@ /* performed automatically by hardware. */ if (hadc->Init.LowPowerAutoPowerOff != ENABLE) { - tmpHALStatus = ADC_Enable(hadc); + tmp_hal_status = ADC_Enable(hadc); } /* Start conversion if ADC is effectively enabled */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { - /* State machine update: Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY_REG; + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP, + HAL_ADC_STATE_REG_BUSY); - /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); /* Clear regular group conversion flag and overrun flag */ /* (To ensure of no unknown state from potential previous ADC */ @@ -879,11 +1100,11 @@ /* Enable ADC overrun interrupt */ switch(hadc->Init.EOCSelection) { - case EOC_SEQ_CONV: + case ADC_EOC_SEQ_CONV: __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOS | ADC_IT_OVR)); break; - /* case EOC_SINGLE_CONV */ + /* case ADC_EOC_SINGLE_CONV */ default: __HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); break; @@ -895,17 +1116,14 @@ /* trigger event. */ hadc->Instance->CR |= ADC_CR_ADSTART; } - - /* Process unlocked */ - __HAL_UNLOCK(hadc); } else { - tmpHALStatus = HAL_BUSY; + tmp_hal_status = HAL_BUSY; } /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } @@ -917,7 +1135,7 @@ */ HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -926,23 +1144,25 @@ __HAL_LOCK(hadc); /* 1. Stop potential conversion on going, on regular group */ - tmpHALStatus = ADC_ConversionStop(hadc); - + tmp_hal_status = ADC_ConversionStop(hadc); + /* Disable ADC peripheral if conversions are effectively stopped */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { /* Disable ADC end of conversion interrupt for regular group */ /* Disable ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); /* 2. Disable the ADC peripheral */ - tmpHALStatus = ADC_Disable(hadc); + tmp_hal_status = ADC_Disable(hadc); /* Check if ADC is effectively disabled */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_READY; + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_READY); } } @@ -950,7 +1170,7 @@ __HAL_UNLOCK(hadc); /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } /** @@ -968,13 +1188,13 @@ */ HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Perform ADC enable and conversion start if no conversion is on going */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { /* Process locked */ __HAL_LOCK(hadc); @@ -984,19 +1204,27 @@ /* performed automatically by hardware. */ if (hadc->Init.LowPowerAutoPowerOff != ENABLE) { - tmpHALStatus = ADC_Enable(hadc); + tmp_hal_status = ADC_Enable(hadc); } /* Start conversion if ADC is effectively enabled */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { - /* State machine update: Change ADC state */ - hadc->State = HAL_ADC_STATE_BUSY_REG; + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP, + HAL_ADC_STATE_REG_BUSY); - /* Set ADC error code to none */ - __HAL_ADC_CLEAR_ERRORCODE(hadc); - + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + /* Set the DMA transfer complete callback */ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; @@ -1030,17 +1258,14 @@ /* trigger event. */ hadc->Instance->CR |= ADC_CR_ADSTART; } - - /* Process unlocked */ - __HAL_UNLOCK(hadc); } else { - tmpHALStatus = HAL_BUSY; + tmp_hal_status = HAL_BUSY; } /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } /** @@ -1052,7 +1277,7 @@ */ HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -1061,34 +1286,34 @@ __HAL_LOCK(hadc); /* 1. Stop potential conversion on going, on regular group */ - tmpHALStatus = ADC_ConversionStop(hadc); + tmp_hal_status = ADC_ConversionStop(hadc); /* Disable ADC peripheral if conversions are effectively stopped */ - if (tmpHALStatus != HAL_ERROR) + if (tmp_hal_status == HAL_OK) { /* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */ hadc->Instance->CFGR1 &= ~ADC_CFGR1_DMAEN; /* Disable the DMA channel (in case of DMA in circular mode or stop while */ /* while DMA transfer is on going) */ - tmpHALStatus = HAL_DMA_Abort(hadc->DMA_Handle); + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); /* Check if DMA channel effectively disabled */ - if (tmpHALStatus != HAL_OK) + if (tmp_hal_status != HAL_OK) { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); } /* Disable ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); /* 2. Disable the ADC peripheral */ - /* Update "tmpHALStatus" only if DMA channel disabling passed, to keep in */ - /* memory a potential failing status. */ - if (tmpHALStatus == HAL_OK) + /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep */ + /* in memory a potential failing status. */ + if (tmp_hal_status == HAL_OK) { - tmpHALStatus = ADC_Disable(hadc); + tmp_hal_status = ADC_Disable(hadc); } else { @@ -1096,10 +1321,12 @@ } /* Check if ADC is effectively disabled */ - if (tmpHALStatus == HAL_OK) + if (tmp_hal_status == HAL_OK) { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_READY; + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_READY); } } @@ -1108,7 +1335,7 @@ __HAL_UNLOCK(hadc); /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } /** @@ -1125,7 +1352,7 @@ /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); - /* @Note: EOC flag is not cleared here by software because automatically */ + /* Note: EOC flag is not cleared here by software because automatically */ /* cleared by hardware when reading register DR. */ /* Clear regular group end of sequence flag */ @@ -1136,61 +1363,6 @@ } /** - * @brief DMA transfer complete callback. - * @param hdma: pointer to DMA handle. - * @retval None - */ -static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) -{ - /* Retrieve ADC handle corresponding to current DMA handle */ - ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* Update state machine on conversion status if not in error state */ - if(hadc->State != HAL_ADC_STATE_ERROR) - { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_EOC_REG; - } - - /* Conversion complete callback */ - HAL_ADC_ConvCpltCallback(hadc); -} - -/** - * @brief DMA half transfer complete callback. - * @param hdma: pointer to DMA handle. - * @retval None - */ -static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) -{ - /* Retrieve ADC handle corresponding to current DMA handle */ - ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* Half conversion callback */ - HAL_ADC_ConvHalfCpltCallback(hadc); -} - -/** - * @brief DMA error callback - * @param hdma: pointer to DMA handle. - * @retval None - */ -static void ADC_DMAError(DMA_HandleTypeDef *hdma) -{ - /* Retrieve ADC handle corresponding to current DMA handle */ - ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_ERROR; - - /* Set ADC error code to DMA error */ - hadc->ErrorCode |= HAL_ADC_ERROR_DMA; - - /* Error callback */ - HAL_ADC_ErrorCallback(hadc); -} - -/** * @brief Handles ADC interrupt request. * @param hadc: ADC handle * @retval None @@ -1207,52 +1379,56 @@ (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOS)) ) { /* Update state machine on conversion status if not in error state */ - if(hadc->State != HAL_ADC_STATE_ERROR) + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_EOC_REG; + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); } - /* Disable interruption if no further conversion upcoming by regular */ - /* external trigger or by continuous mode, */ - /* and if scan sequence if completed. */ - if(__HAL_ADC_IS_SOFTWARE_START_REGULAR(hadc) && - (hadc->Init.ContinuousConvMode == DISABLE) ) + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) { /* If End of Sequence is reached, disable interrupts */ if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) ) { /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */ /* ADSTART==0 (no conversion on going) */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { - /* Disable ADC end of sequence conversion interrupt */ - /* @Note: Overrun interrupt was enabled with EOC interrupt in */ + /* Disable ADC end of single conversion interrupt on group regular */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ /* HAL_Start_IT(), but is not disabled here because can be used */ /* by overrun IRQ process below. */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_READY); } else { /* Change ADC state to error state */ - hadc->State = HAL_ADC_STATE_ERROR; + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); } } } /* Conversion complete callback */ - /* @Note: into callback, to determine if conversion has been triggered */ + /* Note: into callback, to determine if conversion has been triggered */ /* from EOC or EOS, possibility to use: */ /* " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) " */ HAL_ADC_ConvCpltCallback(hadc); /* Clear regular group conversion flag */ - /* @Note: in case of overrun set to OVR_DATA_PRESERVED, end of conversion */ - /* flags clear induces the release of the preserved data. */ + /* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of */ + /* conversion flags clear induces the release of the preserved data.*/ /* Therefore, if the preserved data value is needed, it must be */ /* read preliminarily into HAL_ADC_ConvCpltCallback(). */ __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS) ); @@ -1261,8 +1437,8 @@ /* ========== Check Analog watchdog flags ========== */ if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD)) { - /* Change ADC state */ - hadc->State = HAL_ADC_STATE_AWD; + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); /* Level out of window callback */ HAL_ADC_LevelOutOfWindowCallback(hadc); @@ -1282,14 +1458,14 @@ /* overrun ") */ /* Exception for usage with DMA overrun event always considered as an */ /* error. */ - if ((hadc->Init.Overrun == OVR_DATA_PRESERVED) || + if ((hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED) || HAL_IS_BIT_SET(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN) ) { - /* Change ADC state to error state */ - hadc->State = HAL_ADC_STATE_ERROR; + /* Set ADC error code to overrun */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR); - /* Set ADC error code to overrun */ - hadc->ErrorCode |= HAL_ADC_ERROR_OVR; + /* Clear ADC overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); /* Error callback */ HAL_ADC_ErrorCallback(hadc); @@ -1397,15 +1573,19 @@ */ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; __IO uint32_t wait_loop_index = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_CHANNEL(sConfig->Channel)); assert_param(IS_ADC_RANK(sConfig->Rank)); - assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime)); - + + if (! IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon)) + { + assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime)); + } + /* Process locked */ __HAL_LOCK(hadc); @@ -1414,8 +1594,8 @@ /* conversion on going on regular group: */ /* - Channel number */ /* - Channel sampling time */ - /* - Management of internal measurement channels: Vbat/VrefInt/TempSensor */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + /* - Management of internal measurement channels: VrefInt/TempSensor/Vbat */ + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { /* Configure channel: depending on rank setting, add it or remove it from */ /* ADC conversion sequencer. */ @@ -1423,97 +1603,90 @@ { /* Regular sequence configuration */ /* Set the channel selection register from the selected channel */ - hadc->Instance->CHSELR |= __HAL_ADC_CHSELR_CHANNEL(sConfig->Channel); + hadc->Instance->CHSELR |= ADC_CHSELR_CHANNEL(sConfig->Channel); /* Channel sampling time configuration */ - /* Modify sampling time if needed (not needed in case of reoccurrence */ - /* for several channels programmed consecutively into the sequencer) */ - if (sConfig->SamplingTime != __HAL_ADC_GET_SAMPLINGTIME(hadc)) + /* Management of parameters "SamplingTimeCommon" and "SamplingTime" */ + /* (obsolete): sampling time set in this function with */ + /* parameter "SamplingTime" (obsolete) only if not already set into */ + /* ADC initialization structure with parameter "SamplingTimeCommon". */ + if (! IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon)) { - /* Channel sampling time configuration */ - /* Clear the old sample time */ - hadc->Instance->SMPR &= ~(ADC_SMPR_SMP); - - /* Set the new sample time */ - hadc->Instance->SMPR |= (sConfig->SamplingTime); + /* Modify sampling time if needed (not needed in case of reoccurrence */ + /* for several channels programmed consecutively into the sequencer) */ + if (sConfig->SamplingTime != ADC_GET_SAMPLINGTIME(hadc)) + { + /* Channel sampling time configuration */ + /* Clear the old sample time */ + hadc->Instance->SMPR &= ~(ADC_SMPR_SMP); + + /* Set the new sample time */ + hadc->Instance->SMPR |= ADC_SMPR_SET(sConfig->SamplingTime); + } } - - /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */ + + /* Management of internal measurement channels: VrefInt/TempSensor/Vbat */ /* internal measurement paths enable: If internal channel selected, */ /* enable dedicated internal buffers and path. */ - /* @Note: these internal measurement paths can be disabled using */ - /* HAL_ADC_DeInit() or removing the channel from sequencer with */ - /* channel configuration parameter "Rank". */ - - /* If Channel_16 is selected, enable Temp. sensor measurement path. */ - if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) + /* Note: these internal measurement paths can be disabled using */ + /* HAL_ADC_DeInit() or removing the channel from sequencer with */ + /* channel configuration parameter "Rank". */ + if(ADC_IS_CHANNEL_INTERNAL(sConfig->Channel)) { - ADC->CCR |= ADC_CCR_TSEN; + /* If Channel_16 is selected, enable Temp. sensor measurement path. */ + /* If Channel_17 is selected, enable VREFINT measurement path. */ + /* If Channel_18 is selected, enable VBAT measurement path. */ + ADC->CCR |= ADC_CHANNEL_INTERNAL_PATH(sConfig->Channel); - /* Delay for temperature sensor stabilization time */ - while(wait_loop_index < ADC_TEMPSENSOR_DELAY_CPU_CYCLES) + /* If Temp. sensor is selected, wait for stabilization delay */ + if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) { - wait_loop_index++; + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000)); + while(wait_loop_index != 0) + { + wait_loop_index--; + } } } - /* If Channel_17 is selected, enable VBAT measurement path. */ - else if (sConfig->Channel == ADC_CHANNEL_VBAT) - { - ADC->CCR |= ADC_CCR_VBATEN; - } - /* If Channel_18 is selected, enable VREFINT measurement path. */ - else if (sConfig->Channel == ADC_CHANNEL_VREFINT) - { - ADC->CCR |= ADC_CCR_VREFEN; - } - } else { /* Regular sequence configuration */ /* Reset the channel selection register from the selected channel */ - hadc->Instance->CHSELR &= ~__HAL_ADC_CHSELR_CHANNEL(sConfig->Channel); + hadc->Instance->CHSELR &= ~ADC_CHSELR_CHANNEL(sConfig->Channel); - /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */ + /* Management of internal measurement channels: VrefInt/TempSensor/Vbat */ /* internal measurement paths disable: If internal channel selected, */ /* disable dedicated internal buffers and path. */ - - /* If Channel_16 is selected, disable Temp. sensor measurement path. */ - if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) + if(ADC_IS_CHANNEL_INTERNAL(sConfig->Channel)) { - ADC->CCR &= ~ADC_CCR_TSEN; - } - /* If Channel_17 is selected, disable VBAT measurement path. */ - else if (sConfig->Channel == ADC_CHANNEL_VBAT) - { - ADC->CCR &= ~ADC_CCR_VBATEN; - } - /* If Channel_18 is selected, disable VREFINT measurement path. */ - else if (sConfig->Channel == ADC_CHANNEL_VREFINT) - { - ADC->CCR &= ~ADC_CCR_VREFEN; + /* If Channel_16 is selected, disable Temp. sensor measurement path. */ + /* If Channel_17 is selected, disable VREFINT measurement path. */ + /* If Channel_18 is selected, disable VBAT measurement path. */ + ADC->CCR &= ~ADC_CHANNEL_INTERNAL_PATH(sConfig->Channel); } } - + } - /* If a conversion is on going on regular group, no update on regular */ /* channel could be done on neither of the channel configuration structure */ /* parameters. */ else { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); - tmpHALStatus = HAL_ERROR; + tmp_hal_status = HAL_ERROR; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } @@ -1533,18 +1706,19 @@ */ HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig) { - HAL_StatusTypeDef tmpHALStatus = HAL_OK; + HAL_StatusTypeDef tmp_hal_status = HAL_OK; uint32_t tmpAWDHighThresholdShifted; uint32_t tmpAWDLowThresholdShifted; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode)); assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); /* Verify if threshold is within the selected ADC resolution */ - assert_param(IS_ADC_RANGE(__HAL_ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold)); - assert_param(IS_ADC_RANGE(__HAL_ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold)); + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold)); if(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) { @@ -1559,7 +1733,7 @@ /* conversion on going on regular group: */ /* - Analog watchdog channels */ /* - Analog watchdog thresholds */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) { /* Configuration of analog watchdog: */ /* - Set the analog watchdog enable mode: one or overall group of */ @@ -1570,18 +1744,18 @@ ADC_CFGR1_AWDEN | ADC_CFGR1_AWDCH ); - hadc->Instance->CFGR1 |= ( AnalogWDGConfig->WatchdogMode | - __HAL_ADC_CFGR_AWDCH(AnalogWDGConfig->Channel) ); + hadc->Instance->CFGR1 |= ( AnalogWDGConfig->WatchdogMode | + ADC_CFGR_AWDCH(AnalogWDGConfig->Channel) ); /* Shift the offset in function of the selected ADC resolution: Thresholds*/ /* have to be left-aligned on bit 11, the LSB (right bits) are set to 0 */ - tmpAWDHighThresholdShifted = __HAL_ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold); - tmpAWDLowThresholdShifted = __HAL_ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold); + tmpAWDHighThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold); + tmpAWDLowThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold); /* Set the high and low thresholds */ hadc->Instance->TR &= ~(ADC_TR_HT | ADC_TR_LT); - hadc->Instance->TR |= ( __HAL_ADC_TRX_HIGHTHRESHOLD (tmpAWDHighThresholdShifted) | - tmpAWDLowThresholdShifted ); + hadc->Instance->TR |= ( ADC_TRX_HIGHTHRESHOLD (tmpAWDHighThresholdShifted) | + tmpAWDLowThresholdShifted ); /* Clear the ADC Analog watchdog flag (in case of left enabled by */ /* previous ADC operations) to be ready to use for HAL_ADC_IRQHandler() */ @@ -1606,9 +1780,9 @@ else { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); - tmpHALStatus = HAL_ERROR; + tmp_hal_status = HAL_ERROR; } @@ -1616,7 +1790,7 @@ __HAL_UNLOCK(hadc); /* Return function status */ - return tmpHALStatus; + return tmp_hal_status; } @@ -1647,7 +1821,7 @@ * @param hadc: ADC handle * @retval HAL state */ -HAL_ADC_StateTypeDef HAL_ADC_GetState(ADC_HandleTypeDef* hadc) +uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc) { /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); @@ -1682,6 +1856,12 @@ * @brief Enable the selected ADC. * @note Prerequisite condition to use this function: ADC must be disabled * and voltage regulator must be enabled (done into HAL_ADC_Init()). + * @note If low power mode AutoPowerOff is enabled, power-on/off phases are + * performed automatically by hardware. + * In this mode, this function is useless and must not be called because + * flag ADC_FLAG_RDY is not usable. + * Therefore, this function must be called under condition of + * "if (hadc->Init.LowPowerAutoPowerOff != ENABLE)". * @param hadc: ADC handle * @retval HAL status. */ @@ -1694,16 +1874,16 @@ /* enabling phase not yet completed: flag ADC ready not yet set). */ /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */ /* causes: ADC clock not running, ...). */ - if (__HAL_ADC_IS_ENABLED(hadc) == RESET) + if (ADC_IS_ENABLE(hadc) == RESET) { /* Check if conditions to enable the ADC are fulfilled */ - if (__HAL_ADC_ENABLING_CONDITIONS(hadc) == RESET) + if (ADC_ENABLING_CONDITIONS(hadc) == RESET) { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; - + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); return HAL_ERROR; } @@ -1711,14 +1891,15 @@ /* Enable the ADC peripheral */ __HAL_ADC_ENABLE(hadc); - /* Delay for ADC stabilization time. */ - /* Delay fixed to worst case: maximum CPU frequency */ - while(wait_loop_index < ADC_STAB_DELAY_CPU_CYCLES) + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(wait_loop_index != 0) { - wait_loop_index++; - } + wait_loop_index--; + } - /* Get timeout */ + /* Get tick count */ tickstart = HAL_GetTick(); /* Wait for ADC effectively enabled */ @@ -1727,10 +1908,10 @@ if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT) { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; - + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); return HAL_ERROR; } @@ -1754,12 +1935,12 @@ uint32_t tickstart = 0; /* Verification if ADC is not already disabled: */ - /* @Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */ - /* disabled. */ - if (__HAL_ADC_IS_ENABLED(hadc) != RESET ) + /* Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */ + /* disabled. */ + if (ADC_IS_ENABLE(hadc) != RESET) { /* Check if conditions to disable the ADC are fulfilled */ - if (__HAL_ADC_DISABLING_CONDITIONS(hadc) != RESET) + if (ADC_DISABLING_CONDITIONS(hadc) != RESET) { /* Disable the ADC peripheral */ __HAL_ADC_DISABLE(hadc); @@ -1767,26 +1948,27 @@ else { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; - + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); return HAL_ERROR; } /* Wait for ADC effectively disabled */ + /* Get tick count */ tickstart = HAL_GetTick(); while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADEN)) { - if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT) + if((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT) { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; - + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); return HAL_ERROR; } @@ -1814,7 +1996,7 @@ /* Verification if ADC is not already stopped on regular group to bypass */ /* this function if not needed. */ - if (__HAL_ADC_IS_CONVERSION_ONGOING_REGULAR(hadc)) + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc)) { /* Stop potential conversion on going on regular group */ @@ -1827,6 +2009,7 @@ } /* Wait for conversion effectively stopped */ + /* Get tick count */ tickstart = HAL_GetTick(); while((hadc->Instance->CR & ADC_CR_ADSTART) != RESET) @@ -1834,10 +2017,10 @@ if((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT) { /* Update ADC state machine to error */ - hadc->State = HAL_ADC_STATE_ERROR; - + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + /* Set ADC error code to ADC IP internal error */ - hadc->ErrorCode |= HAL_ADC_ERROR_INTERNAL; + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); return HAL_ERROR; } @@ -1849,6 +2032,102 @@ return HAL_OK; } + +/** + * @brief DMA transfer complete callback. + * @param hdma: pointer to DMA handle. + * @retval None + */ +static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) + { + /* If End of Sequence is reached, disable interrupts */ + if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) ) + { + /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */ + /* ADSTART==0 (no conversion on going) */ + if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) + { + /* Disable ADC end of single conversion interrupt on group regular */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* HAL_Start_IT(), but is not disabled here because can be used */ + /* by overrun IRQ process below. */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_READY); + } + else + { + /* Change ADC state to error state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + } + } + + /* Conversion complete callback */ + HAL_ADC_ConvCpltCallback(hadc); + } + else + { + /* Call DMA error callback */ + hadc->DMA_Handle->XferErrorCallback(hdma); + } + +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma: pointer to DMA handle. + * @retval None + */ +static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Half conversion callback */ + HAL_ADC_ConvHalfCpltCallback(hadc); +} + +/** + * @brief DMA error callback + * @param hdma: pointer to DMA handle. + * @retval None + */ +static void ADC_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); + + /* Set ADC error code to DMA error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA); + + /* Error callback */ + HAL_ADC_ErrorCallback(hadc); +} + /** * @} */