Improve generic & stm32f4 demos
[lwext4.git] / demos / stm32f429_disco / stm / stm32f4_spl / src / stm32f4xx_hal_adc_ex.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f4xx_hal_adc_ex.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0\r
6   * @date    18-February-2014\r
7   * @brief   This file provides firmware functions to manage the following \r
8   *          functionalities of the ADC extension peripheral:\r
9   *           + Extended features functions\r
10   *         \r
11   @verbatim\r
12   ==============================================================================\r
13                     ##### How to use this driver #####\r
14   ==============================================================================\r
15     [..]\r
16     (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():\r
17        (##) Enable the ADC interface clock using __ADC_CLK_ENABLE()\r
18        (##) ADC pins configuration\r
19              (+++) Enable the clock for the ADC GPIOs using the following function:\r
20                    __GPIOx_CLK_ENABLE()  \r
21              (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init() \r
22        (##) In case of using interrupts (e.g. HAL_ADC_Start_IT())\r
23              (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority()\r
24              (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()\r
25              (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler()\r
26       (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())\r
27              (++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE()\r
28              (++) Configure and enable two DMA streams stream for managing data\r
29                  transfer from peripheral to memory (output stream)\r
30              (++) Associate the initilalized DMA handle to the CRYP DMA handle\r
31                  using  __HAL_LINKDMA()\r
32              (++) Configure the priority and enable the NVIC for the transfer complete\r
33                  interrupt on the two DMA Streams. The output stream should have higher\r
34                  priority than the input stream.\r
35                        \r
36      (#) Configure the ADC Prescaler, conversion resolution and data alignment \r
37          using the HAL_ADC_Init() function. \r
38   \r
39      (#) Configure the ADC Injected channels group features, use HAL_ADC_Init()\r
40          and HAL_ADC_ConfigChannel() functions.\r
41          \r
42      (#) Three mode of operations are available within this driver :     \r
43   \r
44      *** Polling mode IO operation ***\r
45      =================================\r
46      [..]    \r
47        (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart() \r
48        (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage\r
49            user can specify the value of timeout according to his end application      \r
50        (+) To read the ADC converted values, use the HAL_ADCEx_InjectedGetValue() function.\r
51        (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop()\r
52   \r
53      *** Interrupt mode IO operation ***    \r
54      ===================================\r
55      [..]    \r
56        (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_IT() \r
57        (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine\r
58        (+) At ADC end of conversion HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can \r
59             add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback \r
60        (+) In case of ADC Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can \r
61             add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback\r
62        (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_IT()\r
63        \r
64             \r
65      *** DMA mode IO operation ***    \r
66      ==============================\r
67      [..]    \r
68        (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_DMA(), at this stage the user specify the length \r
69            of data to be transfered at each end of conversion \r
70        (+) At The end of data transfer ba HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can \r
71             add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback \r
72        (+) In case of transfer Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can \r
73             add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback\r
74         (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_DMA()\r
75         \r
76      *** Multi mode ADCs Regular channels configuration ***\r
77      ======================================================\r
78      [..]        \r
79        (+) Select the Multi mode ADC regular channels features (dual or triple mode)  \r
80           and configure the DMA mode using HAL_ADCEx_MultiModeConfigChannel() functions. \r
81        (+) Start the ADC peripheral using HAL_ADCEx_MultiModeStart_DMA(), at this stage the user specify the length \r
82            of data to be transfered at each end of conversion           \r
83        (+) Read the ADCs converted values using the HAL_ADCEx_MultiModeGetValue() function.\r
84   \r
85   \r
86     @endverbatim\r
87   ******************************************************************************\r
88   * @attention\r
89   *\r
90   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>\r
91   *\r
92   * Redistribution and use in source and binary forms, with or without modification,\r
93   * are permitted provided that the following conditions are met:\r
94   *   1. Redistributions of source code must retain the above copyright notice,\r
95   *      this list of conditions and the following disclaimer.\r
96   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
97   *      this list of conditions and the following disclaimer in the documentation\r
98   *      and/or other materials provided with the distribution.\r
99   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
100   *      may be used to endorse or promote products derived from this software\r
101   *      without specific prior written permission.\r
102   *\r
103   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
104   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
105   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
106   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
107   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
108   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
109   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
110   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
111   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
112   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
113   *\r
114   ******************************************************************************\r
115   */ \r
116 \r
117 /* Includes ------------------------------------------------------------------*/\r
118 #include "stm32f4xx_hal.h"\r
119 \r
120 /** @addtogroup STM32F4xx_HAL_Driver\r
121   * @{\r
122   */\r
123 \r
124 /** @defgroup ADCEx \r
125   * @brief ADC Extended driver modules\r
126   * @{\r
127   */ \r
128 \r
129 #ifdef HAL_ADC_MODULE_ENABLED\r
130     \r
131 /* Private typedef -----------------------------------------------------------*/\r
132 /* Private define ------------------------------------------------------------*/ \r
133 /* Private macro -------------------------------------------------------------*/\r
134 /* Private variables ---------------------------------------------------------*/\r
135 /* Private function prototypes -----------------------------------------------*/\r
136 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma);\r
137 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma);\r
138 static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma); \r
139 /* Private functions ---------------------------------------------------------*/\r
140 \r
141 /** @defgroup ADCEx_Private_Functions\r
142   * @{\r
143   */ \r
144 \r
145 /** @defgroup ADCEx_Group1 Extended features functions \r
146  *  @brief    Extended features functions  \r
147  *\r
148 @verbatim   \r
149  ===============================================================================\r
150                  ##### Extended features functions #####\r
151  ===============================================================================  \r
152     [..]  This section provides functions allowing to:\r
153       (+) Start conversion of injected channel.\r
154       (+) Stop conversion of injected channel.\r
155       (+) Start multimode and enable DMA transfer.\r
156       (+) Stop multimode and disable DMA transfer.\r
157       (+) Get result of injected channel conversion.\r
158       (+) Get result of multimode conversion.\r
159       (+) Configure injected channels.\r
160       (+) Configure multimode.\r
161                \r
162 @endverbatim\r
163   * @{\r
164   */\r
165 \r
166 /**\r
167   * @brief  Enables the selected ADC software start conversion of the injected channels.\r
168   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
169   *         the configuration information for the specified ADC.\r
170   * @retval HAL status\r
171   */\r
172 HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc)\r
173 {\r
174   uint32_t i = 0, tmp1 = 0, tmp2 = 0;\r
175   \r
176   /* Process locked */\r
177   __HAL_LOCK(hadc);\r
178   \r
179   /* Check if a regular conversion is ongoing */\r
180   if(hadc->State == HAL_ADC_STATE_BUSY_REG)\r
181   {\r
182     /* Change ADC state */\r
183     hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;  \r
184   }\r
185   else\r
186   {\r
187     /* Change ADC state */\r
188     hadc->State = HAL_ADC_STATE_BUSY_INJ;\r
189   } \r
190   \r
191   /* Check if ADC peripheral is disabled in order to enable it and wait during \r
192      Tstab time the ADC's stabilization */\r
193   if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)\r
194   {  \r
195     /* Enable the Peripheral */\r
196     __HAL_ADC_ENABLE(hadc);\r
197     \r
198     /* Delay inserted to wait during Tstab time the ADC's stabilazation */\r
199     for(; i <= 540; i++)\r
200     {\r
201       __NOP();\r
202     }\r
203   }\r
204   \r
205   /* Check if Multimode enabled */\r
206   if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))\r
207   {\r
208     tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);\r
209     tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);\r
210     if(tmp1 && tmp2)\r
211     {\r
212       /* Enable the selected ADC software conversion for injected group */\r
213       hadc->Instance->CR2 |= ADC_CR2_JSWSTART;\r
214     }\r
215   }\r
216   else\r
217   {\r
218     tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);\r
219     tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);\r
220     if((hadc->Instance == ADC1) && tmp1 && tmp2)  \r
221     {\r
222       /* Enable the selected ADC software conversion for injected group */\r
223       hadc->Instance->CR2 |= ADC_CR2_JSWSTART;\r
224     }\r
225   }\r
226   \r
227   /* Process unlocked */\r
228   __HAL_UNLOCK(hadc);\r
229   \r
230   /* Return function status */\r
231   return HAL_OK;\r
232 }\r
233 \r
234 /**\r
235   * @brief  Enables the interrupt and starts ADC conversion of injected channels.\r
236   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
237   *         the configuration information for the specified ADC.\r
238   *\r
239   * @retval HAL status.\r
240   */\r
241 HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc)\r
242 {\r
243   uint32_t i = 0, tmp1 = 0, tmp2 =0;\r
244   \r
245   /* Process locked */\r
246   __HAL_LOCK(hadc);\r
247   \r
248   /* Check if a regular conversion is ongoing */\r
249   if(hadc->State == HAL_ADC_STATE_BUSY_REG)\r
250   {\r
251     /* Change ADC state */\r
252     hadc->State = HAL_ADC_STATE_BUSY_INJ_REG;  \r
253   }\r
254   else\r
255   {\r
256     /* Change ADC state */\r
257     hadc->State = HAL_ADC_STATE_BUSY_INJ;\r
258   }\r
259   \r
260   /* Set ADC error code to none */\r
261   hadc->ErrorCode = HAL_ADC_ERROR_NONE;\r
262   \r
263   /* Check if ADC peripheral is disabled in order to enable it and wait during \r
264      Tstab time the ADC's stabilization */\r
265   if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)\r
266   {  \r
267     /* Enable the Peripheral */\r
268     __HAL_ADC_ENABLE(hadc);\r
269     \r
270     /* Delay inserted to wait during Tstab time the ADC's stabilazation */\r
271     for(; i <= 540; i++)\r
272     {\r
273       __NOP();\r
274     }\r
275   }\r
276   \r
277   /* Enable the ADC end of conversion interrupt for injected group */\r
278   __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC);\r
279   \r
280   /* Enable the ADC overrun interrupt */\r
281   __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);\r
282   \r
283   /* Check if Multimode enabled */\r
284   if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI))\r
285   {\r
286     tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);\r
287     tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);\r
288     if(tmp1 && tmp2)\r
289     {\r
290       /* Enable the selected ADC software conversion for injected group */\r
291       hadc->Instance->CR2 |= ADC_CR2_JSWSTART;\r
292     }\r
293   }\r
294   else\r
295   {\r
296     tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN);\r
297     tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO);\r
298     if((hadc->Instance == ADC1) && tmp1 && tmp2)  \r
299     {\r
300       /* Enable the selected ADC software conversion for injected group */\r
301       hadc->Instance->CR2 |= ADC_CR2_JSWSTART;\r
302     }\r
303   }\r
304   \r
305   /* Process unlocked */\r
306   __HAL_UNLOCK(hadc);\r
307   \r
308   /* Return function status */\r
309   return HAL_OK;\r
310 }\r
311 \r
312 /**\r
313   * @brief  Disables ADC and stop conversion of injected channels.\r
314   *\r
315   * @note   Caution: This function will stop also regular channels.  \r
316   *\r
317   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
318   *         the configuration information for the specified ADC.\r
319   * @retval HAL status.\r
320   */\r
321 HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc)\r
322 {\r
323   /* Disable the Peripheral */\r
324   __HAL_ADC_DISABLE(hadc);\r
325   \r
326   /* Change ADC state */\r
327   hadc->State = HAL_ADC_STATE_READY;\r
328   \r
329   /* Return function status */\r
330   return HAL_OK;\r
331 }\r
332 \r
333 /**\r
334   * @brief  Poll for injected conversion complete\r
335   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
336   *         the configuration information for the specified ADC.\r
337   * @param  Timeout: Timeout value in millisecond.  \r
338   * @retval HAL status\r
339   */\r
340 HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)\r
341 {\r
342   uint32_t timeout;\r
343  \r
344   /* Get timeout */\r
345   timeout = HAL_GetTick() + Timeout;  \r
346 \r
347   /* Check End of conversion flag */\r
348   while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC)))\r
349   {\r
350     /* Check for the Timeout */\r
351     if(Timeout != HAL_MAX_DELAY)\r
352     {\r
353       if(HAL_GetTick() >= timeout)\r
354       {\r
355         hadc->State= HAL_ADC_STATE_TIMEOUT;\r
356         /* Process unlocked */\r
357         __HAL_UNLOCK(hadc);\r
358         return HAL_TIMEOUT;\r
359       }\r
360     }\r
361   }\r
362   \r
363   /* Check if a regular conversion is ready */\r
364   if(hadc->State == HAL_ADC_STATE_EOC_REG)\r
365   {\r
366     /* Change ADC state */\r
367     hadc->State = HAL_ADC_STATE_EOC_INJ_REG;  \r
368   }\r
369   else\r
370   {\r
371     /* Change ADC state */\r
372     hadc->State = HAL_ADC_STATE_EOC_INJ;\r
373   }\r
374   \r
375   /* Return ADC state */\r
376   return HAL_OK;\r
377 }      \r
378   \r
379 /**\r
380   * @brief  Disables the interrupt and stop ADC conversion of injected channels.\r
381   * \r
382   * @note   Caution: This function will stop also regular channels.  \r
383   *\r
384   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
385   *         the configuration information for the specified ADC.\r
386   * @retval HAL status.\r
387   */\r
388 HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc)\r
389 {\r
390   /* Disable the ADC end of conversion interrupt for regular group */\r
391   __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);\r
392   \r
393   /* Disable the ADC end of conversion interrupt for injected group */\r
394   __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE);\r
395   \r
396   /* Enable the Periphral */\r
397   __HAL_ADC_DISABLE(hadc);\r
398   \r
399   /* Change ADC state */\r
400   hadc->State = HAL_ADC_STATE_READY;\r
401   \r
402   /* Return function status */\r
403   return HAL_OK;\r
404 }\r
405 \r
406 /**\r
407   * @brief  Gets the converted value from data register of injected channel.\r
408   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
409   *         the configuration information for the specified ADC.\r
410   * @param  InjectedRank: the ADC injected rank.\r
411   *          This parameter can be one of the following values:\r
412   *            @arg ADC_InjectedChannel_1: Injected Channel1 selected\r
413   *            @arg ADC_InjectedChannel_2: Injected Channel2 selected\r
414   *            @arg ADC_InjectedChannel_3: Injected Channel3 selected\r
415   *            @arg ADC_InjectedChannel_4: Injected Channel4 selected\r
416   * @retval None\r
417   */\r
418 uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank)\r
419 {\r
420   __IO uint32_t tmp = 0;\r
421   \r
422   /* Check the parameters */\r
423   assert_param(IS_ADC_INJECTED_RANK(InjectedRank));\r
424   \r
425    /* Clear the ADCx's flag for injected end of conversion */\r
426    __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC);\r
427   \r
428   /* Return the selected ADC converted value */ \r
429   switch(InjectedRank)\r
430   {  \r
431     case ADC_INJECTED_RANK_4:\r
432     {\r
433       tmp =  hadc->Instance->JDR4;\r
434     }  \r
435     break;\r
436     case ADC_INJECTED_RANK_3: \r
437     {  \r
438       tmp =  hadc->Instance->JDR3;\r
439     }  \r
440     break;\r
441     case ADC_INJECTED_RANK_2: \r
442     {  \r
443       tmp =  hadc->Instance->JDR2;\r
444     }\r
445     break;\r
446     case ADC_INJECTED_RANK_1:\r
447     {\r
448       tmp =  hadc->Instance->JDR1;\r
449     }\r
450     break;\r
451     default:\r
452     break;  \r
453   }\r
454   return tmp;\r
455 }\r
456 \r
457 /**\r
458   * @brief  Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral\r
459   * \r
460   * @note   Caution: This function must be used only with the ADC master.  \r
461   *\r
462   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
463   *         the configuration information for the specified ADC.\r
464   * @param  pData:   Pointer to buffer in which transferred from ADC peripheral to memory will be stored. \r
465   * @param  Length:  The length of data to be transferred from ADC peripheral to memory.  \r
466   * @retval None\r
467   */\r
468 HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)\r
469 {\r
470   uint16_t counter = 0;\r
471   \r
472   /* Check the parameters */\r
473   assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));\r
474   assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));\r
475   assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));\r
476   \r
477   /* Process locked */\r
478   __HAL_LOCK(hadc);\r
479   \r
480   /* Enable ADC overrun interrupt */\r
481   __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);\r
482   \r
483   if (hadc->Init.DMAContinuousRequests != DISABLE)\r
484   {\r
485     /* Enable the selected ADC DMA request after last transfer */\r
486     ADC->CCR |= ADC_CCR_DDS;\r
487   }\r
488   else\r
489   {\r
490     /* Disable the selected ADC EOC rising on each regular channel conversion */\r
491     ADC->CCR &= ~ADC_CCR_DDS;\r
492   }\r
493   \r
494   /* Set the DMA transfer complete callback */\r
495   hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt;\r
496   \r
497   /* Set the DMA half transfer complete callback */\r
498   hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt;\r
499      \r
500   /* Set the DMA error callback */\r
501   hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ;\r
502   \r
503   /* Enable the DMA Stream */\r
504   HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length);\r
505   \r
506   /* Change ADC state */\r
507   hadc->State = HAL_ADC_STATE_BUSY_REG;\r
508   \r
509   /* Check if ADC peripheral is disabled in order to enable it and wait during \r
510      Tstab time the ADC's stabilization */\r
511   if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON)\r
512   {  \r
513     /* Enable the Peripheral */\r
514     __HAL_ADC_ENABLE(hadc);\r
515     \r
516     /* Delay inserted to wait during Tstab time the ADC's stabilazation */\r
517     for(; counter <= 540; counter++)\r
518     {\r
519       __NOP();\r
520     }\r
521   }\r
522   \r
523   /* if no external trigger present enable software conversion of regular channels */\r
524   if (hadc->Init.ExternalTrigConvEdge == ADC_EXTERNALTRIGCONVEDGE_NONE)\r
525   {\r
526     /* Enable the selected ADC software conversion for regular group */\r
527     hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;\r
528   }\r
529   \r
530   /* Process unlocked */\r
531   __HAL_UNLOCK(hadc);\r
532   \r
533   /* Return function status */\r
534   return HAL_OK;\r
535 }\r
536 \r
537 /**\r
538   * @brief  Disables ADC DMA (multi-ADC mode) and disables ADC peripheral    \r
539   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
540   *         the configuration information for the specified ADC.\r
541   * @retval None\r
542   */\r
543 HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc)\r
544 {\r
545   /* Process locked */\r
546   __HAL_LOCK(hadc);\r
547   \r
548   /* Enable the Peripheral */\r
549   __HAL_ADC_DISABLE(hadc);\r
550   \r
551   /* Disable ADC overrun interrupt */\r
552   __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);\r
553   \r
554   /* Disable the selected ADC DMA request after last transfer */\r
555   ADC->CCR &= ~ADC_CCR_DDS;\r
556   \r
557   /* Disable the ADC DMA Stream */\r
558   HAL_DMA_Abort(hadc->DMA_Handle);\r
559   \r
560   /* Change ADC state */\r
561   hadc->State = HAL_ADC_STATE_READY;\r
562   \r
563   /* Process unlocked */\r
564   __HAL_UNLOCK(hadc);\r
565     \r
566   /* Return function status */\r
567   return HAL_OK;\r
568 }\r
569 \r
570 /**\r
571   * @brief  Returns the last ADC1, ADC2 and ADC3 regular conversions results \r
572   *         data in the selected multi mode.\r
573   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
574   *         the configuration information for the specified ADC.\r
575   * @retval The converted data value.\r
576   */\r
577 uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc)\r
578 {\r
579   /* Return the multi mode conversion value */\r
580   return ADC->CDR;\r
581 }\r
582 \r
583 /**\r
584   * @brief  Injected conversion complete callback in non blocking mode \r
585   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
586   *         the configuration information for the specified ADC.\r
587   * @retval None\r
588   */\r
589 __weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)\r
590 {\r
591   /* NOTE : This function Should not be modified, when the callback is needed,\r
592             the HAL_ADC_InjectedConvCpltCallback could be implemented in the user file\r
593    */\r
594 }\r
595 \r
596 /**\r
597   * @brief  Configures for the selected ADC injected channel its corresponding\r
598   *         rank in the sequencer and its sample time.\r
599   * @param  hadc: pointer to a ADC_HandleTypeDef structure that contains\r
600   *         the configuration information for the specified ADC.\r
601   * @param  sConfigInjected: ADC configuration structure for injected channel. \r
602   * @retval None\r
603   */\r
604 HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected)\r
605 {\r
606   \r
607 #ifdef USE_FULL_ASSERT  \r
608   uint32_t tmp = 0;\r
609 #endif /* USE_FULL_ASSERT  */\r
610   \r
611   /* Check the parameters */\r
612   assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel));\r
613   assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank));\r
614   assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime));\r
615   assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv));\r
616   assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge));\r
617   assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion));\r
618   assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv));\r
619   assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode));\r
620 \r
621 #ifdef USE_FULL_ASSERT\r
622   tmp = __HAL_ADC_GET_RESOLUTION(hadc);\r
623   assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset));\r
624 #endif /* USE_FULL_ASSERT  */\r
625 \r
626   /* Process locked */\r
627   __HAL_LOCK(hadc);\r
628   \r
629   /* if ADC_Channel_10 ... ADC_Channel_18 is selected */\r
630   if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9)\r
631   {\r
632     /* Clear the old sample time */\r
633     hadc->Instance->SMPR1 &= ~__HAL_ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel);\r
634     \r
635     /* Set the new sample time */\r
636     hadc->Instance->SMPR1 |= __HAL_ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel);\r
637   }\r
638   else /* ADC_Channel include in ADC_Channel_[0..9] */\r
639   {\r
640     /* Clear the old sample time */\r
641     hadc->Instance->SMPR2 &= ~__HAL_ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel);\r
642     \r
643     /* Set the new sample time */\r
644     hadc->Instance->SMPR2 |= __HAL_ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel);\r
645   }\r
646   \r
647   /*---------------------------- ADCx JSQR Configuration -----------------*/\r
648   hadc->Instance->JSQR &= ~(ADC_JSQR_JL);\r
649   hadc->Instance->JSQR |=  __HAL_ADC_SQR1(sConfigInjected->InjectedNbrOfConversion);\r
650   \r
651   /* Rank configuration */\r
652   \r
653   /* Clear the old SQx bits for the selected rank */\r
654   hadc->Instance->JSQR &= ~__HAL_ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);\r
655    \r
656   /* Set the SQx bits for the selected rank */\r
657   hadc->Instance->JSQR |= __HAL_ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion);\r
658 \r
659   /* Select external trigger to start conversion */\r
660   hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL);\r
661   hadc->Instance->CR2 |=  sConfigInjected->ExternalTrigInjecConv;\r
662   \r
663   /* Select external trigger polarity */\r
664   hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN);\r
665   hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge;\r
666   \r
667   if (sConfigInjected->AutoInjectedConv != DISABLE)\r
668   {\r
669     /* Enable the selected ADC automatic injected group conversion */\r
670     hadc->Instance->CR1 |= ADC_CR1_JAUTO;\r
671   }\r
672   else\r
673   {\r
674     /* Disable the selected ADC automatic injected group conversion */\r
675     hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO);\r
676   }\r
677   \r
678   if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE)\r
679   {\r
680     /* Enable the selected ADC injected discontinuous mode */\r
681     hadc->Instance->CR1 |= ADC_CR1_JDISCEN;\r
682   }\r
683   else\r
684   {\r
685     /* Disable the selected ADC injected discontinuous mode */\r
686     hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN);\r
687   }\r
688   \r
689   switch(sConfigInjected->InjectedRank)\r
690   {\r
691     case 1:\r
692       /* Set injected channel 1 offset */\r
693       hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1);\r
694       hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset;\r
695       break;\r
696     case 2:\r
697       /* Set injected channel 2 offset */\r
698       hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2);\r
699       hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset;\r
700       break;\r
701     case 3:\r
702       /* Set injected channel 3 offset */\r
703       hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3);\r
704       hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset;\r
705       break;\r
706     default:\r
707       /* Set injected channel 4 offset */\r
708       hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4);\r
709       hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset;\r
710       break;\r
711   }\r
712   \r
713   /* if ADC1 Channel_18 is selected enable VBAT Channel */\r
714   if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT))\r
715   {\r
716     /* Enable the VBAT channel*/\r
717     ADC->CCR |= ADC_CCR_VBATE;\r
718   }\r
719   \r
720   /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */\r
721   if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT)))\r
722   {\r
723     /* Enable the TSVREFE channel*/\r
724     ADC->CCR |= ADC_CCR_TSVREFE;\r
725   }\r
726   \r
727   /* Process unlocked */\r
728   __HAL_UNLOCK(hadc);\r
729   \r
730   /* Return function status */\r
731   return HAL_OK;\r
732 }\r
733 \r
734 /**\r
735   * @brief  Configures the ADC multi-mode \r
736   * @param  hadc      : pointer to a ADC_HandleTypeDef structure that contains\r
737   *                     the configuration information for the specified ADC.  \r
738   * @param  multimode : pointer to an ADC_MultiModeTypeDef structure that contains \r
739   *                     the configuration information for  multimode.\r
740   * @retval HAL status\r
741   */\r
742 HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode)\r
743 {\r
744   /* Check the parameters */\r
745   assert_param(IS_ADC_MODE(multimode->Mode));\r
746   assert_param(IS_ADC_DMA_ACCESS_MODE(multimode->DMAAccessMode));\r
747   assert_param(IS_ADC_SAMPLING_DELAY(multimode->TwoSamplingDelay));\r
748   \r
749   /* Process locked */\r
750   __HAL_LOCK(hadc);\r
751   \r
752   /* Set ADC mode */\r
753   ADC->CCR &= ~(ADC_CCR_MULTI);\r
754   ADC->CCR |= multimode->Mode;\r
755   \r
756   /* Set the ADC DMA access mode */\r
757   ADC->CCR &= ~(ADC_CCR_DMA);\r
758   ADC->CCR |= multimode->DMAAccessMode;\r
759   \r
760   /* Set delay between two sampling phases */\r
761   ADC->CCR &= ~(ADC_CCR_DELAY);\r
762   ADC->CCR |= multimode->TwoSamplingDelay;\r
763   \r
764   /* Process unlocked */\r
765   __HAL_UNLOCK(hadc);\r
766   \r
767   /* Return function status */\r
768   return HAL_OK;\r
769 }\r
770 \r
771 /**\r
772   * @}\r
773   */\r
774 \r
775   /**\r
776   * @brief  DMA transfer complete callback. \r
777   * @param  hdma: pointer to DMA handle.\r
778   * @retval None\r
779   */\r
780 static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma)   \r
781 {\r
782     ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
783     \r
784   /* Check if an injected conversion is ready */\r
785   if(hadc->State == HAL_ADC_STATE_EOC_INJ)\r
786   {\r
787     /* Change ADC state */\r
788     hadc->State = HAL_ADC_STATE_EOC_INJ_REG;  \r
789   }\r
790   else\r
791   {\r
792     /* Change ADC state */\r
793     hadc->State = HAL_ADC_STATE_EOC_REG;\r
794   }\r
795     \r
796     HAL_ADC_ConvCpltCallback(hadc); \r
797 }\r
798 \r
799 /**\r
800   * @brief  DMA half transfer complete callback. \r
801   * @param  hdma: pointer to DMA handle.\r
802   * @retval None\r
803   */\r
804 static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma)   \r
805 {\r
806     ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
807     /* Conversion complete callback */\r
808     HAL_ADC_ConvHalfCpltCallback(hadc); \r
809 }\r
810 \r
811 /**\r
812   * @brief  DMA error callback \r
813   * @param  hdma: pointer to DMA handle.\r
814   * @retval None\r
815   */\r
816 static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma)   \r
817 {\r
818     ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
819     hadc->State= HAL_ADC_STATE_ERROR;\r
820     /* Set ADC error code to DMA error */\r
821     hadc->ErrorCode |= HAL_ADC_ERROR_DMA;\r
822     HAL_ADC_ErrorCallback(hadc); \r
823 }\r
824 \r
825 /**\r
826   * @}\r
827   */\r
828 \r
829 #endif /* HAL_ADC_MODULE_ENABLED */\r
830 /**\r
831   * @}\r
832   */ \r
833 \r
834 /**\r
835   * @}\r
836   */ \r
837 \r
838 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r