ADC 1.0

- Main Page
- Related Pages
- Classes
- Files

- File List
- File Members

All Classes Files Functions Variables Macros Pages
ADC.cpp
Go to the documentation of this file.
1 /* ADC Library created by Pedro Villanueva
2 * It implements all functions of the Teensy 3.0 internal ADC
3 * Some of the code was extracted from the file analog.c included in the distribution of Teensduino by PJRC.COM
4 *
5 */
6
7
8 /* TODO
9 * Stuff related to the conversion speed and power. Useful if you want more speed or to save power.
10 * Function to measure more that 1 pin consecutively
11 *
12 * bugs:
13 * - analog timer at 16 bits resolution goes from 0 to +1.65 and then jumps to -1.65 to 0
14 * - comparison values don't work in 16 bit differential mode (they are twice what you write)
15 */
16
17
18 #include "ADC.h"
19
20
21 // ADC interrupt function calls a function to add values in the ring buffer
22 // if there is at least one analog timer, if not, it does nothing.
23 // implemented as weak so that an user can redefine it
24 void __attribute__((weak)) adc0_isr(void) {
25 ADC::analogTimer_ADC_Callback();
26 }
27
28
29 // static vars need to be restated here
30 uint8_t ADC::calibrating;
31 uint8_t ADC::var_enableInterrupts;
32 uint8_t ADC::analog_config_bits;
33 uint32_t ADC::analog_max_val;
34 uint8_t ADC::analog_num_average;
35 uint8_t ADC::analog_reference_internal;
36
37 const uint8_t ADC::ledPin = 13;
38
39 ADC::ADC_Config ADC::adc_config; // store the adc config
40 uint8_t ADC::adcWasInUse; // was the adc in use before an analog timer call?
41
42 const uint8_t ADC::channel2sc1a[]= {
43 5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
44 0, 19, 3, 21, 26, 22};
45 const uint8_t ADC::sc1a2channel[]= { // new version, gives directly the pin number
46 34, 0, 0, 36, 23, 14, 20, 21, 16, 17, 0, 0, 19, 18, // 0-13
47 15, 22, 0, 0, 0, 35, 0, 37, 39, 0, 0, 0, 38}; // 14-26
48
49 // struct with the analog timers
50 ADC::AnalogTimer *ADC::analogTimer[];
51
52 // pointer to isr adc
53 void (*ADC::analogTimer_ADC_Callback)(void);
54
55 // the functions for the analog timers
56 ADC::ISR ADC::analogTimerCallback[] = {
57 ADC::analogTimerCallback0,
58 ADC::analogTimerCallback1,
59 ADC::analogTimerCallback2
60 };
61
62
63 /* Constructor
64 *
65 */
66 ADC::ADC() {
67 // default settings: 10 bits resolution (in analog_init), 4 averages, vcc reference, no interrupts and single-ended
68 analog_config_bits = 0;
69 analog_max_val = 1024;
70 analog_num_average = 4;
71 analog_reference_internal = 0;
72 var_enableInterrupts = 0;
73
74 // itinialize analog timers
75 int i = 0;
76 for(i=0; i<MAX_ANALOG_TIMERS; i++) {
77 analogTimer[i] = new AnalogTimer;
78 //analogTimer[i]->pinNumber = -1;
79 }
80 //*analogTimer = new AnalogTimer[MAX_ANALOG_TIMERS]; // doesn't work for some reason
81
82 // call our init
83 ADC::analog_init();
84
85 // point ADC callback to function that does nothing
86 // when the analogTimers are in use, this will point to the correct ADC_callback
87 analogTimer_ADC_Callback = &voidFunction;
88 }
89
90 /* Destructor
91 *
92 */
93 ADC::~ADC() {
94 //dtor
95 int i = 0;
96 for(i=0; i<MAX_ANALOG_TIMERS; i++) {
97 delete analogTimer[i];
98 }
99
100 }
101
102 /* Sets up all initial configurations and starts calibration
103 *
104 */
105 void ADC::analog_init(uint32_t config)
106 {
107
108 VREF_TRM = 0x60;
109 VREF_SC = 0xE1; // enable 1.2 volt ref
110
111 if (analog_reference_internal) {
112 ADC0_SC2 |= ADC_SC2_REFSEL(1); // 1.2V ref
113 } else {
114 ADC0_SC2 |= ADC_SC2_REFSEL(0); // vcc/ext ref
115 }
116
117 // set resolution
118 setResolution(10);
119
120 // number of averages
121 setAveraging(analog_num_average);
122
123 // begin calibration
124 calibrate();
125 }
126
127
128 void ADC::calibrate() {
129 ADC0_SC3 |= ADC_SC3_CAL;
130
131 // calibration works best when averages are 32 and speed is less than 4 MHz
132 calibrating = 1;
133 }
134
135
136 /* Waits until calibration is finished and writes the corresponding registers
137 *
138 */
139 void ADC::wait_for_cal(void)
140 {
141 uint16_t sum;
142
143 while (ADC0_SC3 & ADC_SC3_CAL) { // Bit ADC_SC3_CAL in register ADC0_SC3 cleared when calib. finishes.
144 // wait
145 //serial_print(".");
146 }
147
148 __disable_irq();
149 if (calibrating) {
150 //serial_print("\n");
151 sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
152 sum = (sum / 2) | 0x8000;
153 ADC0_PG = sum;
154 //serial_print("ADC0_PG = ");
155 //serial_phex16(sum);
156 //serial_print("\n");
157 sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
158 sum = (sum / 2) | 0x8000;
159 ADC0_MG = sum;
160 //serial_print("ADC0_MG = ");
161 //serial_phex16(sum);
162 //serial_print("\n");
163 calibrating = 0;
164 }
165 __enable_irq();
166 }
167
168
169
170 /* Set the voltage reference you prefer, default is vcc
171 * It needs to recalibrate
172 */
173 void ADC::setReference(uint8_t type)
174 {
175 if (type) {
176 // internal reference requested
177 if (!analog_reference_internal) {
178 analog_reference_internal = 1;
179 if (calibrating) ADC0_SC3 = 0; // cancel cal
180 calibrate();
181 }
182 } else {
183 // vcc or external reference requested
184 if (analog_reference_internal) {
185 analog_reference_internal = 0;
186 if (calibrating) ADC0_SC3 = 0; // cancel cal
187 calibrate();
188 }
189 }
190 }
191
192
193 /* Change the resolution of the measurement
194 * For single-ended measurements: 8, 10, 12 or 16 bits.
195 * For differential measurements: 9, 11, 13 or 16 bits.
196 * If you want something in between (11 bits single-ended for example) select the inmediate higher
197 * and shift the result one to the right.
198 */
199 void ADC::setResolution(uint8_t bits)
200 {
201 uint8_t config;
202
203 if (bits <8) {
204 config = 8;
205 } else if (bits > 16) {
206 config = 16;
207 } else {
208 config = bits;
209 }
210
211 // if the new res is the "same" as the old, update analog_config_bits, but do nothing else
212 if( (config==8 && analog_config_bits==9) || (config==9 && analog_config_bits==8)
213 || (config==10 && analog_config_bits==11) || (config==11 && analog_config_bits==10)
214 || (config==12 && analog_config_bits==13) || (config==13 && analog_config_bits==12) ) {
215 analog_config_bits = config;
216 } else if (config != analog_config_bits) { // change res
217 analog_config_bits = config;
218
219 // conversion resolution and frequency
220 if ( (analog_config_bits == 8) || (analog_config_bits == 9) ) {
221 ADC0_CFG1 = ADC0_CFG1_24MHZ + ADC_CFG1_MODE(0); // 0 clock divide + Input clock: 24 MHz (run at 24 MHz) + Conversion mode: 8 bit + Sample time: Short
222 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); // b channels + Sample time 2 cycles (I think that if ADC_CFG1_ADLSMP isn't set, then ADC_CFG2_ADLSTS doesn't matter)
223 analog_max_val = 256; // diff mode 9 bits has 1 bit for sign, so max value is the same as single 8 bits
224 } else if ( (analog_config_bits == 10 )|| (analog_config_bits == 11) ) { // total clock cycles to complete conversion: 3 ADCK + 5 BUS + 4 averages*( 20 + 2 ADCK ) = 7.8 us
225 ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP; // Clock divide: 1/2 + Input clock: 24 MHz (run at 12 MHz) + Conversion mode: 10 bit + Sample time: Long
226 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3); // b channels + Sample time 2 extra clock cycles
227 analog_max_val = 1024;
228 } else if ( (analog_config_bits == 12 )|| (analog_config_bits == 13) ) {
229 ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP; // Clock divide: 1/2 + Input clock: 24 MHz (run at 12 MHz) + Conversion mode: 12 bit + Sample time: Long
230 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); // b channels + Sample time: 6 extra clock cycles
231 analog_max_val = 4096;
232 } else {
233 ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP; //Clock divide: 1/2 + Input clock: 24 MHz (run at 12 MHz) + Conversion mode: 16 bit + Sample time: Long
234 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2); // b channels + Sample time: 6 extra clock cycles
235 analog_max_val = 65536;
236 }
237
238 // no recalibration is needed when changing the resolution, p. 619
239 // but it's needed if we change the frequency...
240 if (calibrating) ADC0_SC3 = 0; // cancel cal
241 calibrate(); // re-cal
242 } // end if change res
243 }
244
245 /* Returns the resolution of the ADC
246 *
247 */
248 uint8_t ADC::getResolution() {
249 return analog_config_bits;
250 }
251
252 /* Returns the maximum value for a measurement, that is 2^resolution
253 *
254 */
255 uint32_t ADC::getMaxValue() {
256 return analog_max_val;
257 }
258
259
260 /* Set the number of averages: 0, 4, 8, 16 or 32.
261 *
262 */
263 void ADC::setAveraging(uint8_t num)
264 {
265
266 if (calibrating) wait_for_cal();
267 if (num <= 1) {
268 num = 0;
269 ADC0_SC3 &= !ADC_SC3_AVGE;
270 } else if (num <= 4) {
271 num = 4;
272 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(0);
273 } else if (num <= 8) {
274 num = 8;
275 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(1);
276 } else if (num <= 16) {
277 num = 16;
278 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(2);
279 } else {
280 num = 32;
281 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(3);
282 }
283 analog_num_average = num;
284 }
285
286
287 /* Enable interrupts: An ADC Interrupt will be raised when the conversion is completed
288 * (including hardware averages and if the comparison (if any) is true).
289 */
290 void ADC::enableInterrupts() {
291 var_enableInterrupts = 1;
292 NVIC_ENABLE_IRQ(IRQ_ADC0);
293 }
294
295 /* Disable interrupts
296 *
297 */
298 void ADC::disableInterrupts() {
299 var_enableInterrupts = 0;
300 NVIC_DISABLE_IRQ(IRQ_ADC0);
301 }
302
303
304 /* Enable DMA request: An ADC DMA request will be raised when the conversion is completed
305 * (including hardware averages and if the comparison (if any) is true).
306 */
307 void ADC::enableDMA() {
308 ADC0_SC2 |= ADC_SC2_DMAEN;
309 }
310
311 /* Disable ADC DMA request
312 *
313 */
314 void ADC::disableDMA() {
315 ADC0_SC2 &= !ADC_SC2_DMAEN;
316 }
317
318
319 /* Enable the compare function: A conversion will be completed only when the ADC value
320 * is >= compValue (greaterThan=1) or < compValue (greaterThan=0)
321 * Call it after changing the resolution
322 * Use with interrupts or poll conversion completion with isADC_Complete()
323 */
324 void ADC::enableCompare(int16_t compValue, int greaterThan) {
325 ADC0_SC2 |= ADC_SC2_ACFE | greaterThan*ADC_SC2_ACFGT;
326 ADC0_CV1 = compValue;
327 }
328
329 /* Enable the compare function: A conversion will be completed only when the ADC value
330 * is inside (insideRange=1) or outside (=0) the range given by (lowerLimit, upperLimit),
331 * including (inclusive=1) the limits or not (inclusive=0).
332 * See Table 31-78, p. 617 of the freescale manual.
333 * Call it after changing the resolution
334 * Use with interrupts or poll conversion completion with isComplete()
335 */
336 void ADC::enableCompareRange(int16_t lowerLimit, int16_t upperLimit, int insideRange, int inclusive) {
337
338 if(insideRange && inclusive) { // True if value is inside the range, including the limits. CV1 <= CV2 and ACFGT=1
339 ADC0_CV1 = lowerLimit;
340 ADC0_CV2 = upperLimit;
341 ADC0_SC2 |= ADC_SC2_ACFE | ADC_SC2_ACFGT | ADC_SC2_ACREN;
342 } else if(insideRange && !inclusive) {// True if value is inside the range, excluding the limits. CV1 > CV2 and ACFGT=0
343 ADC0_CV2 = lowerLimit;
344 ADC0_CV1 = upperLimit;
345 ADC0_SC2 |= ADC_SC2_ACFE | ADC_SC2_ACREN;
346 } else if(!insideRange && inclusive) { // True if value is outside of range or is equal to either limit. CV1 > CV2 and ACFGT=1
347 ADC0_CV2 = lowerLimit;
348 ADC0_CV1 = upperLimit;
349 ADC0_SC2 |= ADC_SC2_ACFE | ADC_SC2_ACFGT | ADC_SC2_ACREN;
350 } else if(!insideRange && !inclusive) { // True if value is outside of range and not equal to either limit. CV1 > CV2 and ACFGT=0
351 ADC0_CV1 = lowerLimit;
352 ADC0_CV2 = upperLimit;
353 ADC0_SC2 |= ADC_SC2_ACFE | ADC_SC2_ACREN;
354 }
355 }
356
357 /* Disable the compare function
358 *
359 */
360 void ADC::disableCompare() {
361 ADC0_SC2 &= !ADC_SC2_ACFE;
362 }
363
364
365 /* Reads the analog value of the pin.
366 * It waits until the value is read and then returns the result.
367 * If a comparison has been set up and fails, it will return ADC_ERROR_VALUE.
368 * Set the resolution, number of averages and voltage reference using the appropriate functions.
369 */
370 int ADC::analogRead(uint8_t pin)
371 {
372 uint16_t result;
373
374 if (pin >= 14 && pin <= 39) {
375 if (pin <= 23) {
376 pin -= 14; // 14-23 are A0-A9
377 } else if (pin >= 34) {
378 pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
379 }
380 } else {
381 return ADC_ERROR_VALUE; // all others are invalid
382 }
383
384 if (calibrating) wait_for_cal();
385
386 uint8_t res = getResolution();
387 uint8_t diffRes = 0; // is the new resolution different from the old one?
388
389 // vars to save the current state of the ADC in case it's in use
390 uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2, savedRes;
391 uint8_t wasADCInUse = isConverting(); // is the ADC running now?
392
393 if(wasADCInUse) { // this means we're interrupting a conversion
394 // save the current conversion config, we don't want any other interrupts messing up the configs
395 __disable_irq();
396 //GPIOC_PSOR = 1<<5;
397 savedRes = res;
398 savedSC1A = ADC0_SC1A;
399 savedCFG1 = ADC0_CFG1;
400 savedSC2 = ADC0_SC2;
401 savedSC3 = ADC0_SC3;
402
403 // change the comparison values if interrupting a 16 bits and diff mode
404 if(res==16 && isDifferential()) {
405 ADC0_CV1 /= 2;
406 ADC0_CV2 /= 2;
407 }
408
409 // disable continuous mode in case analogRead is interrupting a continuous mode
410 ADC0_SC3 &= !ADC_SC3_ADCO;
411
412 __enable_irq();
413
414 }
415
416
417 // if the resolution is incorrect (i.e. 9, 11 or 13) silently correct it
418 if( (res==9) || (res==11) || (res==13) ) {
419 setResolution(res-1);
420 diffRes = 1; // resolution changed
421 }
422
423 __disable_irq();
424 ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN; // start conversion on pin and with interrupts enabled if requested
425 __enable_irq();
426
427
428 while (1) {
429 __disable_irq();
430 if ((ADC0_SC1A & ADC_SC1_COCO)) { // conversion completed
431 result = ADC0_RA;
432
433 // if we interrupted a conversion, set it again
434 if (wasADCInUse) {
435 //GPIOC_PCOR = 1<<5;
436
437 // restore ADC config, and restart conversion
438 if(diffRes) setResolution(savedRes); // don't change res if isn't necessary
439 if(res==16 && ((savedSC1A & ADC_SC1_DIFF) >> 5) ) { // change back the comparison values if interrupting a 16 bits and diff mode
440 ADC0_CV1 *= 2;
441 ADC0_CV2 *= 2;
442 }
443 ADC0_CFG1 = savedCFG1;
444 ADC0_SC2 = savedSC2 & 0x7F; // restore first 8 bits
445 ADC0_SC3 = savedSC3 & 0xF; // restore first 4 bits
446 ADC0_SC1A = savedSC1A & 0x7F; // restore first 8 bits
447 }
448 __enable_irq();
449 return result;
450 } else if( ((ADC0_SC2 & ADC_SC2_ADACT) == 0) && ((ADC0_SC1A & ADC_SC1_COCO) == 0) ) { // comparison was false
451 // we needed to check that ADACT wasn't 0 because COCO just turned 1.
452
453 // if we interrupted a conversion, set it again
454 if (wasADCInUse) {
455 //GPIOC_PCOR = 1<<5;
456
457 // restore ADC config, and restart conversion
458 if(diffRes) setResolution(savedRes); // don't change res if isn't necessary
459 if(res==16 && ((savedSC1A & ADC_SC1_DIFF) >> 5) ) { // change back the comparison values if interrupting a 16 bits and diff mode
460 ADC0_CV1 *= 2;
461 ADC0_CV2 *= 2;
462 }
463 ADC0_CFG1 = savedCFG1;
464 ADC0_SC2 = savedSC2 & 0x7F; // restore first 8 bits
465 ADC0_SC3 = savedSC3 & 0xF; // restore first 4 bits
466 ADC0_SC1A = savedSC1A & 0x7F; // restore first 8 bits
467 }
468
469 // comparison was false, we return an error value to indicate this
470 __enable_irq();
471 return ADC_ERROR_VALUE;
472 } // end if comparison false
473
474 __enable_irq();
475 yield();
476 } // end while
477
478 } // analogRead
479
480
481
482 /* Reads the differential analog value of two pins (pinP - pinN)
483 * It waits until the value is read and then returns the result
484 * If a comparison has been set up and fails, it will return -70000
485 * Set the resolution, number of averages and voltage reference using the appropriate functions
486 */
487 int ADC::analogReadDifferential(uint8_t pinP, uint8_t pinN)
488 {
489 int16_t result;
490
491 // check for calibration before setting channels,
492 // because conversion will start as soon as we write to ADC0_SC1A
493 if (calibrating) wait_for_cal();
494
495 uint8_t res = getResolution();
496 uint8_t diffRes = 0; // is the new resolution different from the old one?
497
498 // vars to saved the current state of the ADC in case it's in use
499 uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2, savedRes;
500 uint8_t adcWasInUse = isConverting(); // is the ADC running now?
501
502 if(adcWasInUse) { // this means we're interrupting a conversion
503 // save the current conversion config, we don't want any other interrupts messing up the configs
504 __disable_irq();
505 //GPIOC_PSOR = 1<<5;
506 savedRes = res;
507 savedSC1A = ADC0_SC1A;// & 0x7F; // get first 7 bits
508 savedCFG1 = ADC0_CFG1;
509 savedCFG2 = ADC0_CFG2;
510 savedSC2 = ADC0_SC2;// & 0x7F; // get first 7 bits
511 savedSC3 = ADC0_SC3;// & 0xF; // get first 4 bits
512
513 // disable continuous mode in case analogReadDifferential is interrupting a continuous mode
514 ADC0_SC3 &= !ADC_SC3_ADCO;
515 __enable_irq();
516
517 }
518
519 // if the resolution is incorrect (i.e. 8, 10 or 12) silently correct it
520 if( (res==8) || (res==10) || (res==12) ) {
521 setResolution(res+1);
522 diffRes = 1; // resolution changed
523 } else if(res==16) {
524 ADC0_CV1 /= 2; // correct also compare function in case it was enabled
525 ADC0_CV2 /= 2;
526 }
527
528
529 // once ADC0_SC1A is set, conversion will start, enable interrupts if requested
530 if ( (pinP == A10) && (pinN == A11) ) { // DAD0 selected, pins 34 and 35
531 __disable_irq();
532 ADC0_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN;
533 __enable_irq();
534 } else if ( (pinP == A12) && (pinN == A13) ) { // DAD3 selected, pins 36 and 37
535 __disable_irq();
536 ADC0_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN;
537 __enable_irq();
538 } else {
539 __enable_irq(); // just in case we disabled them in the if above.
540 return ADC_ERROR_DIFF_VALUE; // all others aren't capable of differential measurements, perhaps return analogRead(pinP)-analogRead(pinN)?
541 }
542
543 while (1) {
544 __disable_irq();
545 if ((ADC0_SC1A & ADC_SC1_COCO)) { // conversion completed
546 result = ADC0_RA;
547
548 // if we interrupted a conversion, set it again
549 if (adcWasInUse) {
550 //GPIOC_PTOR = 1<<5;
551
552 // restore ADC config, and restart conversion
553 if(diffRes) setResolution(savedRes); // don't change res if isn't necessary
554 if(res==16) {
555 ADC0_CV1 *= 2; // change back the comparison values
556 ADC0_CV2 *= 2;
557 }
558 ADC0_CFG1 = savedCFG1;
559 ADC0_CFG2 = savedCFG2;
560 ADC0_SC2 = savedSC2 & 0x7F;
561 ADC0_SC3 = savedSC3 & 0xF;
562 ADC0_SC1A = savedSC1A & 0x7F;
563 }
564
565 __enable_irq();
566 if (result & (1<<15)) { // number is negative
567 result |= 0xFFFF0000; // result is a 32 bit integer
568 }
569 return result;
570 } else if( ((ADC0_SC2 & ADC_SC2_ADACT) == 0) && ((ADC0_SC1A & ADC_SC1_COCO) == 0) ) {
571 // we needed to check that ADACT wasn't 0 because COCO just turned 1.
572
573 // if we interrupted a conversion, set it again
574 if (adcWasInUse) {
575 //GPIOC_PTOR = 1<<5;
576
577 // restore ADC config, and restart conversion
578 if(diffRes) setResolution(savedRes); // don't change res if isn't necessary
579 if(res==16) {
580 ADC0_CV1 *= 2; // change back the comparison values
581 ADC0_CV2 *= 2;
582 }
583 ADC0_CFG1 = savedCFG1;
584 ADC0_CFG2 = savedCFG2;
585 ADC0_SC2 = savedSC2 & 0x7F;
586 ADC0_SC3 = savedSC3 & 0xF;
587 ADC0_SC1A = savedSC1A & 0x7F;
588 }
589
590 // comparison was false, we return an error value to indicate this
591 __enable_irq();
592 return ADC_ERROR_DIFF_VALUE;
593 } // end if comparison false
594
595 __enable_irq();
596 yield();
597 } // while
598
599 } // analogReadDifferential
600
601
602
603 /* Starts an analog measurement on the pin.
604 * It returns inmediately, read value with readSingle().
605 * If the pin is incorrect it returns ADC_ERROR_VALUE.
606 */
607 int ADC::startSingleRead(uint8_t pin) {
608
609 if (pin >= 14 && pin <= 39) {
610 if (pin <= 23) {
611 pin -= 14; // 14-23 are A0-A9
612 } else if (pin >= 34) {
613 pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
614 }
615 } else {
616 return ADC_ERROR_VALUE; // all others are invalid
617 }
618
619 if (calibrating) wait_for_cal();
620
621 uint8_t res = getResolution();
622
623 // if the resolution is incorrect (i.e. 9, 11 or 13) silently correct it
624 adc_config.diffRes = 0;
625 if( (res==9) || (res==11) || (res==13) ) {
626 setResolution(res-1);
627 adc_config.diffRes = 1; // resolution changed
628 } else if(res==16){ // make sure the max value corresponds to a single-ended 16 bits mode
629 analog_max_val = 65536;
630 }
631
632 // vars to saved the current state of the ADC in case it's in use
633 adcWasInUse = isConverting(); // is the ADC running now?
634
635 if(adcWasInUse) { // this means we're interrupting a conversion
636 // save the current conversion config, the adc isr will restore the adc
637 __disable_irq();
638 //GPIOC_PSOR = 1<<5;
639 adc_config.savedRes = res;
640 adc_config.savedSC1A = ADC0_SC1A;
641 adc_config.savedCFG1 = ADC0_CFG1;
642 adc_config.savedCFG2 = ADC0_CFG2;
643 adc_config.savedSC2 = ADC0_SC2;
644 adc_config.savedSC3 = ADC0_SC3;
645 //__enable_irq(); //keep irq disabled until we start our conversion
646
647 }
648
649 // select pin for single-ended mode and start conversion, enable interrupts to know when it's done
650 __disable_irq();
651 ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN;
652 __enable_irq();
653
654 }
655
656
657 /* Start a differential conversion between two pins (pinP - pinN).
658 * It returns inmediately, get value with readSingle().
659 * Incorrect pins will return ADC_ERROR_DIFF_VALUE.
660 * Set the resolution, number of averages and voltage reference using the appropriate functions
661 */
662 int ADC::startSingleDifferential(uint8_t pinP, uint8_t pinN)
663 {
664
665 // check for calibration before setting channels,
666 // because conversion will start as soon as we write to ADC0_SC1A
667 if (calibrating) wait_for_cal();
668
669 uint8_t res = getResolution();
670
671 // if the resolution is incorrect (i.e. 8, 10 or 12) silently correct it
672 adc_config.diffRes = 0;
673 if( (res==8) || (res==10) || (res==12) ) {
674 setResolution(res+1);
675 adc_config.diffRes = 1; // resolution changed
676 } else if(res==16) {
677 analog_max_val = 32768; // 16 bit diff mode is actually 15 bits + 1 sign bit
678 }
679
680 // vars to saved the current state of the ADC in case it's in use
681 adcWasInUse = isConverting(); // is the ADC running now?
682
683 if(adcWasInUse) { // this means we're interrupting a conversion
684 // save the current conversion config, the adc isr will restore the adc
685 __disable_irq();
686 //GPIOC_PSOR = 1<<5;
687 adc_config.savedRes = res;
688 adc_config.savedSC1A = ADC0_SC1A;
689 adc_config.savedCFG1 = ADC0_CFG1;
690 adc_config.savedCFG2 = ADC0_CFG2;
691 adc_config.savedSC2 = ADC0_SC2;
692 adc_config.savedSC3 = ADC0_SC3;
693 //__enable_irq(); //keep irq disabled until we start our conversion
694
695 }
696
697 // once ADC0_SC1A is set, conversion will start, enable interrupts if requested
698 if ( (pinP == A10) && (pinN == A11) ) { // DAD0 selected, pins 34 and 35
699 __disable_irq();
700 ADC0_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN;
701 __enable_irq();
702 } else if ( (pinP == A12) && (pinN == A13) ) { // DAD3 selected, pins 36 and 37
703 __disable_irq();
704 ADC0_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN;
705 __enable_irq();
706 } else {
707 __enable_irq();
708 return ADC_ERROR_DIFF_VALUE; // all others aren't capable of differential measurements, perhaps return analogRead(pinP)-analogRead(pinN)?
709 }
710
711 }
712
713 /* Reads the analog value of the single conversion set with startAnalogRead(pin)
714 */
715 int ADC::readSingle() { return analogReadContinuous(); }
716
717
718
719
720 /* Starts continuous conversion on the pin
721 * It returns as soon as the ADC is set, use analogReadContinuous() to read the values
722 * Set the resolution, number of averages and voltage reference using the appropriate functions BEFORE calling this function
723 */
724 void ADC::startContinuous(uint8_t pin)
725 {
726
727 // if the resolution is incorrect (i.e. 9, 11 or 13) silently correct it
728 uint8_t res = getResolution();
729 if( (res==9) || (res==11) || (res==13) ) {
730 setResolution(res-1);
731 } else if(res==16) {
732 analog_max_val = 65536; // make sure a differential function didn't change this
733 }
734
735 // check for calibration before setting channels,
736 if (calibrating) wait_for_cal();
737
738 if (pin >= 14) {
739 if (pin <= 23) {
740 pin -= 14; // 14-23 are A0-A9
741 } else if (pin >= 34 && pin <= 39) {
742 pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
743 } else {
744 return; // all others are invalid
745 }
746 }
747
748 __disable_irq();
749 // set continuous conversion flag
750 ADC0_SC3 |= ADC_SC3_ADCO;
751 // select pin for single-ended mode and start conversion, enable interrupts if requested
752 ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN;
753 __enable_irq();
754 }
755
756
757 /* Starts continuous and differential conversion between the pins (pinP-pinN)
758 * It returns as soon as the ADC is set, use analogReadContinuous() to read the value
759 * Set the resolution, number of averages and voltage reference using the appropriate functions BEFORE calling this function
760 */
761 void ADC::startContinuousDifferential(uint8_t pinP, uint8_t pinN)
762 {
763
764 // if the resolution is incorrect (i.e. 8, 10 or 12) silently correct
765 uint8_t res = getResolution();
766 if( (res==8) || (res==10) || (res==12) ) {
767 setResolution(res+1);
768 } else if(res==16) {
769 analog_max_val = 32768; // 16 bit diff mode is actually 15 bits + 1 sign bit
770 //ADC0_CV1 /= 2; // change back the comparison values
771 //ADC0_CV2 /= 2;
772 }
773
774
775 // check for calibration before setting channels,
776 // because conversion will start as soon as we write to ADC0_SC1A
777 if (calibrating) wait_for_cal();
778
779 // set continuous conversion flag
780 __disable_irq();
781 ADC0_SC3 |= ADC_SC3_ADCO;
782 __enable_irq();
783
784 // select pins for differential mode and start conversion, enable interrupts if requested
785 if ( (pinP == A10) && (pinN == A11) ) { // DAD0 selected, pins 34 and 35
786 __disable_irq();
787 ADC0_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN;
788 __enable_irq();
789 } else if ( (pinP == A12) && (pinN == A13) ) { // DAD3 selected, pins 36 and 37
790 __disable_irq();
791 ADC0_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN;
792 __enable_irq();
793 } else {
794 return;
795 }
796
797 return;
798 }
799
800 /* Reads the analog value of the continuous conversion set with analogStartContinuous(pin)
801 * It returns the last converted value.
802 */
803 int ADC::analogReadContinuous()
804 {
805 // The result is a 16 bit extended sign 2's complement number (the sign bit goes from bit 15 to analog_config_bits-1)
806 // if the number is negative we fill the rest of the 1's upto 32 bits (we extend the sign)
807 int16_t result = ADC0_RA;
808 if (result & (1<<15)) { // number is negative
809 result |= 0xFFFF0000; // result is a 32 bit integer
810 }
811
812 return result;
813 }
814
815 /* Stops continuous conversion
816 */
817 void ADC::stopContinuous()
818 {
819 ADC0_SC1A |= 0x1F; // set channel select to all 1's (31) to stop it.
820
821 return;
822 }
823
824
825 /* void function that does nothing
826 */
827 void ADC::voidFunction(){return;}
828
829 /* Callback from the ADC interrupt, it adds the new value to the ring buffer
830 * it takes around 3 us
831 */
832 void ADC::ADC_callback() {
833 #if debug
834 digitalWriteFast(ledPin, HIGH);
835 #endif
836
837 // get the pin number
838 int pin = sc1a2channel[ADC0_SC1A & 0x1F];
839
840 // find the index of the pin
841 int i = 0;
842 while( (i<MAX_ANALOG_TIMERS) && (analogTimer[i]->pinNumber!=pin) ) {i++;}
843 if( i==MAX_ANALOG_TIMERS) {
844 #if debug
845 digitalWriteFast(ledPin, LOW);
846 #endif
847 return; // the last measurement doesn't belong to an analog timer buffer.
848 }
849
850 // place value in its buffer
851 analogTimer[i]->buffer->write(readSingle());
852
853 // restore ADC config if it was in use before being interrupted by the analog timer
854 if (adcWasInUse) {
855 // restore ADC config, and restart conversion
856 //if(adc_config.diffRes)
857 setResolution(adc_config.savedRes); // don't change res if isn't necessary
858 ADC0_CFG1 = adc_config.savedCFG1;
859 ADC0_CFG2 = adc_config.savedCFG2;
860 ADC0_SC2 = adc_config.savedSC2 & 0x7F;
861 ADC0_SC3 = adc_config.savedSC3 & 0xF;
862 ADC0_SC1A = adc_config.savedSC1A & 0x7F;
863 }
864
865 #if debug
866 digitalWriteFast(ledPin, LOW);
867 #endif
868 }
869
870
871 /* callback function for the analog timers
872 * it takes around 2.5 us
873 */
874 void ADC::analogTimerCallback0() {
875 #if debug
876 digitalWriteFast(ledPin, HIGH);
877 #endif
878
879 uint8_t pin = analogTimer[0]->pinNumber;
880 if(analogTimer[0]->isDiff) {
881 if(pin == A10) {
882 startSingleDifferential(A10, A11);
883 } else if(pin == A12) {
884 startSingleDifferential(A12, A13);
885 }
886 } else {
887 startSingleRead(pin);
888 }
889
890 #if debug
891 digitalWriteFast(ledPin, LOW);
892 #endif
893 }
894 /* callback function for the analog timers
895 * it takes around 2.5 us
896 */
897 void ADC::analogTimerCallback1() {
898 #if debug
899 digitalWriteFast(ledPin, HIGH);
900 #endif
901
902 uint8_t pin = analogTimer[1]->pinNumber;
903 if(analogTimer[1]->isDiff) {
904 if(pin == A10) {
905 startSingleDifferential(A10, A11);
906 } else if(pin == A12) {
907 startSingleDifferential(A12, A13);
908 }
909 } else {
910 startSingleRead(pin);
911 }
912
913 #if debug
914 digitalWriteFast(ledPin, LOW);
915 #endif
916 }
917 /* callback function for the analog timers
918 * it takes around 2.5 us
919 */
920 void ADC::analogTimerCallback2() {
921 #if debug
922 digitalWriteFast(ledPin, HIGH);
923 #endif
924
925 uint8_t pin = analogTimer[2]->pinNumber;
926 if(analogTimer[2]->isDiff) {
927 if(pin == A10) {
928 startSingleDifferential(A10, A11);
929 } else if(pin == A12) {
930 startSingleDifferential(A12, A13);
931 }
932 } else {
933 startSingleRead(pin);
934 }
935
936 #if debug
937 digitalWriteFast(ledPin, LOW);
938 #endif
939 }
940
941 /* Starts a periodic measurement.
942 * The values will be added to a ring buffer of a fixed size.
943 * Read the oldest value with getTimerValue(pin), check if it's the last value with isLastValue(pin).
944 * When the buffer is full, new data will overwrite the oldest values.
945 */
946 int ADC::startAnalogTimer(uint8_t pin, uint32_t period) {
947
948 // check pin
949 if (pin < 14 || pin > 39) {
950 return ANALOG_TIMER_ERROR; // invalid pin
951 }
952
953 // if the resolution is incorrect (i.e. 9, 11 or 13) silently correct it here
954 uint8_t res = getResolution();
955 if( (res==9) || (res==11) || (res==13) ) {
956 setResolution(res-1);
957 }
958
959 // find next timerPin not in use
960 int i = 0;
961 for(i=0; i<MAX_ANALOG_TIMERS; i++) {
962 if(analogTimer[i]->pinNumber==-1) {
963 break;
964 } else if(analogTimer[i]->pinNumber==pin) { // the timer already exists, do nothing
965 return true;
966 }
967 }
968 if( i == (MAX_ANALOG_TIMERS) ) { // All timers are being used, stop at least one of them!
969 return ANALOG_TIMER_ERROR;
970 }
971
972 analogTimer[i]->pinNumber = pin; // reserve a timer for this pin
973
974 // create both objects
975 analogTimer[i]->timer = new IntervalTimer;
976 analogTimer[i]->buffer = new RingBuffer;
977
978 // store period
979 analogTimer[i]->period = period;
980
981 // point the adc_isr to the function that takes care of the timers
982 analogTimer_ADC_Callback = &ADC_callback;
983 // enable interrupts
984 enableInterrupts();
985
986 // start timerPin # i
987 int result = analogTimer[i]->timer->begin(analogTimerCallback[i], period);
988 if(!result) { // begin returns true/false
989 return ANALOG_TIMER_ERROR;
990 }
991
992 return result;
993 }
994
995 /* Starts a periodic measurement using the IntervalTimer library.
996 * The values will be added to a ring buffer of a fixed size.
997 * Read the oldest value with getTimerValue(pinP), check if it's the last value with isLastValue(pinP).
998 * When the buffer is full, new data will overwrite the oldest values.
999 * \param pinP must be A10 or A12.
1000 * \param pinN must be A11 (if pinP=A10) or A13 (if pinP=A12).
1001 * \returns ANALOG_TIMER_ERROR if the timer could not be started. Stop other analog timer and retry.
1002 */
1003 int ADC::startAnalogTimerDifferential(uint8_t pinP, uint8_t pinN, uint32_t period) {
1004
1005 // check pin
1006 if ( (pinP != A10) && (pinP != A12) ) {
1007 return ANALOG_TIMER_ERROR; // invalid pin
1008 }
1009
1010 // if the resolution is incorrect (i.e. 8, 10 or 12) silently correct it here
1011 uint8_t res = getResolution();
1012 if( (res==8) || (res==10) || (res==12) ) {
1013 setResolution(res+1);
1014 }
1015
1016 // find next timerPin not in use
1017 int i = 0;
1018 for(i=0; i<MAX_ANALOG_TIMERS; i++) {
1019 if(analogTimer[i]->pinNumber==-1) {
1020 break;
1021 } else if(analogTimer[i]->pinNumber==pinP) { // the timer already exists, do nothing
1022 return true;
1023 }
1024 }
1025 if( i == (MAX_ANALOG_TIMERS) ) { // All timers are being used, stop at least one of them!
1026 return ANALOG_TIMER_ERROR;
1027 }
1028
1029 analogTimer[i]->pinNumber = pinP; // reserve a timer for this pin
1030
1031 // create both objects
1032 analogTimer[i]->timer = new IntervalTimer;
1033 analogTimer[i]->buffer = new RingBuffer;
1034
1035 analogTimer[i]->period = period;
1036 analogTimer[i]->isDiff = true;
1037
1038 // point the adc_isr to the function that takes care of the timers
1039 analogTimer_ADC_Callback = &ADC_callback;
1040 // enable interrupts
1041 enableInterrupts();
1042
1043 // start timerPin # i
1044 int result = analogTimer[i]->timer->begin(analogTimerCallback[i], period);
1045 if(!result) { // begin returns true/false
1046 return ANALOG_TIMER_ERROR;
1047 }
1048
1049 return result;
1050 }
1051
1052
1053 // Stops the periodic measurement
1054 void ADC::stopAnalogTimer(uint8_t pin) {
1055 // find corresponding timerPin
1056 int i = 0;
1057 while( (i<MAX_ANALOG_TIMERS) && (analogTimer[i]->pinNumber!=pin) ) {i++;}
1058 if( i == MAX_ANALOG_TIMERS ) { // Timer doesn't exist
1059 return;
1060 }
1061
1062 // stop timerPin # i
1063 analogTimer[i]->timer->end();
1064 analogTimer[i]->pinNumber = -1; // timerPin i is free now
1065
1066 delete analogTimer[i]->timer;
1067 delete analogTimer[i]->buffer;
1068
1069 // check if there are more analog timers in use
1070 i = 0;
1071 while( (i<MAX_ANALOG_TIMERS) && (analogTimer[i]->pinNumber!=-1) ) {i++;}
1072 if( i == MAX_ANALOG_TIMERS ) { // no more analog timers
1073 disableInterrupts();
1074 // point the adc_isr to the function that does nothing
1075 analogTimer_ADC_Callback = &voidFunction;
1076 }
1077
1078
1079 return;
1080 }
1081
1082 // Returns the oldest value of the ring buffer where the periodic measurements go
1083 int ADC::getTimerValue(uint8_t pin) {
1084 // find corresponding timerPin
1085 int i = 0;
1086 while( (i<MAX_ANALOG_TIMERS) && (analogTimer[i]->pinNumber!=pin) ) {i++;}
1087 if( i == MAX_ANALOG_TIMERS ) { // Timer not found with that pin number!
1088 return ANALOG_TIMER_ERROR;
1089 }
1090
1091 return analogTimer[i]->buffer->read(); // read the oldest value in the buffer
1092 }
1093
1094 // Is the oldest value also the last one?
1095 bool ADC::isTimerLastValue(uint8_t pin) {
1096 // find corresponding timerPin
1097 int i = 0;
1098 while( (i<MAX_ANALOG_TIMERS) && (analogTimer[i]->pinNumber!=pin) ) {i++;}
1099 if( i == MAX_ANALOG_TIMERS ) { // Timer not found with that pin number!
1100 return ANALOG_TIMER_ERROR;
1101 }
1102
1103 //return timerPin[i].buffer->isEmpty();
1104 return analogTimer[i]->buffer->isEmpty();
1105 }
1106
1107
1108
1109 /* Is the ADC converting at the moment?
1110 * Returns 1 if yes, 0 if not
1111 */
1112 bool ADC::isConverting() {
1113
1114 return (ADC0_SC2 & ADC_SC2_ADACT) >> 7;
1115 }
1116
1117
1118 /* Is an ADC conversion ready?
1119 * Returns 1 if yes, 0 if not.
1120 * When a value is read this function returns 0 until a new value exists
1121 * So it only makes sense to call it before analogRead(), analogReadContinuous() or analogReadDifferential()
1122 */
1123 bool ADC::isComplete() {
1124
1125 return (ADC0_SC1A & ADC_SC1_COCO) >> 7;
1126 }
1127
1128
1129 bool ADC::isDifferential() {
1130 return (ADC0_SC1A & ADC_SC1_DIFF) >> 5;
1131 }
1132
1133 bool ADC::isContinuous() {
1134 return (ADC0_SC3 & ADC_SC3_ADCO) >> 3;
1135 }
ADC::isConverting
static bool isConverting()
Is the ADC converting at the moment?
Definition: ADC.cpp:1112
ADC::startContinuous
void startContinuous(uint8_t pin)
Starts continuous conversion on the pin.
Definition: ADC.cpp:724
ADC::ADC
ADC()
Definition: ADC.cpp:66
ADC::disableCompare
void disableCompare()
Disable the compare function.
Definition: ADC.cpp:360
ADC::isTimerLastValue
bool isTimerLastValue(uint8_t pin)
Is the oldest value also the last one?
Definition: ADC.cpp:1095
ADC::startSingleRead
static int startSingleRead(uint8_t pin)
Starts an analog measurement on the pin and enables interrupts.
Definition: ADC.cpp:607
ADC::enableCompare
void enableCompare(int16_t compValue, int greaterThan)
Enable the compare function to a single value.
Definition: ADC.cpp:324
ADC::isDifferential
static bool isDifferential()
Is the ADC in differential mode?
Definition: ADC.cpp:1129
ADC::analogTimer_ADC_Callback
static void(* analogTimer_ADC_Callback)(void)
Points to the function that takes care of the analogTimers.
Definition: ADC.h:284
ADC::startSingleDifferential
static int startSingleDifferential(uint8_t pinP, uint8_t pinN)
Start a differential conversion between two pins (pinP - pinN) and enables interrupts.
Definition: ADC.cpp:662
ADC::isContinuous
static bool isContinuous()
Is the ADC in continuous mode?
Definition: ADC.cpp:1133
MAX_ANALOG_TIMERS
#define MAX_ANALOG_TIMERS
Definition: ADC.h:26
ADC_ERROR_VALUE
#define ADC_ERROR_VALUE
Definition: ADC.h:59
ADC::getMaxValue
uint32_t getMaxValue()
Returns the maximum value for a measurement.
Definition: ADC.cpp:255
ADC.h
ADC::~ADC
~ADC()
Definition: ADC.cpp:93
ADC::analogRead
static int analogRead(uint8_t pin)
Returns the analog value of the pin.
Definition: ADC.cpp:370
ADC::getTimerValue
int getTimerValue(uint8_t pin)
Returns the oldest value of the ring buffer where the periodic measurements go.
Definition: ADC.cpp:1083
ADC_ERROR_DIFF_VALUE
#define ADC_ERROR_DIFF_VALUE
Definition: ADC.h:58
ADC::setAveraging
void setAveraging(uint8_t num)
Set the number of averages.
Definition: ADC.cpp:263
ADC::stopContinuous
void stopContinuous()
Stops continuous conversion.
Definition: ADC.cpp:817
ADC::setResolution
static void setResolution(uint8_t bits)
Change the resolution of the measurement.
Definition: ADC.cpp:199
ADC::readSingle
static int readSingle()
Reads the analog value of a single conversion.
Definition: ADC.cpp:715
ADC::enableCompareRange
void enableCompareRange(int16_t lowerLimit, int16_t upperLimit, int insideRange, int inclusive)
Enable the compare function to a range.
Definition: ADC.cpp:336
ADC::isComplete
static bool isComplete()
Is an ADC conversion ready?
Definition: ADC.cpp:1123
ADC::disableDMA
void disableDMA()
Disable ADC DMA request.
Definition: ADC.cpp:314
RingBuffer
Definition: RingBuffer.h:15
__attribute__
void __attribute__((weak)) adc0_isr(void)
Definition: ADC.cpp:24
ADC::startContinuousDifferential
void startContinuousDifferential(uint8_t pinP, uint8_t pinN)
Starts continuous conversion between the pins (pinP-pinN).
Definition: ADC.cpp:761
ADC::enableInterrupts
static void enableInterrupts()
Enable interrupts.
Definition: ADC.cpp:290
ADC::getResolution
static uint8_t getResolution()
Returns the resolution of the ADC.
Definition: ADC.cpp:248
ADC::analogReadContinuous
static int analogReadContinuous()
Reads the analog value of a continuous conversion.
Definition: ADC.cpp:803
ANALOG_TIMER_ERROR
#define ANALOG_TIMER_ERROR
Definition: ADC.h:62
ADC::stopAnalogTimer
void stopAnalogTimer(uint8_t pin)
Stops the periodic measurement.
Definition: ADC.cpp:1054
ADC::startAnalogTimer
int startAnalogTimer(uint8_t pin, uint32_t period)
Starts a periodic measurement using the IntervalTimer library.
Definition: ADC.cpp:946
ADC::disableInterrupts
static void disableInterrupts()
Disable interrupts.
Definition: ADC.cpp:298
ADC::analogReadDifferential
static int analogReadDifferential(uint8_t pinP, uint8_t pinN)
Reads the differential analog value of two pins (pinP - pinN).
Definition: ADC.cpp:487
ADC::setReference
void setReference(uint8_t type)
Set the voltage reference you prefer, default is vcc.
Definition: ADC.cpp:173
ADC::enableDMA
void enableDMA()
Enable DMA request.
Definition: ADC.cpp:307
ADC::startAnalogTimerDifferential
int startAnalogTimerDifferential(uint8_t pinP, uint8_t pinN, uint32_t period)
Starts a periodic measurement using the IntervalTimer library.
Definition: ADC.cpp:1003