1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_hal_adc_ex.c
4   * @author  MCD Application Team
5   * @brief   This file provides firmware functions to manage the following
6   *          functionalities of the Analog to Digital Convertor (ADC)
7   *          peripheral:
8   *           + Peripheral Control functions
9   *          Other functions (generic functions) are available in file
10   *          "stm32f0xx_hal_adc.c".
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2016 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   [..]
25   (@) Sections "ADC peripheral features" and "How to use this driver" are
26       available in file of generic functions "stm32l1xx_hal_adc.c".
27   [..]
28   @endverbatim
29   */
30 
31 /* Includes ------------------------------------------------------------------*/
32 #include "stm32f0xx_hal.h"
33 
34 /** @addtogroup STM32F0xx_HAL_Driver
35   * @{
36   */
37 
38 /** @defgroup ADCEx ADCEx
39   * @brief ADC HAL module driver
40   * @{
41   */
42 
43 #ifdef HAL_ADC_MODULE_ENABLED
44 
45 /* Private typedef -----------------------------------------------------------*/
46 /* Private define ------------------------------------------------------------*/
47 /** @defgroup ADCEx_Private_Constants ADCEx Private Constants
48   * @{
49   */
50 
51 /* Fixed timeout values for ADC calibration, enable settling time, disable  */
52   /* settling time.                                                           */
53   /* Values defined to be higher than worst cases: low clock frequency,       */
54   /* maximum prescaler.                                                       */
55   /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock         */
56   /* prescaler 4.                                                             */
57   /* Unit: ms                                                                 */
58   #define ADC_DISABLE_TIMEOUT           2
59   #define ADC_CALIBRATION_TIMEOUT       2U
60 /**
61   * @}
62   */
63 
64 /* Private macros -------------------------------------------------------------*/
65 /* Private variables ---------------------------------------------------------*/
66 /* Private function prototypes -----------------------------------------------*/
67 /* Private functions ---------------------------------------------------------*/
68 
69 /** @defgroup ADCEx_Exported_Functions ADCEx Exported Functions
70   * @{
71   */
72 
73 /** @defgroup ADCEx_Exported_Functions_Group1 Extended Initialization/de-initialization functions
74  *  @brief    Extended Initialization and Configuration functions
75  *
76 @verbatim
77  ===============================================================================
78                       ##### IO operation functions #####
79  ===============================================================================
80     [..]  This section provides functions allowing to:
81       (+) Perform the ADC calibration.
82 @endverbatim
83   * @{
84   */
85 
86 /**
87   * @brief  Perform an ADC automatic self-calibration
88   *         Calibration prerequisite: ADC must be disabled (execute this
89   *         function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
90   * @note   Calibration factor can be read after calibration, using function
91   *         HAL_ADC_GetValue() (value on 7 bits: from DR[6;0]).
92   * @param  hadc ADC handle
93   * @retval HAL status
94   */
HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef * hadc)95 HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc)
96 {
97   HAL_StatusTypeDef tmp_hal_status = HAL_OK;
98   uint32_t tickstart = 0U;
99   uint32_t backup_setting_adc_dma_transfer = 0; /* Note: Variable not declared as volatile because register read is already declared as volatile */
100 
101   /* Check the parameters */
102   assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
103 
104   /* Process locked */
105   __HAL_LOCK(hadc);
106 
107   /* Calibration prerequisite: ADC must be disabled. */
108   if (ADC_IS_ENABLE(hadc) == RESET)
109   {
110     /* Set ADC state */
111     ADC_STATE_CLR_SET(hadc->State,
112                       HAL_ADC_STATE_REG_BUSY,
113                       HAL_ADC_STATE_BUSY_INTERNAL);
114 
115     /* Disable ADC DMA transfer request during calibration */
116     /* Note: Specificity of this STM32 series: Calibration factor is           */
117     /*       available in data register and also transferred by DMA.           */
118     /*       To not insert ADC calibration factor among ADC conversion data   */
119     /*       in array variable, DMA transfer must be disabled during          */
120     /*       calibration.                                                     */
121     backup_setting_adc_dma_transfer = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
122     CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
123 
124     /* Start ADC calibration */
125     hadc->Instance->CR |= ADC_CR_ADCAL;
126 
127     tickstart = HAL_GetTick();
128 
129     /* Wait for calibration completion */
130     while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADCAL))
131     {
132       if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
133       {
134         /* New check to avoid false timeout detection in case of preemption */
135         if(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADCAL))
136         {
137           /* Update ADC state machine to error */
138           ADC_STATE_CLR_SET(hadc->State,
139                             HAL_ADC_STATE_BUSY_INTERNAL,
140                             HAL_ADC_STATE_ERROR_INTERNAL);
141 
142           /* Process unlocked */
143           __HAL_UNLOCK(hadc);
144 
145           return HAL_ERROR;
146         }
147       }
148     }
149 
150     /* Restore ADC DMA transfer request after calibration */
151     SET_BIT(hadc->Instance->CFGR1, backup_setting_adc_dma_transfer);
152 
153     /* Set ADC state */
154     ADC_STATE_CLR_SET(hadc->State,
155                       HAL_ADC_STATE_BUSY_INTERNAL,
156                       HAL_ADC_STATE_READY);
157   }
158   else
159   {
160     /* Update ADC state machine to error */
161     SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
162 
163     tmp_hal_status = HAL_ERROR;
164   }
165 
166   /* Process unlocked */
167   __HAL_UNLOCK(hadc);
168 
169   /* Return function status */
170   return tmp_hal_status;
171 }
172 
173 /**
174   * @}
175   */
176 
177 /**
178   * @}
179   */
180 
181 #endif /* HAL_ADC_MODULE_ENABLED */
182 /**
183   * @}
184   */
185 
186 /**
187   * @}
188   */
189 
190