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>&copy; 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