1 /**
2 ******************************************************************************
3 * @file stm32l0xx_hal_adc_ex.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following
6 * functionalities of the Analog to Digital Convertor (ADC)
7 * peripheral:
8 * + Operation functions
9 * ++ Calibration
10 * +++ ADC automatic self-calibration
11 * +++ Calibration factors get or set
12 * Other functions (generic functions) are available in file
13 * "stm32l0xx_hal_adc.c".
14 *
15 @verbatim
16 [..]
17 (@) Sections "ADC peripheral features" and "How to use this driver" are
18 available in file of generic functions "stm32l0xx_hal_adc.c".
19 [..]
20 @endverbatim
21 ******************************************************************************
22 * @attention
23 *
24 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
25 *
26 * Redistribution and use in source and binary forms, with or without modification,
27 * are permitted provided that the following conditions are met:
28 * 1. Redistributions of source code must retain the above copyright notice,
29 * this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright notice,
31 * this list of conditions and the following disclaimer in the documentation
32 * and/or other materials provided with the distribution.
33 * 3. Neither the name of STMicroelectronics nor the names of its contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 *
48 ******************************************************************************
49 */
50
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32l0xx_hal.h"
53
54 /** @addtogroup STM32L0xx_HAL_Driver
55 * @{
56 */
57
58 /** @defgroup ADCEx ADCEx
59 * @brief ADC Extended HAL module driver
60 * @{
61 */
62
63 #ifdef HAL_ADC_MODULE_ENABLED
64
65 /* Private typedef -----------------------------------------------------------*/
66 /* Private define ------------------------------------------------------------*/
67
68 /** @defgroup ADCEx_Private_Constants ADC Extended Private Constants
69 * @{
70 */
71
72 /* Fixed timeout values for ADC calibration, enable settling time, disable */
73 /* settling time. */
74 /* Values defined to be higher than worst cases: low clock frequency, */
75 /* maximum prescaler. */
76 /* Unit: ms */
77 #define ADC_CALIBRATION_TIMEOUT 10U
78
79 /* Delay for VREFINT stabilization time. */
80 /* Internal reference startup time max value is 3ms (refer to device datasheet, parameter TVREFINT). */
81 /* Unit: ms */
82 #define SYSCFG_BUF_VREFINT_ENABLE_TIMEOUT ((uint32_t) 3U)
83
84 /* Delay for TEMPSENSOR stabilization time. */
85 /* Temperature sensor startup time max value is 10us (refer to device datasheet, parameter tSTART). */
86 /* Unit: ms */
87 #define SYSCFG_BUF_TEMPSENSOR_ENABLE_TIMEOUT ((uint32_t) 1U)
88
89 /* Private macro -------------------------------------------------------------*/
90 /* Private variables ---------------------------------------------------------*/
91 /* Private function prototypes -----------------------------------------------*/
92 /* Exported functions --------------------------------------------------------*/
93
94 /** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions
95 * @{
96 */
97
98 /** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions
99 * @brief Extended IO operation functions
100 *
101 @verbatim
102 ===============================================================================
103 ##### IO operation functions #####
104 ===============================================================================
105 [..] This section provides functions allowing to:
106 (+) Perform the ADC calibration.
107 @endverbatim
108 * @{
109 */
110
111 /**
112 * @brief Perform an ADC automatic self-calibration
113 * Calibration prerequisite: ADC must be disabled (execute this
114 * function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
115 * @note Calibration factor can be read after calibration, using function
116 * HAL_ADC_GetValue() (value on 7 bits: from DR[6;0]).
117 * @param hadc ADC handle
118 * @param SingleDiff: Selection of single-ended or differential input
119 * This parameter can be only of the following values:
120 * @arg ADC_SINGLE_ENDED: Channel in mode input single ended
121 * @retval HAL status
122 */
HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef * hadc,uint32_t SingleDiff)123 HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc, uint32_t SingleDiff)
124 {
125 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
126 uint32_t tickstart = 0U;
127 uint32_t backup_setting_adc_dma_transfer = 0U; /* Note: Variable not declared as volatile because register read is already declared as volatile */
128
129 /* Check the parameters */
130 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
131
132 /* Process locked */
133 __HAL_LOCK(hadc);
134
135 /* Calibration prerequisite: ADC must be disabled. */
136 if (ADC_IS_ENABLE(hadc) == RESET)
137 {
138 /* Set ADC state */
139 ADC_STATE_CLR_SET(hadc->State,
140 HAL_ADC_STATE_REG_BUSY,
141 HAL_ADC_STATE_BUSY_INTERNAL);
142
143 /* Disable ADC DMA transfer request during calibration */
144 /* Note: Specificity of this STM32 serie: Calibration factor is */
145 /* available in data register and also transfered by DMA. */
146 /* To not insert ADC calibration factor among ADC conversion data */
147 /* in array variable, DMA transfer must be disabled during */
148 /* calibration. */
149 backup_setting_adc_dma_transfer = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
150 CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
151
152 /* Start ADC calibration */
153 hadc->Instance->CR |= ADC_CR_ADCAL;
154
155 tickstart = HAL_GetTick();
156
157 /* Wait for calibration completion */
158 while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADCAL))
159 {
160 if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
161 {
162 /* Update ADC state machine to error */
163 ADC_STATE_CLR_SET(hadc->State,
164 HAL_ADC_STATE_BUSY_INTERNAL,
165 HAL_ADC_STATE_ERROR_INTERNAL);
166
167 /* Process unlocked */
168 __HAL_UNLOCK(hadc);
169
170 return HAL_ERROR;
171 }
172 }
173
174 /* Restore ADC DMA transfer request after calibration */
175 SET_BIT(hadc->Instance->CFGR1, backup_setting_adc_dma_transfer);
176
177 /* Set ADC state */
178 ADC_STATE_CLR_SET(hadc->State,
179 HAL_ADC_STATE_BUSY_INTERNAL,
180 HAL_ADC_STATE_READY);
181 }
182 else
183 {
184 /* Update ADC state machine to error */
185 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
186
187 tmp_hal_status = HAL_ERROR;
188 }
189
190 /* Process unlocked */
191 __HAL_UNLOCK(hadc);
192
193 /* Return function status */
194 return tmp_hal_status;
195 }
196
197 /**
198 * @brief Get the calibration factor.
199 * @param hadc: ADC handle.
200 * @param SingleDiff: This parameter can be only:
201 * @arg ADC_SINGLE_ENDED: Channel in mode input single ended.
202 * @retval Calibration value.
203 */
HAL_ADCEx_Calibration_GetValue(ADC_HandleTypeDef * hadc,uint32_t SingleDiff)204 uint32_t HAL_ADCEx_Calibration_GetValue(ADC_HandleTypeDef* hadc, uint32_t SingleDiff)
205 {
206 /* Check the parameters */
207 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
208 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
209
210 /* Return the ADC calibration value */
211 return ((hadc->Instance->CALFACT) & 0x0000007FU);
212 }
213
214 /**
215 * @brief Set the calibration factor to overwrite automatic conversion result.
216 * ADC must be enabled and no conversion is ongoing.
217 * @param hadc: ADC handle
218 * @param SingleDiff: This parameter can be only:
219 * @arg ADC_SINGLE_ENDED: Channel in mode input single ended.
220 * @param CalibrationFactor: Calibration factor (coded on 7 bits maximum)
221 * @retval HAL state
222 */
HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef * hadc,uint32_t SingleDiff,uint32_t CalibrationFactor)223 HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef* hadc, uint32_t SingleDiff, uint32_t CalibrationFactor)
224 {
225 HAL_StatusTypeDef tmp_hal_status = HAL_OK;
226
227 /* Check the parameters */
228 assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
229 assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));
230 assert_param(IS_ADC_CALFACT(CalibrationFactor));
231
232 /* Process locked */
233 __HAL_LOCK(hadc);
234
235 /* Verification of hardware constraints before modifying the calibration */
236 /* factors register: ADC must be enabled, no conversion on going. */
237 if ( (ADC_IS_ENABLE(hadc) != RESET) &&
238 (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) )
239 {
240 /* Set the selected ADC calibration value */
241 hadc->Instance->CALFACT &= ~ADC_CALFACT_CALFACT;
242 hadc->Instance->CALFACT |= CalibrationFactor;
243 }
244 else
245 {
246 /* Update ADC state machine to error */
247 SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
248 /* Update ADC state machine to error */
249 SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
250
251 /* Update ADC state machine to error */
252 tmp_hal_status = HAL_ERROR;
253 }
254
255 /* Process unlocked */
256 __HAL_UNLOCK(hadc);
257
258 /* Return function status */
259 return tmp_hal_status;
260 }
261
262 /**
263 * @brief Enables the buffer of Vrefint for the ADC, required when device is in mode low-power (low-power run, low-power sleep or stop mode)
264 * This function must be called before function HAL_ADC_Init()
265 * (in case of previous ADC operations: function HAL_ADC_DeInit() must be called first)
266 * For more details on procedure and buffer current consumption, refer to device reference manual.
267 * @note This is functional only if the LOCK is not set.
268 * @retval None
269 */
HAL_ADCEx_EnableVREFINT(void)270 HAL_StatusTypeDef HAL_ADCEx_EnableVREFINT(void)
271 {
272 uint32_t tickstart = 0U;
273
274 /* Enable the Buffer for the ADC by setting ENBUF_SENSOR_ADC bit in the CFGR3 register */
275 SET_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUF_VREFINT_ADC);
276
277 /* Wait for Vrefint buffer effectively enabled */
278 /* Get tick count */
279 tickstart = HAL_GetTick();
280
281 while(HAL_IS_BIT_CLR(SYSCFG->CFGR3, SYSCFG_CFGR3_VREFINT_RDYF))
282 {
283 if((HAL_GetTick() - tickstart) > SYSCFG_BUF_VREFINT_ENABLE_TIMEOUT)
284 {
285 return HAL_ERROR;
286 }
287 }
288
289 return HAL_OK;
290 }
291
292 /**
293 * @brief Disables the Buffer Vrefint for the ADC.
294 * @note This is functional only if the LOCK is not set.
295 * @retval None
296 */
HAL_ADCEx_DisableVREFINT(void)297 void HAL_ADCEx_DisableVREFINT(void)
298 {
299 /* Disable the Vrefint by resetting ENBUF_SENSOR_ADC bit in the CFGR3 register */
300 CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUF_VREFINT_ADC);
301 }
302
303 /**
304 * @brief Enables the buffer of temperature sensor for the ADC, required when device is in mode low-power (low-power run, low-power sleep or stop mode)
305 * This function must be called before function HAL_ADC_Init()
306 * (in case of previous ADC operations: function HAL_ADC_DeInit() must be called first)
307 * For more details on procedure and buffer current consumption, refer to device reference manual.
308 * @note This is functional only if the LOCK is not set.
309 * @retval None
310 */
HAL_ADCEx_EnableVREFINTTempSensor(void)311 HAL_StatusTypeDef HAL_ADCEx_EnableVREFINTTempSensor(void)
312 {
313 uint32_t tickstart = 0U;
314
315 /* Enable the Buffer for the ADC by setting ENBUF_SENSOR_ADC bit in the CFGR3 register */
316 SET_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUF_SENSOR_ADC);
317
318 /* Wait for Vrefint buffer effectively enabled */
319 /* Get tick count */
320 tickstart = HAL_GetTick();
321
322 while(HAL_IS_BIT_CLR(SYSCFG->CFGR3, SYSCFG_CFGR3_VREFINT_RDYF))
323 {
324 if((HAL_GetTick() - tickstart) > SYSCFG_BUF_TEMPSENSOR_ENABLE_TIMEOUT)
325 {
326 return HAL_ERROR;
327 }
328 }
329
330 return HAL_OK;
331 }
332
333 /**
334 * @brief Disables the VREFINT and Sensor for the ADC.
335 * @note This is functional only if the LOCK is not set.
336 * @retval None
337 */
HAL_ADCEx_DisableVREFINTTempSensor(void)338 void HAL_ADCEx_DisableVREFINTTempSensor(void)
339 {
340 /* Disable the Vrefint by resetting ENBUF_SENSOR_ADC bit in the CFGR3 register */
341 CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENBUF_SENSOR_ADC);
342 }
343
344 /**
345 * @}
346 */
347
348 /**
349 * @}
350 */
351
352 #endif /* HAL_ADC_MODULE_ENABLED */
353 /**
354 * @}
355 */
356
357 /**
358 * @}
359 */
360
361 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
362