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