1 /**
2 ******************************************************************************
3 * @file stm32f2xx_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 @verbatim
10 ==============================================================================
11 ##### How to use this driver #####
12 ==============================================================================
13 [..]
14 (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():
15 (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE()
16 (##) ADC pins configuration
17 (+++) Enable the clock for the ADC GPIOs using the following function:
18 __HAL_RCC_GPIOx_CLK_ENABLE()
19 (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init()
20 (##) In case of using interrupts (e.g. HAL_ADC_Start_IT())
21 (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority()
22 (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()
23 (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler()
24 (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())
25 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE()
26 (+++) Configure and enable two DMA streams stream for managing data
27 transfer from peripheral to memory (output stream)
28 (+++) Associate the initialized DMA handle to the ADC DMA handle
29 using __HAL_LINKDMA()
30 (+++) Configure the priority and enable the NVIC for the transfer complete
31 interrupt on the two DMA Streams. The output stream should have higher
32 priority than the input stream.
33 (#) Configure the ADC Prescaler, conversion resolution and data alignment
34 using the HAL_ADC_Init() function.
35
36 (#) Configure the ADC Injected channels group features, use HAL_ADC_Init()
37 and HAL_ADC_ConfigChannel() functions.
38
39 (#) Three operation modes are available within this driver:
40
41 *** Polling mode IO operation ***
42 =================================
43 [..]
44 (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart()
45 (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage
46 user can specify the value of timeout according to his end application
47 (+) To read the ADC converted values, use the HAL_ADCEx_InjectedGetValue() function.
48 (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop()
49
50 *** Interrupt mode IO operation ***
51 ===================================
52 [..]
53 (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_IT()
54 (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine
55 (+) At ADC end of conversion HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can
56 add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback
57 (+) In case of ADC Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can
58 add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback
59 (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_IT()
60
61
62 *** Multi mode ADCs Regular channels configuration ***
63 ======================================================
64 [..]
65 (+) Select the Multi mode ADC regular channels features (dual or triple mode)
66 and configure the DMA mode using HAL_ADCEx_MultiModeConfigChannel() functions.
67 (+) Start the ADC peripheral using HAL_ADCEx_MultiModeStart_DMA(), at this stage the user specify the length
68 of data to be transferred at each end of conversion
69 (+) Read the ADCs converted values using the HAL_ADCEx_MultiModeGetValue() function.
70
71
72 @endverbatim
73 ******************************************************************************
74 * @attention
75 *
76 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
77 * All rights reserved.</center></h2>
78 *
79 * This software component is licensed by ST under BSD 3-Clause license,
80 * the "License"; You may not use this file except in compliance with the
81 * License. You may obtain a copy of the License at:
82 * opensource.org/licenses/BSD-3-Clause
83 *
84 ******************************************************************************
85 */
86
87 /* Includes ------------------------------------------------------------------*/
88 #include "stm32f2xx_hal.h"
89
90 /** @addtogroup STM32F2xx_HAL_Driver
91 * @{
92 */
93
94 /** @defgroup ADCEx ADCEx
95 * @brief ADC Extended driver modules
96 * @{
97 */
98
99 #ifdef HAL_ADC_MODULE_ENABLED
100
101 /* Private typedef -----------------------------------------------------------*/
102 /* Private define ------------------------------------------------------------*/
103 /* Private macro -------------------------------------------------------------*/
104 /* Private variables ---------------------------------------------------------*/
105 /** @addtogroup ADCEx_Private_Functions
106 * @{
107 */
108 /* Private function prototypes -----------------------------------------------*/
109 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma);
110 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma);
111 static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma);
112 /**
113 * @}
114 */
115
116 /* Exported functions --------------------------------------------------------*/
117 /** @defgroup ADCEx_Exported_Functions ADC Exported Functions
118 * @{
119 */
120
121 /** @defgroup ADCEx_Exported_Functions_Group1 Extended features functions
122 * @brief Extended features functions
123 *
124 @verbatim
125 ===============================================================================
126 ##### Extended features functions #####
127 ===============================================================================
128 [..] This section provides functions allowing to:
129 (+) Start conversion of injected channel.
130 (+) Stop conversion of injected channel.
131 (+) Start multimode and enable DMA transfer.
132 (+) Stop multimode and disable DMA transfer.
133 (+) Get result of injected channel conversion.
134 (+) Get result of multimode conversion.
135 (+) Configure injected channels.
136 (+) Configure multimode.
137
138 @endverbatim
139 * @{
140 */
141
142 /**
143 * @brief Enables the selected ADC software start conversion of the injected channels.
144 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
145 * the configuration information for the specified ADC.
146 * @retval HAL status
147 */
HAL_ADCEx_InjectedStart(ADC_HandleTypeDef * hadc)148 HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc)
149 {
150 __IO uint32_t counter = 0U;
151 uint32_t tmp1 = 0U, tmp2 = 0U;
152
153 /* Process locked */
154 __HAL_LOCK(hadc);
155
156 /* Enable the ADC peripheral */
157
158 /* Check if ADC peripheral is disabled in order to enable it and wait during
159 Tstab time the ADC's stabilization */
160 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
161 {
162 /* Enable the Peripheral */
163 __HAL_ADC_ENABLE(hadc);
164
165 /* Delay for ADC stabilization time */
166 /* Compute number of CPU cycles to wait for */
167 counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
168 while(counter != 0U)
169 {
170 counter--;
171 }
172 }
173
174 /* Start conversion if ADC is effectively enabled */
175 if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
176 {
177 /* Set ADC state */
178 /* - Clear state bitfield related to injected group conversion results */
179 /* - Set state bitfield related to injected operation */
180 ADC_STATE_CLR_SET(hadc->State,
181 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
182 HAL_ADC_STATE_INJ_BUSY);
183
184 /* Check if a regular conversion is ongoing */
185 /* Note: On this device, there is no ADC error code fields related to */
186 /* conversions on group injected only. In case of conversion on */
187 /* going on group regular, no error code is reset. */
188 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
189 {
190 /* Reset ADC all error code fields */
191 ADC_CLEAR_ERRORCODE(hadc);
192 }
193
194 /* Process unlocked */
195 /* Unlock before starting ADC conversions: in case of potential */
196 /* interruption, to let the process to ADC IRQ Handler. */
197 __HAL_UNLOCK(hadc);
198
199 /* Clear injected group conversion flag */
200 /* (To ensure of no unknown state from potential previous ADC operations) */
201 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
202
203 /* Check if Multimode enabled */
204 if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
205 {
206 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
207 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
208 if(tmp1 && tmp2)
209 {
210 /* Enable the selected ADC software conversion for injected group */
211 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
212 }
213 }
214 else
215 {
216 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
217 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
218 if((hadc->Instance == ADC1) && tmp1 && tmp2)
219 {
220 /* Enable the selected ADC software conversion for injected group */
221 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
222 }
223 }
224 }
225 else
226 {
227 /* Update ADC state machine to error */
228 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
229
230 /* Set ADC error code to ADC IP internal error */
231 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
232 }
233
234 /* Return function status */
235 return HAL_OK;
236 }
237
238 /**
239 * @brief Enables the interrupt and starts ADC conversion of injected channels.
240 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
241 * the configuration information for the specified ADC.
242 *
243 * @retval HAL status.
244 */
HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef * hadc)245 HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)
246 {
247 __IO uint32_t counter = 0U;
248 uint32_t tmp1 = 0U, tmp2 = 0U;
249
250 /* Process locked */
251 __HAL_LOCK(hadc);
252
253 /* Enable the ADC peripheral */
254
255 /* Check if ADC peripheral is disabled in order to enable it and wait during
256 Tstab time the ADC's stabilization */
257 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
258 {
259 /* Enable the Peripheral */
260 __HAL_ADC_ENABLE(hadc);
261
262 /* Delay for ADC stabilization time */
263 /* Compute number of CPU cycles to wait for */
264 counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
265 while(counter != 0U)
266 {
267 counter--;
268 }
269 }
270
271 /* Start conversion if ADC is effectively enabled */
272 if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
273 {
274 /* Set ADC state */
275 /* - Clear state bitfield related to injected group conversion results */
276 /* - Set state bitfield related to injected operation */
277 ADC_STATE_CLR_SET(hadc->State,
278 HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC,
279 HAL_ADC_STATE_INJ_BUSY);
280
281 /* Check if a regular conversion is ongoing */
282 /* Note: On this device, there is no ADC error code fields related to */
283 /* conversions on group injected only. In case of conversion on */
284 /* going on group regular, no error code is reset. */
285 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
286 {
287 /* Reset ADC all error code fields */
288 ADC_CLEAR_ERRORCODE(hadc);
289 }
290
291 /* Process unlocked */
292 /* Unlock before starting ADC conversions: in case of potential */
293 /* interruption, to let the process to ADC IRQ Handler. */
294 __HAL_UNLOCK(hadc);
295
296 /* Clear injected group conversion flag */
297 /* (To ensure of no unknown state from potential previous ADC operations) */
298 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
299
300 /* Enable end of conversion interrupt for injected channels */
301 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);
302
303 /* Check if Multimode enabled */
304 if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))
305 {
306 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
307 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
308 if(tmp1 && tmp2)
309 {
310 /* Enable the selected ADC software conversion for injected group */
311 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
312 }
313 }
314 else
315 {
316 tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);
317 tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);
318 if((hadc->Instance == ADC1) && tmp1 && tmp2)
319 {
320 /* Enable the selected ADC software conversion for injected group */
321 hadc->Instance->CR2 |= ADC_CR2_JSWSTART;
322 }
323 }
324 }
325 else
326 {
327 /* Update ADC state machine to error */
328 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
329
330 /* Set ADC error code to ADC IP internal error */
331 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
332 }
333
334 /* Return function status */
335 return HAL_OK;
336 }
337
338 /**
339 * @brief Stop conversion of injected channels. Disable ADC peripheral if
340 * no regular conversion is on going.
341 * @note If ADC must be disabled and if conversion is on going on
342 * regular group, function HAL_ADC_Stop must be used to stop both
343 * injected and regular groups, and disable the ADC.
344 * @note If injected group mode auto-injection is enabled,
345 * function HAL_ADC_Stop must be used.
346 * @note In case of auto-injection mode, HAL_ADC_Stop must be used.
347 * @param hadc ADC handle
348 * @retval None
349 */
HAL_ADCEx_InjectedStop(ADC_HandleTypeDef * hadc)350 HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)
351 {
352 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
353
354 /* Check the parameters */
355 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
356
357 /* Process locked */
358 __HAL_LOCK(hadc);
359
360 /* Stop potential conversion and disable ADC peripheral */
361 /* Conditioned to: */
362 /* - No conversion on the other group (regular group) is intended to */
363 /* continue (injected and regular groups stop conversion and ADC disable */
364 /* are common) */
365 /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
366 if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
367 HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
368 {
369 /* Stop potential conversion on going, on regular and injected groups */
370 /* Disable ADC peripheral */
371 __HAL_ADC_DISABLE(hadc);
372
373 /* Check if ADC is effectively disabled */
374 if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
375 {
376 /* Set ADC state */
377 ADC_STATE_CLR_SET(hadc->State,
378 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
379 HAL_ADC_STATE_READY);
380 }
381 }
382 else
383 {
384 /* Update ADC state machine to error */
385 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
386
387 tmp_hal_status = HAL_ERROR;
388 }
389
390 /* Process unlocked */
391 __HAL_UNLOCK(hadc);
392
393 /* Return function status */
394 return tmp_hal_status;
395 }
396
397 /**
398 * @brief Poll for injected conversion complete
399 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
400 * the configuration information for the specified ADC.
401 * @param Timeout Timeout value in millisecond.
402 * @retval HAL status
403 */
HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef * hadc,uint32_t Timeout)404 HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
405 {
406 uint32_t tickstart = 0U;
407
408 /* Get tick */
409 tickstart = HAL_GetTick();
410
411 /* Check End of conversion flag */
412 while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC)))
413 {
414 /* Check for the Timeout */
415 if(Timeout != HAL_MAX_DELAY)
416 {
417 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
418 {
419 /* New check to avoid false timeout detection in case of preemption */
420 if(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC)))
421 {
422 hadc->State= HAL_ADC_STATE_TIMEOUT;
423 /* Process unlocked */
424 __HAL_UNLOCK(hadc);
425 return HAL_TIMEOUT;
426 }
427 }
428 }
429 }
430
431 /* Clear injected group conversion flag */
432 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC);
433
434 /* Update ADC state machine */
435 SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC);
436
437 /* Determine whether any further conversion upcoming on group injected */
438 /* by external trigger, continuous mode or scan sequence on going. */
439 /* Note: On STM32F2, there is no independent flag of end of sequence. */
440 /* The test of scan sequence on going is done either with scan */
441 /* sequence disabled or with end of conversion flag set to */
442 /* of end of sequence. */
443 if(ADC_IS_SOFTWARE_START_INJECTED(hadc) &&
444 (HAL_IS_BIT_CLR(hadc->Instance->JSQR, ADC_JSQR_JL) ||
445 HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) &&
446 (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) &&
447 (ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
448 (hadc->Init.ContinuousConvMode == DISABLE) ) ) )
449 {
450 /* Set ADC state */
451 CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY);
452
453 if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY))
454 {
455 SET_BIT(hadc->State, HAL_ADC_STATE_READY);
456 }
457 }
458
459 /* Return ADC state */
460 return HAL_OK;
461 }
462
463 /**
464 * @brief Stop conversion of injected channels, disable interruption of
465 * end-of-conversion. Disable ADC peripheral if no regular conversion
466 * is on going.
467 * @note If ADC must be disabled and if conversion is on going on
468 * regular group, function HAL_ADC_Stop must be used to stop both
469 * injected and regular groups, and disable the ADC.
470 * @note If injected group mode auto-injection is enabled,
471 * function HAL_ADC_Stop must be used.
472 * @param hadc ADC handle
473 * @retval None
474 */
HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef * hadc)475 HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc)
476 {
477 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
478
479 /* Check the parameters */
480 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
481
482 /* Process locked */
483 __HAL_LOCK(hadc);
484
485 /* Stop potential conversion and disable ADC peripheral */
486 /* Conditioned to: */
487 /* - No conversion on the other group (regular group) is intended to */
488 /* continue (injected and regular groups stop conversion and ADC disable */
489 /* are common) */
490 /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */
491 if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) &&
492 HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) )
493 {
494 /* Stop potential conversion on going, on regular and injected groups */
495 /* Disable ADC peripheral */
496 __HAL_ADC_DISABLE(hadc);
497
498 /* Check if ADC is effectively disabled */
499 if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
500 {
501 /* Disable ADC end of conversion interrupt for injected channels */
502 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC);
503
504 /* Set ADC state */
505 ADC_STATE_CLR_SET(hadc->State,
506 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
507 HAL_ADC_STATE_READY);
508 }
509 }
510 else
511 {
512 /* Update ADC state machine to error */
513 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
514
515 tmp_hal_status = HAL_ERROR;
516 }
517
518 /* Process unlocked */
519 __HAL_UNLOCK(hadc);
520
521 /* Return function status */
522 return tmp_hal_status;
523 }
524
525 /**
526 * @brief Gets the converted value from data register of injected channel.
527 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
528 * the configuration information for the specified ADC.
529 * @param InjectedRank the ADC injected rank.
530 * This parameter can be one of the following values:
531 * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected
532 * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected
533 * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected
534 * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected
535 * @retval None
536 */
HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef * hadc,uint32_t InjectedRank)537 uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank)
538 {
539 __IO uint32_t tmp = 0U;
540
541 /* Check the parameters */
542 assert_param(IS_ADC_INJECTED_RANK(InjectedRank));
543
544 /* Clear injected group conversion flag to have similar behaviour as */
545 /* regular group: reading data register also clears end of conversion flag. */
546 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC);
547
548 /* Return the selected ADC converted value */
549 switch(InjectedRank)
550 {
551 case ADC_INJECTED_RANK_4:
552 {
553 tmp = hadc->Instance->JDR4;
554 }
555 break;
556 case ADC_INJECTED_RANK_3:
557 {
558 tmp = hadc->Instance->JDR3;
559 }
560 break;
561 case ADC_INJECTED_RANK_2:
562 {
563 tmp = hadc->Instance->JDR2;
564 }
565 break;
566 case ADC_INJECTED_RANK_1:
567 {
568 tmp = hadc->Instance->JDR1;
569 }
570 break;
571 default:
572 break;
573 }
574 return tmp;
575 }
576
577 /**
578 * @brief Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral
579 *
580 * @note Caution: This function must be used only with the ADC master.
581 *
582 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
583 * the configuration information for the specified ADC.
584 * @param pData Pointer to buffer in which transferred from ADC peripheral to memory will be stored.
585 * @param Length The length of data to be transferred from ADC peripheral to memory.
586 * @retval HAL status
587 */
HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef * hadc,uint32_t * pData,uint32_t Length)588 HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
589 {
590 __IO uint32_t counter = 0U;
591
592 /* Check the parameters */
593 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
594 assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
595 assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
596
597 /* Process locked */
598 __HAL_LOCK(hadc);
599
600 /* Check if ADC peripheral is disabled in order to enable it and wait during
601 Tstab time the ADC's stabilization */
602 if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)
603 {
604 /* Enable the Peripheral */
605 __HAL_ADC_ENABLE(hadc);
606
607 /* Delay for temperature sensor stabilization time */
608 /* Compute number of CPU cycles to wait for */
609 counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
610 while(counter != 0U)
611 {
612 counter--;
613 }
614 }
615
616 /* Start conversion if ADC is effectively enabled */
617 if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON))
618 {
619 /* Set ADC state */
620 /* - Clear state bitfield related to regular group conversion results */
621 /* - Set state bitfield related to regular group operation */
622 ADC_STATE_CLR_SET(hadc->State,
623 HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR,
624 HAL_ADC_STATE_REG_BUSY);
625
626 /* If conversions on group regular are also triggering group injected, */
627 /* update ADC state. */
628 if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET)
629 {
630 ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY);
631 }
632
633 /* State machine update: Check if an injected conversion is ongoing */
634 if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY))
635 {
636 /* Reset ADC error code fields related to conversions on group regular */
637 CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA));
638 }
639 else
640 {
641 /* Reset ADC all error code fields */
642 ADC_CLEAR_ERRORCODE(hadc);
643 }
644
645 /* Process unlocked */
646 /* Unlock before starting ADC conversions: in case of potential */
647 /* interruption, to let the process to ADC IRQ Handler. */
648 __HAL_UNLOCK(hadc);
649
650 /* Set the DMA transfer complete callback */
651 hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt;
652
653 /* Set the DMA half transfer complete callback */
654 hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt;
655
656 /* Set the DMA error callback */
657 hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ;
658
659 /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
660 /* start (in case of SW start): */
661
662 /* Clear regular group conversion flag and overrun flag */
663 /* (To ensure of no unknown state from potential previous ADC operations) */
664 __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC);
665
666 /* Enable ADC overrun interrupt */
667 __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
668
669 if (hadc->Init.DMAContinuousRequests != DISABLE)
670 {
671 /* Enable the selected ADC DMA request after last transfer */
672 ADC->CCR |= ADC_CCR_DDS;
673 }
674 else
675 {
676 /* Disable the selected ADC EOC rising on each regular channel conversion */
677 ADC->CCR &= ~ADC_CCR_DDS;
678 }
679
680 /* Enable the DMA Stream */
681 HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length);
682
683 /* if no external trigger present enable software conversion of regular channels */
684 if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)
685 {
686 /* Enable the selected ADC software conversion for regular group */
687 hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
688 }
689 }
690 else
691 {
692 /* Update ADC state machine to error */
693 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
694
695 /* Set ADC error code to ADC IP internal error */
696 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
697 }
698
699 /* Return function status */
700 return HAL_OK;
701 }
702
703 /**
704 * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral
705 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
706 * the configuration information for the specified ADC.
707 * @retval HAL status
708 */
HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef * hadc)709 HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc)
710 {
711 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
712
713 /* Check the parameters */
714 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
715
716 /* Process locked */
717 __HAL_LOCK(hadc);
718
719 /* Stop potential conversion on going, on regular and injected groups */
720 /* Disable ADC peripheral */
721 __HAL_ADC_DISABLE(hadc);
722
723 /* Check if ADC is effectively disabled */
724 if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON))
725 {
726 /* Disable the selected ADC DMA mode for multimode */
727 ADC->CCR &= ~ADC_CCR_DDS;
728
729 /* Disable the DMA channel (in case of DMA in circular mode or stop while */
730 /* DMA transfer is on going) */
731 tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
732
733 /* Disable ADC overrun interrupt */
734 __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
735
736 /* Set ADC state */
737 ADC_STATE_CLR_SET(hadc->State,
738 HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY,
739 HAL_ADC_STATE_READY);
740 }
741
742 /* Process unlocked */
743 __HAL_UNLOCK(hadc);
744
745 /* Return function status */
746 return tmp_hal_status;
747 }
748
749 /**
750 * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results
751 * data in the selected multi mode.
752 * @param hadc pointer to a ADC_HandleTypeDef structure that contains
753 * the configuration information for the specified ADC.
754 * @retval The converted data value.
755 */
HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef * hadc)756 uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc)
757 {
758 /* Prevent unused argument(s) compilation warning */
759 UNUSED(hadc);
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 = 0U;
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 STM32F2, 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 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1071