libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
adc_common_v2.c
Go to the documentation of this file.
1/** @addtogroup adc_file ADC peripheral API
2@ingroup peripheral_apis
3
4@author @htmlonly © @endhtmlonly
52015 Karl Palsson <karlp@tweak.net.au>
6
7This library supports one style of the Analog to Digital Conversion System in
8the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics.
9
10The style of ADC Peripheral supported by this code is found in the F0, L0 and
11F30x series devices (at the time of writing)
12
13LGPL License Terms @ref lgpl_license
14 */
15
16/*
17 * This file is part of the libopencm3 project.
18 *
19 * Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
20 *
21 * This library is free software: you can redistribute it and/or modify
22 * it under the terms of the GNU Lesser General Public License as published by
23 * the Free Software Foundation, either version 3 of the License, or
24 * (at your option) any later version.
25 *
26 * This library is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU Lesser General Public License for more details.
30 *
31 * You should have received a copy of the GNU Lesser General Public License
32 * along with this library. If not, see <http://www.gnu.org/licenses/>.
33 */
34
35/**@{*/
36
38
39
40/** @brief ADC Read the End-of-Conversion Flag
41 *
42 * This flag is set by hardware at the end of each regular conversion of a
43 * channel when a new data is available in the ADCx_DR register.
44 *
45 * @param[in] adc Unsigned int32. ADC block register address base
46 * @ref adc_reg_base
47 * @returns bool. End of conversion flag.
48 */
49bool adc_eoc(uint32_t adc)
50{
51 return ADC_ISR(adc) & ADC_ISR_EOC;
52}
53
54/** @brief ADC Read the End-of-Sequence Flag for Regular Conversions
55 *
56 * This flag is set after all channels of an regular group have been
57 * converted.
58 *
59 * @param[in] adc Unsigned int32. ADC block register address base
60 * @ref adc_reg_base
61 * @returns bool. End of conversion flag.
62 */
63bool adc_eos(uint32_t adc)
64{
65 return ADC_ISR(adc) & ADC_ISR_EOS;
66}
67
68/**
69 * Turn on the ADC (async)
70 * @sa adc_wait_power_on
71 * @param adc ADC Block register address base @ref adc_reg_base
72 */
73void adc_power_on_async(uint32_t adc)
74{
75 ADC_CR(adc) |= ADC_CR_ADEN;
76}
77
78/**
79 * Is the ADC powered up and ready?
80 * @sa adc_power_on_async
81 * @param adc ADC Block register address base @ref adc_reg_base
82 * @return true if adc is ready for use
83 */
84bool adc_is_power_on(uint32_t adc)
85{
86 return ADC_ISR(adc) & ADC_ISR_ADRDY;
87}
88
89/**
90 * Turn on the ADC
91 * @sa adc_power_on_async
92 * @param adc ADC Block register address base @ref adc_reg_base
93 */
94void adc_power_on(uint32_t adc)
95{
97 while (!adc_is_power_on(adc));
98}
99
100/**
101 * Turn off the ADC (async)
102 * This will actually block if it needs to turn off a currently running
103 * conversion, as per ref man. (Handles injected on hardware that supports
104 * injected conversions.
105 * @sa adc_wait_power_off
106 * @param adc ADC Block register address base @ref adc_reg_base
107 */
108void adc_power_off_async(uint32_t adc)
109{
110 if (adc_is_power_off(adc)) {
111 return;
112 }
113
114 uint32_t checks = ADC_CR_ADSTART;
115 uint32_t stops = ADC_CR_ADSTP;
116#if defined(ADC_CR_JADSTART)
117 checks |= ADC_CR_JADSTART;
118 stops |= ADC_CR_JADSTP;
119#endif
120 if (ADC_CR(adc) & checks) {
121 ADC_CR(adc) |= stops;
122 while (ADC_CR(adc) & checks);
123 }
124 ADC_CR(adc) |= ADC_CR_ADDIS;
125}
126
127/**
128 * Is the ADC powered down?
129 * @sa adc_power_off_async
130 * @param adc ADC Block register address base @ref adc_reg_base
131 */
132bool adc_is_power_off(uint32_t adc)
133{
134 return !(ADC_CR(adc) & ADC_CR_ADEN);
135}
136
137/**
138 * Turn off the ADC
139 * This will actually block if it needs to turn off a currently running
140 * conversion, as per ref man.
141 * @sa adc_power_off_async
142 * @param adc ADC Block register address base @ref adc_reg_base
143 */
144void adc_power_off(uint32_t adc)
145{
147 while (!adc_is_power_off(adc));
148}
149
150/**
151 * Start the ADC calibration and immediately return.
152 * @sa adc_calibrate
153 * @sa adc_is_calibrating
154 * @param adc ADC Block register address base @ref adc_reg_base
155 */
156void adc_calibrate_async(uint32_t adc)
157{
158 ADC_CR(adc) |= ADC_CR_ADCAL;
159}
160
161/**
162 * Is the ADC Calibrating?
163 * @param adc ADC Block register address base @ref adc_reg_base
164 * @return true if the adc is currently calibrating
165 */
166bool adc_is_calibrating(uint32_t adc)
167{
168 return ADC_CR(adc) & ADC_CR_ADCAL;
169}
170
171/**
172 * Start ADC calibration and wait for it to finish
173 * @param adc ADC Block register address base @ref adc_reg_base
174 */
175void adc_calibrate(uint32_t adc)
176{
178 while (adc_is_calibrating(adc));
179}
180
181/**
182 * Enable Continuous Conversion Mode
183 * In this mode the ADC starts a new conversion of a single channel or a channel
184 * group immediately following completion of the previous channel group
185 * conversion.
186 *
187 * @param[in] adc ADC block register address base @ref adc_reg_base
188 */
190{
192}
193
194/**
195 * Enable Single Conversion Mode
196 * In this mode the ADC performs a conversion of one channel or a channel group
197 * and stops.
198 *
199 * @param[in] adc ADC block register address base @ref adc_reg_base
200 */
202{
203 ADC_CFGR1(adc) &= ~ADC_CFGR1_CONT;
204}
205
206/** @brief ADC Set Resolution
207 *
208 * ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a
209 * corresponding reduction in conversion time.
210 *
211 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
212 * @param[in] resolution Unsigned int16. Resolution value (@ref adc_api_res)
213 */
214void adc_set_resolution(uint32_t adc, uint16_t resolution)
215{
216 ADC_CFGR1(adc) = (ADC_CFGR1(adc) & ~ADC_CFGR1_RES_MASK) | resolution;
217}
218
219/** @brief ADC Set the Data as Left Aligned
220 *
221 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
222 */
223void adc_set_left_aligned(uint32_t adc)
224{
226}
227
228/** @brief ADC Set the Data as Right Aligned
229 *
230 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
231 */
232void adc_set_right_aligned(uint32_t adc)
233{
234 ADC_CFGR1(adc) &= ~ADC_CFGR1_ALIGN;
235}
236
237/** @brief ADC Enable DMA Transfers
238 *
239 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
240 */
241void adc_enable_dma(uint32_t adc)
242{
244}
245
246/** @brief ADC Disable DMA Transfers
247 *
248 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
249 */
250void adc_disable_dma(uint32_t adc)
251{
252 ADC_CFGR1(adc) &= ~ADC_CFGR1_DMAEN;
253}
254
255/** @brief ADC Enable the Overrun Interrupt
256 *
257 * The overrun interrupt is generated when data is not read from a result
258 * register before the next conversion is written. If DMA is enabled, all
259 * transfers are terminated and any conversion sequence is aborted.
260 *
261 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
262 */
264{
265 ADC_IER(adc) |= ADC_IER_OVRIE;
266}
267
268/** @brief ADC Disable the Overrun Interrupt
269 *
270 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
271 */
273{
274 ADC_IER(adc) &= ~ADC_IER_OVRIE;
275}
276
277/** @brief ADC Read the Overrun Flag
278 *
279 * The overrun flag is set when data is not read from a result register before
280 * the next conversion is written. If DMA is enabled, all transfers are
281 * terminated and any conversion sequence is aborted.
282 *
283 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
284 */
285bool adc_get_overrun_flag(uint32_t adc)
286{
287 return ADC_ISR(adc) & ADC_ISR_OVR;
288}
289
290/** @brief ADC Clear Overrun Flags
291 *
292 * The overrun flag is cleared. Note that if an overrun occurs, DMA is
293 * terminated.
294 * The flag must be cleared and the DMA stream and ADC reinitialised to resume
295 * conversions (see the reference manual).
296 *
297 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
298 */
299void adc_clear_overrun_flag(uint32_t adc)
300{
301 ADC_ISR(adc) = ADC_ISR_OVR;
302}
303
304/** @brief ADC Enable Regular End-Of-Conversion Interrupt
305 *
306 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
307 */
308void adc_enable_eoc_interrupt(uint32_t adc)
309{
310 ADC_IER(adc) |= ADC_IER_EOCIE;
311}
312
313/** @brief ADC Disable Regular End-Of-Conversion Interrupt
314 *
315 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
316 */
318{
319 ADC_IER(adc) &= ~ADC_IER_EOCIE;
320}
321
322/** @brief ADC Read from the Regular Conversion Result Register
323 *
324 * The result read back is 12 bits, right or left aligned within the first
325 * 16 bits.
326 *
327 * @param[in] adc Unsigned int32. ADC block register address base
328 * @ref adc_reg_base
329 * @returns Unsigned int32 conversion result.
330 */
331uint32_t adc_read_regular(uint32_t adc)
332{
333 return ADC_DR(adc);
334}
335
336/**
337 * Enable the temperature sensor (only)
338 * The channel this is available on is unfortunately not
339 * consistent, even though the bit used to enable it is.
340 * @sa adc_disable_temperature_sensor
341 */
343{
345}
346
347/**
348 * Disable the temperature sensor (only)
349 * @sa adc_enable_temperature_sensor
350 */
352{
353 ADC_CCR(ADC1) &= ~ADC_CCR_TSEN;
354}
355
356/**
357 * Enable the internal voltage reference (only)
358 * The channel this is available on is unfortunately not
359 * consistent, even though the bit used to enable it is.
360 * FIXME - on f3, you can actually have it on ADC34 as well!
361 * @sa adc_disable_vrefint
362 */
364{
366}
367
368/**
369 * Disable the internal voltage reference (only)
370 * @sa adc_enable_vrefint
371 */
373{
374 ADC_CCR(ADC1) &= ~ADC_CCR_VREFEN;
375}
376
377/** @brief ADC Software Triggered Conversion on Regular Channels
378 *
379 * This starts conversion on a set of defined regular channels.
380 * Depending on the configuration bits EXTEN, a conversion will start
381 * immediately (software trigger configuration) or once a regular hardware
382 * trigger event occurs (hardware trigger configuration)
383 *
384 * @param[in] adc ADC block register address base @ref adc_reg_base
385 */
387{
388 /* Start conversion on regular channels. */
389 ADC_CR(adc) |= ADC_CR_ADSTART;
390}
391
392/** @brief Enable circular mode for DMA transfers
393 *
394 * For this to work it needs to be ebabled on the DMA side as well.
395 *
396 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
397 */
399{
401}
402
403/** @brief Disable circular mode for DMA transfers
404 *
405 * @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
406 */
408{
409 ADC_CFGR1(adc) &= ~ADC_CFGR1_DMACFG;
410}
411
412/** Enable Delayed Conversion Mode.
413 *
414 * @param[in] adc ADC block register address base @ref adc_reg_base
415 */
417{
419}
420
421/** Enable Delayed Conversion Mode.
422 *
423 * @param[in] adc ADC block register address base @ref adc_reg_base
424 */
426{
427 ADC_CFGR1(adc) &= ~ADC_CFGR1_AUTDLY;
428}
429
430/**@}*/
#define ADC_CCR_TSEN
TSEN: Enable Temperature Sensor.
#define ADC_CCR_VREFEN
VREFEN: Enable internal Voltage Reference.
#define ADC_CFGR1_DMAEN
DMAEN: Direct memory access enable.
#define ADC_CFGR1_CONT
CONT: Single / continuous conversion mode for regular conversions.
#define ADC_CFGR1_ALIGN
ALIGN: Data alignment.
Definition: g0/adc.h:122
#define ADC_CFGR1_AUTDLY
AUTDLY: Delayed conversion mode.
#define ADC_CFGR1_DMACFG
DMACFG: Direct memory access configuration.
#define ADC_CR_ADSTART
ADSTART: ADC start of regular conversion.
#define ADC_CR_ADEN
ADEN: ADC enable control.
#define ADC_CR_ADSTP
ADSTP: ADC stop of regular conversion command.
#define ADC_CR_ADCAL
ADCAL: ADC calibration.
#define ADC_CR_ADDIS
ADDIS: ADC disable command.
void adc_enable_delayed_conversion_mode(uint32_t adc)
Enable Delayed Conversion Mode.
void adc_start_conversion_regular(uint32_t adc)
ADC Software Triggered Conversion on Regular Channels.
void adc_disable_temperature_sensor(void)
Disable the temperature sensor (only)
void adc_disable_overrun_interrupt(uint32_t adc)
ADC Disable the Overrun Interrupt.
void adc_power_off(uint32_t adc)
Turn off the ADC This will actually block if it needs to turn off a currently running conversion,...
void adc_enable_vrefint(void)
Enable the internal voltage reference (only) The channel this is available on is unfortunately not co...
void adc_enable_dma_circular_mode(uint32_t adc)
Enable circular mode for DMA transfers.
void adc_calibrate_async(uint32_t adc)
Start the ADC calibration and immediately return.
void adc_disable_vrefint(void)
Disable the internal voltage reference (only)
void adc_set_continuous_conversion_mode(uint32_t adc)
Enable Continuous Conversion Mode In this mode the ADC starts a new conversion of a single channel or...
bool adc_is_calibrating(uint32_t adc)
Is the ADC Calibrating?
void adc_clear_overrun_flag(uint32_t adc)
ADC Clear Overrun Flags.
void adc_set_single_conversion_mode(uint32_t adc)
Enable Single Conversion Mode In this mode the ADC performs a conversion of one channel or a channel ...
bool adc_is_power_on(uint32_t adc)
Is the ADC powered up and ready?
Definition: adc_common_v2.c:84
void adc_power_on_async(uint32_t adc)
Turn on the ADC (async)
Definition: adc_common_v2.c:73
void adc_set_resolution(uint32_t adc, uint16_t resolution)
ADC Set Resolution.
void adc_power_on(uint32_t adc)
Turn on the ADC.
Definition: adc_common_v2.c:94
uint32_t adc_read_regular(uint32_t adc)
ADC Read from the Regular Conversion Result Register.
void adc_enable_eoc_interrupt(uint32_t adc)
ADC Enable Regular End-Of-Conversion Interrupt.
void adc_disable_eoc_interrupt(uint32_t adc)
ADC Disable Regular End-Of-Conversion Interrupt.
bool adc_eos(uint32_t adc)
ADC Read the End-of-Sequence Flag for Regular Conversions.
Definition: adc_common_v2.c:63
void adc_enable_temperature_sensor(void)
Enable the temperature sensor (only) The channel this is available on is unfortunately not consistent...
void adc_disable_dma(uint32_t adc)
ADC Disable DMA Transfers.
void adc_set_left_aligned(uint32_t adc)
ADC Set the Data as Left Aligned.
void adc_power_off_async(uint32_t adc)
Turn off the ADC (async) This will actually block if it needs to turn off a currently running convers...
void adc_set_right_aligned(uint32_t adc)
ADC Set the Data as Right Aligned.
void adc_disable_delayed_conversion_mode(uint32_t adc)
Enable Delayed Conversion Mode.
void adc_enable_overrun_interrupt(uint32_t adc)
ADC Enable the Overrun Interrupt.
void adc_enable_dma(uint32_t adc)
ADC Enable DMA Transfers.
void adc_disable_dma_circular_mode(uint32_t adc)
Disable circular mode for DMA transfers.
bool adc_get_overrun_flag(uint32_t adc)
ADC Read the Overrun Flag.
bool adc_is_power_off(uint32_t adc)
Is the ADC powered down?
void adc_calibrate(uint32_t adc)
Start ADC calibration and wait for it to finish.
bool adc_eoc(uint32_t adc)
ADC Read the End-of-Conversion Flag.
Definition: adc_common_v2.c:49
#define ADC_IER_OVRIE
OVRIE: Overrun interrupt enable.
Definition: adc_common_v2.h:92
#define ADC_IER_EOCIE
EOCIE: End of regular conversion interrupt enable.
Definition: adc_common_v2.h:97
#define ADC_ISR_ADRDY
ADRDY: Ready flag.
Definition: adc_common_v2.h:81
#define ADC_ISR_EOS
EOS: End of sequence conversions flag.
Definition: adc_common_v2.h:74
#define ADC_ISR_OVR
OVR: Overrun flag.
Definition: adc_common_v2.h:72
#define ADC_ISR_EOC
EOS: End of regular conversion flag.
Definition: adc_common_v2.h:77
#define ADC1
Definition: g0/adc.h:40
#define ADC_CR(adc)
Control Register.
Definition: adc_common_v2.h:46
#define ADC_ISR(adc)
ADC interrupt and status register.
Definition: adc_common_v2.h:42
#define ADC_CCR(adc)
Common Configuration register.
Definition: adc_common_v2.h:60
#define ADC_IER(adc)
Interrupt Enable Register.
Definition: adc_common_v2.h:44
#define ADC_DR(adc)
Regular Data Register.
Definition: adc_common_v2.h:56
#define ADC_CFGR1(adc)
Configuration Register 1.
Definition: adc_common_v2.h:48