1 /**
2 ******************************************************************************
3 * @file stm32n6xx_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 * "stm32n6xx_hal_adc.c".
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2023 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 "stm32n6xx_hal_adc.c".
27 [..]
28 @endverbatim
29 ******************************************************************************
30 */
31
32 /* Includes ------------------------------------------------------------------*/
33 #include "stm32n6xx_hal.h"
34
35 /** @addtogroup STM32N6xx_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 #define ADC_JSQR_FIELDS ((ADC_JSQR_JL | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN |\
54 ADC_JSQR_JSQ1 | ADC_JSQR_JSQ2 |\
55 ADC_JSQR_JSQ3 | ADC_JSQR_JSQ4 )) /*!< ADC_JSQR fields of parameters that can be updated anytime
56 once the ADC is enabled */
57
58 #define ADC_JSQR_LOW_FIELDS (ADC_JSQR_JL | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN) /*!< ADC_JSQR fields of parameters that can be updated anytime
59 once the ADC is enabled */
60
61 /* Fixed timeout value for ADC calibration. */
62 /* Values defined to be higher than worst cases: low clock frequency */
63 /* Ex of profile low frequency: (refer to device datasheet, parameter "fADC") */
64 /* Conversion_cycle = (12.5 + 1499.5) = 1512 */
65 /* Calibration_time MAX = Conversion_cycle / fADC_min */
66 /* = 1512 / (0.7MHz) = 2.16 ms */
67 /* Used timeout value includes a margin versus theoretical max value */
68 #define ADC_CALIBRATION_TIMEOUT (5UL) /*!< ADC calibration time-out value (unit: ms) */
69
70 #define ADC_CALIBRATION_STEPS (8UL) /*!< Number of ADC measurement during calibration procedure */
71 /**
72 * @}
73 */
74
75 /* Private macro -------------------------------------------------------------*/
76 /* Private variables ---------------------------------------------------------*/
77 /* Private function prototypes -----------------------------------------------*/
78 static HAL_StatusTypeDef ADC_Calibration_MeasureOffset(ADC_HandleTypeDef *hadc,
79 uint32_t SingleDiff,
80 uint32_t *pCalibrationFactor);
81 /* Exported functions --------------------------------------------------------*/
82
83 /** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions
84 * @{
85 */
86
87 /** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions
88 * @brief Extended IO operation functions
89 *
90 @verbatim
91 ===============================================================================
92 ##### IO operation functions #####
93 ===============================================================================
94 [..] This section provides functions allowing to:
95
96 (+) Perform the ADC self-calibration for single and differential ending.
97 (+) Get calibration factors for single or differential ending.
98 (+) Set calibration factors for single or differential ending.
99
100 (+) Start conversion of ADC group injected.
101 (+) Stop conversion of ADC group injected.
102 (+) Poll for conversion complete on ADC group injected.
103 (+) Get result of ADC group injected channel conversion.
104 (+) Start conversion of ADC group injected and enable interruptions.
105 (+) Stop conversion of ADC group injected and disable interruptions.
106
107 (+) When multimode feature is available, start multimode and enable DMA transfer.
108 (+) Stop multimode and disable ADC DMA transfer.
109 (+) Get result of multimode conversion.
110
111 @endverbatim
112 * @{
113 */
114
115 /**
116 * @brief Perform an ADC automatic self-calibration
117 * Calibration prerequisite: ADC must be disabled (execute this
118 * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
119 * @note Note: This calibration may reduce ADC full range. It is only
120 * recommended for application that needs precise measurement and not
121 * on full range (Vref+ minus few hundreds of mV, refer to reference
122 * manual).
123 * The calibration procedure removes ADC conversion offset error. After
124 * calibration ADC full range is reduced to
125 * [Vref-; (Vref+)-CALFACT_x].
126 * @param hadc ADC handle
127 * @param SingleDiff Selection of single-ended or differential input
128 * This parameter can be one of the following values:
129 * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
130 * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input
131 * single ended and differential ended
132 * @retval HAL status
133 */
HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef * hadc,uint32_t SingleDiff)134 HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
135 {
136 HAL_StatusTypeDef tmp_hal_status;
137 uint32_t calibration_factor;
138 uint32_t offset_required_single_end = 0UL;
139 uint32_t backup_trigger_settings;
140 uint32_t backup_offset_config[4];
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 /* Enable ADC if not already enabled */
150 tmp_hal_status = ADC_Enable(hadc);
151
152 /* Ensure no conversion is ongoing and ADC enabled correctly */
153 if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
154 && (tmp_hal_status == HAL_OK))
155 {
156 /* Set ADC state */
157 ADC_STATE_CLR_SET(hadc->State,
158 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
159 HAL_ADC_STATE_BUSY_INTERNAL);
160
161 /* Save ADC to current configuration */
162 backup_trigger_settings = READ_REG(hadc->Instance->CFGR1);
163 backup_offset_config[0] = LL_ADC_GetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_1);
164 backup_offset_config[1] = LL_ADC_GetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_2);
165 backup_offset_config[2] = LL_ADC_GetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_3);
166 backup_offset_config[3] = LL_ADC_GetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_4);
167
168 /* Force ADC configuration for calibration */
169 CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMNGT | ADC_CFGR1_EXTEN | ADC_CFGR1_CONT | ADC_CFGR1_RES);
170 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_1, 0);
171 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_2, 0);
172 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_3, 0);
173 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_4, 0);
174
175 /* Disable additional offset before calibration start */
176 LL_ADC_DisableCalibrationOffset(hadc->Instance);
177
178 /* Start ADC offset measurement in single ended mode */
179 tmp_hal_status = ADC_Calibration_MeasureOffset(hadc, ADC_SINGLE_ENDED, &calibration_factor);
180
181 if (tmp_hal_status == HAL_OK)
182 {
183 /* Store the singled-ended calibration factor in CALFACT_S[8:0]. */
184 LL_ADC_SetCalibrationFactor(hadc->Instance, LL_ADC_SINGLE_ENDED, calibration_factor);
185
186 if ((SingleDiff & ADC_DIFFERENTIAL_ENDED) == ADC_DIFFERENTIAL_ENDED)
187 {
188 /* Store calibration offset state after single-ended calibration. */
189 /* keep the same setting for differential-ended calibration. */
190 offset_required_single_end = LL_ADC_IsCalibrationOffsetEnabled(hadc->Instance);
191
192 /* Start ADC offset measurement in differential ended mode */
193 tmp_hal_status = ADC_Calibration_MeasureOffset(hadc, ADC_DIFFERENTIAL_ENDED, &calibration_factor);
194
195 if (tmp_hal_status == HAL_OK)
196 {
197 /* Store the differential-ended calibration factor in CALFACT_D[8:0]. */
198 LL_ADC_SetCalibrationFactor(hadc->Instance, LL_ADC_DIFFERENTIAL_ENDED, calibration_factor);
199
200 /* Additional calibration offset is applied to both single-ended */
201 /* and differential-ended conversion mode. */
202 /* If calibration offset was enabled by differential-ended */
203 /* calibration, single-ended mode should be recalibrated using with */
204 /* calibration offset enabled. */
205 if (offset_required_single_end != LL_ADC_IsCalibrationOffsetEnabled(hadc->Instance))
206 {
207 /* Start ADC offset measurement in single-ended mode */
208 tmp_hal_status = ADC_Calibration_MeasureOffset(hadc, ADC_SINGLE_ENDED, &calibration_factor);
209
210 if (tmp_hal_status == HAL_OK)
211 {
212 /* Store the singled-ended calibration factor in CALFACT_S[8:0]. */
213 LL_ADC_SetCalibrationFactor(hadc->Instance, LL_ADC_SINGLE_ENDED, calibration_factor);
214 }
215 else
216 {
217 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
218
219 /* Note: No need to update variable "tmp_hal_status" here: */
220 /* already set to state "HAL_ERROR" by function disabling */
221 /* the ADC. */
222 }
223 }
224 else
225 {
226 /* nothing to do */
227 }
228 }
229 else
230 {
231 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
232
233 /* Note: No need to update variable "tmp_hal_status" here: already */
234 /* set to state "HAL_ERROR" by function disabling the ADC. */
235 }
236 }
237 else
238 {
239 /* Prevent unused argument(s) compilation warning if no assert_param */
240 /* check (Only used for differential mode calibration) */
241 UNUSED(offset_required_single_end);
242 }
243 }
244 else
245 {
246 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
247
248 /* Note: No need to update variable "tmp_hal_status" here: already set */
249 /* to state "HAL_ERROR" by function disabling the ADC. */
250 }
251
252 /* End of calibration procedure */
253 LL_ADC_StopCalibration(hadc->Instance);
254
255 /* Restore ADC configuration to previous state */
256 WRITE_REG(hadc->Instance->CFGR1, backup_trigger_settings);
257 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_1, backup_offset_config[0]);
258 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_2, backup_offset_config[1]);
259 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_3, backup_offset_config[2]);
260 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_4, backup_offset_config[3]);
261
262 /* Set ADC state */
263 ADC_STATE_CLR_SET(hadc->State,
264 HAL_ADC_STATE_BUSY_INTERNAL,
265 HAL_ADC_STATE_READY);
266 }
267 else
268 {
269 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
270
271 /* Note: No need to update variable "tmp_hal_status" here: already set */
272 /* to state "HAL_ERROR" by function disabling the ADC. */
273 }
274
275 __HAL_UNLOCK(hadc);
276
277 return tmp_hal_status;
278 }
279
280 /**
281 * @brief Get the calibration factor.
282 * @param hadc ADC handle.
283 * @param SingleDiff This parameter can be only:
284 * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
285 * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input
286 * differential ended
287 * @retval Calibration value.
288 */
HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef * hadc,uint32_t SingleDiff)289 uint32_t HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef *hadc, uint32_t SingleDiff)
290 {
291 /* Check the parameters */
292 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
293 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
294 /* Return the selected ADC calibration value */
295 return LL_ADC_GetCalibrationFactor(hadc->Instance, SingleDiff);
296 }
297
298 /**
299 * @brief Set the calibration factor to overwrite automatic conversion result.
300 * ADC must be enabled and no conversion is ongoing.
301 * @param hadc ADC handle
302 * @param SingleDiff This parameter can be only:
303 * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended
304 * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input
305 * differential ended
306 * @param CalibrationFactor Calibration factor (coded on 7 bits maximum)
307 * @retval HAL state
308 */
HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef * hadc,uint32_t SingleDiff,uint32_t CalibrationFactor)309 HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff,
310 uint32_t CalibrationFactor)
311 {
312 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
313 uint32_t tmp_adc_is_conversion_on_going_regular;
314 uint32_t tmp_adc_is_conversion_on_going_injected;
315
316 /* Check the parameters */
317 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
318 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
319 assert_param(IS_ADC_CALFACT(CalibrationFactor));
320
321 /* Process locked */
322 __HAL_LOCK(hadc);
323
324 /* Verification of hardware constraints before modifying the calibration */
325 /* factors register: ADC must be enabled, no conversion on going. */
326 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
327 tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
328 if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL)
329 && (tmp_adc_is_conversion_on_going_regular == 0UL)
330 && (tmp_adc_is_conversion_on_going_injected == 0UL)
331 )
332 {
333 /* Set the selected ADC calibration value */
334 LL_ADC_SetCalibrationFactor(hadc->Instance, SingleDiff, CalibrationFactor);
335 }
336 else
337 {
338 /* Update ADC state machine */
339 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
340 /* Update ADC error code */
341 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
342
343 /* Update ADC state machine to error */
344 tmp_hal_status = HAL_ERROR;
345 }
346
347 __HAL_UNLOCK(hadc);
348
349 return tmp_hal_status;
350 }
351 /**
352 * @brief Enable ADC, start conversion of injected group.
353 * @note Interruptions enabled in this function: None.
354 * @note Case of multimode enabled when multimode feature is available:
355 * HAL_ADCEx_InjectedStart() API must be called for ADC slave first,
356 * then for ADC master.
357 * For ADC slave, ADC is enabled only (conversion is not started).
358 * For ADC master, ADC is enabled and multimode conversion is started.
359 * @param hadc ADC handle.
360 * @retval HAL status
361 */
HAL_ADCEx_InjectedStart(ADC_HandleTypeDef * hadc)362 HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc)
363 {
364 HAL_StatusTypeDef tmp_hal_status;
365 #if defined(ADC_MULTIMODE_SUPPORT)
366 uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
367 #endif /* ADC_MULTIMODE_SUPPORT */
368
369 /* Check the parameters */
370 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
371
372 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
373 {
374 return HAL_BUSY;
375 }
376 else
377 {
378 /* Process locked */
379 __HAL_LOCK(hadc);
380
381 /* Enable the ADC peripheral */
382 tmp_hal_status = ADC_Enable(hadc);
383
384 /* Start conversion if ADC is effectively enabled */
385 if (tmp_hal_status == HAL_OK)
386 {
387 /* Check if a regular conversion is ongoing */
388 if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
389 {
390 /* Set ADC error code to none */
391 ADC_CLEAR_ERRORCODE(hadc);
392 }
393
394 /* Set ADC state */
395 /* - Clear state bitfield related to injected group conversion results */
396 /* - Set state bitfield related to injected operation */
397 ADC_STATE_CLR_SET(hadc->State,
398 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
399 HAL_ADC_STATE_INJ_BUSY);
400
401 #if defined(ADC_MULTIMODE_SUPPORT)
402 /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
403 - if ADC instance is master or if multimode feature is not available
404 - if multimode setting is disabled (ADC instance slave in independent mode) */
405 if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
406 || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
407 )
408 {
409 CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
410 }
411 #endif /* ADC_MULTIMODE_SUPPORT */
412
413 /* Clear ADC group injected group conversion flag */
414 /* (To ensure of no unknown state from potential previous ADC operations) */
415 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
416
417 /* Unlock before starting ADC conversions: in case of potential */
418 /* interruption, to let the process to ADC IRQ Handler. */
419 __HAL_UNLOCK(hadc);
420
421 /* Enable conversion of injected group, if automatic injected conversion */
422 /* is disabled. */
423 /* If software start has been selected, conversion starts immediately. */
424 /* If external trigger has been selected, conversion will start at next */
425 /* trigger event. */
426 /* Case of multimode enabled (when multimode feature is available): */
427 /* if ADC is slave, */
428 /* - ADC is enabled only (conversion is not started), */
429 /* - if multimode only concerns regular conversion, ADC is enabled */
430 /* and conversion is started. */
431 /* If ADC is master or independent, */
432 /* - ADC is enabled and conversion is started. */
433 #if defined(ADC_MULTIMODE_SUPPORT)
434 if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
435 || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
436 || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
437 || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
438 )
439 {
440 /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
441 if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
442 {
443 LL_ADC_INJ_StartConversion(hadc->Instance);
444 }
445 }
446 else
447 {
448 /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
449 SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
450 }
451 #else
452 if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
453 {
454 /* Start ADC group injected conversion */
455 LL_ADC_INJ_StartConversion(hadc->Instance);
456 }
457 #endif /* ADC_MULTIMODE_SUPPORT */
458
459 }
460 else
461 {
462 __HAL_UNLOCK(hadc);
463 }
464
465 return tmp_hal_status;
466 }
467 }
468
469 /**
470 * @brief Stop conversion of injected channels. Disable ADC peripheral if
471 * no regular conversion is on going.
472 * @note If ADC must be disabled and if conversion is on going on
473 * regular group, function HAL_ADC_Stop must be used to stop both
474 * injected and regular groups, and disable the ADC.
475 * @note If injected group mode auto-injection is enabled,
476 * function HAL_ADC_Stop must be used.
477 * @note In case of multimode enabled (when multimode feature is available),
478 * HAL_ADCEx_InjectedStop() must be called for ADC master first, then for ADC slave.
479 * For ADC master, conversion is stopped and ADC is disabled.
480 * For ADC slave, ADC is disabled only (conversion stop of ADC master
481 * has already stopped conversion of ADC slave).
482 * @param hadc ADC handle.
483 * @retval HAL status
484 */
HAL_ADCEx_InjectedStop(ADC_HandleTypeDef * hadc)485 HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc)
486 {
487 HAL_StatusTypeDef tmp_hal_status;
488
489 /* Check the parameters */
490 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
491
492 /* Process locked */
493 __HAL_LOCK(hadc);
494
495 /* 1. Stop potential conversion on going on injected group only. */
496 tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
497
498 /* Disable ADC peripheral if injected conversions are effectively stopped */
499 /* and if no conversion on regular group is on-going */
500 if (tmp_hal_status == HAL_OK)
501 {
502 if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
503 {
504 /* 2. Disable the ADC peripheral */
505 tmp_hal_status = ADC_Disable(hadc);
506
507 /* Check if ADC is effectively disabled */
508 if (tmp_hal_status == HAL_OK)
509 {
510 /* Set ADC state */
511 ADC_STATE_CLR_SET(hadc->State,
512 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
513 HAL_ADC_STATE_READY);
514 }
515 }
516 /* Conversion on injected group is stopped, but ADC not disabled since */
517 /* conversion on regular group is still running. */
518 else
519 {
520 /* Set ADC state */
521 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
522 }
523 }
524
525 __HAL_UNLOCK(hadc);
526
527 return tmp_hal_status;
528 }
529
530 /**
531 * @brief Wait for injected group conversion to be completed.
532 * @param hadc ADC handle
533 * @param Timeout Timeout value in millisecond.
534 * @note Depending on hadc->Init.EOCSelection, JEOS or JEOC is
535 * checked and cleared depending on AUTDLY bit status.
536 * @retval HAL status
537 */
HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef * hadc,uint32_t Timeout)538 HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)
539 {
540 uint32_t tickstart;
541 uint32_t tmp_Flag_End;
542 uint32_t tmp_adc_inj_is_trigger_source_sw_start;
543 uint32_t tmp_adc_reg_is_trigger_source_sw_start;
544 uint32_t tmp_cfgr;
545 #if defined(ADC_MULTIMODE_SUPPORT)
546 const ADC_TypeDef *tmpADC_Master;
547 uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
548 #endif /* ADC_MULTIMODE_SUPPORT */
549
550 /* Check the parameters */
551 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
552
553 /* If end of sequence selected */
554 if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
555 {
556 tmp_Flag_End = ADC_FLAG_JEOS;
557 }
558 else /* end of conversion selected */
559 {
560 tmp_Flag_End = ADC_FLAG_JEOC;
561 }
562
563 /* Get timeout */
564 tickstart = HAL_GetTick();
565
566 /* Wait until End of Conversion or Sequence flag is raised */
567 while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
568 {
569 /* Check if timeout is disabled (set to infinite wait) */
570 if (Timeout != HAL_MAX_DELAY)
571 {
572 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
573 {
574 /* New check to avoid false timeout detection in case of preemption */
575 if ((hadc->Instance->ISR & tmp_Flag_End) == 0UL)
576 {
577 /* Update ADC state machine to timeout */
578 SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
579
580 __HAL_UNLOCK(hadc);
581
582 return HAL_TIMEOUT;
583 }
584 }
585 }
586 }
587
588 /* Retrieve ADC configuration */
589 tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance);
590 tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance);
591 /* Get relevant register CFGR1 in ADC instance of ADC master or slave */
592 /* in function of multimode state (for devices with multimode */
593 /* available). */
594 #if defined(ADC_MULTIMODE_SUPPORT)
595 if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
596 || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
597 || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
598 || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
599 )
600 {
601 tmp_cfgr = READ_REG(hadc->Instance->CFGR1);
602 }
603 else
604 {
605 tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance);
606 tmp_cfgr = READ_REG(tmpADC_Master->CFGR1);
607 }
608 #else
609 tmp_cfgr = READ_REG(hadc->Instance->CFGR1);
610 #endif /* ADC_MULTIMODE_SUPPORT */
611
612 /* Update ADC state machine */
613 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
614
615 /* Determine whether any further conversion upcoming on group injected */
616 /* by external trigger or by automatic injected conversion */
617 /* from group regular. */
618 if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL) ||
619 ((READ_BIT(tmp_cfgr, ADC_CFGR1_JAUTO) == 0UL) &&
620 ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) &&
621 (READ_BIT(tmp_cfgr, ADC_CFGR1_CONT) == 0UL))))
622 {
623 /* Check whether end of sequence is reached */
624 if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS))
625 {
626 /* Set ADC state */
627 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
628
629 if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
630 {
631 SET_BIT(hadc->State, HAL_ADC_STATE_READY);
632 }
633
634 }
635 }
636
637 /* Clear polled flag */
638 if (tmp_Flag_End == ADC_FLAG_JEOS)
639 {
640 /* Clear end of sequence JEOS flag of injected group if low power feature */
641 /* "LowPowerAutoWait " is disabled, to not interfere with this feature. */
642 /* For injected groups, no new conversion will start before JEOS is */
643 /* cleared. */
644 if (READ_BIT(tmp_cfgr, ADC_CFGR1_AUTDLY) == 0UL)
645 {
646 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
647 }
648 }
649 else
650 {
651 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
652 }
653
654 /* Return API HAL status */
655 return HAL_OK;
656 }
657
658 /**
659 * @brief Enable ADC, start conversion of injected group with interruption.
660 * @note Interruptions enabled in this function according to initialization
661 * setting : JEOC (end of conversion) or JEOS (end of sequence)
662 * @note Case of multimode enabled (when multimode feature is enabled):
663 * HAL_ADCEx_InjectedStart_IT() API must be called for ADC slave first,
664 * then for ADC master.
665 * For ADC slave, ADC is enabled only (conversion is not started).
666 * For ADC master, ADC is enabled and multimode conversion is started.
667 * @param hadc ADC handle.
668 * @retval HAL status.
669 */
HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef * hadc)670 HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc)
671 {
672 HAL_StatusTypeDef tmp_hal_status;
673 #if defined(ADC_MULTIMODE_SUPPORT)
674 uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
675 #endif /* ADC_MULTIMODE_SUPPORT */
676
677 /* Check the parameters */
678 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
679
680 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL)
681 {
682 return HAL_BUSY;
683 }
684 else
685 {
686 /* Process locked */
687 __HAL_LOCK(hadc);
688
689 /* Enable the ADC peripheral */
690 tmp_hal_status = ADC_Enable(hadc);
691
692 /* Start conversion if ADC is effectively enabled */
693 if (tmp_hal_status == HAL_OK)
694 {
695 /* Check if a regular conversion is ongoing */
696 if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL)
697 {
698 /* Set ADC error code to none */
699 ADC_CLEAR_ERRORCODE(hadc);
700 }
701
702 /* Set ADC state */
703 /* - Clear state bitfield related to injected group conversion results */
704 /* - Set state bitfield related to injected operation */
705 ADC_STATE_CLR_SET(hadc->State,
706 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
707 HAL_ADC_STATE_INJ_BUSY);
708
709 #if defined(ADC_MULTIMODE_SUPPORT)
710 /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit
711 - if ADC instance is master or if multimode feature is not available
712 - if multimode setting is disabled (ADC instance slave in independent mode) */
713 if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
714 || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
715 )
716 {
717 CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
718 }
719 #endif /* ADC_MULTIMODE_SUPPORT */
720
721 /* Clear ADC group injected group conversion flag */
722 /* (To ensure of no unknown state from potential previous ADC operations) */
723 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS));
724
725 /* Unlock before starting ADC conversions: in case of potential */
726 /* interruption, to let the process to ADC IRQ Handler. */
727 __HAL_UNLOCK(hadc);
728
729 /* Enable ADC end of conversion interrupt */
730 switch (hadc->Init.EOCSelection)
731 {
732 case ADC_EOC_SEQ_CONV:
733 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
734 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS);
735 break;
736 /* case ADC_EOC_SINGLE_CONV */
737 default:
738 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS);
739 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
740 break;
741 }
742
743 /* Enable conversion of injected group, if automatic injected conversion */
744 /* is disabled. */
745 /* If software start has been selected, conversion starts immediately. */
746 /* If external trigger has been selected, conversion will start at next */
747 /* trigger event. */
748 /* Case of multimode enabled (when multimode feature is available): */
749 /* if ADC is slave, */
750 /* - ADC is enabled only (conversion is not started), */
751 /* - if multimode only concerns regular conversion, ADC is enabled */
752 /* and conversion is started. */
753 /* If ADC is master or independent, */
754 /* - ADC is enabled and conversion is started. */
755 #if defined(ADC_MULTIMODE_SUPPORT)
756 if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance)
757 || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT)
758 || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT)
759 || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL)
760 )
761 {
762 /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
763 if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
764 {
765 LL_ADC_INJ_StartConversion(hadc->Instance);
766 }
767 }
768 else
769 {
770 /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */
771 SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE);
772 }
773 #else
774 if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT)
775 {
776 /* Start ADC group injected conversion */
777 LL_ADC_INJ_StartConversion(hadc->Instance);
778 }
779 #endif /* ADC_MULTIMODE_SUPPORT */
780
781 }
782 else
783 {
784 __HAL_UNLOCK(hadc);
785 }
786
787 return tmp_hal_status;
788 }
789 }
790
791 /**
792 * @brief Stop conversion of injected channels, disable interruption of
793 * end-of-conversion. Disable ADC peripheral if no regular conversion
794 * is on going.
795 * @note If ADC must be disabled and if conversion is on going on
796 * regular group, function HAL_ADC_Stop must be used to stop both
797 * injected and regular groups, and disable the ADC.
798 * @note If injected group mode auto-injection is enabled,
799 * function HAL_ADC_Stop must be used.
800 * @note Case of multimode enabled (when multimode feature is available):
801 * HAL_ADCEx_InjectedStop_IT() API must be called for ADC master first,
802 * then for ADC slave.
803 * For ADC master, conversion is stopped and ADC is disabled.
804 * For ADC slave, ADC is disabled only (conversion stop of ADC master
805 * has already stopped conversion of ADC slave).
806 * @note In case of auto-injection mode, HAL_ADC_Stop() must be used.
807 * @param hadc ADC handle
808 * @retval HAL status
809 */
HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef * hadc)810 HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc)
811 {
812 HAL_StatusTypeDef tmp_hal_status;
813
814 /* Check the parameters */
815 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
816
817 /* Process locked */
818 __HAL_LOCK(hadc);
819
820 /* 1. Stop potential conversion on going on injected group only. */
821 tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP);
822
823 /* Disable ADC peripheral if injected conversions are effectively stopped */
824 /* and if no conversion on the other group (regular group) is intended to */
825 /* continue. */
826 if (tmp_hal_status == HAL_OK)
827 {
828 /* Disable ADC end of conversion interrupt for injected channels */
829 __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_JEOC | ADC_IT_JEOS));
830
831 if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
832 {
833 /* 2. Disable the ADC peripheral */
834 tmp_hal_status = ADC_Disable(hadc);
835
836 /* Check if ADC is effectively disabled */
837 if (tmp_hal_status == HAL_OK)
838 {
839 /* Set ADC state */
840 ADC_STATE_CLR_SET(hadc->State,
841 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
842 HAL_ADC_STATE_READY);
843 }
844 }
845 /* Conversion on injected group is stopped, but ADC not disabled since */
846 /* conversion on regular group is still running. */
847 else
848 {
849 /* Set ADC state */
850 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
851 }
852 }
853
854 __HAL_UNLOCK(hadc);
855
856 return tmp_hal_status;
857 }
858
859 #if defined(ADC_MULTIMODE_SUPPORT)
860 /**
861 * @brief Enable ADC, start MultiMode conversion and transfer regular results through DMA.
862 * @note Multimode must have been previously configured using
863 * HAL_ADCEx_MultiModeConfigChannel() function.
864 * Interruptions enabled in this function:
865 * overrun, DMA half transfer, DMA transfer complete.
866 * Each of these interruptions has its dedicated callback function.
867 * @note Conversion data of both multimode ADC instances will take each one buffer element, therefore
868 buffer total size should be doubled to get similar data size for each ADC instance vs independent mode.
869 * @note State field of Slave ADC handle is not updated in this configuration:
870 * user should not rely on it for information related to Slave regular
871 * conversions.
872 * @param hadc ADC handle of ADC master (handle of ADC slave must not be used)
873 * @param pData Destination Buffer address.
874 * @param Length Length of data to be transferred from ADC peripheral to memory (unit: number of transfers)
875 * @retval HAL status
876 */
HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef * hadc,uint32_t * pData,uint32_t Length)877 HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length)
878 {
879 HAL_StatusTypeDef tmp_hal_status;
880 ADC_HandleTypeDef tmphadcSlave;
881 ADC_Common_TypeDef *tmp_adc_common;
882 uint32_t LengthInBytes;
883 DMA_NodeConfTypeDef node_conf;
884
885 /* Check the parameters */
886 assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
887 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
888 assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
889
890 if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
891 {
892 return HAL_BUSY;
893 }
894 else
895 {
896 /* Process locked */
897 __HAL_LOCK(hadc);
898
899 /* Temporary handle minimum initialization */
900 __HAL_ADC_RESET_HANDLE_STATE(&tmphadcSlave);
901 ADC_CLEAR_ERRORCODE(&tmphadcSlave);
902
903 /* Set a temporary handle of the ADC slave associated to the ADC master */
904 ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
905
906 if (tmphadcSlave.Instance == NULL)
907 {
908 /* Set ADC state */
909 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
910
911 __HAL_UNLOCK(hadc);
912
913 return HAL_ERROR;
914 }
915
916 /* Enable the ADC peripherals: master and slave (in case if not already */
917 /* enabled previously) */
918 tmp_hal_status = ADC_Enable(hadc);
919 if (tmp_hal_status == HAL_OK)
920 {
921 tmp_hal_status = ADC_Enable(&tmphadcSlave);
922 }
923
924 /* Start multimode conversion of ADCs pair */
925 if (tmp_hal_status == HAL_OK)
926 {
927 /* Set ADC state */
928 ADC_STATE_CLR_SET(hadc->State,
929 (HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP),
930 HAL_ADC_STATE_REG_BUSY);
931
932 /* Set ADC error code to none */
933 ADC_CLEAR_ERRORCODE(hadc);
934
935 /* Set the DMA transfer complete callback */
936 hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
937
938 /* Set the DMA half transfer complete callback */
939 hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
940
941 /* Set the DMA error callback */
942 hadc->DMA_Handle->XferErrorCallback = ADC_DMAError ;
943
944 /* Pointer to the common control register */
945 tmp_adc_common = __LL_ADC_COMMON_INSTANCE(hadc->Instance);
946
947 /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
948 /* start (in case of SW start): */
949
950 /* Clear regular group conversion flag and overrun flag */
951 /* (To ensure of no unknown state from potential previous ADC operations) */
952 __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
953
954 /* Unlock before starting ADC conversions: in case of potential */
955 /* interruption, to let the process to ADC IRQ Handler. */
956 __HAL_UNLOCK(hadc);
957
958 /* Enable ADC overrun interrupt */
959 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
960
961 /* Start the DMA channel */
962 if ((hadc->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
963 {
964 if ((hadc->DMA_Handle->LinkedListQueue != NULL) && (hadc->DMA_Handle->LinkedListQueue->Head != NULL))
965 {
966 /* Length should be converted to number of bytes */
967 if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hadc->DMA_Handle->LinkedListQueue->Head) != HAL_OK)
968 {
969 return HAL_ERROR;
970 }
971
972 /* Length should be converted to number of bytes */
973 if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
974 {
975 /* Word -> Bytes */
976 LengthInBytes = Length * 4U;
977 }
978 else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
979 {
980 /* Halfword -> Bytes */
981 LengthInBytes = Length * 2U;
982 }
983 else /* Bytes */
984 {
985 /* Same size already expressed in Bytes */
986 LengthInBytes = Length;
987 }
988
989 hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = (uint32_t)LengthInBytes;
990 hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
991 (uint32_t)&tmp_adc_common->CDR;
992 hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
993
994 tmp_hal_status = HAL_DMAEx_List_Start_IT(hadc->DMA_Handle);
995 }
996 else
997 {
998 tmp_hal_status = HAL_ERROR;
999 }
1000 }
1001 else
1002 {
1003 /* Length should be converted to number of bytes */
1004 if (hadc->DMA_Handle->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
1005 {
1006 /* Word -> Bytes */
1007 LengthInBytes = Length * 4U;
1008 }
1009 else if (hadc->DMA_Handle->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
1010 {
1011 /* Halfword -> Bytes */
1012 LengthInBytes = Length * 2U;
1013 }
1014 else /* Bytes */
1015 {
1016 /* Same size already expressed in Bytes */
1017 LengthInBytes = Length;
1018 }
1019
1020 tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&tmp_adc_common->CDR, (uint32_t)pData,
1021 LengthInBytes);
1022 }
1023
1024 if (tmp_hal_status != HAL_ERROR)
1025 {
1026 /* Enable conversion of regular group. */
1027 /* If software start has been selected, conversion starts immediately. */
1028 /* If external trigger has been selected, conversion will start at next */
1029 /* trigger event. */
1030 /* Start ADC group regular conversion */
1031 LL_ADC_REG_StartConversion(hadc->Instance);
1032 }
1033 }
1034 else
1035 {
1036 __HAL_UNLOCK(hadc);
1037 }
1038
1039 return tmp_hal_status;
1040 }
1041 }
1042
1043 /**
1044 * @brief Stop multimode ADC conversion, disable ADC DMA transfer, disable ADC peripheral.
1045 * @note Multimode is kept enabled after this function. MultiMode DMA bits
1046 * (MDMA and DMACFG bits of common CCR register) are maintained. To disable
1047 * Multimode (set with HAL_ADCEx_MultiModeConfigChannel()), ADC must be
1048 * reinitialized using HAL_ADC_Init() or HAL_ADC_DeInit(), or the user can
1049 * resort to HAL_ADCEx_DisableMultiMode() API.
1050 * @note In case of DMA configured in circular mode, function
1051 * HAL_ADC_Stop_DMA() must be called after this function with handle of
1052 * ADC slave, to properly disable the DMA channel.
1053 * @param hadc ADC handle of ADC master (handle of ADC slave must not be used)
1054 * @retval HAL status
1055 */
HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef * hadc)1056 HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc)
1057 {
1058 HAL_StatusTypeDef tmp_hal_status;
1059 uint32_t tickstart;
1060 ADC_HandleTypeDef tmphadcSlave;
1061 uint32_t tmphadcSlave_conversion_on_going;
1062 HAL_StatusTypeDef tmphadcSlave_disable_status;
1063
1064 /* Check the parameters */
1065 assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
1066
1067 /* Process locked */
1068 __HAL_LOCK(hadc);
1069
1070
1071 /* 1. Stop potential multimode conversion on going, on regular and injected groups */
1072 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP);
1073
1074 /* Disable ADC peripheral if conversions are effectively stopped */
1075 if (tmp_hal_status == HAL_OK)
1076 {
1077 /* Temporary handle minimum initialization */
1078 __HAL_ADC_RESET_HANDLE_STATE(&tmphadcSlave);
1079 ADC_CLEAR_ERRORCODE(&tmphadcSlave);
1080
1081 /* Set a temporary handle of the ADC slave associated to the ADC master */
1082 ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
1083
1084 if (tmphadcSlave.Instance == NULL)
1085 {
1086 /* Update ADC state machine to error */
1087 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
1088
1089 __HAL_UNLOCK(hadc);
1090
1091 return HAL_ERROR;
1092 }
1093
1094 /* Procedure to disable the ADC peripheral: wait for conversions */
1095 /* effectively stopped (ADC master and ADC slave), then disable ADC */
1096
1097 /* 1. Wait for ADC conversion completion for ADC master and ADC slave */
1098 tickstart = HAL_GetTick();
1099
1100 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
1101 while ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL)
1102 || (tmphadcSlave_conversion_on_going == 1UL)
1103 )
1104 {
1105 if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
1106 {
1107 /* New check to avoid false timeout detection in case of preemption */
1108 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
1109 if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL)
1110 || (tmphadcSlave_conversion_on_going == 1UL)
1111 )
1112 {
1113 /* Update ADC state machine to error */
1114 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
1115
1116 __HAL_UNLOCK(hadc);
1117
1118 return HAL_ERROR;
1119 }
1120 }
1121
1122 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
1123 }
1124
1125 /* Disable the DMA channel (in case of DMA in circular mode or stop */
1126 /* while DMA transfer is on going) */
1127 /* Note: DMA channel of ADC slave should be stopped after this function */
1128 /* with HAL_ADC_Stop_DMA() API. */
1129 if (hadc->DMA_Handle->State == HAL_DMA_STATE_BUSY)
1130 {
1131 tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
1132
1133 /* Check if DMA channel effectively disabled */
1134 if (tmp_hal_status == HAL_ERROR)
1135 {
1136 /* Update ADC state machine to error */
1137 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
1138 }
1139 }
1140
1141 /* Disable ADC overrun interrupt */
1142 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
1143
1144 /* 2. Disable the ADC peripherals: master and slave */
1145 /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep in */
1146 /* memory a potential failing status. */
1147 if (tmp_hal_status == HAL_OK)
1148 {
1149 tmphadcSlave_disable_status = ADC_Disable(&tmphadcSlave);
1150 if ((ADC_Disable(hadc) == HAL_OK) &&
1151 (tmphadcSlave_disable_status == HAL_OK))
1152 {
1153 tmp_hal_status = HAL_OK;
1154 }
1155 }
1156 else
1157 {
1158 /* In case of error, attempt to disable ADC master and slave without status assert */
1159 (void) ADC_Disable(hadc);
1160 (void) ADC_Disable(&tmphadcSlave);
1161 }
1162
1163 /* Set ADC state (ADC master) */
1164 ADC_STATE_CLR_SET(hadc->State,
1165 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
1166 HAL_ADC_STATE_READY);
1167 }
1168
1169 __HAL_UNLOCK(hadc);
1170
1171 return tmp_hal_status;
1172 }
1173
1174 /**
1175 * @brief Return the last ADC Master and Slave regular conversions results when in multimode configuration.
1176 * @note Multimode data contains ADC master and slave conversion data
1177 * concatenated. Data is usable under conditions of ADC multimode
1178 * data format selected and data width,
1179 * refer to @ref ADCEx_Dual_Mode_Data_Format.
1180 * The recommended method, without any constraint, is to use
1181 * DMA transfer. refer to @ref HAL_ADCEx_MultiModeStart_DMA.
1182 * @note Another solution exists to retrieve multimode conversion data
1183 * without packing (refer to @ref LL_ADC_REG_ReadMultiConvNoPacking)
1184 * but with timing constraints.
1185 * The recommended method, without any constraint, is to use
1186 * DMA transfer. refer to @ref HAL_ADCEx_MultiModeStart_DMA.
1187 * @param hadc ADC handle of ADC Master (handle of ADC Slave must not be used)
1188 * @retval The converted data values.
1189 */
HAL_ADCEx_MultiModeGetValue(const ADC_HandleTypeDef * hadc)1190 uint32_t HAL_ADCEx_MultiModeGetValue(const ADC_HandleTypeDef *hadc)
1191 {
1192 const ADC_Common_TypeDef *tmpADC_Common;
1193
1194 /* Check the parameters */
1195 assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
1196
1197 /* Prevent unused argument(s) compilation warning if no assert_param check */
1198 /* and possible no usage in __LL_ADC_COMMON_INSTANCE() below */
1199 UNUSED(hadc);
1200
1201 /* Pointer to the common control register */
1202 tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance);
1203
1204 /* Return the multi mode conversion value */
1205 return tmpADC_Common->CDR;
1206 }
1207 #endif /* ADC_MULTIMODE_SUPPORT */
1208
1209 /**
1210 * @brief Get ADC injected group conversion result.
1211 * @note Reading register JDRx automatically clears ADC flag JEOC
1212 * (ADC group injected end of unitary conversion).
1213 * @note This function returns an unsigned value. Using the ADC offset
1214 * feature can result in negative conversion data.
1215 * To read conversion data with ADC offset enabled
1216 * use function @ref HAL_ADCEx_InjectedGetSignedValue.
1217 * @note This function does not clear ADC flag JEOS
1218 * (ADC group injected end of sequence conversion)
1219 * Occurrence of flag JEOS rising:
1220 * - If sequencer is composed of 1 rank, flag JEOS is equivalent
1221 * to flag JEOC.
1222 * - If sequencer is composed of several ranks, during the scan
1223 * sequence flag JEOC only is raised, at the end of the scan sequence
1224 * both flags JEOC and EOS are raised.
1225 * Flag JEOS must not be cleared by this function because
1226 * it would not be compliant with low power features
1227 * (feature low power auto-wait, not available on all STM32 families).
1228 * To clear this flag, either use function:
1229 * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
1230 * model polling: @ref HAL_ADCEx_InjectedPollForConversion()
1231 * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
1232 * @param hadc ADC handle
1233 * @param InjectedRank the converted ADC injected rank.
1234 * This parameter can be one of the following values:
1235 * @arg @ref ADC_INJECTED_RANK_1 ADC group injected rank 1
1236 * @arg @ref ADC_INJECTED_RANK_2 ADC group injected rank 2
1237 * @arg @ref ADC_INJECTED_RANK_3 ADC group injected rank 3
1238 * @arg @ref ADC_INJECTED_RANK_4 ADC group injected rank 4
1239 * @retval ADC group injected conversion data
1240 */
HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef * hadc,uint32_t InjectedRank)1241 uint32_t HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef *hadc, uint32_t InjectedRank)
1242 {
1243 uint32_t tmp_jdr;
1244
1245 /* Check the parameters */
1246 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1247 assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
1248
1249 /* Get ADC converted value */
1250 switch (InjectedRank)
1251 {
1252 case ADC_INJECTED_RANK_4:
1253 tmp_jdr = hadc->Instance->JDR4;
1254 break;
1255 case ADC_INJECTED_RANK_3:
1256 tmp_jdr = hadc->Instance->JDR3;
1257 break;
1258 case ADC_INJECTED_RANK_2:
1259 tmp_jdr = hadc->Instance->JDR2;
1260 break;
1261 case ADC_INJECTED_RANK_1:
1262 default:
1263 tmp_jdr = hadc->Instance->JDR1;
1264 break;
1265 }
1266
1267 /* Return ADC converted value */
1268 return tmp_jdr;
1269 }
1270
1271 /**
1272 * @brief Get ADC injected group conversion result.
1273 * @note Reading register JDRx automatically clears ADC flag JEOC
1274 * (ADC group injected end of unitary conversion).
1275 * @note This function does not clear ADC flag JEOS
1276 * (ADC group injected end of sequence conversion)
1277 * Occurrence of flag JEOS rising:
1278 * - If sequencer is composed of 1 rank, flag JEOS is equivalent
1279 * to flag JEOC.
1280 * - If sequencer is composed of several ranks, during the scan
1281 * sequence flag JEOC only is raised, at the end of the scan sequence
1282 * both flags JEOC and EOS are raised.
1283 * Flag JEOS must not be cleared by this function because
1284 * it would not be compliant with low power features
1285 * (feature low power auto-wait, not available on all STM32 families).
1286 * To clear this flag, either use function:
1287 * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
1288 * model polling: @ref HAL_ADCEx_InjectedPollForConversion()
1289 * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS).
1290 * @param hadc ADC handle
1291 * @param InjectedRank the converted ADC injected rank.
1292 * This parameter can be one of the following values:
1293 * @arg @ref ADC_INJECTED_RANK_1 ADC group injected rank 1
1294 * @arg @ref ADC_INJECTED_RANK_2 ADC group injected rank 2
1295 * @arg @ref ADC_INJECTED_RANK_3 ADC group injected rank 3
1296 * @arg @ref ADC_INJECTED_RANK_4 ADC group injected rank 4
1297 * @retval ADC group injected conversion data
1298 */
HAL_ADCEx_InjectedGetSignedValue(const ADC_HandleTypeDef * hadc,uint32_t InjectedRank)1299 int32_t HAL_ADCEx_InjectedGetSignedValue(const ADC_HandleTypeDef *hadc, uint32_t InjectedRank)
1300 {
1301 int32_t tmp_jdr;
1302
1303 /* Check the parameters */
1304 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1305 assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
1306
1307 /* Get ADC converted value */
1308 switch (InjectedRank)
1309 {
1310 case ADC_INJECTED_RANK_4:
1311 tmp_jdr = (int32_t)(hadc->Instance->JDR4);
1312 break;
1313 case ADC_INJECTED_RANK_3:
1314 tmp_jdr = (int32_t)(hadc->Instance->JDR3);
1315 break;
1316 case ADC_INJECTED_RANK_2:
1317 tmp_jdr = (int32_t)(hadc->Instance->JDR2);
1318 break;
1319 case ADC_INJECTED_RANK_1:
1320 default:
1321 tmp_jdr = (int32_t)(hadc->Instance->JDR1);
1322 break;
1323 }
1324
1325 /* Return ADC converted value */
1326 return tmp_jdr;
1327 }
1328
1329 /**
1330 * @brief Injected conversion complete callback in non-blocking mode.
1331 * @param hadc ADC handle
1332 * @retval None
1333 */
HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef * hadc)1334 __weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
1335 {
1336 /* Prevent unused argument(s) compilation warning */
1337 UNUSED(hadc);
1338
1339 /* NOTE : This function should not be modified. When the callback is needed,
1340 function HAL_ADCEx_InjectedConvCpltCallback must be implemented in the user file.
1341 */
1342 }
1343
1344 /**
1345 * @brief Analog watchdog 2 callback in non-blocking mode.
1346 * @param hadc ADC handle
1347 * @retval None
1348 */
HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef * hadc)1349 __weak void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc)
1350 {
1351 /* Prevent unused argument(s) compilation warning */
1352 UNUSED(hadc);
1353
1354 /* NOTE : This function should not be modified. When the callback is needed,
1355 function HAL_ADCEx_LevelOutOfWindow2Callback must be implemented in the user file.
1356 */
1357 }
1358
1359 /**
1360 * @brief Analog watchdog 3 callback in non-blocking mode.
1361 * @param hadc ADC handle
1362 * @retval None
1363 */
HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef * hadc)1364 __weak void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc)
1365 {
1366 /* Prevent unused argument(s) compilation warning */
1367 UNUSED(hadc);
1368
1369 /* NOTE : This function should not be modified. When the callback is needed,
1370 function HAL_ADCEx_LevelOutOfWindow3Callback must be implemented in the user file.
1371 */
1372 }
1373
1374
1375 /**
1376 * @brief End Of Sampling callback in non-blocking mode.
1377 * @param hadc ADC handle
1378 * @retval None
1379 */
HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef * hadc)1380 __weak void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc)
1381 {
1382 /* Prevent unused argument(s) compilation warning */
1383 UNUSED(hadc);
1384
1385 /* NOTE : This function should not be modified. When the callback is needed,
1386 function HAL_ADCEx_EndOfSamplingCallback must be implemented in the user file.
1387 */
1388 }
1389
1390 /**
1391 * @brief Stop ADC conversion of regular group (and injected channels in
1392 * case of auto_injection mode), disable ADC peripheral if no
1393 * conversion is on going on injected group.
1394 * @param hadc ADC handle
1395 * @retval HAL status.
1396 */
HAL_ADCEx_RegularStop(ADC_HandleTypeDef * hadc)1397 HAL_StatusTypeDef HAL_ADCEx_RegularStop(ADC_HandleTypeDef *hadc)
1398 {
1399 HAL_StatusTypeDef tmp_hal_status;
1400
1401 /* Check the parameters */
1402 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1403
1404 /* Process locked */
1405 __HAL_LOCK(hadc);
1406
1407 /* 1. Stop potential regular conversion on going */
1408 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1409
1410 /* Disable ADC peripheral if regular conversions are effectively stopped
1411 and if no injected conversions are on-going */
1412 if (tmp_hal_status == HAL_OK)
1413 {
1414 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1415 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1416
1417 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1418 {
1419 /* 2. Disable the ADC peripheral */
1420 tmp_hal_status = ADC_Disable(hadc);
1421
1422 /* Check if ADC is effectively disabled */
1423 if (tmp_hal_status == HAL_OK)
1424 {
1425 /* Set ADC state */
1426 ADC_STATE_CLR_SET(hadc->State,
1427 HAL_ADC_STATE_INJ_BUSY,
1428 HAL_ADC_STATE_READY);
1429 }
1430 }
1431 /* Conversion on injected group is stopped, but ADC not disabled since */
1432 /* conversion on regular group is still running. */
1433 else
1434 {
1435 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
1436 }
1437 }
1438
1439 __HAL_UNLOCK(hadc);
1440
1441 return tmp_hal_status;
1442 }
1443
1444
1445 /**
1446 * @brief Stop ADC conversion of ADC groups regular and injected,
1447 * disable interrution of end-of-conversion,
1448 * disable ADC peripheral if no conversion is on going
1449 * on injected group.
1450 * @param hadc ADC handle
1451 * @retval HAL status.
1452 */
HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef * hadc)1453 HAL_StatusTypeDef HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef *hadc)
1454 {
1455 HAL_StatusTypeDef tmp_hal_status;
1456
1457 /* Check the parameters */
1458 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1459
1460 /* Process locked */
1461 __HAL_LOCK(hadc);
1462
1463 /* 1. Stop potential regular conversion on going */
1464 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1465
1466 /* Disable ADC peripheral if conversions are effectively stopped
1467 and if no injected conversion is on-going */
1468 if (tmp_hal_status == HAL_OK)
1469 {
1470 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1471 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1472
1473 /* Disable all regular-related interrupts */
1474 __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
1475
1476 /* 2. Disable ADC peripheral if no injected conversions are on-going */
1477 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1478 {
1479 tmp_hal_status = ADC_Disable(hadc);
1480 /* if no issue reported */
1481 if (tmp_hal_status == HAL_OK)
1482 {
1483 /* Set ADC state */
1484 ADC_STATE_CLR_SET(hadc->State,
1485 HAL_ADC_STATE_INJ_BUSY,
1486 HAL_ADC_STATE_READY);
1487 }
1488 }
1489 else
1490 {
1491 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
1492 }
1493 }
1494
1495 __HAL_UNLOCK(hadc);
1496
1497 return tmp_hal_status;
1498 }
1499
1500 /**
1501 * @brief Stop ADC conversion of regular group (and injected group in
1502 * case of auto_injection mode), disable ADC DMA transfer, disable
1503 * ADC peripheral if no conversion is on going
1504 * on injected group.
1505 * @note HAL_ADCEx_RegularStop_DMA() function is dedicated to single-ADC mode only.
1506 * For multimode (when multimode feature is available),
1507 * HAL_ADCEx_RegularMultiModeStop_DMA() API must be used.
1508 * @param hadc ADC handle
1509 * @retval HAL status.
1510 */
HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef * hadc)1511 HAL_StatusTypeDef HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef *hadc)
1512 {
1513 HAL_StatusTypeDef tmp_hal_status;
1514
1515 /* Check the parameters */
1516 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1517
1518 /* Process locked */
1519 __HAL_LOCK(hadc);
1520
1521 /* 1. Stop potential regular conversion on going */
1522 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1523
1524 /* Disable ADC peripheral if conversions are effectively stopped
1525 and if no injected conversion is on-going */
1526 if (tmp_hal_status == HAL_OK)
1527 {
1528 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1529 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1530
1531 /* Disable ADC DMA (ADC DMA configuration ADC_CFGR1_DMACFG is kept) */
1532 MODIFY_REG(hadc->Instance->CFGR1, ADC_CFGR1_DMNGT_0 | ADC_CFGR1_DMNGT_1, 0UL);
1533
1534 /* Disable the DMA channel (in case of DMA in circular mode or stop while */
1535 /* while DMA transfer is on going) */
1536 tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
1537
1538 /* Check if DMA channel effectively disabled */
1539 if (tmp_hal_status != HAL_OK)
1540 {
1541 /* Update ADC state machine to error */
1542 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
1543 }
1544
1545 /* Disable ADC overrun interrupt */
1546 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
1547
1548 /* 2. Disable the ADC peripheral */
1549 /* Update "tmp_hal_status" only if DMA channel disabling passed, */
1550 /* to keep in memory a potential failing status. */
1551 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1552 {
1553 if (tmp_hal_status == HAL_OK)
1554 {
1555 tmp_hal_status = ADC_Disable(hadc);
1556 }
1557 else
1558 {
1559 (void)ADC_Disable(hadc);
1560 }
1561
1562 /* Check if ADC is effectively disabled */
1563 if (tmp_hal_status == HAL_OK)
1564 {
1565 /* Set ADC state */
1566 ADC_STATE_CLR_SET(hadc->State,
1567 HAL_ADC_STATE_INJ_BUSY,
1568 HAL_ADC_STATE_READY);
1569 }
1570 }
1571 else
1572 {
1573 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
1574 }
1575 }
1576
1577 __HAL_UNLOCK(hadc);
1578
1579 return tmp_hal_status;
1580 }
1581
1582 #if defined(ADC_MULTIMODE_SUPPORT)
1583 /**
1584 * @brief Stop DMA-based multimode ADC conversion, disable ADC DMA transfer, disable ADC peripheral if no injected
1585 * conversion is on-going.
1586 * @note Multimode is kept enabled after this function. Multimode DMA bits
1587 * (MDMA and DMACFG bits of common CCR register) are maintained. To disable
1588 * multimode (set with HAL_ADCEx_MultiModeConfigChannel()), ADC must be
1589 * reinitialized using HAL_ADC_Init() or HAL_ADC_DeInit(), or the user can
1590 * resort to HAL_ADCEx_DisableMultiMode() API.
1591 * @note In case of DMA configured in circular mode, function
1592 * HAL_ADCEx_RegularStop_DMA() must be called after this function with handle of
1593 * ADC slave, to properly disable the DMA channel.
1594 * @param hadc ADC handle of ADC master (handle of ADC slave must not be used)
1595 * @retval HAL status
1596 */
HAL_ADCEx_RegularMultiModeStop_DMA(ADC_HandleTypeDef * hadc)1597 HAL_StatusTypeDef HAL_ADCEx_RegularMultiModeStop_DMA(ADC_HandleTypeDef *hadc)
1598 {
1599 HAL_StatusTypeDef tmp_hal_status;
1600 uint32_t tickstart;
1601 ADC_HandleTypeDef tmphadcSlave;
1602 uint32_t tmphadcSlave_conversion_on_going;
1603
1604 /* Check the parameters */
1605 assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
1606
1607 /* Process locked */
1608 __HAL_LOCK(hadc);
1609
1610
1611 /* 1. Stop potential multimode conversion on going, on regular groups */
1612 tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP);
1613
1614 /* Disable ADC peripheral if conversions are effectively stopped */
1615 if (tmp_hal_status == HAL_OK)
1616 {
1617 /* Clear HAL_ADC_STATE_REG_BUSY bit */
1618 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1619
1620 /* Temporary handle minimum initialization */
1621 __HAL_ADC_RESET_HANDLE_STATE(&tmphadcSlave);
1622 ADC_CLEAR_ERRORCODE(&tmphadcSlave);
1623
1624 /* Set a temporary handle of the ADC slave associated to the ADC master */
1625 ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
1626
1627 if (tmphadcSlave.Instance == NULL)
1628 {
1629 /* Update ADC state machine to error */
1630 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
1631
1632 __HAL_UNLOCK(hadc);
1633
1634 return HAL_ERROR;
1635 }
1636
1637 /* Procedure to disable the ADC peripheral: wait for conversions */
1638 /* effectively stopped (ADC master and ADC slave), then disable ADC */
1639
1640 /* 1. Wait for ADC conversion completion for ADC master and ADC slave */
1641 tickstart = HAL_GetTick();
1642
1643 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
1644 while ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL)
1645 || (tmphadcSlave_conversion_on_going == 1UL)
1646 )
1647 {
1648 if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
1649 {
1650 /* New check to avoid false timeout detection in case of preemption */
1651 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
1652 if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL)
1653 || (tmphadcSlave_conversion_on_going == 1UL)
1654 )
1655 {
1656 /* Update ADC state machine to error */
1657 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
1658
1659 __HAL_UNLOCK(hadc);
1660
1661 return HAL_ERROR;
1662 }
1663 }
1664
1665 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
1666 }
1667
1668 /* Disable the DMA channel (in case of DMA in circular mode or stop */
1669 /* while DMA transfer is on going) */
1670 /* Note: DMA channel of ADC slave should be stopped after this function */
1671 /* with HAL_ADCEx_RegularStop_DMA() API. */
1672 tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
1673
1674 /* Check if DMA channel effectively disabled */
1675 if (tmp_hal_status != HAL_OK)
1676 {
1677 /* Update ADC state machine to error */
1678 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
1679 }
1680
1681 /* Disable ADC overrun interrupt */
1682 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
1683
1684 /* 2. Disable the ADC peripherals: master and slave if no injected */
1685 /* conversion is on-going. */
1686 /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep in */
1687 /* memory a potential failing status. */
1688 if (tmp_hal_status == HAL_OK)
1689 {
1690 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1691 {
1692 tmp_hal_status = ADC_Disable(hadc);
1693 if (tmp_hal_status == HAL_OK)
1694 {
1695 if (LL_ADC_INJ_IsConversionOngoing((&tmphadcSlave)->Instance) == 0UL)
1696 {
1697 tmp_hal_status = ADC_Disable(&tmphadcSlave);
1698 }
1699 }
1700 }
1701
1702 if (tmp_hal_status == HAL_OK)
1703 {
1704 /* Both Master and Slave ADC's could be disabled. Update Master State */
1705 /* Clear HAL_ADC_STATE_INJ_BUSY bit, set HAL_ADC_STATE_READY bit */
1706 ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY);
1707 }
1708 else
1709 {
1710 /* injected (Master or Slave) conversions are still on-going,
1711 no Master State change */
1712 }
1713 }
1714 }
1715
1716 __HAL_UNLOCK(hadc);
1717
1718 return tmp_hal_status;
1719 }
1720 #endif /* ADC_MULTIMODE_SUPPORT */
1721
1722 /**
1723 * @}
1724 */
1725
1726 /** @defgroup ADCEx_Exported_Functions_Group2 ADC Extended Peripheral Control functions
1727 * @brief ADC Extended Peripheral Control functions
1728 *
1729 @verbatim
1730 ===============================================================================
1731 ##### Peripheral Control functions #####
1732 ===============================================================================
1733 [..] This section provides functions allowing to:
1734 (+) Configure channels on injected group
1735 (+) Configure multimode (when multimode feature is available)
1736 (+) Disable ADC voltage regulator
1737 (+) Enter ADC deep-power-down mode
1738
1739 @endverbatim
1740 * @{
1741 */
1742
1743 /**
1744 * @brief Configure a channel to be assigned to ADC group injected.
1745 * @note Possibility to update parameters on the fly:
1746 * This function initializes injected group, following calls to this
1747 * function can be used to reconfigure some parameters of structure
1748 * "ADC_InjectionConfTypeDef" on the fly, without resetting the ADC.
1749 * The setting of these parameters is conditioned to ADC state:
1750 * Refer to comments of structure "ADC_InjectionConfTypeDef".
1751 * @note In case of usage of internal measurement channels (VrefInt, ...):
1752 * These internal paths can be disabled using function
1753 * HAL_ADC_DeInit().
1754 * @param hadc ADC handle
1755 * @param pConfigInjected Structure of ADC injected group and ADC channel for
1756 * injected group.
1757 * @retval HAL status
1758 */
HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef * hadc,const ADC_InjectionConfTypeDef * pConfigInjected)1759 HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc,
1760 const ADC_InjectionConfTypeDef *pConfigInjected)
1761 {
1762 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
1763 uint32_t tmpOffsetShifted;
1764 uint32_t tmp_config_common_path_internal_channel;
1765 uint32_t tmp_config_path_internal_channel;
1766 uint32_t tmp_adc_is_conversion_on_going_regular;
1767 uint32_t tmp_adc_is_conversion_on_going_injected;
1768
1769 /* Check the parameters */
1770 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
1771 assert_param(IS_ADC_SAMPLING_TIME(pConfigInjected->InjectedSamplingTime));
1772 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(pConfigInjected->InjectedSingleDiff));
1773 assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->AutoInjectedConv));
1774 assert_param(IS_ADC_EXTTRIGINJEC_EDGE(pConfigInjected->ExternalTrigInjecConvEdge));
1775 assert_param(IS_ADC_EXTTRIGINJEC(hadc->Instance, pConfigInjected->ExternalTrigInjecConv));
1776 assert_param(IS_ADC_OFFSET_NUMBER(pConfigInjected->InjectedOffsetNumber));
1777 assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), pConfigInjected->InjectedOffset));
1778 assert_param(IS_ADC_OFFSET_SIGN(pConfigInjected->InjectedOffsetSign));
1779 assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjecOversamplingMode));
1780
1781 if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE)
1782 {
1783 assert_param(IS_ADC_INJECTED_RANK(pConfigInjected->InjectedRank));
1784 assert_param(IS_ADC_INJECTED_NB_CONV(pConfigInjected->InjectedNbrOfConversion));
1785 assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjectedDiscontinuousConvMode));
1786 }
1787
1788 /* Check offset range according to oversampling setting */
1789 if (hadc->Init.OversamplingMode == ENABLE)
1790 {
1791 assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc),
1792 pConfigInjected->InjectedOffset / (hadc->Init.Oversampling.Ratio + 1U)));
1793 }
1794 else
1795 {
1796 assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), pConfigInjected->InjectedOffset));
1797 }
1798
1799 /* JDISCEN and JAUTO bits can't be set at the same time */
1800 assert_param(!((pConfigInjected->InjectedDiscontinuousConvMode == ENABLE) \
1801 && (pConfigInjected->AutoInjectedConv == ENABLE)));
1802
1803 /* DISCEN and JAUTO bits can't be set at the same time */
1804 assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (pConfigInjected->AutoInjectedConv == ENABLE)));
1805
1806 /* Verification of channel number */
1807 if (pConfigInjected->InjectedSingleDiff != ADC_DIFFERENTIAL_ENDED)
1808 {
1809 assert_param(IS_ADC_CHANNEL(hadc, pConfigInjected->InjectedChannel));
1810 }
1811 else
1812 {
1813 assert_param(IS_ADC_DIFF_CHANNEL(hadc, pConfigInjected->InjectedChannel));
1814 }
1815
1816 /* ADC must be disabled to set configuration bits */
1817 if (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
1818 {
1819 return HAL_ERROR;
1820 }
1821
1822 /* Process locked */
1823 __HAL_LOCK(hadc);
1824
1825 /* Configuration of injected group sequencer: */
1826 /* - if scan mode is disabled: */
1827 /* * Injected channels sequence length is set to 0x00: 1 channel */
1828 /* converted (channel on injected rank 1) */
1829 /* Parameter "InjectedNbrOfConversion" is discarded. */
1830 /* - if scan mode is enabled: */
1831 /* * Injected channels sequence length is set to parameter */
1832 /* "InjectedNbrOfConversion". */
1833 /* Note: Scan mode is not present by hardware on this device, but used */
1834 /* by software for alignment over all STM32 devices. */
1835
1836 if ((hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) ||
1837 (pConfigInjected->InjectedNbrOfConversion == 1U))
1838 {
1839 /* Configuration of context register JSQR: */
1840 /* - number of ranks in injected group sequencer: fixed to 1st rank */
1841 /* (scan mode disabled, only rank 1 used) */
1842 /* - external trigger to start conversion */
1843 /* - external trigger polarity */
1844 /* - channel set to rank 1 (scan mode disabled, only rank 1 can be used) */
1845
1846 if (pConfigInjected->InjectedRank == ADC_INJECTED_RANK_1)
1847 {
1848 /* Enable external trigger if trigger selection is different of */
1849 /* software start. */
1850 /* Note: This configuration keeps the hardware feature of parameter */
1851 /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */
1852 /* software start. */
1853 if (pConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
1854 {
1855 MODIFY_REG(hadc->Instance->JSQR,
1856 ADC_JSQR_FIELDS,
1857 ADC_JSQR_RK(pConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1)
1858 | (pConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
1859 | pConfigInjected->ExternalTrigInjecConvEdge);
1860 }
1861 else
1862 {
1863 MODIFY_REG(hadc->Instance->JSQR,
1864 ADC_JSQR_FIELDS,
1865 ADC_JSQR_RK(pConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1));
1866 }
1867 }
1868 }
1869 else
1870 {
1871 /* Case of scan mode enabled, several channels to set into injected group */
1872 /* sequencer. */
1873
1874 MODIFY_REG(hadc->Instance->JSQR,
1875 ADC_JSQR_LOW_FIELDS,
1876 ADC_JSQR_RK(pConfigInjected->InjectedChannel, pConfigInjected->InjectedRank)
1877 | (pConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL)
1878 | pConfigInjected->ExternalTrigInjecConvEdge
1879 | ((pConfigInjected->InjectedNbrOfConversion - 1U) & ADC_JSQR_JL));
1880 }
1881
1882 /* Parameters update conditioned to ADC state: */
1883 /* Parameters that can be updated when ADC is disabled or enabled without */
1884 /* conversion on going on injected group: */
1885 /* - Injected discontinuous mode: can be enabled only if auto-injected */
1886 /* mode is disabled. */
1887 if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL)
1888 {
1889 /* ADC channels preselection */
1890 LL_ADC_SetChannelPreselection(hadc->Instance, pConfigInjected->InjectedChannel);
1891
1892 /* If auto-injected mode is disabled: no constraint */
1893 if (pConfigInjected->AutoInjectedConv == DISABLE)
1894 {
1895 MODIFY_REG(hadc->Instance->CFGR1,
1896 ADC_CFGR1_JDISCEN,
1897 ADC_CFGR1_INJECT_DISCCONTINUOUS((uint32_t)pConfigInjected->InjectedDiscontinuousConvMode));
1898 }
1899 /* If auto-injected mode is enabled: Injected discontinuous setting is */
1900 /* discarded. */
1901 else
1902 {
1903 MODIFY_REG(hadc->Instance->CFGR1,
1904 ADC_CFGR1_JDISCEN,
1905 ADC_CFGR1_INJECT_DISCCONTINUOUS((uint32_t)pConfigInjected->InjectedDiscontinuousConvMode));
1906 }
1907
1908 }
1909
1910 /* Parameters update conditioned to ADC state: */
1911 /* Parameters that can be updated when ADC is disabled or enabled without */
1912 /* conversion on going on regular and injected groups: */
1913 /* - Automatic injected conversion: can be enabled if injected group */
1914 /* external triggers are disabled. */
1915 /* - Channel sampling time */
1916 /* - Channel offset */
1917 tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance);
1918 tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance);
1919
1920 if ((tmp_adc_is_conversion_on_going_regular == 0UL)
1921 && (tmp_adc_is_conversion_on_going_injected == 0UL)
1922 )
1923 {
1924 /* If injected group external triggers are disabled (set to injected */
1925 /* software start): no constraint */
1926 if ((pConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START)
1927 || (pConfigInjected->ExternalTrigInjecConvEdge == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE))
1928 {
1929 if (pConfigInjected->AutoInjectedConv == ENABLE)
1930 {
1931 SET_BIT(hadc->Instance->CFGR1, ADC_CFGR1_JAUTO);
1932 }
1933 else
1934 {
1935 CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_JAUTO);
1936 }
1937 }
1938 /* If Automatic injected conversion was intended to be set and could not */
1939 /* due to injected group external triggers enabled, error is reported. */
1940 else
1941 {
1942 if (pConfigInjected->AutoInjectedConv == ENABLE)
1943 {
1944 /* Update ADC state machine to error */
1945 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
1946
1947 tmp_hal_status = HAL_ERROR;
1948 }
1949 else
1950 {
1951 CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_JAUTO);
1952 }
1953 }
1954
1955 if (pConfigInjected->InjecOversamplingMode == ENABLE)
1956 {
1957 assert_param(IS_ADC_OVERSAMPLING_RATIO(pConfigInjected->InjecOversampling.Ratio));
1958 assert_param(IS_ADC_RIGHT_BIT_SHIFT(pConfigInjected->InjecOversampling.RightBitShift));
1959
1960 /* JOVSE must be reset in case of triggered regular mode */
1961 assert_param(!(READ_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS) ==
1962 (ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS)));
1963
1964 /* Configuration of Injected Oversampler: */
1965 /* - Oversampling Ratio */
1966 /* - Right bit shift */
1967
1968 /* Enable OverSampling mode */
1969 MODIFY_REG(hadc->Instance->CFGR2,
1970 ADC_CFGR2_JOVSE |
1971 ADC_CFGR2_OVSR |
1972 ADC_CFGR2_OVSS,
1973 ADC_CFGR2_JOVSE |
1974 ((pConfigInjected->InjecOversampling.Ratio - 1UL) << ADC_CFGR2_OVSR_Pos) |
1975 pConfigInjected->InjecOversampling.RightBitShift
1976 );
1977 }
1978 else
1979 {
1980 /* Disable Regular OverSampling */
1981 CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_JOVSE);
1982 }
1983
1984 /* Set sampling time of the selected ADC channel */
1985 LL_ADC_SetChannelSamplingTime(hadc->Instance, pConfigInjected->InjectedChannel,
1986 pConfigInjected->InjectedSamplingTime);
1987
1988 /* Configure the offset: offset enable/disable, channel, offset value */
1989
1990 /* Shift the offset with respect to the selected ADC resolution. */
1991 /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
1992 tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, pConfigInjected->InjectedOffset);
1993
1994 if (pConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE)
1995 {
1996 /* Set ADC selected offset number */
1997 LL_ADC_SetOffsetChannel(hadc->Instance, pConfigInjected->InjectedOffsetNumber, pConfigInjected->InjectedChannel);
1998 LL_ADC_SetOffsetLevel(hadc->Instance, pConfigInjected->InjectedOffsetNumber, tmpOffsetShifted);
1999
2000 assert_param(IS_ADC_OFFSET_SIGN(pConfigInjected->InjectedOffsetSign));
2001 assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjectedOffsetSignedSaturation));
2002 assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjectedOffsetSaturation));
2003 /* Signed and unsigned saturation cannot be set at the same time */
2004 assert_param(!((pConfigInjected->InjectedOffsetSignedSaturation == ENABLE)
2005 && (pConfigInjected->InjectedOffsetSaturation == ENABLE)));
2006
2007 /* Set ADC selected offset sign */
2008 LL_ADC_SetOffsetSign(hadc->Instance, pConfigInjected->InjectedOffsetNumber, pConfigInjected->InjectedOffsetSign);
2009 /* Set ADC selected offset signed saturation */
2010 LL_ADC_SetOffsetSignedSaturation(hadc->Instance, pConfigInjected->InjectedOffsetNumber,
2011 (pConfigInjected->InjectedOffsetSignedSaturation == ENABLE)
2012 ? LL_ADC_OFFSET_SIGNED_SAT_ENABLE \
2013 : LL_ADC_OFFSET_SIGNED_SAT_DISABLE);
2014 /* Set ADC offset unsigned saturation */
2015 LL_ADC_SetOffsetUnsignedSaturation(hadc->Instance, pConfigInjected->InjectedOffsetNumber, \
2016 (pConfigInjected->InjectedOffsetSaturation == ENABLE) \
2017 ? LL_ADC_OFFSET_UNSIGNED_SAT_ENABLE \
2018 : LL_ADC_OFFSET_UNSIGNED_SAT_DISABLE);
2019 }
2020 else
2021 {
2022 /* Scan each offset register to check if the selected channel is targeted. */
2023 /* If this is the case, the corresponding offset number is disabled. */
2024 /* Scan each offset register to check if the selected channel is targeted.
2025 If this is the case, the corresponding offset number is disabled. */
2026 if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1))
2027 == __HAL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel))
2028 {
2029 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_1, 0UL);
2030 }
2031 if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2))
2032 == __HAL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel))
2033 {
2034 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_2, 0UL);
2035 }
2036 if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3))
2037 == __HAL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel))
2038 {
2039 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_3, 0UL);
2040 }
2041 if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4))
2042 == __HAL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel))
2043 {
2044 LL_ADC_SetOffsetLevel(hadc->Instance, LL_ADC_OFFSET_4, 0UL);
2045 }
2046 }
2047
2048 }
2049 /* Parameters update conditioned to ADC state: */
2050 /* Parameters that can be updated only when ADC is disabled: */
2051 /* - Single or differential mode */
2052 /* - Internal measurement channels: Vbat/VrefInt/TempSensor */
2053 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
2054 {
2055 /* Set mode single-ended or differential input of the selected ADC channel */
2056 LL_ADC_SetChannelSingleDiff(hadc->Instance, pConfigInjected->InjectedChannel, pConfigInjected->InjectedSingleDiff);
2057
2058 /* Configuration of differential mode */
2059 if (pConfigInjected->InjectedSingleDiff == ADC_DIFFERENTIAL_ENDED)
2060 {
2061 /* Set ADC channel preselection of corresponding negative channel */
2062 LL_ADC_SetChannelPreselection(hadc->Instance,
2063 __HAL_ADC_CHANNEL_DIFF_NEG_INPUT(hadc, pConfigInjected->InjectedChannel));
2064 }
2065
2066 }
2067
2068 /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */
2069 /* internal measurement paths enable: If internal channel selected, */
2070 /* enable dedicated internal buffers and path. */
2071 /* Note: these internal measurement paths can be disabled using */
2072 /* HAL_ADC_DeInit(). */
2073
2074 if (__LL_ADC_IS_CHANNEL_INTERNAL(pConfigInjected->InjectedChannel))
2075 {
2076 tmp_config_common_path_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance));
2077 tmp_config_path_internal_channel = LL_ADC_GetPathInternalCh(hadc->Instance);
2078
2079 /* If the requested internal measurement path has already been enabled, */
2080 /* bypass the configuration processing. */
2081 if ((pConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT)
2082 && ((tmp_config_common_path_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL))
2083 {
2084 if (ADC_VREFINT_INSTANCE(hadc))
2085 {
2086 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance),
2087 LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_common_path_internal_channel);
2088 }
2089 }
2090 else if ((pConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT)
2091 && ((tmp_config_common_path_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL))
2092 {
2093 if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc))
2094 {
2095 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance),
2096 LL_ADC_PATH_INTERNAL_VBAT | tmp_config_common_path_internal_channel);
2097 }
2098 }
2099 else if (((pConfigInjected->InjectedChannel == ADC_CHANNEL_VDDCORE)
2100 && ((tmp_config_path_internal_channel & LL_ADC_PATH_INTERNAL_VDDCORE) == 0UL)))
2101 {
2102 if (ADC_VDDCORE_INSTANCE(hadc))
2103 {
2104 LL_ADC_SetPathInternalCh(hadc->Instance, LL_ADC_PATH_INTERNAL_VDDCORE | tmp_config_path_internal_channel);
2105 }
2106 }
2107 else
2108 {
2109 /* nothing to do */
2110 }
2111 }
2112
2113 __HAL_UNLOCK(hadc);
2114
2115 return tmp_hal_status;
2116 }
2117
2118 #if defined(ADC_MULTIMODE_SUPPORT)
2119 /**
2120 * @brief Enable ADC multimode and configure multimode parameters
2121 * @note Possibility to update parameters on the fly:
2122 * This function initializes multimode parameters, following
2123 * calls to this function can be used to reconfigure some parameters
2124 * of structure "ADC_MultiModeTypeDef" on the fly, without resetting
2125 * the ADCs.
2126 * The setting of these parameters is conditioned to ADC state.
2127 * For parameters constraints, see comments of structure
2128 * "ADC_MultiModeTypeDef".
2129 * @note To move back configuration from multimode to single mode, ADC must
2130 * be reset (using function HAL_ADC_Init() ).
2131 * @param hadc Master ADC handle
2132 * @param pMultimode Structure of ADC multimode configuration
2133 * @retval HAL status
2134 */
HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef * hadc,const ADC_MultiModeTypeDef * pMultimode)2135 HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc,
2136 const ADC_MultiModeTypeDef *pMultimode)
2137 {
2138 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
2139 ADC_Common_TypeDef *tmpADC_Common;
2140 ADC_HandleTypeDef tmphadcSlave;
2141 uint32_t tmphadcSlave_conversion_on_going;
2142
2143 /* Check the parameters */
2144 assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance));
2145 assert_param(IS_ADC_MULTIMODE(pMultimode->Mode));
2146 if (pMultimode->Mode != ADC_MODE_INDEPENDENT)
2147 {
2148 assert_param(IS_ADC_DUAL_DATA_MODE(pMultimode->DualModeData));
2149 assert_param(IS_ADC_SAMPLING_DELAY(pMultimode->TwoSamplingDelay));
2150 }
2151
2152 /* Process locked */
2153 __HAL_LOCK(hadc);
2154
2155 /* Temporary handle minimum initialization */
2156 __HAL_ADC_RESET_HANDLE_STATE(&tmphadcSlave);
2157 ADC_CLEAR_ERRORCODE(&tmphadcSlave);
2158
2159 ADC_MULTI_SLAVE(hadc, &tmphadcSlave);
2160
2161 if (tmphadcSlave.Instance == NULL)
2162 {
2163 /* Update ADC state machine to error */
2164 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
2165
2166 __HAL_UNLOCK(hadc);
2167
2168 return HAL_ERROR;
2169 }
2170
2171 /* ADC must be disabled to set configuration bits */
2172 if (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
2173 {
2174 if (LL_ADC_IsEnabled(tmphadcSlave.Instance) != 0UL)
2175 {
2176 return HAL_ERROR;
2177 }
2178 }
2179
2180 /* Parameters update conditioned to ADC state: */
2181 /* Parameters that can be updated when ADC is disabled or enabled without */
2182 /* conversion on going on regular group: */
2183 /* - Multimode DMA configuration */
2184 /* - Multimode DMA mode */
2185 tmphadcSlave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmphadcSlave)->Instance);
2186 if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL)
2187 && (tmphadcSlave_conversion_on_going == 0UL))
2188 {
2189 /* Pointer to the common control register */
2190 tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance);
2191
2192 /* If multimode is selected, configure all multimode parameters. */
2193 /* Otherwise, reset multimode parameters (can be used in case of */
2194 /* transition from multimode to independent mode). */
2195 if (pMultimode->Mode != ADC_MODE_INDEPENDENT)
2196 {
2197 MODIFY_REG(tmpADC_Common->CCR, ADC_CCR_DAMDF, pMultimode->DualModeData);
2198
2199 /* Parameters that can be updated only when ADC is disabled: */
2200 /* - Multimode mode selection */
2201 /* - Multimode delay */
2202 /* Note: Delay range depends on selected resolution: */
2203 /* from 1 to 12 clock cycles for 12 bits */
2204 /* from 1 to 10 clock cycles for 10 bits, */
2205 /* from 1 to 8 clock cycles for 8 bits */
2206 /* from 1 to 6 clock cycles for 6 bits */
2207 /* If a higher delay is selected, it will be clipped to maximum delay */
2208 /* range */
2209 if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
2210 {
2211 MODIFY_REG(tmpADC_Common->CCR,
2212 ADC_CCR_DUAL |
2213 ADC_CCR_DELAY,
2214 pMultimode->Mode |
2215 pMultimode->TwoSamplingDelay
2216 );
2217 }
2218 }
2219 else /* ADC_MODE_INDEPENDENT */
2220 {
2221 CLEAR_BIT(tmpADC_Common->CCR, ADC_CCR_DAMDF);
2222
2223 /* Parameters that can be updated only when ADC is disabled: */
2224 /* - Multimode mode selection */
2225 /* - Multimode delay */
2226 if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL)
2227 {
2228 CLEAR_BIT(tmpADC_Common->CCR, ADC_CCR_DUAL | ADC_CCR_DELAY);
2229 }
2230 }
2231 }
2232 /* If one of the ADC sharing the same common group is enabled, no update */
2233 /* could be done on neither of the multimode structure parameters. */
2234 else
2235 {
2236 /* Update ADC state machine to error */
2237 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
2238
2239 tmp_hal_status = HAL_ERROR;
2240 }
2241
2242 __HAL_UNLOCK(hadc);
2243
2244 return tmp_hal_status;
2245 }
2246 #endif /* ADC_MULTIMODE_SUPPORT */
2247
2248 /**
2249 * @brief Enter ADC deep-power-down mode
2250 * @note This mode is achieved in setting DEEPPWD bit and allows to save power
2251 * in reducing leakage currents. It is particularly interesting before
2252 * entering stop modes.
2253 * @note Setting DEEPPWD automatically clears ADVREGEN bit and disables the
2254 * ADC voltage regulator. This means that this API encompasses
2255 * HAL_ADCEx_DisableVoltageRegulator(). Additionally, the internal
2256 * calibration is lost.
2257 * @note To exit the ADC deep-power-down mode, the user is expected to
2258 * resort to HAL_ADC_Init() API as well as to relaunch a calibration
2259 * with HAL_ADCEx_Calibration_Start() API or to re-apply a previously
2260 * saved calibration factor.
2261 * @param hadc ADC handle
2262 * @retval HAL status
2263 */
HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef * hadc)2264 HAL_StatusTypeDef HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef *hadc)
2265 {
2266 HAL_StatusTypeDef tmp_hal_status;
2267
2268 /* Check the parameters */
2269 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
2270
2271 /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */
2272 if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
2273 {
2274 LL_ADC_EnableDeepPowerDown(hadc->Instance);
2275 tmp_hal_status = HAL_OK;
2276 }
2277 else
2278 {
2279 tmp_hal_status = HAL_ERROR;
2280 }
2281
2282 return tmp_hal_status;
2283 }
2284
2285 /**
2286 * @}
2287 */
2288
2289 /**
2290 * @}
2291 */
2292
2293 /**
2294 * @brief Measure ADC offset during calibration
2295 * @note To measure ADC calibration offset ADC must be enabled and calibration
2296 * mode should be enabled. This function is intended to be used inside
2297 * function @ref HAL_ADCEx_Calibration_Start
2298 * @param hadc ADC handle
2299 * @param SingleDiff
2300 * @param pCalibrationFactor ADC measurement offset
2301 * @retval HAL status
2302 */
ADC_Calibration_MeasureOffset(ADC_HandleTypeDef * hadc,uint32_t SingleDiff,uint32_t * pCalibrationFactor)2303 HAL_StatusTypeDef ADC_Calibration_MeasureOffset(ADC_HandleTypeDef *hadc,
2304 uint32_t SingleDiff,
2305 uint32_t *pCalibrationFactor)
2306 {
2307 int32_t calib_factor_avg = 0;
2308 uint32_t calibration_step;
2309 uint32_t tickstart;
2310
2311 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
2312
2313 if (LL_ADC_IsEnabled(hadc->Instance) != 0UL)
2314 {
2315 /* Start ADC calibration */
2316 LL_ADC_StartCalibration(hadc->Instance, SingleDiff);
2317
2318 do
2319 {
2320 /* Measure current ADC offset */
2321
2322 /* With calibration mode enabled, start multiple conversion and */
2323 /* accumulate data to compute ADC conversion offset. */
2324 /* The calibration factor will be the averaged converted value */
2325 for (calibration_step = 0; calibration_step < ADC_CALIBRATION_STEPS; calibration_step++)
2326 {
2327 LL_ADC_REG_StartConversion(hadc->Instance);
2328
2329 /* Wait for ADC conversion to end */
2330 /* Get tick count */
2331 tickstart = HAL_GetTick();
2332 while (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
2333 {
2334 if ((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
2335 {
2336 /* New check to avoid false timeout detection in case of preemption */
2337 if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL)
2338 {
2339 /* Update ADC state machine to error */
2340 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
2341
2342 /* Set ADC error code to ADC peripheral internal error */
2343 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
2344
2345 return HAL_ERROR;
2346 }
2347 }
2348 }
2349
2350 calib_factor_avg += (int32_t)(LL_ADC_REG_ReadConversionData32(hadc->Instance));
2351 } /* end of calibration steps */
2352
2353 /* Compute the average data */
2354 calib_factor_avg = calib_factor_avg / (int32_t)(calibration_step);
2355
2356 if (SingleDiff == ADC_DIFFERENTIAL_ENDED)
2357 {
2358 /* In differential mode, subtract averaged data by 0x7FF (middle */
2359 /* value for differential ended corresponding to a null offset) */
2360 calib_factor_avg = calib_factor_avg - 0x7FF;
2361 }
2362 else
2363 {
2364 /* nothing to do */
2365 }
2366 if (calib_factor_avg <= 0)
2367 {
2368 if (LL_ADC_IsCalibrationOffsetEnabled(hadc->Instance) == 0UL)
2369 {
2370 LL_ADC_EnableCalibrationOffset(hadc->Instance);
2371 }
2372 else
2373 {
2374 /* If calibration additional offset is enabled, measured calibration */
2375 /* factor should be different than 0. */
2376 tmp_hal_status = HAL_ERROR;
2377
2378 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
2379 }
2380 }
2381 else
2382 {
2383 *pCalibrationFactor = (uint32_t)(calib_factor_avg);
2384 }
2385 } while ((calib_factor_avg <= 0) && (tmp_hal_status == HAL_OK));
2386 }
2387 else
2388 {
2389 /* Update ADC state machine to error */
2390 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
2391
2392 tmp_hal_status = HAL_ERROR;
2393 }
2394
2395 return tmp_hal_status;
2396 }
2397
2398
2399 #endif /* HAL_ADC_MODULE_ENABLED */
2400 /**
2401 * @}
2402 */
2403
2404 /**
2405 * @}
2406 */
2407