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 /* Return the multi mode conversion value */
758 return ADC->CDR;
759 }
760
761 /**
762 * @brief Injected conversion complete callback in non blocking mode
763 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
764 * the configuration information for the specified ADC.
765 * @retval None
766 */
HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef * hadc)767 __weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
768 {
769 /* Prevent unused argument(s) compilation warning */
770 UNUSED(hadc);
771 /* NOTE : This function Should not be modified, when the callback is needed,
772 the HAL_ADC_InjectedConvCpltCallback could be implemented in the user file
773 */
774 }
775
776 /**
777 * @brief Configures for the selected ADC injected channel its corresponding
778 * rank in the sequencer and its sample time.
779 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
780 * the configuration information for the specified ADC.
781 * @param sConfigInjected ADC configuration structure for injected channel.
782 * @retval None
783 */
HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef * hadc,ADC_InjectionConfTypeDef * sConfigInjected)784 HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected)
785 {
786
787 #ifdef USE_FULL_ASSERT
788 uint32_t tmp = 0;
789 #endif /* USE_FULL_ASSERT */
790
791 /* Check the parameters */
792 assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel));
793 assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));
794 assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));
795 assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv));
796 assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion));
797 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));
798 assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));
799
800 #ifdef USE_FULL_ASSERT
801 tmp = ADC_GET_RESOLUTION(hadc);
802 assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset));
803 #endif /* USE_FULL_ASSERT */
804
805 if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
806 {
807 assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));
808 }
809
810 /* Process locked */
811 __HAL_LOCK(hadc);
812
813 /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
814 if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9)
815 {
816 /* Clear the old sample time */
817 hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel);
818
819 /* Set the new sample time */
820 hadc->Instance->SMPR1 |= ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel);
821 }
822 else /* ADC_Channel include in ADC_Channel_[0..9] */
823 {
824 /* Clear the old sample time */
825 hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel);
826
827 /* Set the new sample time */
828 hadc->Instance->SMPR2 |= ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel);
829 }
830
831 /*---------------------------- ADCx JSQR Configuration -----------------*/
832 hadc->Instance->JSQR &= ~(ADC_JSQR_JL);
833 hadc->Instance->JSQR |= ADC_SQR1(sConfigInjected->InjectedNbrOfConversion);
834
835 /* Rank configuration */
836
837 /* Clear the old SQx bits for the selected rank */
838 hadc->Instance->JSQR &= ~ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);
839
840 /* Set the SQx bits for the selected rank */
841 hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);
842
843 /* Enable external trigger if trigger selection is different of software */
844 /* start. */
845 /* Note: This configuration keeps the hardware feature of parameter */
846 /* ExternalTrigConvEdge "trigger edge none" equivalent to */
847 /* software start. */
848 if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START)
849 {
850 /* Select external trigger to start conversion */
851 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
852 hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConv;
853
854 /* Select external trigger polarity */
855 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);
856 hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge;
857 }
858 else
859 {
860 /* Reset the external trigger */
861 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);
862 hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);
863 }
864
865 if (sConfigInjected->AutoInjectedConv != DISABLE)
866 {
867 /* Enable the selected ADC automatic injected group conversion */
868 hadc->Instance->CR1 |= ADC_CR1_JAUTO;
869 }
870 else
871 {
872 /* Disable the selected ADC automatic injected group conversion */
873 hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO);
874 }
875
876 if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE)
877 {
878 /* Enable the selected ADC injected discontinuous mode */
879 hadc->Instance->CR1 |= ADC_CR1_JDISCEN;
880 }
881 else
882 {
883 /* Disable the selected ADC injected discontinuous mode */
884 hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN);
885 }
886
887 switch(sConfigInjected->InjectedRank)
888 {
889 case 1:
890 /* Set injected channel 1 offset */
891 hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1);
892 hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset;
893 break;
894 case 2:
895 /* Set injected channel 2 offset */
896 hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2);
897 hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset;
898 break;
899 case 3:
900 /* Set injected channel 3 offset */
901 hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3);
902 hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset;
903 break;
904 default:
905 /* Set injected channel 4 offset */
906 hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4);
907 hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset;
908 break;
909 }
910
911 /* if ADC1 Channel_18 is selected enable VBAT Channel */
912 if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT))
913 {
914 /* Enable the VBAT channel*/
915 ADC->CCR |= ADC_CCR_VBATE;
916 }
917
918 /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */
919 if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT)))
920 {
921 /* Enable the TSVREFE channel*/
922 ADC->CCR |= ADC_CCR_TSVREFE;
923 }
924
925 /* Process unlocked */
926 __HAL_UNLOCK(hadc);
927
928 /* Return function status */
929 return HAL_OK;
930 }
931
932 /**
933 * @brief Configures the ADC multi-mode
934 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
935 * the configuration information for the specified ADC.
936 * @param multimode pointer to an ADC_MultiModeTypeDef structure that contains
937 * the configuration information for multimode.
938 * @retval HAL status
939 */
HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef * hadc,ADC_MultiModeTypeDef * multimode)940 HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)
941 {
942 /* Check the parameters */
943 assert_param(IS_ADC_MODE(multimode->Mode));
944 assert_param(IS_ADC_DMA_ACCESS_MODE(multimode->DMAAccessMode));
945 assert_param(IS_ADC_SAMPLING_DELAY(multimode->TwoSamplingDelay));
946
947 /* Process locked */
948 __HAL_LOCK(hadc);
949
950 /* Set ADC mode */
951 ADC->CCR &= ~(ADC_CCR_MULTI);
952 ADC->CCR |= multimode->Mode;
953
954 /* Set the ADC DMA access mode */
955 ADC->CCR &= ~(ADC_CCR_DMA);
956 ADC->CCR |= multimode->DMAAccessMode;
957
958 /* Set delay between two sampling phases */
959 ADC->CCR &= ~(ADC_CCR_DELAY);
960 ADC->CCR |= multimode->TwoSamplingDelay;
961
962 /* Process unlocked */
963 __HAL_UNLOCK(hadc);
964
965 /* Return function status */
966 return HAL_OK;
967 }
968
969 /**
970 * @}
971 */
972
973 /**
974 * @brief DMA transfer complete callback.
975 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
976 * the configuration information for the specified DMA module.
977 * @retval None
978 */
ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef * hdma)979 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma)
980 {
981 /* Retrieve ADC handle corresponding to current DMA handle */
982 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
983
984 /* Update state machine on conversion status if not in error state */
985 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA))
986 {
987 /* Update ADC state machine */
988 SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
989
990 /* Determine whether any further conversion upcoming on group regular */
991 /* by external trigger, continuous mode or scan sequence on going. */
992 /* Note: On STM32F7, there is no independent flag of end of sequence. */
993 /* The test of scan sequence on going is done either with scan */
994 /* sequence disabled or with end of conversion flag set to */
995 /* of end of sequence. */
996 if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
997 (hadc->Init.ContinuousConvMode == DISABLE) &&
998 (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) ||
999 HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) )
1000 {
1001 /* Disable ADC end of single conversion interrupt on group regular */
1002 /* Note: Overrun interrupt was enabled with EOC interrupt in */
1003 /* HAL_ADC_Start_IT(), but is not disabled here because can be used */
1004 /* by overrun IRQ process below. */
1005 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
1006
1007 /* Set ADC state */
1008 CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY);
1009
1010 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY))
1011 {
1012 SET_BIT(hadc->State, HAL_ADC_STATE_READY);
1013 }
1014 }
1015
1016 /* Conversion complete callback */
1017 HAL_ADC_ConvCpltCallback(hadc);
1018 }
1019 else
1020 {
1021 /* Call DMA error callback */
1022 hadc->DMA_Handle->XferErrorCallback(hdma);
1023 }
1024 }
1025
1026 /**
1027 * @brief DMA half transfer complete callback.
1028 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1029 * the configuration information for the specified DMA module.
1030 * @retval None
1031 */
ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef * hdma)1032 static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma)
1033 {
1034 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1035 /* Conversion complete callback */
1036 HAL_ADC_ConvHalfCpltCallback(hadc);
1037 }
1038
1039 /**
1040 * @brief DMA error callback
1041 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1042 * the configuration information for the specified DMA module.
1043 * @retval None
1044 */
ADC_MultiModeDMAError(DMA_HandleTypeDef * hdma)1045 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma)
1046 {
1047 ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1048 hadc->State= HAL_ADC_STATE_ERROR_DMA;
1049 /* Set ADC error code to DMA error */
1050 hadc->ErrorCode |= HAL_ADC_ERROR_DMA;
1051 HAL_ADC_ErrorCallback(hadc);
1052 }
1053
1054 /**
1055 * @}
1056 */
1057
1058 #endif /* HAL_ADC_MODULE_ENABLED */
1059 /**
1060 * @}
1061 */
1062
1063 /**
1064 * @}
1065 */
1066
1067