2 ******************************************************************************
3 * @file stm32f4xx_hal_adc.c
4 * @author MCD Application Team
7 * @brief This file provides firmware functions to manage the following
8 * functionalities of the Analog to Digital Convertor (ADC) peripheral:
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + State and errors functions
14 ==============================================================================
15 ##### ADC Peripheral features #####
16 ==============================================================================
18 (#) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution.
19 (#) Interrupt generation at the end of conversion, end of injected conversion,
20 and in case of analog watchdog or overrun events
21 (#) Single and continuous conversion modes.
22 (#) Scan mode for automatic conversion of channel 0 to channel x.
23 (#) Data alignment with in-built data coherency.
24 (#) Channel-wise programmable sampling time.
25 (#) External trigger option with configurable polarity for both regular and
27 (#) Dual/Triple mode (on devices with 2 ADCs or more).
28 (#) Configurable DMA data storage in Dual/Triple ADC mode.
29 (#) Configurable delay between conversions in Dual/Triple interleaved mode.
30 (#) ADC conversion type (refer to the datasheets).
31 (#) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at
33 (#) ADC input range: VREF(minus) = VIN = VREF(plus).
34 (#) DMA request generation during regular channel conversion.
37 ##### How to use this driver #####
38 ==============================================================================
40 (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():
41 (##) Enable the ADC interface clock using __ADC_CLK_ENABLE()
42 (##) ADC pins configuration
43 (+++) Enable the clock for the ADC GPIOs using the following function:
45 (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init()
46 (##) In case of using interrupts (e.g. HAL_ADC_Start_IT())
47 (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority()
48 (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()
49 (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler()
50 (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())
51 (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()
52 (+++) Configure and enable two DMA streams stream for managing data
53 transfer from peripheral to memory (output stream)
54 (+++) Associate the initilalized DMA handle to the CRYP DMA handle
56 (+++) Configure the priority and enable the NVIC for the transfer complete
57 interrupt on the two DMA Streams. The output stream should have higher
58 priority than the input stream.
60 (#) Configure the ADC Prescaler, conversion resolution and data alignment
61 using the HAL_ADC_Init() function.
63 (#) Configure the ADC regular channels group features, use HAL_ADC_Init()
64 and HAL_ADC_ConfigChannel() functions.
66 (#) Three operation modes are available within this driver :
68 *** Polling mode IO operation ***
69 =================================
71 (+) Start the ADC peripheral using HAL_ADC_Start()
72 (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage
73 user can specify the value of timeout according to his end application
74 (+) To read the ADC converted values, use the HAL_ADC_GetValue() function.
75 (+) Stop the ADC peripheral using HAL_ADC_Stop()
77 *** Interrupt mode IO operation ***
78 ===================================
80 (+) Start the ADC peripheral using HAL_ADC_Start_IT()
81 (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine
82 (+) At ADC end of conversion HAL_ADC_ConvCpltCallback() function is executed and user can
83 add his own code by customization of function pointer HAL_ADC_ConvCpltCallback
84 (+) In case of ADC Error, HAL_ADC_ErrorCallback() function is executed and user can
85 add his own code by customization of function pointer HAL_ADC_ErrorCallback
86 (+) Stop the ADC peripheral using HAL_ADC_Stop_IT()
88 *** DMA mode IO operation ***
89 ==============================
91 (+) Start the ADC peripheral using HAL_ADC_Start_DMA(), at this stage the user specify the length
92 of data to be transferred at each end of conversion
93 (+) At The end of data transfer by HAL_ADC_ConvCpltCallback() function is executed and user can
94 add his own code by customization of function pointer HAL_ADC_ConvCpltCallback
95 (+) In case of transfer Error, HAL_ADC_ErrorCallback() function is executed and user can
96 add his own code by customization of function pointer HAL_ADC_ErrorCallback
97 (+) Stop the ADC peripheral using HAL_ADC_Stop_DMA()
99 *** ADC HAL driver macros list ***
100 =============================================
102 Below the list of most used macros in ADC HAL driver.
104 (+) __HAL_ADC_ENABLE : Enable the ADC peripheral
105 (+) __HAL_ADC_DISABLE : Disable the ADC peripheral
106 (+) __HAL_ADC_ENABLE_IT: Enable the ADC end of conversion interrupt
107 (+) __HAL_ADC_DISABLE_IT: Disable the ADC end of conversion interrupt
108 (+) __HAL_ADC_GET_IT_SOURCE: Check if the specified ADC interrupt source is enabled or disabled
109 (+) __HAL_ADC_CLEAR_FLAG: Clear the ADC's pending flags
110 (+) __HAL_ADC_GET_FLAG: Get the selected ADC's flag status
111 (+) __HAL_ADC_GET_RESOLUTION: Return resolution bits in CR1 register
114 (@) You can refer to the ADC HAL driver header file for more useful macros
117 ******************************************************************************
120 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
122 * Redistribution and use in source and binary forms, with or without modification,
123 * are permitted provided that the following conditions are met:
124 * 1. Redistributions of source code must retain the above copyright notice,
125 * this list of conditions and the following disclaimer.
126 * 2. Redistributions in binary form must reproduce the above copyright notice,
127 * this list of conditions and the following disclaimer in the documentation
128 * and/or other materials provided with the distribution.
129 * 3. Neither the name of STMicroelectronics nor the names of its contributors
130 * may be used to endorse or promote products derived from this software
131 * without specific prior written permission.
133 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
134 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
135 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
136 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
137 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
138 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
139 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
140 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
141 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
142 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144 ******************************************************************************
147 /* Includes ------------------------------------------------------------------*/
148 #include "stm32f4xx_hal.h"
150 /** @addtogroup STM32F4xx_HAL_Driver
155 * @brief ADC driver modules
159 #ifdef HAL_ADC_MODULE_ENABLED
161 /* Private typedef -----------------------------------------------------------*/
162 /* Private define ------------------------------------------------------------*/
163 /* Private macro -------------------------------------------------------------*/
164 /* Private variables ---------------------------------------------------------*/
165 /* Private function prototypes -----------------------------------------------*/
166 static void ADC_Init(ADC_HandleTypeDef* hadc);
167 static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma);
168 static void ADC_DMAError(DMA_HandleTypeDef *hdma);
169 static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma);
170 /* Private functions ---------------------------------------------------------*/
172 /** @defgroup ADC_Private_Functions
176 /** @defgroup ADC_Group1 Initialization and de-initialization functions
177 * @brief Initialization and Configuration functions
180 ===============================================================================
181 ##### Initialization and de-initialization functions #####
182 ===============================================================================
183 [..] This section provides functions allowing to:
184 (+) Initialize and configure the ADC.
185 (+) De-initialize the ADC.
192 * @brief Initializes the ADCx peripheral according to the specified parameters
193 * in the ADC_InitStruct and initializes the ADC MSP.
195 * @note This function is used to configure the global features of the ADC (
196 * ClockPrescaler, Resolution, Data Alignment and number of conversion), however,
197 * the rest of the configuration parameters are specific to the regular
198 * channels group (scan mode activation, continuous mode activation,
199 * External trigger source and edge, DMA continuous request after the
200 * last transfer and End of conversion selection).
202 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
203 * the configuration information for the specified ADC.
206 HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
208 /* Check ADC handle */
214 /* Check the parameters */
215 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
216 assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler));
217 assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution));
218 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ScanConvMode));
219 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
220 assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
221 assert_param(IS_ADC_EXT_TRIG(hadc->Init.ExternalTrigConv));
222 assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign));
223 assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion));
224 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
225 assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection));
226 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
228 if(hadc->State == HAL_ADC_STATE_RESET)
230 /* Init the low level hardware */
231 HAL_ADC_MspInit(hadc);
234 /* Initialize the ADC state */
235 hadc->State = HAL_ADC_STATE_BUSY;
237 /* Set ADC parameters */
240 /* Set ADC error code to none */
241 hadc->ErrorCode = HAL_ADC_ERROR_NONE;
243 /* Initialize the ADC state */
244 hadc->State = HAL_ADC_STATE_READY;
249 /* Return function status */
254 * @brief Deinitializes the ADCx peripheral registers to their default reset values.
255 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
256 * the configuration information for the specified ADC.
259 HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
261 /* Check ADC handle */
267 /* Check the parameters */
268 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
270 /* Change ADC state */
271 hadc->State = HAL_ADC_STATE_BUSY;
273 /* DeInit the low level hardware */
274 HAL_ADC_MspDeInit(hadc);
276 /* Set ADC error code to none */
277 hadc->ErrorCode = HAL_ADC_ERROR_NONE;
279 /* Change ADC state */
280 hadc->State = HAL_ADC_STATE_RESET;
282 /* Return function status */
287 * @brief Initializes the ADC MSP.
288 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
289 * the configuration information for the specified ADC.
292 __weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
294 /* NOTE : This function Should not be modified, when the callback is needed,
295 the HAL_ADC_MspInit could be implemented in the user file
300 * @brief DeInitializes the ADC MSP.
301 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
302 * the configuration information for the specified ADC.
305 __weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
307 /* NOTE : This function Should not be modified, when the callback is needed,
308 the HAL_ADC_MspDeInit could be implemented in the user file
316 /** @defgroup ADC_Group2 IO operation functions
317 * @brief IO operation functions
320 ===============================================================================
321 ##### IO operation functions #####
322 ===============================================================================
323 [..] This section provides functions allowing to:
324 (+) Start conversion of regular channel.
325 (+) Stop conversion of regular channel.
326 (+) Start conversion of regular channel and enable interrupt.
327 (+) Stop conversion of regular channel and disable interrupt.
328 (+) Start conversion of regular channel and enable DMA transfer.
329 (+) Stop conversion of regular channel and disable DMA transfer.
330 (+) Handle ADC interrupt request.
337 * @brief Enables ADC and starts conversion of the regular channels.
338 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
339 * the configuration information for the specified ADC.
342 HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
346 /* Check the parameters */
347 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
348 assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
353 /* Check if an injected conversion is ongoing */
354 if(hadc->State == HAL_ADC_STATE_BUSY_INJ)
356 /* Change ADC state */
357 hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;
361 /* Change ADC state */
362 hadc->State = HAL_ADC_STATE_BUSY_REG;
365 /* Check if ADC peripheral is disabled in order to enable it and wait during
366 Tstab time the ADC's stabilization */
367 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
369 /* Enable the Peripheral */
370 __HAL_ADC_ENABLE(hadc);
372 /* Delay inserted to wait during Tstab time the ADC's stabilazation */
379 /* Check if Multimode enabled */
380 if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
382 /* if no external trigger present enable software conversion of regular channels */
383 if(hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE)
385 /* Enable the selected ADC software conversion for regular group */
386 hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
391 /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
392 if((hadc->Instance == ADC1) && (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE))
394 /* Enable the selected ADC software conversion for regular group */
395 hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
399 /* Process unlocked */
402 /* Return function status */
407 * @brief Disables ADC and stop conversion of regular channels.
409 * @note Caution: This function will stop also injected channels.
411 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
412 * the configuration information for the specified ADC.
414 * @retval HAL status.
416 HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
418 /* Disable the Peripheral */
419 __HAL_ADC_DISABLE(hadc);
421 /* Change ADC state */
422 hadc->State = HAL_ADC_STATE_READY;
424 /* Return function status */
429 * @brief Poll for regular conversion complete
430 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
431 * the configuration information for the specified ADC.
432 * @param Timeout: Timeout value in millisecond.
435 HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
437 uint32_t tickstart = 0;
440 tickstart = HAL_GetTick();
442 /* Check End of conversion flag */
443 while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC)))
445 /* Check for the Timeout */
446 if(Timeout != HAL_MAX_DELAY)
448 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
450 hadc->State= HAL_ADC_STATE_TIMEOUT;
451 /* Process unlocked */
458 /* Check if an injected conversion is ready */
459 if(hadc->State == HAL_ADC_STATE_EOC_INJ)
461 /* Change ADC state */
462 hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
466 /* Change ADC state */
467 hadc->State = HAL_ADC_STATE_EOC_REG;
470 /* Return ADC state */
475 * @brief Poll for conversion event
476 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
477 * the configuration information for the specified ADC.
478 * @param EventType: the ADC event type.
479 * This parameter can be one of the following values:
480 * @arg AWD_EVENT: ADC Analog watch Dog event.
481 * @arg OVR_EVENT: ADC Overrun event.
482 * @param Timeout: Timeout value in millisecond.
485 HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout)
487 uint32_t tickstart = 0;
489 /* Check the parameters */
490 assert_param(IS_ADC_EVENT_TYPE(EventType));
493 tickstart = HAL_GetTick();
495 /* Check selected event flag */
496 while(!(__HAL_ADC_GET_FLAG(hadc,EventType)))
498 /* Check for the Timeout */
499 if(Timeout != HAL_MAX_DELAY)
501 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
503 hadc->State= HAL_ADC_STATE_TIMEOUT;
504 /* Process unlocked */
511 /* Check analog watchdog flag */
512 if(EventType == AWD_EVENT)
514 /* Change ADC state */
515 hadc->State = HAL_ADC_STATE_AWD;
517 /* Clear the ADCx's analog watchdog flag */
518 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
522 /* Change ADC state */
523 hadc->State = HAL_ADC_STATE_ERROR;
525 /* Clear the ADCx's Overrun flag */
526 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
529 /* Return ADC state */
535 * @brief Enables the interrupt and starts ADC conversion of regular channels.
536 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
537 * the configuration information for the specified ADC.
538 * @retval HAL status.
540 HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
544 /* Check the parameters */
545 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
546 assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
551 /* Check if an injected conversion is ongoing */
552 if(hadc->State == HAL_ADC_STATE_BUSY_INJ)
554 /* Change ADC state */
555 hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;
559 /* Change ADC state */
560 hadc->State = HAL_ADC_STATE_BUSY_REG;
563 /* Set ADC error code to none */
564 hadc->ErrorCode = HAL_ADC_ERROR_NONE;
566 /* Check if ADC peripheral is disabled in order to enable it and wait during
567 Tstab time the ADC's stabilization */
568 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
570 /* Enable the Peripheral */
571 __HAL_ADC_ENABLE(hadc);
573 /* Delay inserted to wait during Tstab time the ADC's stabilazation */
580 /* Enable the ADC overrun interrupt */
581 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
583 /* Enable the ADC end of conversion interrupt for regular group */
584 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC);
586 /* Check if Multimode enabled */
587 if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
589 /* if no externel trigger present enable software conversion of regular channels */
590 if (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE)
592 /* Enable the selected ADC software conversion for regular group */
593 hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
598 /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
599 if ((hadc->Instance == (ADC_TypeDef*)0x40012000) && (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE))
601 /* Enable the selected ADC software conversion for regular group */
602 hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
606 /* Process unlocked */
609 /* Return function status */
614 * @brief Disables the interrupt and stop ADC conversion of regular channels.
616 * @note Caution: This function will stop also injected channels.
618 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
619 * the configuration information for the specified ADC.
620 * @retval HAL status.
622 HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc)
624 /* Disable the ADC end of conversion interrupt for regular group */
625 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
627 /* Disable the ADC end of conversion interrupt for injected group */
628 __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE);
630 /* Enable the Periphral */
631 __HAL_ADC_DISABLE(hadc);
633 /* Change ADC state */
634 hadc->State = HAL_ADC_STATE_READY;
636 /* Return function status */
641 * @brief Handles ADC interrupt request
642 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
643 * the configuration information for the specified ADC.
646 void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
648 uint32_t tmp1 = 0, tmp2 = 0;
650 /* Check the parameters */
651 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
652 assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion));
653 assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection));
655 tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC);
656 tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC);
657 /* Check End of conversion flag for regular channels */
660 /* Check if an injected conversion is ready */
661 if(hadc->State == HAL_ADC_STATE_EOC_INJ)
663 /* Change ADC state */
664 hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
668 /* Change ADC state */
669 hadc->State = HAL_ADC_STATE_EOC_REG;
672 if((hadc->Init.ContinuousConvMode == DISABLE) && (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE))
674 if(hadc->Init.EOCSelection == EOC_SEQ_CONV)
676 /* DISABLE the ADC end of conversion interrupt for regular group */
677 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
679 /* DISABLE the ADC overrun interrupt */
680 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
684 if (hadc->NbrOfCurrentConversionRank == 0)
686 hadc->NbrOfCurrentConversionRank = hadc->Init.NbrOfConversion;
689 /* Decrement the number of conversion when an interrupt occurs */
690 hadc->NbrOfCurrentConversionRank--;
692 /* Check if all conversions are finished */
693 if(hadc->NbrOfCurrentConversionRank == 0)
695 /* DISABLE the ADC end of conversion interrupt for regular group */
696 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
698 /* DISABLE the ADC overrun interrupt */
699 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
704 /* Conversion complete callback */
705 HAL_ADC_ConvCpltCallback(hadc);
707 /* Clear the ADCx flag for regular end of conversion */
708 __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_EOC);
711 tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC);
712 tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC);
713 /* Check End of conversion flag for injected channels */
716 /* Check if a regular conversion is ready */
717 if(hadc->State == HAL_ADC_STATE_EOC_REG)
719 /* Change ADC state */
720 hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
724 /* Change ADC state */
725 hadc->State = HAL_ADC_STATE_EOC_INJ;
728 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
729 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
730 if(((hadc->Init.ContinuousConvMode == DISABLE) || tmp1) && tmp2)
732 /* DISABLE the ADC end of conversion interrupt for injected group */
733 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
736 /* Conversion complete callback */
737 HAL_ADCEx_InjectedConvCpltCallback(hadc);
739 /* Clear the ADCx flag for injected end of conversion */
740 __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC);
743 tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD);
744 tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD);
745 /* Check Analog watchdog flag */
748 /* Change ADC state */
749 hadc->State = HAL_ADC_STATE_AWD;
751 /* Clear the ADCx's Analog watchdog flag */
752 __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_AWD);
754 /* Level out of window callback */
755 HAL_ADC_LevelOutOfWindowCallback(hadc);
758 tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_OVR);
759 tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_OVR);
760 /* Check Overrun flag */
763 /* Change ADC state to overrun state */
764 hadc->State = HAL_ADC_STATE_ERROR;
766 /* Set ADC error code to overrun */
767 hadc->ErrorCode |= HAL_ADC_ERROR_OVR;
769 /* Clear the Overrun flag */
770 __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_OVR);
773 HAL_ADC_ErrorCallback(hadc);
778 * @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral
779 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
780 * the configuration information for the specified ADC.
781 * @param pData: The destination Buffer address.
782 * @param Length: The length of data to be transferred from ADC peripheral to memory.
785 HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
789 /* Check the parameters */
790 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
791 assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
796 /* Enable ADC overrun interrupt */
797 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
799 /* Enable ADC DMA mode */
800 hadc->Instance->CR2 |= ADC_CR2_DMA;
802 /* Set the DMA transfer complete callback */
803 hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
805 /* Set the DMA half transfer complete callback */
806 hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
808 /* Set the DMA error callback */
809 hadc->DMA_Handle->XferErrorCallback = ADC_DMAError ;
811 /* Enable the DMA Stream */
812 HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
814 /* Change ADC state */
815 hadc->State = HAL_ADC_STATE_BUSY_REG;
817 /* Check if ADC peripheral is disabled in order to enable it and wait during
818 Tstab time the ADC's stabilization */
819 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
821 /* Enable the Peripheral */
822 __HAL_ADC_ENABLE(hadc);
824 /* Delay inserted to wait during Tstab time the ADC's stabilazation */
831 /* if no external trigger present enable software conversion of regular channels */
832 if (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE)
834 /* Enable the selected ADC software conversion for regular group */
835 hadc->Instance->CR2 |= ADC_CR2_SWSTART;
838 /* Process unlocked */
841 /* Return function status */
846 * @brief Disables ADC DMA (Single-ADC mode) and disables ADC peripheral
847 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
848 * the configuration information for the specified ADC.
851 HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc)
853 /* Disable the Periphral */
854 __HAL_ADC_DISABLE(hadc);
856 /* Disable ADC overrun interrupt */
857 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
859 /* Disable the selected ADC DMA mode */
860 hadc->Instance->CR2 &= ~ADC_CR2_DMA;
862 /* Disable the ADC DMA Stream */
863 HAL_DMA_Abort(hadc->DMA_Handle);
865 /* Change ADC state */
866 hadc->State = HAL_ADC_STATE_READY;
868 /* Return function status */
873 * @brief Gets the converted value from data register of regular channel.
874 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
875 * the configuration information for the specified ADC.
876 * @retval Converted value
878 uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
880 /* Return the selected ADC converted value */
881 return hadc->Instance->DR;
885 * @brief Regular conversion complete callback in non blocking mode
886 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
887 * the configuration information for the specified ADC.
890 __weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
892 /* NOTE : This function Should not be modified, when the callback is needed,
893 the HAL_ADC_ConvCpltCallback could be implemented in the user file
898 * @brief Regular conversion half DMA transfer callback in non blocking mode
899 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
900 * the configuration information for the specified ADC.
903 __weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
905 /* NOTE : This function Should not be modified, when the callback is needed,
906 the HAL_ADC_ConvHalfCpltCallback could be implemented in the user file
911 * @brief Analog watchdog callback in non blocking mode
912 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
913 * the configuration information for the specified ADC.
916 __weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
918 /* NOTE : This function Should not be modified, when the callback is needed,
919 the HAL_ADC_LevelOoutOfWindowCallback could be implemented in the user file
924 * @brief Error ADC callback.
925 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
926 * the configuration information for the specified ADC.
929 __weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
931 /* NOTE : This function Should not be modified, when the callback is needed,
932 the HAL_ADC_ErrorCallback could be implemented in the user file
940 /** @defgroup ADC_Group3 Peripheral Control functions
941 * @brief Peripheral Control functions
944 ===============================================================================
945 ##### Peripheral Control functions #####
946 ===============================================================================
947 [..] This section provides functions allowing to:
948 (+) Configure regular channels.
949 (+) Configure injected channels.
950 (+) Configure multimode.
951 (+) Configure the analog watch dog.
958 * @brief Configures for the selected ADC regular channel its corresponding
959 * rank in the sequencer and its sample time.
960 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
961 * the configuration information for the specified ADC.
962 * @param sConfig: ADC configuration structure.
965 HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)
967 /* Check the parameters */
968 assert_param(IS_ADC_CHANNEL(sConfig->Channel));
969 assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank));
970 assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));
975 /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
976 if (sConfig->Channel > ADC_CHANNEL_9)
978 /* Clear the old sample time */
979 hadc->Instance->SMPR1 &= ~__HAL_ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel);
981 /* Set the new sample time */
982 hadc->Instance->SMPR1 |= __HAL_ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel);
984 else /* ADC_Channel include in ADC_Channel_[0..9] */
986 /* Clear the old sample time */
987 hadc->Instance->SMPR2 &= ~__HAL_ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel);
989 /* Set the new sample time */
990 hadc->Instance->SMPR2 |= __HAL_ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel);
993 /* For Rank 1 to 6 */
994 if (sConfig->Rank < 7)
996 /* Clear the old SQx bits for the selected rank */
997 hadc->Instance->SQR3 &= ~__HAL_ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank);
999 /* Set the SQx bits for the selected rank */
1000 hadc->Instance->SQR3 |= __HAL_ADC_SQR3_RK(sConfig->Channel, sConfig->Rank);
1002 /* For Rank 7 to 12 */
1003 else if (sConfig->Rank < 13)
1005 /* Clear the old SQx bits for the selected rank */
1006 hadc->Instance->SQR2 &= ~__HAL_ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank);
1008 /* Set the SQx bits for the selected rank */
1009 hadc->Instance->SQR2 |= __HAL_ADC_SQR2_RK(sConfig->Channel, sConfig->Rank);
1011 /* For Rank 13 to 16 */
1014 /* Clear the old SQx bits for the selected rank */
1015 hadc->Instance->SQR1 &= ~__HAL_ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank);
1017 /* Set the SQx bits for the selected rank */
1018 hadc->Instance->SQR1 |= __HAL_ADC_SQR1_RK(sConfig->Channel, sConfig->Rank);
1021 /* if ADC1 Channel_18 is selected enable VBAT Channel */
1022 if ((hadc->Instance == ADC1) && (sConfig->Channel == ADC_CHANNEL_VBAT))
1024 /* Enable the VBAT channel*/
1025 ADC->CCR |= ADC_CCR_VBATE;
1028 /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */
1029 if ((hadc->Instance == ADC1) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT)))
1031 /* Enable the TSVREFE channel*/
1032 ADC->CCR |= ADC_CCR_TSVREFE;
1035 /* Process unlocked */
1038 /* Return function status */
1043 * @brief Configures the analog watchdog.
1044 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
1045 * the configuration information for the specified ADC.
1046 * @param AnalogWDGConfig : pointer to an ADC_AnalogWDGConfTypeDef structure
1047 * that contains the configuration information of ADC analog watchdog.
1048 * @retval HAL status
1050 HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig)
1052 #ifdef USE_FULL_ASSERT
1054 #endif /* USE_FULL_ASSERT */
1056 /* Check the parameters */
1057 assert_param(IS_ADC_ANALOG_WATCHDOG(AnalogWDGConfig->WatchdogMode));
1058 assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
1059 assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode));
1061 #ifdef USE_FULL_ASSERT
1062 tmp = __HAL_ADC_GET_RESOLUTION(hadc);
1063 assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->HighThreshold));
1064 assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->LowThreshold));
1065 #endif /* USE_FULL_ASSERT */
1067 /* Process locked */
1070 if(AnalogWDGConfig->ITMode == ENABLE)
1072 /* Enable the ADC Analog watchdog interrupt */
1073 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD);
1077 /* Disable the ADC Analog watchdog interrupt */
1078 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD);
1081 /* Clear AWDEN, JAWDEN and AWDSGL bits */
1082 hadc->Instance->CR1 &= ~(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN | ADC_CR1_AWDEN);
1084 /* Set the analog watchdog enable mode */
1085 hadc->Instance->CR1 |= AnalogWDGConfig->WatchdogMode;
1087 /* Set the high threshold */
1088 hadc->Instance->HTR = AnalogWDGConfig->HighThreshold;
1090 /* Set the low threshold */
1091 hadc->Instance->LTR = AnalogWDGConfig->LowThreshold;
1093 /* Clear the Analog watchdog channel select bits */
1094 hadc->Instance->CR1 &= ~ADC_CR1_AWDCH;
1096 /* Set the Analog watchdog channel */
1097 hadc->Instance->CR1 |= AnalogWDGConfig->Channel;
1099 /* Process unlocked */
1102 /* Return function status */
1110 /** @defgroup ADC_Group4 ADC Peripheral State functions
1111 * @brief ADC Peripheral State functions
1114 ===============================================================================
1115 ##### Peripheral State and errors functions #####
1116 ===============================================================================
1118 This subsection provides functions allowing to
1119 (+) Check the ADC state
1120 (+) Check the ADC Error
1127 * @brief return the ADC state
1128 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
1129 * the configuration information for the specified ADC.
1132 HAL_ADC_StateTypeDef HAL_ADC_GetState(ADC_HandleTypeDef* hadc)
1134 /* Return ADC state */
1139 * @brief Return the ADC error code
1140 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
1141 * the configuration information for the specified ADC.
1142 * @retval ADC Error Code
1144 uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc)
1146 return hadc->ErrorCode;
1154 * @brief Initializes the ADCx peripheral according to the specified parameters
1155 * in the ADC_InitStruct without initializing the ADC MSP.
1156 * @param hadc: pointer to a ADC_HandleTypeDef structure that contains
1157 * the configuration information for the specified ADC.
1160 static void ADC_Init(ADC_HandleTypeDef* hadc)
1163 /* Set ADC parameters */
1164 /* Set the ADC clock prescaler */
1165 ADC->CCR &= ~(ADC_CCR_ADCPRE);
1166 ADC->CCR |= hadc->Init.ClockPrescaler;
1168 /* Set ADC scan mode */
1169 hadc->Instance->CR1 &= ~(ADC_CR1_SCAN);
1170 hadc->Instance->CR1 |= __HAL_ADC_CR1_SCANCONV(hadc->Init.ScanConvMode);
1172 /* Set ADC resolution */
1173 hadc->Instance->CR1 &= ~(ADC_CR1_RES);
1174 hadc->Instance->CR1 |= hadc->Init.Resolution;
1176 /* Set ADC data alignment */
1177 hadc->Instance->CR2 &= ~(ADC_CR2_ALIGN);
1178 hadc->Instance->CR2 |= hadc->Init.DataAlign;
1180 /* Select external trigger to start conversion */
1181 hadc->Instance->CR2 &= ~(ADC_CR2_EXTSEL);
1182 hadc->Instance->CR2 |= hadc->Init.ExternalTrigConv;
1184 /* Select external trigger polarity */
1185 hadc->Instance->CR2 &= ~(ADC_CR2_EXTEN);
1186 hadc->Instance->CR2 |= hadc->Init.ExternalTrigConvEdge;
1188 /* Enable or disable ADC continuous conversion mode */
1189 hadc->Instance->CR2 &= ~(ADC_CR2_CONT);
1190 hadc->Instance->CR2 |= __HAL_ADC_CR2_CONTINUOUS(hadc->Init.ContinuousConvMode);
1192 if (hadc->Init.DiscontinuousConvMode != DISABLE)
1194 assert_param(IS_ADC_REGULAR_DISC_NUMBER(hadc->Init.NbrOfDiscConversion));
1196 /* Enable the selected ADC regular discontinuous mode */
1197 hadc->Instance->CR1 |= (uint32_t)ADC_CR1_DISCEN;
1199 /* Set the number of channels to be converted in discontinuous mode */
1200 hadc->Instance->CR1 &= ~(ADC_CR1_DISCNUM);
1201 hadc->Instance->CR1 |= __HAL_ADC_CR1_DISCONTINUOUS(hadc->Init.NbrOfDiscConversion);
1205 /* Disable the selected ADC regular discontinuous mode */
1206 hadc->Instance->CR1 &= ~(ADC_CR1_DISCEN);
1209 /* Set ADC number of conversion */
1210 hadc->Instance->SQR1 &= ~(ADC_SQR1_L);
1211 hadc->Instance->SQR1 |= __HAL_ADC_SQR1(hadc->Init.NbrOfConversion);
1213 /* Enable or disable ADC DMA continuous request */
1214 hadc->Instance->CR2 &= ~(ADC_CR2_DDS);
1215 hadc->Instance->CR2 |= __HAL_ADC_CR2_DMAContReq(hadc->Init.DMAContinuousRequests);
1217 /* Enable or disable ADC end of conversion selection */
1218 hadc->Instance->CR2 &= ~(ADC_CR2_EOCS);
1219 hadc->Instance->CR2 |= __HAL_ADC_CR2_EOCSelection(hadc->Init.EOCSelection);
1223 * @brief DMA transfer complete callback.
1224 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1225 * the configuration information for the specified DMA module.
1228 static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
1230 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1232 /* Check if an injected conversion is ready */
1233 if(hadc->State == HAL_ADC_STATE_EOC_INJ)
1235 /* Change ADC state */
1236 hadc->State = HAL_ADC_STATE_EOC_INJ_REG;
1240 /* Change ADC state */
1241 hadc->State = HAL_ADC_STATE_EOC_REG;
1244 HAL_ADC_ConvCpltCallback(hadc);
1248 * @brief DMA half transfer complete callback.
1249 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1250 * the configuration information for the specified DMA module.
1253 static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
1255 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1256 /* Conversion complete callback */
1257 HAL_ADC_ConvHalfCpltCallback(hadc);
1261 * @brief DMA error callback
1262 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
1263 * the configuration information for the specified DMA module.
1266 static void ADC_DMAError(DMA_HandleTypeDef *hdma)
1268 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1269 hadc->State= HAL_ADC_STATE_ERROR;
1270 /* Set ADC error code to DMA error */
1271 hadc->ErrorCode |= HAL_ADC_ERROR_DMA;
1272 HAL_ADC_ErrorCallback(hadc);
1280 #endif /* HAL_ADC_MODULE_ENABLED */
1289 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/