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