1 /**
2 ******************************************************************************
3 * @file stm32wbaxx_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 Converter (ADC)
7 * peripheral:
8 * + Peripheral Control functions
9 * Other functions (generic functions) are available in file
10 * "stm32wbaxx_hal_adc.c".
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2022 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 "stm32wbaxx_hal_adc.c".
27 [..]
28 @endverbatim
29 ******************************************************************************
30 */
31
32 /* Includes ------------------------------------------------------------------*/
33 #include "stm32wbaxx_hal.h"
34
35 /** @addtogroup STM32WBAxx_HAL_Driver
36 * @{
37 */
38
39 /** @defgroup ADCEx ADCEx
40 * @brief ADC Extended HAL module driver
41 * @{
42 */
43
44 #ifdef HAL_ADC_MODULE_ENABLED
45
46 /* Private typedef -----------------------------------------------------------*/
47 /* Private define ------------------------------------------------------------*/
48
49 /** @defgroup ADCEx_Private_Constants ADC Extended Private Constants
50 * @{
51 */
52
53 /* Fixed timeout value for ADC calibration. */
54 /* Values defined to be higher than worst cases: maximum ratio between ADC */
55 /* and CPU clock frequencies. */
56 /* Example of profile low frequency : ADC frequency at 31.25kHz (ADC clock */
57 /* source PLL 8MHz, ADC clock prescaler 256), CPU frequency 100MHz. */
58 /* Calibration time max = 116 / fADC (refer to datasheet) */
59 /* = 371 200 CPU cycles */
60 #define ADC_CALIBRATION_TIMEOUT (178176UL) /*!< ADC calibration time-out value (unit: CPU cycles) */
61
62 /**
63 * @}
64 */
65
66 /* Private macro -------------------------------------------------------------*/
67 /* Private variables ---------------------------------------------------------*/
68 /* Private function prototypes -----------------------------------------------*/
69 /* Exported functions --------------------------------------------------------*/
70
71 /** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions
72 * @{
73 */
74
75 /** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions
76 * @brief Extended IO operation functions
77 *
78 @verbatim
79 ===============================================================================
80 ##### IO operation functions #####
81 ===============================================================================
82 [..] This section provides functions allowing to:
83
84 (+) Perform the ADC self-calibration.
85 (+) Get calibration factors.
86 (+) Set calibration factors.
87
88 @endverbatim
89 * @{
90 */
91
92 /**
93 * @brief Perform an ADC automatic self-calibration
94 * Calibration prerequisite: ADC must be disabled (execute this
95 * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
96 * @note Calibration factor can be read after calibration, using function
97 * HAL_ADC_GetValue() (value on 7 bits: from DR[6;0]).
98 * @param hadc ADC handle
99 * @retval HAL status
100 */
HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef * hadc)101 HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc)
102 {
103 HAL_StatusTypeDef tmp_hal_status;
104 __IO uint32_t wait_loop_index = 0UL;
105 uint32_t backup_setting_cfgr1;
106 uint32_t backup_setting_pwrr;
107
108 /* Check the parameters */
109 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
110
111 __HAL_LOCK(hadc);
112
113 /* Calibration prerequisite: ADC must be disabled. */
114
115 /* Disable the ADC (if not already disabled) */
116 tmp_hal_status = ADC_Disable(hadc);
117
118 /* Check if ADC is effectively disabled */
119 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
120 {
121 /* Set ADC state */
122 ADC_STATE_CLR_SET(hadc->State,
123 HAL_ADC_STATE_REG_BUSY,
124 HAL_ADC_STATE_BUSY_INTERNAL);
125
126 /* Manage settings impacting calibration */
127 /* - Disable ADC mode auto power-off */
128 /* - Disable ADC DMA transfer request during calibration */
129 /* Note: Specificity of this STM32 series: Calibration factor is */
130 /* available in data register and also transferred by DMA. */
131 /* To not insert ADC calibration factor among ADC conversion data */
132 /* in array variable, DMA transfer must be disabled during */
133 /* calibration. */
134 backup_setting_pwrr = READ_BIT(hadc->Instance->PWRR, ADC_PWRR_AUTOFF);
135 backup_setting_cfgr1 = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
136 CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
137 CLEAR_BIT(hadc->Instance->PWRR, ADC_PWRR_AUTOFF);
138
139 /* Start ADC calibration */
140 SET_BIT(hadc->Instance->CR, ADC_CR_ADCAL);
141
142 /* Wait for calibration completion */
143 while (LL_ADC_IsCalibrationOnGoing(hadc->Instance) != 0UL)
144 {
145 wait_loop_index++;
146 if (wait_loop_index >= ADC_CALIBRATION_TIMEOUT)
147 {
148 /* Update ADC state machine to error */
149 ADC_STATE_CLR_SET(hadc->State,
150 HAL_ADC_STATE_BUSY_INTERNAL,
151 HAL_ADC_STATE_ERROR_INTERNAL);
152
153 __HAL_UNLOCK(hadc);
154
155 return HAL_ERROR;
156 }
157 }
158
159 /* Restore configuration after calibration */
160 SET_BIT(hadc->Instance->CFGR1, backup_setting_cfgr1);
161 SET_BIT(hadc->Instance->PWRR, backup_setting_pwrr);
162
163 /* Set ADC state */
164 ADC_STATE_CLR_SET(hadc->State,
165 HAL_ADC_STATE_BUSY_INTERNAL,
166 HAL_ADC_STATE_READY);
167 }
168 else
169 {
170 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
171
172 /* Note: No need to update variable "tmp_hal_status" here: already set */
173 /* to state "HAL_ERROR" by function disabling the ADC. */
174 }
175
176 __HAL_UNLOCK(hadc);
177
178 return tmp_hal_status;
179 }
180
181 /**
182 * @brief Get the calibration factor.
183 * @param hadc ADC handle.
184 * @retval Calibration value.
185 */
HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef * hadc)186 uint32_t HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef *hadc)
187 {
188 /* Check the parameters */
189 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
190
191 /* Return the selected ADC calibration value */
192 return ((hadc->Instance->CALFACT) & 0x0000007FU);
193 }
194
195 /**
196 * @brief Set the calibration factor to overwrite automatic conversion result.
197 * ADC must be enabled and no conversion is ongoing.
198 * @param hadc ADC handle
199 * @param CalibrationFactor Calibration factor (coded on 7 bits maximum)
200 * @retval HAL state
201 */
HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef * hadc,uint32_t CalibrationFactor)202 HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t CalibrationFactor)
203 {
204 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
205 uint32_t tmp_adc_is_conversion_on_going_regular;
206
207 /* Check the parameters */
208 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
209 assert_param(IS_ADC_CALFACT(CalibrationFactor));
210
211 __HAL_LOCK(hadc);
212
213 /* Verification of hardware constraints before modifying the calibration */
214 /* factors register: ADC must be enabled, no conversion on going. */
215 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
216
217 if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
218 && (tmp_adc_is_conversion_on_going_regular == 0UL)
219 )
220 {
221 hadc->Instance->CALFACT &= ~ADC_CALFACT_CALFACT;
222 hadc->Instance->CALFACT |= CalibrationFactor;
223 }
224 else
225 {
226 /* Update ADC state machine */
227 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
228 /* Update ADC error code */
229 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
230
231 /* Update ADC state machine to error */
232 tmp_hal_status = HAL_ERROR;
233 }
234
235 __HAL_UNLOCK(hadc);
236
237 return tmp_hal_status;
238 }
239
240 /**
241 * @brief Analog watchdog 2 callback in non-blocking mode.
242 * @param hadc ADC handle
243 * @retval None
244 */
HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef * hadc)245 __weak void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc)
246 {
247 /* Prevent unused argument(s) compilation warning */
248 UNUSED(hadc);
249
250 /* NOTE : This function should not be modified. When the callback is needed,
251 function HAL_ADCEx_LevelOutOfWindow2Callback must be implemented in the user file.
252 */
253 }
254
255 /**
256 * @brief Analog watchdog 3 callback in non-blocking mode.
257 * @param hadc ADC handle
258 * @retval None
259 */
HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef * hadc)260 __weak void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc)
261 {
262 /* Prevent unused argument(s) compilation warning */
263 UNUSED(hadc);
264
265 /* NOTE : This function should not be modified. When the callback is needed,
266 function HAL_ADCEx_LevelOutOfWindow3Callback must be implemented in the user file.
267 */
268 }
269
270
271 /**
272 * @brief End Of Sampling callback in non-blocking mode.
273 * @param hadc ADC handle
274 * @retval None
275 */
HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef * hadc)276 __weak void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc)
277 {
278 /* Prevent unused argument(s) compilation warning */
279 UNUSED(hadc);
280
281 /* NOTE : This function should not be modified. When the callback is needed,
282 function HAL_ADCEx_EndOfSamplingCallback must be implemented in the user file.
283 */
284 }
285
286 /**
287 * @brief ADC internal voltage regulator ready callback in non-blocking mode.
288 * @param hadc ADC handle
289 * @retval None
290 */
HAL_ADCEx_LDOReadyCallback(ADC_HandleTypeDef * hadc)291 __weak void HAL_ADCEx_LDOReadyCallback(ADC_HandleTypeDef *hadc)
292 {
293 /* Prevent unused argument(s) compilation warning */
294 UNUSED(hadc);
295
296 /* NOTE : This function should not be modified. When the callback is needed,
297 function HAL_ADCEx_LDOReadyCallback must be implemented in the user file.
298 */
299 }
300
301 /**
302 * @}
303 */
304
305 /**
306 * @brief Disable ADC voltage regulator.
307 * @note Disabling voltage regulator allows to save power. This operation can
308 * be carried out only when ADC is disabled.
309 * @note To enable again the voltage regulator, the user is expected to
310 * resort to HAL_ADC_Init() API.
311 * @param hadc ADC handle
312 * @retval HAL status
313 */
HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef * hadc)314 HAL_StatusTypeDef HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef *hadc)
315 {
316 HAL_StatusTypeDef tmp_hal_status;
317
318 /* Check the parameters */
319 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
320
321 /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
322 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
323 {
324 LL_ADC_DisableInternalRegulator(hadc->Instance);
325 tmp_hal_status = HAL_OK;
326 }
327 else
328 {
329 tmp_hal_status = HAL_ERROR;
330 }
331
332 return tmp_hal_status;
333 }
334
335 /**
336 * @}
337 */
338
339 /**
340 * @}
341 */
342
343 #endif /* HAL_ADC_MODULE_ENABLED */
344 /**
345 * @}
346 */
347
348 /**
349 * @}
350 */
351