Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

qm_adc.c
1 /*
2 * {% copyright %}
3 */
4
5 #include "qm_adc.h"
6 #include "clk.h"
7 #include <string.h>
8
9 /* FIFO_INTERRUPT_THRESHOLD is used by qm_adc_irq_convert to set the threshold
10 * at which the FIFO will trigger an interrupt. */
11 #define FIFO_INTERRUPT_THRESHOLD (16)
12
13 #define QM_ADC_CHAN_SEQ_MAX (32)
14
15 /* ADC commands. */
16 #define QM_ADC_CMD_START_SINGLE (0)
17 #define QM_ADC_CMD_START_CONT (1)
18 #define QM_ADC_CMD_RESET_CAL (2)
19 #define QM_ADC_CMD_START_CAL (3)
20 #define QM_ADC_CMD_LOAD_CAL (4)
21 #define QM_ADC_CMD_STOP_CONT (5)
22
23 static uint8_t sample_window[QM_ADC_NUM];
24 static qm_adc_resolution_t resolution[QM_ADC_NUM];
25
26 static qm_adc_xfer_t *irq_xfer[QM_ADC_NUM];
27 static uint32_t count[QM_ADC_NUM];
28 static bool dummy_conversion = false;
29
30 /* Callbacks for mode change and calibration. */
31 static void (*mode_callback[QM_ADC_NUM])(void *data, int error,
32 qm_adc_status_t status,
33 qm_adc_cb_source_t source);
34 static void (*cal_callback[QM_ADC_NUM])(void *data, int error,
35 qm_adc_status_t status,
36 qm_adc_cb_source_t source);
37 static void *mode_callback_data[QM_ADC_NUM];
38 static void *cal_callback_data[QM_ADC_NUM];
39
40 /* ISR handler for command/calibration complete. */
41 static void qm_adc_isr_handler(const qm_adc_t adc)
42 {
43 uint32_t int_status = 0;
44 uint32_t i, samples_to_read;
45
46 int_status = QM_ADC[adc].adc_intr_status;
47
48 /* FIFO overrun interrupt. */
49 if (int_status & QM_ADC_INTR_STATUS_FO) {
50 /* Stop the transfer. */
51 QM_ADC[adc].adc_cmd = QM_ADC_CMD_STOP_CONT;
52 /* Disable all interrupts. */
53 QM_ADC[adc].adc_intr_enable = 0;
54 /* Call the user callback. */
55 if (irq_xfer[adc]->callback) {
56 irq_xfer[adc]->callback(irq_xfer[adc]->callback_data,
57 -EIO, QM_ADC_OVERFLOW,
58 QM_ADC_TRANSFER);
59 }
60 }
61
62 /* Continuous mode command complete interrupt. */
63 if (int_status & QM_ADC_INTR_STATUS_CONT_CC) {
64 /* Clear the interrupt. */
65 QM_ADC[adc].adc_intr_status &= QM_ADC_INTR_STATUS_CONT_CC;
66
67 /* Calculate the number of samples to read. */
68 samples_to_read = QM_ADC[adc].adc_fifo_count;
69 if (samples_to_read >
70 (irq_xfer[adc]->samples_len - count[adc])) {
71 samples_to_read =
72 irq_xfer[adc]->samples_len - count[adc];
73 }
74
75 /* Copy data out of FIFO. The sample must be shifted right by
76 * 2, 4 or 6 bits for 10, 8 and 6 bit resolution respectively
77 * to get the correct value. */
78 for (i = 0; i < samples_to_read; i++) {
79 irq_xfer[adc]->samples[count[adc]] =
80 (QM_ADC[adc].adc_sample >>
81 (2 * (3 - resolution[adc])));
82 count[adc]++;
83 }
84
85 /* Check if we have the requested number of samples, stop the
86 * conversion and call the user callback function. */
87 if (count[adc] == irq_xfer[adc]->samples_len) {
88 /* Stop the transfer. */
89 QM_ADC[adc].adc_cmd = QM_ADC_CMD_STOP_CONT;
90 /* Disable all interrupts. */
91 QM_ADC[adc].adc_intr_enable = 0;
92 /* Call the user callback. */
93 if (irq_xfer[adc]->callback) {
94 irq_xfer[adc]->callback(
95 irq_xfer[adc]->callback_data, 0,
96 QM_ADC_COMPLETE, QM_ADC_TRANSFER);
97 }
98 }
99 }
100
101 /* The Command Complete interrupt is currently used to notify of the
102 * completion of a calibration command or a dummy conversion. */
103 if ((int_status & QM_ADC_INTR_STATUS_CC) && (!dummy_conversion)) {
104 /* Disable and clear the Command Complete interrupt */
105 QM_ADC[adc].adc_intr_enable &= ~QM_ADC_INTR_ENABLE_CC;
106 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
107
108 /* Call the user callback if it is set. */
109 if (cal_callback[adc]) {
110 cal_callback[adc](irq_xfer[adc]->callback_data, 0,
111 QM_ADC_IDLE, QM_ADC_CAL_COMPLETE);
112 }
113 }
114
115 /* This dummy conversion is needed when switching to normal mode or
116 * normal mode with calibration. */
117 if ((int_status & QM_ADC_INTR_STATUS_CC) && (dummy_conversion)) {
118 /* Flush the FIFO to get rid of the dummy values. */
119 QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;
120 /* Disable and clear the Command Complete interrupt. */
121 QM_ADC[adc].adc_intr_enable &= ~QM_ADC_INTR_ENABLE_CC;
122 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
123
124 dummy_conversion = false;
125
126 /* Call the user callback if it is set. */
127 if (mode_callback[adc]) {
128 mode_callback[adc](irq_xfer[adc]->callback_data, 0,
129 QM_ADC_IDLE, QM_ADC_MODE_CHANGED);
130 }
131 }
132 }
133
134 /* ISR handler for mode change. */
135 static void qm_adc_pwr_0_isr_handler(const qm_adc_t adc)
136 {
137 /* Clear the interrupt. Note that this operates differently to the
138 * QM_ADC_INTR_STATUS regiseter because you have to write to the
139 * QM_ADC_OP_MODE register, Interrupt Enable bit to clear. */
140 QM_ADC[adc].adc_op_mode &= ~QM_ADC_OP_MODE_IE;
141
142 /* Perform a dummy conversion if we are transitioning to Normal Mode or
143 * Normal Mode With Calibration */
144 if ((QM_ADC[adc].adc_op_mode & QM_ADC_OP_MODE_OM_MASK) >=
145 QM_ADC_MODE_NORM_CAL) {
146
147 /* Set the first sequence register back to its default (ch 0) */
148 QM_ADC[adc].adc_seq0 = QM_ADC_CAL_SEQ_TABLE_DEFAULT;
149 /* Clear the command complete interrupt status field */
150 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
151
152 dummy_conversion = true;
153
154 /* Run a dummy conversion */
155 QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_SINGLE);
156 } else {
157 /* Call the user callback function */
158 if (mode_callback[adc]) {
159 mode_callback[adc](irq_xfer[adc]->callback_data, 0,
160 QM_ADC_IDLE, QM_ADC_MODE_CHANGED);
161 }
162 }
163 }
164
165 /* ISR for ADC 0 Command/Calibration Complete. */
166 QM_ISR_DECLARE(qm_adc_0_cal_isr)
167 {
168 qm_adc_isr_handler(QM_ADC_0);
169
170 QM_ISR_EOI(QM_IRQ_ADC_0_CAL_INT_VECTOR);
171 }
172
173 /* ISR for ADC 0 Mode Change. */
174 QM_ISR_DECLARE(qm_adc_0_pwr_isr)
175 {
176 qm_adc_pwr_0_isr_handler(QM_ADC_0);
177
178 QM_ISR_EOI(QM_IRQ_ADC_0_PWR_0_VECTOR);
179 }
180
181 static void setup_seq_table(const qm_adc_t adc, qm_adc_xfer_t *xfer)
182 {
183 uint32_t i, offset = 0;
184 volatile uint32_t *reg_pointer = NULL;
185
186 /* Loop over all of the channels to be added. */
187 for (i = 0; i < xfer->ch_len; i++) {
188 /* Get a pointer to the correct address. */
189 reg_pointer = &QM_ADC[adc].adc_seq0 + (i / 4);
190 /* Get the offset within the register */
191 offset = ((i % 4) * 8);
192 /* Clear the Last bit from all entries we will use. */
193 *reg_pointer &= ~(1 << (offset + 7));
194 /* Place the channel numnber into the sequence table. */
195 *reg_pointer |= (xfer->ch[i] << offset);
196 }
197
198 if (reg_pointer) {
199 /* Set the correct Last bit. */
200 *reg_pointer |= (1 << (offset + 7));
201 }
202 }
203
204 int qm_adc_calibrate(const qm_adc_t adc)
205 {
206 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
207
208 /* Clear the command complete interrupt status field. */
209 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
210 /* Start the calibration and wait for it to complete. */
211 QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_CAL);
212 while (!(QM_ADC[adc].adc_intr_status & QM_ADC_INTR_STATUS_CC))
213 ;
214 /* Clear the command complete interrupt status field again. */
215 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
216
217 return 0;
218 }
219
220 int qm_adc_irq_calibrate(const qm_adc_t adc,
221 void (*callback)(void *data, int error,
222 qm_adc_status_t status,
223 qm_adc_cb_source_t source),
224 void *callback_data)
225 {
226 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
227
228 /* Set the callback. */
229 cal_callback[adc] = callback;
230 cal_callback_data[adc] = callback_data;
231
232 /* Clear and enable the command complete interrupt. */
233 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
234 QM_ADC[adc].adc_intr_enable |= QM_ADC_INTR_ENABLE_CC;
235
236 /* Start the calibration */
237 QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_CAL);
238
239 return 0;
240 }
241
242 int qm_adc_set_calibration(const qm_adc_t adc, const qm_adc_calibration_t cal)
243 {
244 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
245 QM_CHECK(cal < 0x3F, -EINVAL);
246
247 /* Clear the command complete interrupt status field. */
248 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
249
250 /* Set the calibration data and wait for it to complete. */
251 QM_ADC[adc].adc_cmd = ((cal << QM_ADC_CMD_CAL_DATA_OFFSET) |
252 QM_ADC_CMD_IE | QM_ADC_CMD_LOAD_CAL);
253 while (!(QM_ADC[adc].adc_intr_status & QM_ADC_INTR_STATUS_CC))
254 ;
255 /* Clear the command complete interrupt status field again. */
256 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
257
258 return 0;
259 }
260
261 int qm_adc_get_calibration(const qm_adc_t adc, qm_adc_calibration_t *const cal)
262 {
263 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
264 QM_CHECK(NULL != cal, -EINVAL);
265
266 *cal = QM_ADC[adc].adc_calibration;
267
268 return 0;
269 }
270
271 int qm_adc_set_mode(const qm_adc_t adc, const qm_adc_mode_t mode)
272 {
273 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
274 QM_CHECK(mode <= QM_ADC_MODE_NORM_NO_CAL, -EINVAL);
275
276 /* Issue mode change command and wait for it to complete. */
277 QM_ADC[adc].adc_op_mode = mode;
278 while ((QM_ADC[adc].adc_op_mode & QM_ADC_OP_MODE_OM_MASK) != mode)
279 ;
280
281 /* Perform a dummy conversion if we are transitioning to Normal Mode. */
282 if ((mode >= QM_ADC_MODE_NORM_CAL)) {
283 /* Set the first sequence register back to its default. */
284 QM_ADC[adc].adc_seq0 = QM_ADC_CAL_SEQ_TABLE_DEFAULT;
285
286 /* Clear the command complete interrupt status field. */
287 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
288 /* Run a dummy convert and wait for it to complete. */
289 QM_ADC[adc].adc_cmd = (QM_ADC_CMD_IE | QM_ADC_CMD_START_SINGLE);
290 while (!(QM_ADC[adc].adc_intr_status & QM_ADC_INTR_STATUS_CC))
291 ;
292
293 /* Flush the FIFO to get rid of the dummy values. */
294 QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;
295 /* Clear the command complete interrupt status field. */
296 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC;
297 }
298
299 return 0;
300 }
301
302 int qm_adc_irq_set_mode(const qm_adc_t adc, const qm_adc_mode_t mode,
303 void (*callback)(void *data, int error,
304 qm_adc_status_t status,
305 qm_adc_cb_source_t source),
306 void *callback_data)
307 {
308 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
309 QM_CHECK(mode <= QM_ADC_MODE_NORM_NO_CAL, -EINVAL);
310
311 /* Set the callback. */
312 mode_callback[adc] = callback;
313 mode_callback_data[adc] = callback_data;
314
315 /* When transitioning to Normal Mode or Normal Mode With Calibration,
316 * enable command complete interrupt to perform a dummy conversion. */
317 if ((mode >= QM_ADC_MODE_NORM_CAL)) {
318 QM_ADC[adc].adc_intr_enable |= QM_ADC_INTR_ENABLE_CC;
319 }
320
321 /* Issue mode change command. Completion if this command is notified via
322 * the ADC Power interrupt source, which is serviced separately to the
323 * Command/Calibration Complete interrupt. */
324 QM_ADC[adc].adc_op_mode = (QM_ADC_OP_MODE_IE | mode);
325
326 return 0;
327 }
328
329 int qm_adc_set_config(const qm_adc_t adc, const qm_adc_config_t *const cfg)
330 {
331 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
332 QM_CHECK(NULL != cfg, -EINVAL);
333 QM_CHECK(cfg->resolution <= QM_ADC_RES_12_BITS, -EINVAL);
334 /* Convert cfg->resolution to actual resolution (2x+6) and add 2 to get
335 * minimum value for window size. */
336 QM_CHECK(cfg->window >= ((cfg->resolution * 2) + 8), -EINVAL);
337
338 /* Set the sample window and resolution. */
339 sample_window[adc] = cfg->window;
340 resolution[adc] = cfg->resolution;
341
342 return 0;
343 }
344
345 int qm_adc_convert(const qm_adc_t adc, qm_adc_xfer_t *xfer,
346 qm_adc_status_t *const status)
347 {
348 uint32_t i;
349
350 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
351 QM_CHECK(NULL != xfer, -EINVAL);
352 QM_CHECK(NULL != xfer->ch, -EINVAL);
353 QM_CHECK(NULL != xfer->samples, -EINVAL);
354 QM_CHECK(xfer->ch_len > 0, -EINVAL);
355 QM_CHECK(xfer->ch_len <= QM_ADC_CHAN_SEQ_MAX, -EINVAL);
356 QM_CHECK(xfer->samples_len > 0, -EINVAL);
357 QM_CHECK(xfer->samples_len <= QM_ADC_FIFO_LEN, -EINVAL);
358
359 /* Flush the FIFO. */
360 QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;
361
362 /* Populate the sample sequence table. */
363 setup_seq_table(adc, xfer);
364
365 /* Issue cmd: window & resolution, number of samples, command. */
366 QM_ADC[adc].adc_cmd =
367 (sample_window[adc] << QM_ADC_CMD_SW_OFFSET |
368 resolution[adc] << QM_ADC_CMD_RESOLUTION_OFFSET |
369 ((xfer->samples_len - 1) << QM_ADC_CMD_NS_OFFSET) |
370 QM_ADC_CMD_START_SINGLE);
371
372 /* Wait for fifo count to reach number of samples. */
373 while (QM_ADC[adc].adc_fifo_count != xfer->samples_len)
374 ;
375
376 if (status) {
377 *status = QM_ADC_COMPLETE;
378 }
379
380 /* Read the value into the data structure. The sample must be shifted
381 * right by 2, 4 or 6 bits for 10, 8 and 6 bit resolution respectively
382 * to get the correct value. */
383 for (i = 0; i < xfer->samples_len; i++) {
384 xfer->samples[i] =
385 (QM_ADC[adc].adc_sample >> (2 * (3 - resolution[adc])));
386 }
387
388 return 0;
389 }
390
391 int qm_adc_irq_convert(const qm_adc_t adc, qm_adc_xfer_t *xfer)
392 {
393 QM_CHECK(adc < QM_ADC_NUM, -EINVAL);
394 QM_CHECK(NULL != xfer, -EINVAL);
395 QM_CHECK(NULL != xfer->ch, -EINVAL);
396 QM_CHECK(NULL != xfer->samples, -EINVAL);
397 QM_CHECK(xfer->ch_len > 0, -EINVAL);
398 QM_CHECK(xfer->ch_len <= QM_ADC_CHAN_SEQ_MAX, -EINVAL);
399 QM_CHECK(xfer->samples_len > 0, -EINVAL);
400
401 /* Reset the count and flush the FIFO. */
402 count[adc] = 0;
403 QM_ADC[adc].adc_sample = QM_ADC_FIFO_CLEAR;
404
405 /* Populate the sample sequence table. */
406 setup_seq_table(adc, xfer);
407
408 /* Copy the xfer struct so we can get access from the ISR. */
409 irq_xfer[adc] = xfer;
410
411 /* Clear all pending interrupts. */
412 QM_ADC[adc].adc_intr_status = QM_ADC_INTR_STATUS_CC |
413 QM_ADC_INTR_STATUS_FO |
414 QM_ADC_INTR_STATUS_CONT_CC;
415 /* Enable the continuous command and fifo overrun interupts. */
416 QM_ADC[adc].adc_intr_enable =
417 QM_ADC_INTR_ENABLE_FO | QM_ADC_INTR_ENABLE_CONT_CC;
418
419 /* Issue cmd: window & resolution, number of samples, interrupt enable
420 * and start continuous coversion command. If xfer->samples_len is less
421 * than FIFO_INTERRUPT_THRESHOLD extra samples will be discarded in the
422 * ISR. */
423 QM_ADC[adc].adc_cmd =
424 (sample_window[adc] << QM_ADC_CMD_SW_OFFSET |
425 resolution[adc] << QM_ADC_CMD_RESOLUTION_OFFSET |
426 ((FIFO_INTERRUPT_THRESHOLD - 1) << QM_ADC_CMD_NS_OFFSET) |
427 QM_ADC_CMD_IE | QM_ADC_CMD_START_CONT);
428
429 return 0;
430 }
qm_adc_xfer_t::callback
void(* callback)(void *data, int error, qm_adc_status_t status, qm_adc_cb_source_t source)
Transfer callback.
Definition: qm_adc.h:124
qm_adc_mode_t
qm_adc_mode_t
ADC operating mode type.
Definition: qm_adc.h:49
qm_adc_xfer_t::ch
qm_adc_channel_t * ch
Channel sequence array (1-32 channels).
Definition: qm_adc.h:108
QM_ADC_COMPLETE
ADC transfer complete.
Definition: qm_adc.h:32
qm_adc_config_t::resolution
qm_adc_resolution_t resolution
12, 10, 8, 6-bit resolution.
Definition: qm_adc.h:101
qm_adc_xfer_t
ADC transfer type.
Definition: qm_adc.h:107
qm_adc_irq_set_mode
int qm_adc_irq_set_mode(const qm_adc_t adc, const qm_adc_mode_t mode, void(*callback)(void *data, int error, qm_adc_status_t status, qm_adc_cb_source_t source), void *callback_data)
Switch operating mode of ADC.
Definition: qm_adc.c:302
qm_adc_irq_calibrate
int qm_adc_irq_calibrate(const qm_adc_t adc, void(*callback)(void *data, int error, qm_adc_status_t status, qm_adc_cb_source_t source), void *callback_data)
Calibrate the ADC.
Definition: qm_adc.c:220
qm_adc_get_calibration
int qm_adc_get_calibration(const qm_adc_t adc, qm_adc_calibration_t *const cal)
Get the current calibration data for an ADC.
Definition: qm_adc.c:261
qm_adc_t
qm_adc_t
Number of ADC controllers.
Definition: qm_soc_regs.h:1066
qm_adc_status_t
qm_adc_status_t
Definition: qm_adc.h:30
QM_ADC_CAL_COMPLETE
Calibration complete callback.
Definition: qm_adc.h:88
QM_ADC_MODE_CHANGED
Mode change complete callback.
Definition: qm_adc.h:87
qm_adc_cb_source_t
qm_adc_cb_source_t
ADC interrupt callback source.
Definition: qm_adc.h:85
qm_adc_xfer_t::ch_len
uint8_t ch_len
Number of channels in the above array.
Definition: qm_adc.h:109
qm_adc_xfer_t::samples_len
uint32_t samples_len
Length of sample array.
Definition: qm_adc.h:111
qm_adc_xfer_t::callback_data
void * callback_data
Callback user data.
Definition: qm_adc.h:126
qm_adc_irq_convert
int qm_adc_irq_convert(const qm_adc_t adc, qm_adc_xfer_t *xfer)
Asynchronously read values from the ADC.
Definition: qm_adc.c:391
qm_adc_convert
int qm_adc_convert(const qm_adc_t adc, qm_adc_xfer_t *xfer, qm_adc_status_t *const status)
Synchronously read values from the ADC.
Definition: qm_adc.c:345
QM_ADC_TRANSFER
Transfer complete or error callback.
Definition: qm_adc.h:86
qm_adc_config_t
ADC configuration type.
Definition: qm_adc.h:94
qm_adc_set_config
int qm_adc_set_config(const qm_adc_t adc, const qm_adc_config_t *const cfg)
Set ADC configuration.
Definition: qm_adc.c:329
qm_adc_xfer_t::samples
qm_adc_sample_t * samples
Array to store samples.
Definition: qm_adc.h:110
qm_adc_calibrate
int qm_adc_calibrate(const qm_adc_t adc)
Calibrate the ADC.
Definition: qm_adc.c:204
qm_adc_set_mode
int qm_adc_set_mode(const qm_adc_t adc, const qm_adc_mode_t mode)
Switch operating mode of ADC.
Definition: qm_adc.c:271
QM_ADC_IDLE
ADC idle.
Definition: qm_adc.h:31
QM_ADC_OVERFLOW
ADC FIFO overflow error.
Definition: qm_adc.h:33
qm_adc_calibration_t
uint8_t qm_adc_calibration_t
ADC calibration type.
Definition: qm_adc.h:28
QM_ISR_DECLARE
QM_ISR_DECLARE(qm_adc_0_cal_isr)
ISR for ADC 0 convert and calibration interrupt.
Definition: qm_adc.c:166
qm_adc_set_calibration
int qm_adc_set_calibration(const qm_adc_t adc, const qm_adc_calibration_t cal)
Set ADC calibration data.
Definition: qm_adc.c:242
QM_ADC_RES_12_BITS
12-bit mode.
Definition: qm_adc.h:43
qm_adc_resolution_t
qm_adc_resolution_t
ADC resolution type.
Definition: qm_adc.h:39
qm_adc_config_t::window
uint8_t window
Sample interval in ADC clock cycles, defines the period to wait between the start of each sample and ...
Definition: qm_adc.h:100
QM_ADC_MODE_NORM_CAL
Normal mode, with calibration.
Definition: qm_adc.h:53
QM_ADC_MODE_NORM_NO_CAL
Normal mode, no calibration.
Definition: qm_adc.h:54