1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_adc_ex.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following
6 * functionalities of the ADC extension peripheral:
7 * + Extended features functions
8 *
9 ******************************************************************************
10 * @attention
11 *
12 * Copyright (c) 2017 STMicroelectronics.
13 * All rights reserved.
14 *
15 * This software is licensed under terms that can be found in the LICENSE file
16 * in the root directory of this software component.
17 * If no LICENSE file comes with this software, it is provided AS-IS.
18 *
19 ******************************************************************************
20 @verbatim
21 ==============================================================================
22 ##### How to use this driver #####
23 ==============================================================================
24 [..]
25 (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():
26 (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE()
27 (##) ADC pins configuration
28 (+++) Enable the clock for the ADC GPIOs using the following function:
29 __HAL_RCC_GPIOx_CLK_ENABLE()
30 (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init()
31 (##) In case of using interrupts (e.g. HAL_ADC_Start_IT())
32 (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority()
33 (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()
34 (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler()
35 (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())
36 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE()
37 (+++) Configure and enable two DMA streams stream for managing data
38 transfer from peripheral to memory (output stream)
39 (+++) Associate the initialized DMA handle to the ADC DMA handle
40 using __HAL_LINKDMA()
41 (+++) Configure the priority and enable the NVIC for the transfer complete
42 interrupt on the two DMA Streams. The output stream should have higher
43 priority than the input stream.
44 (#) Configure the ADC Prescaler, conversion resolution and data alignment
45 using the HAL_ADC_Init() function.
46
47 (#) Configure the ADC Injected channels group features, use HAL_ADC_Init()
48 and HAL_ADC_ConfigChannel() functions.
49
50 (#) Three operation modes are available within this driver :
51
52 *** Polling mode IO operation ***
53 =================================
54 [..]
55 (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart()
56 (+) Wait for end of conversion using HAL_ADCEx_InjectedPollForConversion(), at this stage
57 user can specify the value of timeout according to his end application
58 (+) To read the ADC converted values, use the HAL_ADCEx_InjectedGetValue() function.
59 (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop()
60
61 *** Interrupt mode IO operation ***
62 ===================================
63 [..]
64 (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_IT()
65 (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine
66 (+) At ADC end of conversion HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can
67 add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback
68 (+) In case of ADC Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can
69 add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback
70 (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_IT()
71
72 *** Multi mode ADCs Regular channels configuration ***
73 ======================================================
74 [..]
75 (+) Select the Multi mode ADC regular channels features (dual or triple mode)
76 and configure the DMA mode using HAL_ADCEx_MultiModeConfigChannel() functions.
77 (+) Start the ADC peripheral using HAL_ADCEx_MultiModeStart_DMA(), at this stage the user specify the length
78 of data to be transferred at each end of conversion
79 (+) Read the ADCs converted values using the HAL_ADCEx_MultiModeGetValue() function.
80
81
82 @endverbatim
83 ******************************************************************************
84 */
85
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32f7xx_hal.h"
88
89 /** @addtogroup STM32F7xx_HAL_Driver
90 * @{
91 */
92
93 /** @defgroup ADCEx ADCEx
94 * @brief ADC Extended driver modules
95 * @{
96 */
97
98 #ifdef HAL_ADC_MODULE_ENABLED
99
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
102 /* Private macro -------------------------------------------------------------*/
103 /* Private variables ---------------------------------------------------------*/
104 /** @addtogroup ADCEx_Private_Functions
105 * @{
106 */
107 /* Private function prototypes -----------------------------------------------*/
108 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma);
109 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma);
110 static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma);
111 /**
112 * @}
113 */
114
115 /* Exported functions --------------------------------------------------------*/
116 /** @defgroup ADCEx_Exported_Functions ADC Exported Functions
117 * @{
118 */
119
120 /** @defgroup ADCEx_Exported_Functions_Group1 Extended features functions
121 * @brief Extended features functions
122 *
123 @verbatim
124 ===============================================================================
125 ##### Extended features functions #####
126 ===============================================================================
127 [..] This section provides functions allowing to:
128 (+) Start conversion of injected channel.
129 (+) Stop conversion of injected channel.
130 (+) Start multimode and enable DMA transfer.
131 (+) Stop multimode and disable DMA transfer.
132 (+) Get result of injected channel conversion.
133 (+) Get result of multimode conversion.
134 (+) Configure injected channels.
135 (+) Configure multimode.
136
137 @endverbatim
138 * @{
139 */
140
141 /**
142 * @brief Enables the selected ADC software start conversion of the injected channels.
143 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
144 * the configuration information for the specified ADC.
145 * @retval HAL status
146 */
HAL_ADCEx_InjectedStart(ADC_HandleTypeDef * hadc)147 HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc)
148 {
149 __IO uint32_t counter = 0;
150 uint32_t tmp1 = 0, tmp2 = 0;
151
152 /* Process locked */
153 __HAL_LOCK(hadc);
154
155 /* Enable the ADC peripheral */
156
157 /* Check if ADC peripheral is disabled in order to enable it and wait during
158 Tstab time the ADC's stabilization */
159 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
160 {
161 /* Enable the Peripheral */
162 __HAL_ADC_ENABLE(hadc);
163
164 /* Delay for ADC stabilization time */
165 /* Compute number of CPU cycles to wait for */
166 counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
167 while(counter != 0)
168 {
169 counter--;
170 }
171 }
172
173 /* Start conversion if ADC is effectively enabled */
174 if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
175 {
176 /* Set ADC state */
177 /* - Clear state bitfield related to injected group conversion results */
178 /* - Set state bitfield related to injected operation */
179 ADC_STATE_CLR_SET(hadc->State,
180 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
181 HAL_ADC_STATE_INJ_BUSY);
182
183 /* Check if a regular conversion is ongoing */
184 /* Note: On this device, there is no ADC error code fields related to */
185 /* conversions on group injected only. In case of conversion on */
186 /* going on group regular, no error code is reset. */
187 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
188 {
189 /* Reset ADC all error code fields */
190 ADC_CLEAR_ERRORCODE(hadc);
191 }
192
193 /* Process unlocked */
194 /* Unlock before starting ADC conversions: in case of potential */
195 /* interruption, to let the process to ADC IRQ Handler. */
196 __HAL_UNLOCK(hadc);
197
198 /* Clear injected group conversion flag */
199 /* (To ensure of no unknown state from potential previous ADC operations) */
200 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
201
202 /* Check if Multimode enabled */
203 if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
204 {
205 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
206 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
207 if(tmp1 && tmp2)
208 {
209 /* Enable the selected ADC software conversion for injected group */
210 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
211 }
212 }
213 else
214 {
215 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
216 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
217 if((hadc->Instance == ADC1) && tmp1 && tmp2)
218 {
219 /* Enable the selected ADC software conversion for injected group */
220 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
221 }
222 }
223 }
224 else
225 {
226 /* Update ADC state machine to error */
227 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
228
229 /* Set ADC error code to ADC IP internal error */
230 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
231 }
232
233 /* Return function status */
234 return HAL_OK;
235 }
236
237 /**
238 * @brief Enables the interrupt and starts ADC conversion of injected channels.
239 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
240 * the configuration information for the specified ADC.
241 *
242 * @retval HAL status.
243 */
HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef * hadc)244 HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)
245 {
246 __IO uint32_t counter = 0;
247 uint32_t tmp1 = 0, tmp2 = 0;
248
249 /* Process locked */
250 __HAL_LOCK(hadc);
251
252 /* Enable the ADC peripheral */
253
254 /* Check if ADC peripheral is disabled in order to enable it and wait during
255 Tstab time the ADC's stabilization */
256 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
257 {
258 /* Enable the Peripheral */
259 __HAL_ADC_ENABLE(hadc);
260
261 /* Delay for ADC stabilization time */
262 /* Compute number of CPU cycles to wait for */
263 counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
264 while(counter != 0)
265 {
266 counter--;
267 }
268 }
269
270 /* Start conversion if ADC is effectively enabled */
271 if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
272 {
273 /* Set ADC state */
274 /* - Clear state bitfield related to injected group conversion results */
275 /* - Set state bitfield related to injected operation */
276 ADC_STATE_CLR_SET(hadc->State,
277 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
278 HAL_ADC_STATE_INJ_BUSY);
279
280 /* Check if a regular conversion is ongoing */
281 /* Note: On this device, there is no ADC error code fields related to */
282 /* conversions on group injected only. In case of conversion on */
283 /* going on group regular, no error code is reset. */
284 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
285 {
286 /* Reset ADC all error code fields */
287 ADC_CLEAR_ERRORCODE(hadc);
288 }
289
290 /* Process unlocked */
291 /* Unlock before starting ADC conversions: in case of potential */
292 /* interruption, to let the process to ADC IRQ Handler. */
293 __HAL_UNLOCK(hadc);
294
295 /* Clear injected group conversion flag */
296 /* (To ensure of no unknown state from potential previous ADC operations) */
297 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
298
299 /* Enable end of conversion interrupt for injected channels */
300 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
301
302 /* Check if Multimode enabled */
303 if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
304 {
305 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
306 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
307 if(tmp1 && tmp2)
308 {
309 /* Enable the selected ADC software conversion for injected group */
310 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
311 }
312 }
313 else
314 {
315 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
316 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
317 if((hadc->Instance == ADC1) && tmp1 && tmp2)
318 {
319 /* Enable the selected ADC software conversion for injected group */
320 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
321 }
322 }
323 }
324 else
325 {
326 /* Update ADC state machine to error */
327 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
328
329 /* Set ADC error code to ADC IP internal error */
330 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
331 }
332
333 /* Return function status */
334 return HAL_OK;
335 }
336
337 /**
338 * @brief Stop conversion of injected channels. Disable ADC peripheral if
339 * no regular conversion is on going.
340 * @note If ADC must be disabled and if conversion is on going on
341 * regular group, function HAL_ADC_Stop must be used to stop both
342 * injected and regular groups, and disable the ADC.
343 * @note If injected group mode auto-injection is enabled,
344 * function HAL_ADC_Stop must be used.
345 * @note In case of auto-injection mode, HAL_ADC_Stop must be used.
346 * @param hadc ADC handle
347 * @retval None
348 */
HAL_ADCEx_InjectedStop(ADC_HandleTypeDef * hadc)349 HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)
350 {
351 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
352
353 /* Check the parameters */
354 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
355
356 /* Process locked */
357 __HAL_LOCK(hadc);
358
359 /* Stop potential conversion and disable ADC peripheral */
360 /* Conditioned to: */
361 /* - No conversion on the other group (regular group) is intended to */
362 /* continue (injected and regular groups stop conversion and ADC disable */
363 /* are common) */
364 /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
365 if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
366 HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
367 {
368 /* Stop potential conversion on going, on regular and injected groups */
369 /* Disable ADC peripheral */
370 __HAL_ADC_DISABLE(hadc);
371
372 /* Check if ADC is effectively disabled */
373 if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
374 {
375 /* Set ADC state */
376 ADC_STATE_CLR_SET(hadc->State,
377 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
378 HAL_ADC_STATE_READY);
379 }
380 }
381 else
382 {
383 /* Update ADC state machine to error */
384 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
385
386 tmp_hal_status = HAL_ERROR;
387 }
388
389 /* Process unlocked */
390 __HAL_UNLOCK(hadc);
391
392 /* Return function status */
393 return tmp_hal_status;
394 }
395
396 /**
397 * @brief Poll for injected conversion complete
398 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
399 * the configuration information for the specified ADC.
400 * @param Timeout Timeout value in millisecond.
401 * @retval HAL status
402 */
HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef * hadc,uint32_t Timeout)403 HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
404 {
405 uint32_t tickstart = 0;
406
407 /* Get tick */
408 tickstart = HAL_GetTick();
409
410 /* Check End of conversion flag */
411 while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC)))
412 {
413 /* Check for the Timeout */
414 if(Timeout != HAL_MAX_DELAY)
415 {
416 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
417 {
418 /* New check to avoid false timeout detection in case of preemption */
419 if(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC)))
420 {
421 hadc->State= HAL_ADC_STATE_TIMEOUT;
422 /* Process unlocked */
423 __HAL_UNLOCK(hadc);
424 return HAL_TIMEOUT;
425 }
426 }
427 }
428 }
429
430 /* Clear injected group conversion flag */
431 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC);
432
433 /* Update ADC state machine */
434 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
435
436 /* Determine whether any further conversion upcoming on group injected */
437 /* by external trigger, continuous mode or scan sequence on going. */
438 /* Note: On STM32F7, there is no independent flag of end of sequence. */
439 /* The test of scan sequence on going is done either with scan */
440 /* sequence disabled or with end of conversion flag set to */
441 /* of end of sequence. */
442 if(ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
443 (HAL_IS_BIT_CLR(hadc->Instance->JSQR, ADC_JSQR_JL) ||
444 HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) &&
445 (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
446 (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
447 (hadc->Init.ContinuousConvMode == DISABLE) ) ) )
448 {
449 /* Set ADC state */
450 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
451
452 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
453 {
454 SET_BIT(hadc->State, HAL_ADC_STATE_READY);
455 }
456 }
457
458 /* Return ADC state */
459 return HAL_OK;
460 }
461
462 /**
463 * @brief Stop conversion of injected channels, disable interruption of
464 * end-of-conversion. Disable ADC peripheral if no regular conversion
465 * is on going.
466 * @note If ADC must be disabled and if conversion is on going on
467 * regular group, function HAL_ADC_Stop must be used to stop both
468 * injected and regular groups, and disable the ADC.
469 * @note If injected group mode auto-injection is enabled,
470 * function HAL_ADC_Stop must be used.
471 * @param hadc ADC handle
472 * @retval None
473 */
HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef * hadc)474 HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc)
475 {
476 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
477
478 /* Check the parameters */
479 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
480
481 /* Process locked */
482 __HAL_LOCK(hadc);
483
484 /* Stop potential conversion and disable ADC peripheral */
485 /* Conditioned to: */
486 /* - No conversion on the other group (regular group) is intended to */
487 /* continue (injected and regular groups stop conversion and ADC disable */
488 /* are common) */
489 /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
490 if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
491 HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
492 {
493 /* Stop potential conversion on going, on regular and injected groups */
494 /* Disable ADC peripheral */
495 __HAL_ADC_DISABLE(hadc);
496
497 /* Check if ADC is effectively disabled */
498 if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
499 {
500 /* Disable ADC end of conversion interrupt for injected channels */
501 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
502
503 /* Set ADC state */
504 ADC_STATE_CLR_SET(hadc->State,
505 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
506 HAL_ADC_STATE_READY);
507 }
508 }
509 else
510 {
511 /* Update ADC state machine to error */
512 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
513
514 tmp_hal_status = HAL_ERROR;
515 }
516
517 /* Process unlocked */
518 __HAL_UNLOCK(hadc);
519
520 /* Return function status */
521 return tmp_hal_status;
522 }
523
524 /**
525 * @brief Gets the converted value from data register of injected channel.
526 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
527 * the configuration information for the specified ADC.
528 * @param InjectedRank the ADC injected rank.
529 * This parameter can be one of the following values:
530 * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected
531 * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected
532 * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected
533 * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected
534 * @retval None
535 */
HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef * hadc,uint32_t InjectedRank)536 uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank)
537 {
538 __IO uint32_t tmp = 0;
539
540 /* Check the parameters */
541 assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
542
543 /* Clear injected group conversion flag to have similar behaviour as */
544 /* regular group: reading data register also clears end of conversion flag. */
545 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
546
547 /* Return the selected ADC converted value */
548 switch(InjectedRank)
549 {
550 case ADC_INJECTED_RANK_4:
551 {
552 tmp = hadc->Instance->JDR4;
553 }
554 break;
555 case ADC_INJECTED_RANK_3:
556 {
557 tmp = hadc->Instance->JDR3;
558 }
559 break;
560 case ADC_INJECTED_RANK_2:
561 {
562 tmp = hadc->Instance->JDR2;
563 }
564 break;
565 case ADC_INJECTED_RANK_1:
566 {
567 tmp = hadc->Instance->JDR1;
568 }
569 break;
570 default:
571 break;
572 }
573 return tmp;
574 }
575
576 /**
577 * @brief Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral
578 *
579 * @note Caution: This function must be used only with the ADC master.
580 *
581 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
582 * the configuration information for the specified ADC.
583 * @param pData Pointer to buffer in which transferred from ADC peripheral to memory will be stored.
584 * @param Length The length of data to be transferred from ADC peripheral to memory.
585 * @retval HAL status
586 */
HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef * hadc,uint32_t * pData,uint32_t Length)587 HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
588 {
589 __IO uint32_t counter = 0;
590
591 /* Check the parameters */
592 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
593 assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
594 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
595
596 /* Process locked */
597 __HAL_LOCK(hadc);
598
599 /* Check if ADC peripheral is disabled in order to enable it and wait during
600 Tstab time the ADC's stabilization */
601 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
602 {
603 /* Enable the Peripheral */
604 __HAL_ADC_ENABLE(hadc);
605
606 /* Delay for temperature sensor stabilization time */
607 /* Compute number of CPU cycles to wait for */
608 counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000));
609 while(counter != 0)
610 {
611 counter--;
612 }
613 }
614
615 /* Start conversion if ADC is effectively enabled */
616 if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
617 {
618 /* Set ADC state */
619 /* - Clear state bitfield related to regular group conversion results */
620 /* - Set state bitfield related to regular group operation */
621 ADC_STATE_CLR_SET(hadc->State,
622 HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR,
623 HAL_ADC_STATE_REG_BUSY);
624
625 /* If conversions on group regular are also triggering group injected, */
626 /* update ADC state. */
627 if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
628 {
629 ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
630 }
631
632 /* State machine update: Check if an injected conversion is ongoing */
633 if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
634 {
635 /* Reset ADC error code fields related to conversions on group regular */
636 CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
637 }
638 else
639 {
640 /* Reset ADC all error code fields */
641 ADC_CLEAR_ERRORCODE(hadc);
642 }
643
644 /* Process unlocked */
645 /* Unlock before starting ADC conversions: in case of potential */
646 /* interruption, to let the process to ADC IRQ Handler. */
647 __HAL_UNLOCK(hadc);
648
649 /* Set the DMA transfer complete callback */
650 hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt;
651
652 /* Set the DMA half transfer complete callback */
653 hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt;
654
655 /* Set the DMA error callback */
656 hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ;
657
658 /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
659 /* start (in case of SW start): */
660
661 /* Clear regular group conversion flag and overrun flag */
662 /* (To ensure of no unknown state from potential previous ADC operations) */
663 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
664
665 /* Enable ADC overrun interrupt */
666 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
667
668 if (hadc->Init.DMAContinuousRequests != DISABLE)
669 {
670 /* Enable the selected ADC DMA request after last transfer */
671 ADC->CCR |= ADC_CCR_DDS;
672 }
673 else
674 {
675 /* Disable the selected ADC EOC rising on each regular channel conversion */
676 ADC->CCR &= ~ADC_CCR_DDS;
677 }
678
679 /* Enable the DMA Stream */
680 HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length);
681
682 /* if no external trigger present enable software conversion of regular channels */
683 if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
684 {
685 /* Enable the selected ADC software conversion for regular group */
686 hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
687 }
688 }
689 else
690 {
691 /* Update ADC state machine to error */
692 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
693
694 /* Set ADC error code to ADC IP internal error */
695 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
696 }
697
698 /* Return function status */
699 return HAL_OK;
700 }
701
702 /**
703 * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral
704 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
705 * the configuration information for the specified ADC.
706 * @retval HAL status
707 */
HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef * hadc)708 HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc)
709 {
710 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
711
712 /* Check the parameters */
713 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
714
715 /* Process locked */
716 __HAL_LOCK(hadc);
717
718 /* Stop potential conversion on going, on regular and injected groups */
719 /* Disable ADC peripheral */
720 __HAL_ADC_DISABLE(hadc);
721
722 /* Check if ADC is effectively disabled */
723 if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
724 {
725 /* Disable the selected ADC DMA mode for multimode */
726 ADC->CCR &= ~ADC_CCR_DDS;
727
728 /* Disable the DMA channel (in case of DMA in circular mode or stop while */
729 /* DMA transfer is on going) */
730 tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
731
732 /* Disable ADC overrun interrupt */
733 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
734
735 /* Set ADC state */
736 ADC_STATE_CLR_SET(hadc->State,
737 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
738 HAL_ADC_STATE_READY);
739 }
740
741 /* Process unlocked */
742 __HAL_UNLOCK(hadc);
743
744 /* Return function status */
745 return tmp_hal_status;
746 }
747
748 /**
749 * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results
750 * data in the selected multi mode.
751 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
752 * the configuration information for the specified ADC.
753 * @retval The converted data value.
754 */
HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef * hadc)755 uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc)
756 {
757 /* Prevent unused argument(s) compilation warning */
758 UNUSED(hadc);
759
760 /* Return the multi mode conversion value */
761 return ADC->CDR;
762 }
763
764 /**
765 * @brief Injected conversion complete callback in non blocking mode
766 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
767 * the configuration information for the specified ADC.
768 * @retval None
769 */
HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef * hadc)770 __weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
771 {
772 /* Prevent unused argument(s) compilation warning */
773 UNUSED(hadc);
774 /* NOTE : This function Should not be modified, when the callback is needed,
775 the HAL_ADC_InjectedConvCpltCallback could be implemented in the user file
776 */
777 }
778
779 /**
780 * @brief Configures for the selected ADC injected channel its corresponding
781 * rank in the sequencer and its sample time.
782 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
783 * the configuration information for the specified ADC.
784 * @param sConfigInjected ADC configuration structure for injected channel.
785 * @retval None
786 */
HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef * hadc,ADC_InjectionConfTypeDef * sConfigInjected)787 HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected)
788 {
789
790 #ifdef USE_FULL_ASSERT
791 uint32_t tmp = 0;
792 #endif /* USE_FULL_ASSERT */
793
794 /* Check the parameters */
795 assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel));
796 assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
797 assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
798 assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv));
799 assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion));
800 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
801 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
802
803 #ifdef USE_FULL_ASSERT
804 tmp = ADC_GET_RESOLUTION(hadc);
805 assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset));
806 #endif /* USE_FULL_ASSERT */
807
808 if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
809 {
810 assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
811 }
812
813 /* Process locked */
814 __HAL_LOCK(hadc);
815
816 /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
817 if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9)
818 {
819 /* Clear the old sample time */
820 hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel);
821
822 /* Set the new sample time */
823 hadc->Instance->SMPR1 |= ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel);
824 }
825 else /* ADC_Channel include in ADC_Channel_[0..9] */
826 {
827 /* Clear the old sample time */
828 hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel);
829
830 /* Set the new sample time */
831 hadc->Instance->SMPR2 |= ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel);
832 }
833
834 /*---------------------------- ADCx JSQR Configuration -----------------*/
835 hadc->Instance->JSQR &= ~(ADC_JSQR_JL);
836 hadc->Instance->JSQR |= ADC_SQR1(sConfigInjected->InjectedNbrOfConversion);
837
838 /* Rank configuration */
839
840 /* Clear the old SQx bits for the selected rank */
841 hadc->Instance->JSQR &= ~ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);
842
843 /* Set the SQx bits for the selected rank */
844 hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);
845
846 /* Enable external trigger if trigger selection is different of software */
847 /* start. */
848 /* Note: This configuration keeps the hardware feature of parameter */
849 /* ExternalTrigConvEdge "trigger edge none" equivalent to */
850 /* software start. */
851 if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
852 {
853 /* Select external trigger to start conversion */
854 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
855 hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConv;
856
857 /* Select external trigger polarity */
858 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);
859 hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge;
860 }
861 else
862 {
863 /* Reset the external trigger */
864 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
865 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);
866 }
867
868 if (sConfigInjected->AutoInjectedConv != DISABLE)
869 {
870 /* Enable the selected ADC automatic injected group conversion */
871 hadc->Instance->CR1 |= ADC_CR1_JAUTO;
872 }
873 else
874 {
875 /* Disable the selected ADC automatic injected group conversion */
876 hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO);
877 }
878
879 if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE)
880 {
881 /* Enable the selected ADC injected discontinuous mode */
882 hadc->Instance->CR1 |= ADC_CR1_JDISCEN;
883 }
884 else
885 {
886 /* Disable the selected ADC injected discontinuous mode */
887 hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN);
888 }
889
890 switch(sConfigInjected->InjectedRank)
891 {
892 case 1:
893 /* Set injected channel 1 offset */
894 hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1);
895 hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset;
896 break;
897 case 2:
898 /* Set injected channel 2 offset */
899 hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2);
900 hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset;
901 break;
902 case 3:
903 /* Set injected channel 3 offset */
904 hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3);
905 hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset;
906 break;
907 default:
908 /* Set injected channel 4 offset */
909 hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4);
910 hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset;
911 break;
912 }
913
914 /* if ADC1 Channel_18 is selected enable VBAT Channel */
915 if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT))
916 {
917 /* Enable the VBAT channel*/
918 ADC->CCR |= ADC_CCR_VBATE;
919 }
920
921 /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */
922 if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT)))
923 {
924 /* Enable the TSVREFE channel*/
925 ADC->CCR |= ADC_CCR_TSVREFE;
926 }
927
928 /* Process unlocked */
929 __HAL_UNLOCK(hadc);
930
931 /* Return function status */
932 return HAL_OK;
933 }
934
935 /**
936 * @brief Configures the ADC multi-mode
937 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
938 * the configuration information for the specified ADC.
939 * @param multimode pointer to an ADC_MultiModeTypeDef structure that contains
940 * the configuration information for multimode.
941 * @retval HAL status
942 */
HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef * hadc,ADC_MultiModeTypeDef * multimode)943 HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)
944 {
945 /* Check the parameters */
946 assert_param(IS_ADC_MODE(multimode->Mode));
947 assert_param(IS_ADC_DMA_ACCESS_MODE(multimode->DMAAccessMode));
948 assert_param(IS_ADC_SAMPLING_DELAY(multimode->TwoSamplingDelay));
949
950 /* Process locked */
951 __HAL_LOCK(hadc);
952
953 /* Set ADC mode */
954 ADC->CCR &= ~(ADC_CCR_MULTI);
955 ADC->CCR |= multimode->Mode;
956
957 /* Set the ADC DMA access mode */
958 ADC->CCR &= ~(ADC_CCR_DMA);
959 ADC->CCR |= multimode->DMAAccessMode;
960
961 /* Set delay between two sampling phases */
962 ADC->CCR &= ~(ADC_CCR_DELAY);
963 ADC->CCR |= multimode->TwoSamplingDelay;
964
965 /* Process unlocked */
966 __HAL_UNLOCK(hadc);
967
968 /* Return function status */
969 return HAL_OK;
970 }
971
972 /**
973 * @}
974 */
975
976 /**
977 * @brief DMA transfer complete callback.
978 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
979 * the configuration information for the specified DMA module.
980 * @retval None
981 */
ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef * hdma)982 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma)
983 {
984 /* Retrieve ADC handle corresponding to current DMA handle */
985 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
986
987 /* Update state machine on conversion status if not in error state */
988 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA))
989 {
990 /* Update ADC state machine */
991 SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
992
993 /* Determine whether any further conversion upcoming on group regular */
994 /* by external trigger, continuous mode or scan sequence on going. */
995 /* Note: On STM32F7, there is no independent flag of end of sequence. */
996 /* The test of scan sequence on going is done either with scan */
997 /* sequence disabled or with end of conversion flag set to */
998 /* of end of sequence. */
999 if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
1000 (hadc->Init.ContinuousConvMode == DISABLE) &&
1001 (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) ||
1002 HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) )
1003 {
1004 /* Disable ADC end of single conversion interrupt on group regular */
1005 /* Note: Overrun interrupt was enabled with EOC interrupt in */
1006 /* HAL_ADC_Start_IT(), but is not disabled here because can be used */
1007 /* by overrun IRQ process below. */
1008 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
1009
1010 /* Set ADC state */
1011 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1012
1013 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
1014 {
1015 SET_BIT(hadc->State, HAL_ADC_STATE_READY);
1016 }
1017 }
1018
1019 /* Conversion complete callback */
1020 HAL_ADC_ConvCpltCallback(hadc);
1021 }
1022 else
1023 {
1024 /* Call DMA error callback */
1025 hadc->DMA_Handle->XferErrorCallback(hdma);
1026 }
1027 }
1028
1029 /**
1030 * @brief DMA half transfer complete callback.
1031 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1032 * the configuration information for the specified DMA module.
1033 * @retval None
1034 */
ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef * hdma)1035 static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma)
1036 {
1037 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1038 /* Conversion complete callback */
1039 HAL_ADC_ConvHalfCpltCallback(hadc);
1040 }
1041
1042 /**
1043 * @brief DMA error callback
1044 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1045 * the configuration information for the specified DMA module.
1046 * @retval None
1047 */
ADC_MultiModeDMAError(DMA_HandleTypeDef * hdma)1048 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma)
1049 {
1050 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1051 hadc->State= HAL_ADC_STATE_ERROR_DMA;
1052 /* Set ADC error code to DMA error */
1053 hadc->ErrorCode |= HAL_ADC_ERROR_DMA;
1054 HAL_ADC_ErrorCallback(hadc);
1055 }
1056
1057 /**
1058 * @}
1059 */
1060
1061 #endif /* HAL_ADC_MODULE_ENABLED */
1062 /**
1063 * @}
1064 */
1065
1066 /**
1067 * @}
1068 */
1069
1070