1 /**
2 ******************************************************************************
3 * @file stm32wbxx_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 * + Operation functions
9 * ++ Start, stop, get result of conversions of ADC group injected,
10 * using 2 possible modes: polling, interruption (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
11 * ++ Calibration
12 * +++ ADC automatic self-calibration
13 * +++ Calibration factors get or set
14 * + Control functions
15 * ++ Channels configuration on ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx )
16 * + State functions
17 * ++ ADC group injected contexts queue management (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx )
18 * Other functions (generic functions) are available in file
19 * "stm32wbxx_hal_adc.c".
20 ******************************************************************************
21 * @attention
22 *
23 * Copyright (c) 2019 STMicroelectronics.
24 * All rights reserved.
25 *
26 * This software is licensed under terms that can be found in the LICENSE file
27 * in the root directory of this software component.
28 * If no LICENSE file comes with this software, it is provided AS-IS.
29 *
30 ******************************************************************************
31 @verbatim
32 [..]
33 (@) Sections "ADC peripheral features" and "How to use this driver" are
34 available in file of generic functions "stm32wbxx_hal_adc.c".
35 [..]
36 @endverbatim
37 ******************************************************************************
38 */
39
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32wbxx_hal.h"
42
43 /** @addtogroup STM32WBxx_HAL_Driver
44 * @{
45 */
46
47 /** @defgroup ADCEx ADCEx
48 * @brief ADC Extended HAL module driver
49 * @{
50 */
51
52 #ifdef HAL_ADC_MODULE_ENABLED
53
54 /* Private typedef -----------------------------------------------------------*/
55 /* Private define ------------------------------------------------------------*/
56
57 /** @defgroup ADCEx_Private_Constants ADC Extended Private Constants
58 * @{
59 */
60
61 #define ADC_JSQR_FIELDS ((ADC_JSQR_JL | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN |\
62 ADC_JSQR_JSQ1 | ADC_JSQR_JSQ2 |\
63 ADC_JSQR_JSQ3 | ADC_JSQR_JSQ4 )) /*!< ADC_JSQR fields of parameters that can be updated anytime
64 once the ADC is enabled */
65
66 /* Fixed timeout value for ADC calibration. */
67 /* Values defined to be higher than worst cases: maximum ratio between ADC */
68 /* and CPU clock frequencies. */
69 /* Example of profile low frequency : ADC frequency at 46.9kHz (ADC clock */
70 /* source PLL SAI 12MHz, ADC clock prescaler 256), CPU frequency 64MHz. */
71 /* Calibration time max = 116 / fADC (refer to datasheet) */
72 /* = 158 379 CPU cycles */
73 #define ADC_CALIBRATION_TIMEOUT (158379UL) /*!< ADC calibration time-out value (unit: CPU cycles) */
74 #define ADC_DISABLE_TIMEOUT (2UL)
75
76 /**
77 * @}
78 */
79
80 /* Private macro -------------------------------------------------------------*/
81 /* Private variables ---------------------------------------------------------*/
82 /* Private function prototypes -----------------------------------------------*/
83 /* Exported functions --------------------------------------------------------*/
84
85 /** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions
86 * @{
87 */
88
89 /** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions
90 * @brief Extended IO operation functions
91 *
92 @verbatim
93 ===============================================================================
94 ##### IO operation functions #####
95 ===============================================================================
96 [..] This section provides functions allowing to:
97
98 (+) Perform the ADC self-calibration for single or differential ending.
99 (+) Get calibration factors for single or differential ending.
100 (+) Set calibration factors for single or differential ending.
101
102 (+) Start conversion of ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
103 (+) Stop conversion of ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
104 (+) Poll for conversion complete on ADC group injected (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
105 (+) Get result of ADC group injected channel conversion (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
106 (+) Start conversion of ADC group injected and enable interruptions (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
107 (+) Stop conversion of ADC group injected and disable interruptions (not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx ).
108
109 @endverbatim
110 * @{
111 */
112
113 /**
114 * @brief Perform an ADC automatic self-calibration
115 * Calibration prerequisite: ADC must be disabled (execute this
116 * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
117 * @param hadc ADC handle
118 * @param SingleDiff Selection of single-ended or differential input
119 * This parameter can be one of the following values:
120 * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
121 * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended (1)
122 *
123 * (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
124 * @retval HAL status
125 */
HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef * hadc,uint32_t SingleDiff)126 HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
127 {
128 #if defined(ADC_SUPPORT_2_5_MSPS)
129 UNUSED(SingleDiff);
130
131 uint32_t calibration_index;
132 uint32_t calibration_factor_accumulated = 0;
133 uint32_t backup_setting_cfgr1;
134 uint32_t tickstart;
135 uint32_t adc_clk_async_presc;
136 __IO uint32_t delay_cpu_cycles;
137 #endif /* ADC_SUPPORT_2_5_MSPS */
138
139 HAL_StatusTypeDef tmp_hal_status;
140 __IO uint32_t wait_loop_index = 0UL;
141
142 /* Check the parameters */
143 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
144 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
145
146 /* Process locked */
147 __HAL_LOCK(hadc);
148
149 /* Calibration prerequisite: ADC must be disabled. */
150
151 /* Disable the ADC (if not already disabled) */
152 tmp_hal_status = ADC_Disable(hadc);
153
154 /* Check if ADC is effectively disabled */
155 if (tmp_hal_status == HAL_OK)
156 {
157 /* Set ADC state */
158 #if defined(ADC_SUPPORT_2_5_MSPS)
159 ADC_STATE_CLR_SET(hadc->State,
160 HAL_ADC_STATE_REG_BUSY,
161 HAL_ADC_STATE_BUSY_INTERNAL);
162 #else
163 ADC_STATE_CLR_SET(hadc->State,
164 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
165 HAL_ADC_STATE_BUSY_INTERNAL);
166 #endif /* ADC_SUPPORT_2_5_MSPS */
167
168 /* Start ADC calibration in mode single-ended or differential */
169 #if defined(ADC_SUPPORT_2_5_MSPS)
170 /* Manage settings impacting calibration */
171 /* - Disable ADC mode auto power-off */
172 /* - Disable ADC DMA transfer request during calibration */
173 /* Note: Specificity of this STM32 series: Calibration factor is */
174 /* available in data register and also transferred by DMA. */
175 /* To not insert ADC calibration factor among ADC conversion data */
176 /* in array variable, DMA transfer must be disabled during */
177 /* calibration. */
178 backup_setting_cfgr1 = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_AUTOFF);
179 CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_AUTOFF);
180
181 /* ADC calibration procedure */
182 /* Note: Perform an averaging of 8 calibrations for optimized accuracy */
183 for (calibration_index = 0UL; calibration_index < 8UL; calibration_index++)
184 {
185 /* Start ADC calibration */
186 LL_ADC_StartCalibration(hadc->Instance);
187
188 #else
189 LL_ADC_StartCalibration(hadc->Instance, SingleDiff);
190 #endif /* ADC_SUPPORT_2_5_MSPS */
191
192 /* Wait for calibration completion */
193 while (LL_ADC_IsCalibrationOnGoing(hadc->Instance) != 0UL)
194 {
195 wait_loop_index++;
196 if (wait_loop_index >= ADC_CALIBRATION_TIMEOUT)
197 {
198 /* Update ADC state machine to error */
199 ADC_STATE_CLR_SET(hadc->State,
200 HAL_ADC_STATE_BUSY_INTERNAL,
201 HAL_ADC_STATE_ERROR_INTERNAL);
202
203 /* Process unlocked */
204 __HAL_UNLOCK(hadc);
205
206 return HAL_ERROR;
207 }
208 }
209 #if defined(ADC_SUPPORT_2_5_MSPS)
210 calibration_factor_accumulated += LL_ADC_GetCalibrationFactor(hadc->Instance);
211 }
212 /* Compute average */
213 calibration_factor_accumulated /= calibration_index;
214 /* Apply calibration factor (requires ADC enable and disable process) */
215 LL_ADC_Enable(hadc->Instance);
216
217 /* Case of ADC clocked at low frequency: Delay required between ADC enable and disable actions */
218 if(LL_ADC_GetClock(hadc->Instance) == LL_ADC_CLOCK_ASYNC)
219 {
220 adc_clk_async_presc = LL_ADC_GetCommonClock(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
221
222 if(adc_clk_async_presc >= LL_ADC_CLOCK_ASYNC_DIV16)
223 {
224 /* Delay loop initialization and execution */
225 /* Delay depends on ADC clock prescaler: Compute ADC clock asynchronous prescaler to decimal format */
226 delay_cpu_cycles = (1U << ((adc_clk_async_presc >> ADC_CCR_PRESC_Pos) - 3U));
227 /* Divide variable by 2 to compensate partially CPU processing cycles */
228 delay_cpu_cycles >>= 1U;
229
230 while(delay_cpu_cycles != 0)
231 {
232 delay_cpu_cycles--;
233 }
234 }
235 }
236
237 LL_ADC_SetCalibrationFactor(hadc->Instance, calibration_factor_accumulated);
238 LL_ADC_Disable(hadc->Instance);
239
240 /* Wait for ADC effectively disabled before changing configuration */
241 /* Get tick count */
242 tickstart = HAL_GetTick();
243
244 while (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
245 {
246 if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
247 {
248 /* New check to avoid false timeout detection in case of preemption */
249 if (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
250 {
251 /* Update ADC state machine to error */
252 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
253
254 /* Set ADC error code to ADC peripheral internal error */
255 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
256
257 return HAL_ERROR;
258 }
259 }
260 }
261
262 /* Restore configuration after calibration */
263 SET_BIT(hadc->Instance->CFGR1, backup_setting_cfgr1);
264 #endif /* ADC_SUPPORT_2_5_MSPS */
265
266 /* Set ADC state */
267 ADC_STATE_CLR_SET(hadc->State,
268 HAL_ADC_STATE_BUSY_INTERNAL,
269 HAL_ADC_STATE_READY);
270 }
271 else
272 {
273 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
274
275 /* Note: No need to update variable "tmp_hal_status" here: already set */
276 /* to state "HAL_ERROR" by function disabling the ADC. */
277 }
278
279 /* Process unlocked */
280 __HAL_UNLOCK(hadc);
281
282 /* Return function status */
283 return tmp_hal_status;
284 }
285
286 /**
287 * @brief Get the calibration factor.
288 * @param hadc ADC handle.
289 * @param SingleDiff This parameter can be only:
290 * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
291 * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended (1)
292 *
293 * (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
294 * @retval Calibration value.
295 */
HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef * hadc,uint32_t SingleDiff)296 uint32_t HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
297 {
298 #if defined(ADC_SUPPORT_2_5_MSPS)
299 UNUSED(SingleDiff);
300 #endif /* ADC_SUPPORT_2_5_MSPS */
301
302 /* Check the parameters */
303 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
304 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
305
306 /* Return the selected ADC calibration value */
307 #if defined(ADC_SUPPORT_2_5_MSPS)
308 return LL_ADC_GetCalibrationFactor(hadc->Instance);
309 #else
310 return LL_ADC_GetCalibrationFactor(hadc->Instance, SingleDiff);
311 #endif /* ADC_SUPPORT_2_5_MSPS */
312 }
313
314 /**
315 * @brief Set the calibration factor to overwrite automatic conversion result.
316 * ADC must be enabled and no conversion is ongoing.
317 * @param hadc ADC handle
318 * @param SingleDiff This parameter can be only:
319 * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
320 * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended (1)
321 *
322 * (1) On STM32WB series, parameter not available on devices: STM32WB10xx, STM32WB15xx, STM32WB1Mxx.
323 * @param CalibrationFactor Calibration factor (coded on 7 bits maximum)
324 * @retval HAL state
325 */
HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef * hadc,uint32_t SingleDiff,uint32_t CalibrationFactor)326 HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff, uint32_t CalibrationFactor)
327 {
328 #if defined(ADC_SUPPORT_2_5_MSPS)
329 UNUSED(SingleDiff);
330 #endif /* ADC_SUPPORT_2_5_MSPS */
331
332 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
333 uint32_t tmp_adc_is_conversion_on_going_regular;
334 #if defined(ADC_SUPPORT_2_5_MSPS)
335 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
336 #else
337 uint32_t tmp_adc_is_conversion_on_going_injected;
338 #endif /* ADC_SUPPORT_2_5_MSPS */
339
340 /* Check the parameters */
341 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
342 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
343 assert_param(IS_ADC_CALFACT(CalibrationFactor));
344
345 /* Process locked */
346 __HAL_LOCK(hadc);
347
348 /* Verification of hardware constraints before modifying the calibration */
349 /* factors register: ADC must be enabled, no conversion on going. */
350 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
351 #if defined(ADC_SUPPORT_2_5_MSPS)
352 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
353 #else
354 tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
355 #endif /* ADC_SUPPORT_2_5_MSPS */
356
357 if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
358 && (tmp_adc_is_conversion_on_going_regular == 0UL)
359 #if defined(ADC_SUPPORT_2_5_MSPS)
360 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
361 #else
362 && (tmp_adc_is_conversion_on_going_injected == 0UL)
363 #endif /* ADC_SUPPORT_2_5_MSPS */
364 )
365 {
366 /* Set the selected ADC calibration value */
367 #if defined(ADC_SUPPORT_2_5_MSPS)
368 LL_ADC_SetCalibrationFactor(hadc->Instance, CalibrationFactor);
369 #else
370 LL_ADC_SetCalibrationFactor(hadc->Instance, SingleDiff, CalibrationFactor);
371 #endif /* ADC_SUPPORT_2_5_MSPS */
372 }
373 else
374 {
375 /* Update ADC state machine */
376 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
377 /* Update ADC error code */
378 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
379
380 /* Update ADC state machine to error */
381 tmp_hal_status = HAL_ERROR;
382 }
383
384 /* Process unlocked */
385 __HAL_UNLOCK(hadc);
386
387 /* Return function status */
388 return tmp_hal_status;
389 }
390
391 #if defined(ADC_SUPPORT_2_5_MSPS)
392 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
393 #else
394 /**
395 * @brief Enable ADC, start conversion of injected group.
396 * @note Interruptions enabled in this function: None.
397 * @param hadc ADC handle.
398 * @retval HAL status
399 */
HAL_ADCEx_InjectedStart(ADC_HandleTypeDef * hadc)400 HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc)
401 {
402 HAL_StatusTypeDef tmp_hal_status;
403 uint32_t tmp_config_injected_queue;
404
405 /* Check the parameters */
406 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
407
408 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
409 {
410 return HAL_BUSY;
411 }
412 else
413 {
414 /* In case of software trigger detection enabled, JQDIS must be set
415 (which can be done only if ADSTART and JADSTART are both cleared).
416 If JQDIS is not set at that point, returns an error
417 - since software trigger detection is disabled. User needs to
418 resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS.
419 - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means
420 the queue is empty */
421 tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
422
423 if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL)
424 && (tmp_config_injected_queue == 0UL)
425 )
426 {
427 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
428 return HAL_ERROR;
429 }
430
431 /* Process locked */
432 __HAL_LOCK(hadc);
433
434 /* Enable the ADC peripheral */
435 tmp_hal_status = ADC_Enable(hadc);
436
437 /* Start conversion if ADC is effectively enabled */
438 if (tmp_hal_status == HAL_OK)
439 {
440 /* Check if a regular conversion is ongoing */
441 if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL)
442 {
443 /* Reset ADC error code field related to injected conversions only */
444 CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
445 }
446 else
447 {
448 /* Set ADC error code to none */
449 ADC_CLEAR_ERRORCODE(hadc);
450 }
451
452 /* Set ADC state */
453 /* - Clear state bitfield related to injected group conversion results */
454 /* - Set state bitfield related to injected operation */
455 ADC_STATE_CLR_SET(hadc->State,
456 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
457 HAL_ADC_STATE_INJ_BUSY);
458
459 /* Clear ADC group injected group conversion flag */
460 /* (To ensure of no unknown state from potential previous ADC operations) */
461 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
462
463 /* Process unlocked */
464 /* Unlock before starting ADC conversions: in case of potential */
465 /* interruption, to let the process to ADC IRQ Handler. */
466 __HAL_UNLOCK(hadc);
467
468 /* Enable conversion of injected group, if automatic injected conversion */
469 /* is disabled. */
470 /* If software start has been selected, conversion starts immediately. */
471 /* If external trigger has been selected, conversion will start at next */
472 /* trigger event. */
473 if(LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
474 {
475 /* Start ADC group injected conversion */
476 LL_ADC_INJ_StartConversion(hadc->Instance);
477 }
478 }
479 else
480 {
481 /* Process unlocked */
482 __HAL_UNLOCK(hadc);
483 }
484
485 /* Return function status */
486 return tmp_hal_status;
487 }
488 }
489
490 /**
491 * @brief Stop conversion of injected channels. Disable ADC peripheral if
492 * no regular conversion is on going.
493 * @note If ADC must be disabled and if conversion is on going on
494 * regular group, function HAL_ADC_Stop must be used to stop both
495 * injected and regular groups, and disable the ADC.
496 * @note If injected group mode auto-injection is enabled,
497 * function HAL_ADC_Stop must be used.
498 * @param hadc ADC handle.
499 * @retval HAL status
500 */
HAL_ADCEx_InjectedStop(ADC_HandleTypeDef * hadc)501 HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc)
502 {
503 HAL_StatusTypeDef tmp_hal_status;
504
505 /* Check the parameters */
506 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
507
508 /* Process locked */
509 __HAL_LOCK(hadc);
510
511 /* 1. Stop potential conversion on going on injected group only. */
512 tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
513
514 /* Disable ADC peripheral if injected conversions are effectively stopped */
515 /* and if no conversion on regular group is on-going */
516 if (tmp_hal_status == HAL_OK)
517 {
518 if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
519 {
520 /* 2. Disable the ADC peripheral */
521 tmp_hal_status = ADC_Disable(hadc);
522
523 /* Check if ADC is effectively disabled */
524 if (tmp_hal_status == HAL_OK)
525 {
526 /* Set ADC state */
527 ADC_STATE_CLR_SET(hadc->State,
528 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
529 HAL_ADC_STATE_READY);
530 }
531 }
532 /* Conversion on injected group is stopped, but ADC not disabled since */
533 /* conversion on regular group is still running. */
534 else
535 {
536 /* Set ADC state */
537 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
538 }
539 }
540
541 /* Process unlocked */
542 __HAL_UNLOCK(hadc);
543
544 /* Return function status */
545 return tmp_hal_status;
546 }
547
548 /**
549 * @brief Wait for injected group conversion to be completed.
550 * @param hadc ADC handle
551 * @param Timeout Timeout value in millisecond.
552 * @note Depending on hadc->Init.EOCSelection, JEOS or JEOC is
553 * checked and cleared depending on AUTDLY bit status.
554 * @retval HAL status
555 */
HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef * hadc,uint32_t Timeout)556 HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
557 {
558 uint32_t tickstart;
559 uint32_t tmp_Flag_End;
560 uint32_t tmp_adc_inj_is_trigger_source_sw_start;
561 uint32_t tmp_adc_reg_is_trigger_source_sw_start;
562 uint32_t tmp_cfgr;
563
564 /* Check the parameters */
565 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
566
567 /* If end of sequence selected */
568 if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
569 {
570 tmp_Flag_End = ADC_FLAG_JEOS;
571 }
572 else /* end of conversion selected */
573 {
574 tmp_Flag_End = ADC_FLAG_JEOC;
575 }
576
577 /* Get timeout */
578 tickstart = HAL_GetTick();
579
580 /* Wait until End of Conversion or Sequence flag is raised */
581 while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
582 {
583 /* Check if timeout is disabled (set to infinite wait) */
584 if (Timeout != HAL_MAX_DELAY)
585 {
586 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
587 {
588 /* New check to avoid false timeout detection in case of preemption */
589 if ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
590 {
591 /* Update ADC state machine to timeout */
592 SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
593
594 /* Process unlocked */
595 __HAL_UNLOCK(hadc);
596
597 return HAL_TIMEOUT;
598 }
599 }
600 }
601 }
602
603 /* Retrieve ADC configuration */
604 tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
605 tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
606 tmp_cfgr = READ_REG(hadc->Instance->CFGR);
607
608 /* Update ADC state machine */
609 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
610
611 /* Determine whether any further conversion upcoming on group injected */
612 /* by external trigger or by automatic injected conversion */
613 /* from group regular. */
614 if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL) ||
615 ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) &&
616 ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
617 (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL))))
618 {
619 /* Check whether end of sequence is reached */
620 if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
621 {
622 /* Particular case if injected contexts queue is enabled: */
623 /* when the last context has been fully processed, JSQR is reset */
624 /* by the hardware. Even if no injected conversion is planned to come */
625 /* (queue empty, triggers are ignored), it can start again */
626 /* immediately after setting a new context (JADSTART is still set). */
627 /* Therefore, state of HAL ADC injected group is kept to busy. */
628 if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQM) == 0UL)
629 {
630 /* Set ADC state */
631 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
632
633 if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
634 {
635 SET_BIT(hadc->State, HAL_ADC_STATE_READY);
636 }
637 }
638 }
639 }
640
641 /* Clear polled flag */
642 if (tmp_Flag_End == ADC_FLAG_JEOS)
643 {
644 /* Clear end of sequence JEOS flag of injected group if low power feature */
645 /* "LowPowerAutoWait " is disabled, to not interfere with this feature. */
646 /* For injected groups, no new conversion will start before JEOS is */
647 /* cleared. */
648 if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_AUTDLY) == 0UL)
649 {
650 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
651 }
652 }
653 else
654 {
655 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
656 }
657
658 /* Return API HAL status */
659 return HAL_OK;
660 }
661
662 /**
663 * @brief Enable ADC, start conversion of injected group with interruption.
664 * @note Interruptions enabled in this function according to initialization
665 * setting : JEOC (end of conversion) or JEOS (end of sequence)
666 * @param hadc ADC handle.
667 * @retval HAL status.
668 */
HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef * hadc)669 HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc)
670 {
671 HAL_StatusTypeDef tmp_hal_status;
672 uint32_t tmp_config_injected_queue;
673
674 /* Check the parameters */
675 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
676
677 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
678 {
679 return HAL_BUSY;
680 }
681 else
682 {
683 /* In case of software trigger detection enabled, JQDIS must be set
684 (which can be done only if ADSTART and JADSTART are both cleared).
685 If JQDIS is not set at that point, returns an error
686 - since software trigger detection is disabled. User needs to
687 resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS.
688 - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means
689 the queue is empty */
690 tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
691
692 if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL)
693 && (tmp_config_injected_queue == 0UL)
694 )
695 {
696 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
697 return HAL_ERROR;
698 }
699
700 /* Process locked */
701 __HAL_LOCK(hadc);
702
703 /* Enable the ADC peripheral */
704 tmp_hal_status = ADC_Enable(hadc);
705
706 /* Start conversion if ADC is effectively enabled */
707 if (tmp_hal_status == HAL_OK)
708 {
709 /* Check if a regular conversion is ongoing */
710 if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL)
711 {
712 /* Reset ADC error code field related to injected conversions only */
713 CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF);
714 }
715 else
716 {
717 /* Set ADC error code to none */
718 ADC_CLEAR_ERRORCODE(hadc);
719 }
720
721 /* Set ADC state */
722 /* - Clear state bitfield related to injected group conversion results */
723 /* - Set state bitfield related to injected operation */
724 ADC_STATE_CLR_SET(hadc->State,
725 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
726 HAL_ADC_STATE_INJ_BUSY);
727
728 /* Clear ADC group injected group conversion flag */
729 /* (To ensure of no unknown state from potential previous ADC operations) */
730 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
731
732 /* Process unlocked */
733 /* Unlock before starting ADC conversions: in case of potential */
734 /* interruption, to let the process to ADC IRQ Handler. */
735 __HAL_UNLOCK(hadc);
736
737 /* Enable ADC Injected context queue overflow interrupt if this feature */
738 /* is enabled. */
739 if ((hadc->Instance->CFGR & ADC_CFGR_JQM) != 0UL)
740 {
741 __HAL_ADC_ENABLE_IT(hadc, ADC_FLAG_JQOVF);
742 }
743
744 /* Enable ADC end of conversion interrupt */
745 switch (hadc->Init.EOCSelection)
746 {
747 case ADC_EOC_SEQ_CONV:
748 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
749 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS);
750 break;
751 /* case ADC_EOC_SINGLE_CONV */
752 default:
753 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS);
754 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
755 break;
756 }
757
758 /* Enable conversion of injected group, if automatic injected conversion */
759 /* is disabled. */
760 /* If software start has been selected, conversion starts immediately. */
761 /* If external trigger has been selected, conversion will start at next */
762 /* trigger event. */
763 if(LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
764 {
765 /* Start ADC group injected conversion */
766 LL_ADC_INJ_StartConversion(hadc->Instance);
767 }
768 }
769 else
770 {
771 /* Process unlocked */
772 __HAL_UNLOCK(hadc);
773 }
774
775 /* Return function status */
776 return tmp_hal_status;
777 }
778 }
779
780 /**
781 * @brief Stop conversion of injected channels, disable interruption of
782 * end-of-conversion. Disable ADC peripheral if no regular conversion
783 * is on going.
784 * @note If ADC must be disabled and if conversion is on going on
785 * regular group, function HAL_ADC_Stop must be used to stop both
786 * injected and regular groups, and disable the ADC.
787 * @note If injected group mode auto-injection is enabled,
788 * function HAL_ADC_Stop must be used.
789 * @note In case of auto-injection mode, HAL_ADC_Stop() must be used.
790 * @param hadc ADC handle
791 * @retval HAL status
792 */
HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef * hadc)793 HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc)
794 {
795 HAL_StatusTypeDef tmp_hal_status;
796
797 /* Check the parameters */
798 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
799
800 /* Process locked */
801 __HAL_LOCK(hadc);
802
803 /* 1. Stop potential conversion on going on injected group only. */
804 tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
805
806 /* Disable ADC peripheral if injected conversions are effectively stopped */
807 /* and if no conversion on the other group (regular group) is intended to */
808 /* continue. */
809 if (tmp_hal_status == HAL_OK)
810 {
811 /* Disable ADC end of conversion interrupt for injected channels */
812 __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_JEOC | ADC_IT_JEOS | ADC_FLAG_JQOVF));
813
814 if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
815 {
816 /* 2. Disable the ADC peripheral */
817 tmp_hal_status = ADC_Disable(hadc);
818
819 /* Check if ADC is effectively disabled */
820 if (tmp_hal_status == HAL_OK)
821 {
822 /* Set ADC state */
823 ADC_STATE_CLR_SET(hadc->State,
824 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
825 HAL_ADC_STATE_READY);
826 }
827 }
828 /* Conversion on injected group is stopped, but ADC not disabled since */
829 /* conversion on regular group is still running. */
830 else
831 {
832 /* Set ADC state */
833 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
834 }
835 }
836
837 /* Process unlocked */
838 __HAL_UNLOCK(hadc);
839
840 /* Return function status */
841 return tmp_hal_status;
842 }
843 #endif /* ADC_SUPPORT_2_5_MSPS */
844
845 #if defined(ADC_SUPPORT_2_5_MSPS)
846 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
847 #else
848 /**
849 * @brief Get ADC injected group conversion result.
850 * @note Reading register JDRx automatically clears ADC flag JEOC
851 * (ADC group injected end of unitary conversion).
852 * @note This function does not clear ADC flag JEOS
853 * (ADC group injected end of sequence conversion)
854 * Occurrence of flag JEOS rising:
855 * - If sequencer is composed of 1 rank, flag JEOS is equivalent
856 * to flag JEOC.
857 * - If sequencer is composed of several ranks, during the scan
858 * sequence flag JEOC only is raised, at the end of the scan sequence
859 * both flags JEOC and EOS are raised.
860 * Flag JEOS must not be cleared by this function because
861 * it would not be compliant with low power features
862 * (feature low power auto-wait, not available on all STM32 families).
863 * To clear this flag, either use function:
864 * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
865 * model polling: @ref HAL_ADCEx_InjectedPollForConversion()
866 * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
867 * @param hadc ADC handle
868 * @param InjectedRank the converted ADC injected rank.
869 * This parameter can be one of the following values:
870 * @arg @ref ADC_INJECTED_RANK_1 ADC group injected rank 1
871 * @arg @ref ADC_INJECTED_RANK_2 ADC group injected rank 2
872 * @arg @ref ADC_INJECTED_RANK_3 ADC group injected rank 3
873 * @arg @ref ADC_INJECTED_RANK_4 ADC group injected rank 4
874 * @retval ADC group injected conversion data
875 */
HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef * hadc,uint32_t InjectedRank)876 uint32_t HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef *hadc, uint32_t InjectedRank)
877 {
878 uint32_t tmp_jdr;
879
880 /* Check the parameters */
881 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
882 assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
883
884 /* Get ADC converted value */
885 switch (InjectedRank)
886 {
887 case ADC_INJECTED_RANK_4:
888 tmp_jdr = hadc->Instance->JDR4;
889 break;
890 case ADC_INJECTED_RANK_3:
891 tmp_jdr = hadc->Instance->JDR3;
892 break;
893 case ADC_INJECTED_RANK_2:
894 tmp_jdr = hadc->Instance->JDR2;
895 break;
896 case ADC_INJECTED_RANK_1:
897 default:
898 tmp_jdr = hadc->Instance->JDR1;
899 break;
900 }
901
902 /* Return ADC converted value */
903 return tmp_jdr;
904 }
905
906 /**
907 * @brief Injected conversion complete callback in non-blocking mode.
908 * @param hadc ADC handle
909 * @retval None
910 */
HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef * hadc)911 __weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
912 {
913 /* Prevent unused argument(s) compilation warning */
914 UNUSED(hadc);
915
916 /* NOTE : This function should not be modified. When the callback is needed,
917 function HAL_ADCEx_InjectedConvCpltCallback must be implemented in the user file.
918 */
919 }
920
921 /**
922 * @brief Injected context queue overflow callback.
923 * @note This callback is called if injected context queue is enabled
924 (parameter "QueueInjectedContext" in injected channel configuration)
925 and if a new injected context is set when queue is full (maximum 2
926 contexts).
927 * @param hadc ADC handle
928 * @retval None
929 */
HAL_ADCEx_InjectedQueueOverflowCallback(ADC_HandleTypeDef * hadc)930 __weak void HAL_ADCEx_InjectedQueueOverflowCallback(ADC_HandleTypeDef *hadc)
931 {
932 /* Prevent unused argument(s) compilation warning */
933 UNUSED(hadc);
934
935 /* NOTE : This function should not be modified. When the callback is needed,
936 function HAL_ADCEx_InjectedQueueOverflowCallback must be implemented in the user file.
937 */
938 }
939 #endif /* ADC_SUPPORT_2_5_MSPS */
940
941 /**
942 * @brief Analog watchdog 2 callback in non-blocking mode.
943 * @param hadc ADC handle
944 * @retval None
945 */
HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef * hadc)946 __weak void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc)
947 {
948 /* Prevent unused argument(s) compilation warning */
949 UNUSED(hadc);
950
951 /* NOTE : This function should not be modified. When the callback is needed,
952 function HAL_ADCEx_LevelOutOfWindow2Callback must be implemented in the user file.
953 */
954 }
955
956 /**
957 * @brief Analog watchdog 3 callback in non-blocking mode.
958 * @param hadc ADC handle
959 * @retval None
960 */
HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef * hadc)961 __weak void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc)
962 {
963 /* Prevent unused argument(s) compilation warning */
964 UNUSED(hadc);
965
966 /* NOTE : This function should not be modified. When the callback is needed,
967 function HAL_ADCEx_LevelOutOfWindow3Callback must be implemented in the user file.
968 */
969 }
970
971
972 /**
973 * @brief End Of Sampling callback in non-blocking mode.
974 * @param hadc ADC handle
975 * @retval None
976 */
HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef * hadc)977 __weak void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc)
978 {
979 /* Prevent unused argument(s) compilation warning */
980 UNUSED(hadc);
981
982 /* NOTE : This function should not be modified. When the callback is needed,
983 function HAL_ADCEx_EndOfSamplingCallback must be implemented in the user file.
984 */
985 }
986
987 #if defined(ADC_SUPPORT_2_5_MSPS)
988 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
989 #else
990 /**
991 * @brief Stop ADC conversion of regular group (and injected channels in
992 * case of auto_injection mode), disable ADC peripheral if no
993 * conversion is on going on injected group.
994 * @param hadc ADC handle
995 * @retval HAL status.
996 */
HAL_ADCEx_RegularStop(ADC_HandleTypeDef * hadc)997 HAL_StatusTypeDef HAL_ADCEx_RegularStop(ADC_HandleTypeDef *hadc)
998 {
999 HAL_StatusTypeDef tmp_hal_status;
1000
1001 /* Check the parameters */
1002 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1003
1004 /* Process locked */
1005 __HAL_LOCK(hadc);
1006
1007 /* 1. Stop potential regular conversion on going */
1008 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1009
1010 /* Disable ADC peripheral if regular conversions are effectively stopped
1011 and if no injected conversions are on-going */
1012 if (tmp_hal_status == HAL_OK)
1013 {
1014 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1015 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1016
1017 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1018 {
1019 /* 2. Disable the ADC peripheral */
1020 tmp_hal_status = ADC_Disable(hadc);
1021
1022 /* Check if ADC is effectively disabled */
1023 if (tmp_hal_status == HAL_OK)
1024 {
1025 /* Set ADC state */
1026 ADC_STATE_CLR_SET(hadc->State,
1027 HAL_ADC_STATE_INJ_BUSY,
1028 HAL_ADC_STATE_READY);
1029 }
1030 }
1031 /* Conversion on injected group is stopped, but ADC not disabled since */
1032 /* conversion on regular group is still running. */
1033 else
1034 {
1035 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
1036 }
1037 }
1038
1039 /* Process unlocked */
1040 __HAL_UNLOCK(hadc);
1041
1042 /* Return function status */
1043 return tmp_hal_status;
1044 }
1045
1046
1047 /**
1048 * @brief Stop ADC conversion of ADC groups regular and injected,
1049 * disable interrution of end-of-conversion,
1050 * disable ADC peripheral if no conversion is on going
1051 * on injected group.
1052 * @param hadc ADC handle
1053 * @retval HAL status.
1054 */
HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef * hadc)1055 HAL_StatusTypeDef HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef *hadc)
1056 {
1057 HAL_StatusTypeDef tmp_hal_status;
1058
1059 /* Check the parameters */
1060 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1061
1062 /* Process locked */
1063 __HAL_LOCK(hadc);
1064
1065 /* 1. Stop potential regular conversion on going */
1066 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1067
1068 /* Disable ADC peripheral if conversions are effectively stopped
1069 and if no injected conversion is on-going */
1070 if (tmp_hal_status == HAL_OK)
1071 {
1072 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1073 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1074
1075 /* Disable all regular-related interrupts */
1076 __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
1077
1078 /* 2. Disable ADC peripheral if no injected conversions are on-going */
1079 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1080 {
1081 tmp_hal_status = ADC_Disable(hadc);
1082 /* if no issue reported */
1083 if (tmp_hal_status == HAL_OK)
1084 {
1085 /* Set ADC state */
1086 ADC_STATE_CLR_SET(hadc->State,
1087 HAL_ADC_STATE_INJ_BUSY,
1088 HAL_ADC_STATE_READY);
1089 }
1090 }
1091 else
1092 {
1093 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
1094 }
1095 }
1096
1097 /* Process unlocked */
1098 __HAL_UNLOCK(hadc);
1099
1100 /* Return function status */
1101 return tmp_hal_status;
1102 }
1103
1104 /**
1105 * @brief Stop ADC conversion of regular group (and injected group in
1106 * case of auto_injection mode), disable ADC DMA transfer, disable
1107 * ADC peripheral if no conversion is on going
1108 * on injected group.
1109 * @param hadc ADC handle
1110 * @retval HAL status.
1111 */
HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef * hadc)1112 HAL_StatusTypeDef HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef *hadc)
1113 {
1114 HAL_StatusTypeDef tmp_hal_status;
1115
1116 /* Check the parameters */
1117 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1118
1119 /* Process locked */
1120 __HAL_LOCK(hadc);
1121
1122 /* 1. Stop potential regular conversion on going */
1123 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1124
1125 /* Disable ADC peripheral if conversions are effectively stopped
1126 and if no injected conversion is on-going */
1127 if (tmp_hal_status == HAL_OK)
1128 {
1129 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1130 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1131
1132 /* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */
1133 CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN);
1134
1135 /* Disable the DMA channel (in case of DMA in circular mode or stop while */
1136 /* while DMA transfer is on going) */
1137 tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
1138
1139 /* Check if DMA channel effectively disabled */
1140 if (tmp_hal_status != HAL_OK)
1141 {
1142 /* Update ADC state machine to error */
1143 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
1144 }
1145
1146 /* Disable ADC overrun interrupt */
1147 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
1148
1149 /* 2. Disable the ADC peripheral */
1150 /* Update "tmp_hal_status" only if DMA channel disabling passed, */
1151 /* to keep in memory a potential failing status. */
1152 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1153 {
1154 if (tmp_hal_status == HAL_OK)
1155 {
1156 tmp_hal_status = ADC_Disable(hadc);
1157 }
1158 else
1159 {
1160 (void)ADC_Disable(hadc);
1161 }
1162
1163 /* Check if ADC is effectively disabled */
1164 if (tmp_hal_status == HAL_OK)
1165 {
1166 /* Set ADC state */
1167 ADC_STATE_CLR_SET(hadc->State,
1168 HAL_ADC_STATE_INJ_BUSY,
1169 HAL_ADC_STATE_READY);
1170 }
1171 }
1172 else
1173 {
1174 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
1175 }
1176 }
1177
1178 /* Process unlocked */
1179 __HAL_UNLOCK(hadc);
1180
1181 /* Return function status */
1182 return tmp_hal_status;
1183 }
1184 #endif /* ADC_SUPPORT_2_5_MSPS */
1185
1186 /**
1187 * @}
1188 */
1189
1190 #if defined(ADC_SUPPORT_2_5_MSPS)
1191 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
1192 #else
1193 /** @defgroup ADCEx_Exported_Functions_Group2 ADC Extended Peripheral Control functions
1194 * @brief ADC Extended Peripheral Control functions
1195 *
1196 @verbatim
1197 ===============================================================================
1198 ##### Peripheral Control functions #####
1199 ===============================================================================
1200 [..] This section provides functions allowing to:
1201 (+) Configure channels on injected group
1202 (+) Enable or Disable Injected Queue
1203 (+) Disable ADC voltage regulator
1204 (+) Enter ADC deep-power-down mode
1205
1206 @endverbatim
1207 * @{
1208 */
1209
1210 /**
1211 * @brief Configure a channel to be assigned to ADC group injected.
1212 * @note Possibility to update parameters on the fly:
1213 * This function initializes injected group, following calls to this
1214 * function can be used to reconfigure some parameters of structure
1215 * "ADC_InjectionConfTypeDef" on the fly, without resetting the ADC.
1216 * The setting of these parameters is conditioned to ADC state:
1217 * Refer to comments of structure "ADC_InjectionConfTypeDef".
1218 * @note In case of usage of internal measurement channels:
1219 * Vbat/VrefInt/TempSensor.
1220 * These internal paths can be disabled using function
1221 * HAL_ADC_DeInit().
1222 * @note Caution: For Injected Context Queue use, a context must be fully
1223 * defined before start of injected conversion. All channels are configured
1224 * consecutively for the same ADC instance. Therefore, the number of calls to
1225 * HAL_ADCEx_InjectedConfigChannel() must be equal to the value of parameter
1226 * InjectedNbrOfConversion for each context.
1227 * - Example 1: If 1 context is intended to be used (or if there is no use of the
1228 * Injected Queue Context feature) and if the context contains 3 injected ranks
1229 * (InjectedNbrOfConversion = 3), HAL_ADCEx_InjectedConfigChannel() must be
1230 * called once for each channel (i.e. 3 times) before starting a conversion.
1231 * This function must not be called to configure a 4th injected channel:
1232 * it would start a new context into context queue.
1233 * - Example 2: If 2 contexts are intended to be used and each of them contains
1234 * 3 injected ranks (InjectedNbrOfConversion = 3),
1235 * HAL_ADCEx_InjectedConfigChannel() must be called once for each channel and
1236 * for each context (3 channels x 2 contexts = 6 calls). Conversion can
1237 * start once the 1st context is set, that is after the first three
1238 * HAL_ADCEx_InjectedConfigChannel() calls. The 2nd context can be set on the fly.
1239 * @param hadc ADC handle
1240 * @param sConfigInjected Structure of ADC injected group and ADC channel for
1241 * injected group.
1242 * @retval HAL status
1243 */
HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef * hadc,const ADC_InjectionConfTypeDef * sConfigInjected)1244 HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, const ADC_InjectionConfTypeDef *sConfigInjected)
1245 {
1246 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
1247 uint32_t tmpOffsetShifted;
1248 uint32_t tmp_config_internal_channel;
1249 uint32_t tmp_adc_is_conversion_on_going_regular;
1250 uint32_t tmp_adc_is_conversion_on_going_injected;
1251 __IO uint32_t wait_loop_index = 0;
1252
1253 uint32_t tmp_JSQR_ContextQueueBeingBuilt = 0U;
1254
1255 /* Check the parameters */
1256 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1257 assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
1258 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(sConfigInjected->InjectedSingleDiff));
1259 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
1260 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->QueueInjectedContext));
1261 assert_param(IS_ADC_EXTTRIGINJEC_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
1262 assert_param(IS_ADC_EXTTRIGINJEC(hadc, sConfigInjected->ExternalTrigInjecConv));
1263 assert_param(IS_ADC_OFFSET_NUMBER(sConfigInjected->InjectedOffsetNumber));
1264 assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), sConfigInjected->InjectedOffset));
1265 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjecOversamplingMode));
1266
1267 if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
1268 {
1269 assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
1270 assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion));
1271 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
1272 }
1273
1274
1275 /* if JOVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is
1276 ignored (considered as reset) */
1277 assert_param(!((sConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE) && (sConfigInjected->InjecOversamplingMode == ENABLE)));
1278
1279 /* JDISCEN and JAUTO bits can't be set at the same time */
1280 assert_param(!((sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) && (sConfigInjected->AutoInjectedConv == ENABLE)));
1281
1282 /* DISCEN and JAUTO bits can't be set at the same time */
1283 assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (sConfigInjected->AutoInjectedConv == ENABLE)));
1284
1285 /* Verification of channel number */
1286 if (sConfigInjected->InjectedSingleDiff != ADC_DIFFERENTIAL_ENDED)
1287 {
1288 assert_param(IS_ADC_CHANNEL(hadc, sConfigInjected->InjectedChannel));
1289 }
1290 else
1291 {
1292 assert_param(IS_ADC_DIFF_CHANNEL(hadc, sConfigInjected->InjectedChannel));
1293 }
1294
1295 /* Process locked */
1296 __HAL_LOCK(hadc);
1297
1298 /* Configuration of injected group sequencer: */
1299 /* Hardware constraint: Must fully define injected context register JSQR */
1300 /* before make it entering into injected sequencer queue. */
1301 /* */
1302 /* - if scan mode is disabled: */
1303 /* * Injected channels sequence length is set to 0x00: 1 channel */
1304 /* converted (channel on injected rank 1) */
1305 /* Parameter "InjectedNbrOfConversion" is discarded. */
1306 /* * Injected context register JSQR setting is simple: register is fully */
1307 /* defined on one call of this function (for injected rank 1) and can */
1308 /* be entered into queue directly. */
1309 /* - if scan mode is enabled: */
1310 /* * Injected channels sequence length is set to parameter */
1311 /* "InjectedNbrOfConversion". */
1312 /* * Injected context register JSQR setting more complex: register is */
1313 /* fully defined over successive calls of this function, for each */
1314 /* injected channel rank. It is entered into queue only when all */
1315 /* injected ranks have been set. */
1316 /* Note: Scan mode is not present by hardware on this device, but used */
1317 /* by software for alignment over all STM32 devices. */
1318
1319 if ((hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) ||
1320 (sConfigInjected->InjectedNbrOfConversion == 1U))
1321 {
1322 /* Configuration of context register JSQR: */
1323 /* - number of ranks in injected group sequencer: fixed to 1st rank */
1324 /* (scan mode disabled, only rank 1 used) */
1325 /* - external trigger to start conversion */
1326 /* - external trigger polarity */
1327 /* - channel set to rank 1 (scan mode disabled, only rank 1 can be used) */
1328
1329 if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
1330 {
1331 /* Enable external trigger if trigger selection is different of */
1332 /* software start. */
1333 /* Note: This configuration keeps the hardware feature of parameter */
1334 /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */
1335 /* software start. */
1336 if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
1337 {
1338 tmp_JSQR_ContextQueueBeingBuilt = (ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1)
1339 | (sConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
1340 | sConfigInjected->ExternalTrigInjecConvEdge
1341 );
1342 }
1343 else
1344 {
1345 tmp_JSQR_ContextQueueBeingBuilt = (ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1));
1346 }
1347
1348 MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, tmp_JSQR_ContextQueueBeingBuilt);
1349 /* For debug and informative reasons, hadc handle saves JSQR setting */
1350 hadc->InjectionConfig.ContextQueue = tmp_JSQR_ContextQueueBeingBuilt;
1351
1352 }
1353 }
1354 else
1355 {
1356 /* Case of scan mode enabled, several channels to set into injected group */
1357 /* sequencer. */
1358 /* */
1359 /* Procedure to define injected context register JSQR over successive */
1360 /* calls of this function, for each injected channel rank: */
1361 /* 1. Start new context and set parameters related to all injected */
1362 /* channels: injected sequence length and trigger. */
1363
1364 /* if hadc->InjectionConfig.ChannelCount is equal to 0, this is the first */
1365 /* call of the context under setting */
1366 if (hadc->InjectionConfig.ChannelCount == 0U)
1367 {
1368 /* Initialize number of channels that will be configured on the context */
1369 /* being built */
1370 hadc->InjectionConfig.ChannelCount = sConfigInjected->InjectedNbrOfConversion;
1371 /* Handle hadc saves the context under build up over each HAL_ADCEx_InjectedConfigChannel()
1372 call, this context will be written in JSQR register at the last call.
1373 At this point, the context is merely reset */
1374 hadc->InjectionConfig.ContextQueue = 0x00000000U;
1375
1376 /* Configuration of context register JSQR: */
1377 /* - number of ranks in injected group sequencer */
1378 /* - external trigger to start conversion */
1379 /* - external trigger polarity */
1380
1381 /* Enable external trigger if trigger selection is different of */
1382 /* software start. */
1383 /* Note: This configuration keeps the hardware feature of parameter */
1384 /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */
1385 /* software start. */
1386 if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
1387 {
1388 tmp_JSQR_ContextQueueBeingBuilt = ((sConfigInjected->InjectedNbrOfConversion - 1U)
1389 | (sConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
1390 | sConfigInjected->ExternalTrigInjecConvEdge
1391 );
1392 }
1393 else
1394 {
1395 tmp_JSQR_ContextQueueBeingBuilt = ((sConfigInjected->InjectedNbrOfConversion - 1U));
1396 }
1397
1398 }
1399
1400 /* 2. Continue setting of context under definition with parameter */
1401 /* related to each channel: channel rank sequence */
1402 /* Clear the old JSQx bits for the selected rank */
1403 tmp_JSQR_ContextQueueBeingBuilt &= ~ADC_JSQR_RK(ADC_SQR3_SQ10, sConfigInjected->InjectedRank);
1404
1405 /* Set the JSQx bits for the selected rank */
1406 tmp_JSQR_ContextQueueBeingBuilt |= ADC_JSQR_RK(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank);
1407
1408 /* Decrease channel count */
1409 hadc->InjectionConfig.ChannelCount--;
1410
1411 /* 3. tmp_JSQR_ContextQueueBeingBuilt is fully built for this HAL_ADCEx_InjectedConfigChannel()
1412 call, aggregate the setting to those already built during the previous
1413 HAL_ADCEx_InjectedConfigChannel() calls (for the same context of course) */
1414 hadc->InjectionConfig.ContextQueue |= tmp_JSQR_ContextQueueBeingBuilt;
1415
1416 /* 4. End of context setting: if this is the last channel set, then write context
1417 into register JSQR and make it enter into queue */
1418 if (hadc->InjectionConfig.ChannelCount == 0U)
1419 {
1420 MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, hadc->InjectionConfig.ContextQueue);
1421 }
1422 }
1423
1424 /* Parameters update conditioned to ADC state: */
1425 /* Parameters that can be updated when ADC is disabled or enabled without */
1426 /* conversion on going on injected group: */
1427 /* - Injected context queue: Queue disable (active context is kept) or */
1428 /* enable (context decremented, up to 2 contexts queued) */
1429 /* - Injected discontinuous mode: can be enabled only if auto-injected */
1430 /* mode is disabled. */
1431 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1432 {
1433 /* If auto-injected mode is disabled: no constraint */
1434 if (sConfigInjected->AutoInjectedConv == DISABLE)
1435 {
1436 MODIFY_REG(hadc->Instance->CFGR,
1437 ADC_CFGR_JQM | ADC_CFGR_JDISCEN,
1438 ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)sConfigInjected->QueueInjectedContext) |
1439 ADC_CFGR_INJECT_DISCCONTINUOUS((uint32_t)sConfigInjected->InjectedDiscontinuousConvMode));
1440 }
1441 /* If auto-injected mode is enabled: Injected discontinuous setting is */
1442 /* discarded. */
1443 else
1444 {
1445 MODIFY_REG(hadc->Instance->CFGR,
1446 ADC_CFGR_JQM | ADC_CFGR_JDISCEN,
1447 ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)sConfigInjected->QueueInjectedContext));
1448 }
1449
1450 }
1451
1452 /* Parameters update conditioned to ADC state: */
1453 /* Parameters that can be updated when ADC is disabled or enabled without */
1454 /* conversion on going on regular and injected groups: */
1455 /* - Automatic injected conversion: can be enabled if injected group */
1456 /* external triggers are disabled. */
1457 /* - Channel sampling time */
1458 /* - Channel offset */
1459 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
1460 tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
1461
1462 if ((tmp_adc_is_conversion_on_going_regular == 0UL)
1463 && (tmp_adc_is_conversion_on_going_injected == 0UL)
1464 )
1465 {
1466 /* If injected group external triggers are disabled (set to injected */
1467 /* software start): no constraint */
1468 if ((sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START)
1469 || (sConfigInjected->ExternalTrigInjecConvEdge == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE))
1470 {
1471 if (sConfigInjected->AutoInjectedConv == ENABLE)
1472 {
1473 SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
1474 }
1475 else
1476 {
1477 CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
1478 }
1479 }
1480 /* If Automatic injected conversion was intended to be set and could not */
1481 /* due to injected group external triggers enabled, error is reported. */
1482 else
1483 {
1484 if (sConfigInjected->AutoInjectedConv == ENABLE)
1485 {
1486 /* Update ADC state machine to error */
1487 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
1488
1489 tmp_hal_status = HAL_ERROR;
1490 }
1491 else
1492 {
1493 CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO);
1494 }
1495 }
1496
1497 if (sConfigInjected->InjecOversamplingMode == ENABLE)
1498 {
1499 assert_param(IS_ADC_OVERSAMPLING_RATIO(sConfigInjected->InjecOversampling.Ratio));
1500 assert_param(IS_ADC_RIGHT_BIT_SHIFT(sConfigInjected->InjecOversampling.RightBitShift));
1501
1502 /* JOVSE must be reset in case of triggered regular mode */
1503 assert_param(!(READ_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS) == (ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS)));
1504
1505 /* Configuration of Injected Oversampler: */
1506 /* - Oversampling Ratio */
1507 /* - Right bit shift */
1508
1509 /* Enable OverSampling mode */
1510 MODIFY_REG(hadc->Instance->CFGR2,
1511 ADC_CFGR2_JOVSE |
1512 ADC_CFGR2_OVSR |
1513 ADC_CFGR2_OVSS,
1514 ADC_CFGR2_JOVSE |
1515 sConfigInjected->InjecOversampling.Ratio |
1516 sConfigInjected->InjecOversampling.RightBitShift
1517 );
1518 }
1519 else
1520 {
1521 /* Disable Regular OverSampling */
1522 CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_JOVSE);
1523 }
1524
1525 /* Set sampling time of the selected ADC channel */
1526 LL_ADC_SetChannelSamplingTime(hadc->Instance, sConfigInjected->InjectedChannel, sConfigInjected->InjectedSamplingTime);
1527
1528 /* Configure the offset: offset enable/disable, channel, offset value */
1529
1530 /* Shift the offset with respect to the selected ADC resolution. */
1531 /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
1532 tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, sConfigInjected->InjectedOffset);
1533
1534 if (sConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE)
1535 {
1536 /* Set ADC selected offset number */
1537 LL_ADC_SetOffset(hadc->Instance, sConfigInjected->InjectedOffsetNumber, sConfigInjected->InjectedChannel,
1538 tmpOffsetShifted);
1539
1540 }
1541 else
1542 {
1543 /* Scan each offset register to check if the selected channel is targeted. */
1544 /* If this is the case, the corresponding offset number is disabled. */
1545 if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
1546 {
1547 LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_1, LL_ADC_OFFSET_DISABLE);
1548 }
1549 if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
1550 {
1551 LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_2, LL_ADC_OFFSET_DISABLE);
1552 }
1553 if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
1554 {
1555 LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_3, LL_ADC_OFFSET_DISABLE);
1556 }
1557 if(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) == __LL_ADC_CHANNEL_TO_DECIMAL_NB(sConfigInjected->InjectedChannel))
1558 {
1559 LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_4, LL_ADC_OFFSET_DISABLE);
1560 }
1561 }
1562
1563 }
1564
1565 /* Parameters update conditioned to ADC state: */
1566 /* Parameters that can be updated only when ADC is disabled: */
1567 /* - Single or differential mode */
1568 /* - Internal measurement channels: Vbat/VrefInt/TempSensor */
1569 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
1570 {
1571 /* Set mode single-ended or differential input of the selected ADC channel */
1572 LL_ADC_SetChannelSingleDiff(hadc->Instance, sConfigInjected->InjectedChannel, sConfigInjected->InjectedSingleDiff);
1573
1574 /* Configuration of differential mode */
1575 /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */
1576 if (sConfigInjected->InjectedSingleDiff == ADC_DIFFERENTIAL_ENDED)
1577 {
1578 /* Set sampling time of the selected ADC channel */
1579 LL_ADC_SetChannelSamplingTime(hadc->Instance, (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL((__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)sConfigInjected->InjectedChannel) + 1UL) & 0x1FUL)), sConfigInjected->InjectedSamplingTime);
1580 }
1581
1582 /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */
1583 /* internal measurement paths enable: If internal channel selected, */
1584 /* enable dedicated internal buffers and path. */
1585 /* Note: these internal measurement paths can be disabled using */
1586 /* HAL_ADC_DeInit(). */
1587
1588 if(__LL_ADC_IS_CHANNEL_INTERNAL(sConfigInjected->InjectedChannel))
1589 {
1590 /* Configuration of common ADC parameters (continuation) */
1591 /* Software is allowed to change common parameters only when all ADCs */
1592 /* of the common group are disabled. */
1593 if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
1594 {
1595 tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
1596
1597 /* If the requested internal measurement path has already been enabled, */
1598 /* bypass the configuration processing. */
1599 if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL))
1600 {
1601 if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc))
1602 {
1603 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel);
1604
1605 /* Delay for temperature sensor stabilization time */
1606 /* Wait loop initialization and execution */
1607 /* Note: Variable divided by 2 to compensate partially */
1608 /* CPU processing cycles, scaling in us split to not */
1609 /* exceed 32 bits register capacity and handle low frequency. */
1610 wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
1611 while(wait_loop_index != 0UL)
1612 {
1613 wait_loop_index--;
1614 }
1615 }
1616 }
1617 else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
1618 {
1619 if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc))
1620 {
1621 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel);
1622 }
1623 }
1624 else if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
1625 {
1626 if (ADC_VREFINT_INSTANCE(hadc))
1627 {
1628 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel);
1629 }
1630 }
1631 else
1632 {
1633 /* nothing to do */
1634 }
1635 }
1636 /* If the requested internal measurement path has already been enabled */
1637 /* and other ADC of the common group are enabled, internal */
1638 /* measurement paths cannot be enabled. */
1639 else
1640 {
1641 /* Update ADC state machine to error */
1642 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
1643
1644 tmp_hal_status = HAL_ERROR;
1645 }
1646 }
1647
1648 }
1649
1650 /* Process unlocked */
1651 __HAL_UNLOCK(hadc);
1652
1653 /* Return function status */
1654 return tmp_hal_status;
1655 }
1656 #endif /* ADC_SUPPORT_2_5_MSPS */
1657
1658 #if defined(ADC_SUPPORT_2_5_MSPS)
1659 /* Feature "ADC group injected" not available on ADC peripheral of this STM32WB device */
1660 #else
1661 /**
1662 * @brief Enable Injected Queue
1663 * @note This function resets CFGR register JQDIS bit in order to enable the
1664 * Injected Queue. JQDIS can be written only when ADSTART and JDSTART
1665 * are both equal to 0 to ensure that no regular nor injected
1666 * conversion is ongoing.
1667 * @param hadc ADC handle
1668 * @retval HAL status
1669 */
HAL_ADCEx_EnableInjectedQueue(ADC_HandleTypeDef * hadc)1670 HAL_StatusTypeDef HAL_ADCEx_EnableInjectedQueue(ADC_HandleTypeDef *hadc)
1671 {
1672 HAL_StatusTypeDef tmp_hal_status;
1673 uint32_t tmp_adc_is_conversion_on_going_regular;
1674 uint32_t tmp_adc_is_conversion_on_going_injected;
1675
1676 /* Check the parameters */
1677 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1678
1679 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
1680 tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
1681
1682 /* Parameter can be set only if no conversion is on-going */
1683 if ((tmp_adc_is_conversion_on_going_regular == 0UL)
1684 && (tmp_adc_is_conversion_on_going_injected == 0UL)
1685 )
1686 {
1687 CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS);
1688
1689 /* Update state, clear previous result related to injected queue overflow */
1690 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF);
1691
1692 tmp_hal_status = HAL_OK;
1693 }
1694 else
1695 {
1696 tmp_hal_status = HAL_ERROR;
1697 }
1698
1699 return tmp_hal_status;
1700 }
1701
1702 /**
1703 * @brief Disable Injected Queue
1704 * @note This function sets CFGR register JQDIS bit in order to disable the
1705 * Injected Queue. JQDIS can be written only when ADSTART and JDSTART
1706 * are both equal to 0 to ensure that no regular nor injected
1707 * conversion is ongoing.
1708 * @param hadc ADC handle
1709 * @retval HAL status
1710 */
HAL_ADCEx_DisableInjectedQueue(ADC_HandleTypeDef * hadc)1711 HAL_StatusTypeDef HAL_ADCEx_DisableInjectedQueue(ADC_HandleTypeDef *hadc)
1712 {
1713 HAL_StatusTypeDef tmp_hal_status;
1714 uint32_t tmp_adc_is_conversion_on_going_regular;
1715 uint32_t tmp_adc_is_conversion_on_going_injected;
1716
1717 /* Check the parameters */
1718 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1719
1720 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
1721 tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
1722
1723 /* Parameter can be set only if no conversion is on-going */
1724 if ((tmp_adc_is_conversion_on_going_regular == 0UL)
1725 && (tmp_adc_is_conversion_on_going_injected == 0UL)
1726 )
1727 {
1728 LL_ADC_INJ_SetQueueMode(hadc->Instance, LL_ADC_INJ_QUEUE_DISABLE);
1729 tmp_hal_status = HAL_OK;
1730 }
1731 else
1732 {
1733 tmp_hal_status = HAL_ERROR;
1734 }
1735
1736 return tmp_hal_status;
1737 }
1738 #endif /* ADC_SUPPORT_2_5_MSPS */
1739
1740 /**
1741 * @brief Disable ADC voltage regulator.
1742 * @note Disabling voltage regulator allows to save power. This operation can
1743 * be carried out only when ADC is disabled.
1744 * @note To enable again the voltage regulator, the user is expected to
1745 * resort to HAL_ADC_Init() API.
1746 * @param hadc ADC handle
1747 * @retval HAL status
1748 */
HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef * hadc)1749 HAL_StatusTypeDef HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef *hadc)
1750 {
1751 HAL_StatusTypeDef tmp_hal_status;
1752
1753 /* Check the parameters */
1754 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1755
1756 /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
1757 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
1758 {
1759 LL_ADC_DisableInternalRegulator(hadc->Instance);
1760 tmp_hal_status = HAL_OK;
1761 }
1762 else
1763 {
1764 tmp_hal_status = HAL_ERROR;
1765 }
1766
1767 return tmp_hal_status;
1768 }
1769
1770 #if defined(ADC_SUPPORT_2_5_MSPS)
1771 /* Feature " ADC deep power-down" not available on ADC peripheral of this STM32WB device */
1772 #else
1773 /**
1774 * @brief Enter ADC deep power-down mode
1775 * @note This mode is achieved in setting DEEPPWD bit and allows to save power
1776 * in reducing leakage currents. It is particularly interesting before
1777 * entering stop modes.
1778 * @note Setting DEEPPWD automatically clears ADVREGEN bit and disables the
1779 * ADC voltage regulator. This means that this API encompasses
1780 * HAL_ADCEx_DisableVoltageRegulator(). Additionally, the internal
1781 * calibration is lost.
1782 * @note To exit the ADC deep-power-down mode, the user is expected to
1783 * resort to HAL_ADC_Init() API as well as to relaunch a calibration
1784 * with HAL_ADCEx_Calibration_Start() API or to re-apply a previously
1785 * saved calibration factor.
1786 * @param hadc ADC handle
1787 * @retval HAL status
1788 */
HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef * hadc)1789 HAL_StatusTypeDef HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef *hadc)
1790 {
1791 HAL_StatusTypeDef tmp_hal_status;
1792
1793 /* Check the parameters */
1794 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1795
1796 /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
1797 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
1798 {
1799 LL_ADC_EnableDeepPowerDown(hadc->Instance);
1800 tmp_hal_status = HAL_OK;
1801 }
1802 else
1803 {
1804 tmp_hal_status = HAL_ERROR;
1805 }
1806
1807 return tmp_hal_status;
1808 }
1809 #endif /* ADC_SUPPORT_2_5_MSPS */
1810
1811 /**
1812 * @}
1813 */
1814
1815 /**
1816 * @}
1817 */
1818
1819 #endif /* HAL_ADC_MODULE_ENABLED */
1820 /**
1821 * @}
1822 */
1823
1824 /**
1825 * @}
1826 */
1827