ADC  1.0
 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) {
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 */
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 */
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 */
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 */
291  var_enableInterrupts = 1;
292  NVIC_ENABLE_IRQ(IRQ_ADC0);
293 }
294 
295 /* Disable interrupts
296 *
297 */
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 */
308  ADC0_SC2 |= ADC_SC2_DMAEN;
309 }
310 
311 /* Disable ADC DMA request
312 *
313 */
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 */
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 */
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 */
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 */
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
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
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 */
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 */
1124 
1125  return (ADC0_SC1A & ADC_SC1_COCO) >> 7;
1126 }
1127 
1128 
1130  return (ADC0_SC1A & ADC_SC1_DIFF) >> 5;
1131 }
1132 
1134  return (ADC0_SC3 & ADC_SC3_ADCO) >> 3;
1135 }
static bool isConverting()
Is the ADC converting at the moment?
Definition: ADC.cpp:1112
void startContinuous(uint8_t pin)
Starts continuous conversion on the pin.
Definition: ADC.cpp:724
ADC()
Definition: ADC.cpp:66
void disableCompare()
Disable the compare function.
Definition: ADC.cpp:360
bool isTimerLastValue(uint8_t pin)
Is the oldest value also the last one?
Definition: ADC.cpp:1095
static int startSingleRead(uint8_t pin)
Starts an analog measurement on the pin and enables interrupts.
Definition: ADC.cpp:607
void enableCompare(int16_t compValue, int greaterThan)
Enable the compare function to a single value.
Definition: ADC.cpp:324
static bool isDifferential()
Is the ADC in differential mode?
Definition: ADC.cpp:1129
static void(* analogTimer_ADC_Callback)(void)
Points to the function that takes care of the analogTimers.
Definition: ADC.h:284
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
static bool isContinuous()
Is the ADC in continuous mode?
Definition: ADC.cpp:1133
#define MAX_ANALOG_TIMERS
Definition: ADC.h:26
#define ADC_ERROR_VALUE
Definition: ADC.h:59
uint32_t getMaxValue()
Returns the maximum value for a measurement.
Definition: ADC.cpp:255
~ADC()
Definition: ADC.cpp:93
static int analogRead(uint8_t pin)
Returns the analog value of the pin.
Definition: ADC.cpp:370
int getTimerValue(uint8_t pin)
Returns the oldest value of the ring buffer where the periodic measurements go.
Definition: ADC.cpp:1083
#define ADC_ERROR_DIFF_VALUE
Definition: ADC.h:58
void setAveraging(uint8_t num)
Set the number of averages.
Definition: ADC.cpp:263
void stopContinuous()
Stops continuous conversion.
Definition: ADC.cpp:817
static void setResolution(uint8_t bits)
Change the resolution of the measurement.
Definition: ADC.cpp:199
static int readSingle()
Reads the analog value of a single conversion.
Definition: ADC.cpp:715
void enableCompareRange(int16_t lowerLimit, int16_t upperLimit, int insideRange, int inclusive)
Enable the compare function to a range.
Definition: ADC.cpp:336
static bool isComplete()
Is an ADC conversion ready?
Definition: ADC.cpp:1123
void disableDMA()
Disable ADC DMA request.
Definition: ADC.cpp:314
void __attribute__((weak)) adc0_isr(void)
Definition: ADC.cpp:24
void startContinuousDifferential(uint8_t pinP, uint8_t pinN)
Starts continuous conversion between the pins (pinP-pinN).
Definition: ADC.cpp:761
static void enableInterrupts()
Enable interrupts.
Definition: ADC.cpp:290
static uint8_t getResolution()
Returns the resolution of the ADC.
Definition: ADC.cpp:248
static int analogReadContinuous()
Reads the analog value of a continuous conversion.
Definition: ADC.cpp:803
#define ANALOG_TIMER_ERROR
Definition: ADC.h:62
void stopAnalogTimer(uint8_t pin)
Stops the periodic measurement.
Definition: ADC.cpp:1054
int startAnalogTimer(uint8_t pin, uint32_t period)
Starts a periodic measurement using the IntervalTimer library.
Definition: ADC.cpp:946
static void disableInterrupts()
Disable interrupts.
Definition: ADC.cpp:298
static int analogReadDifferential(uint8_t pinP, uint8_t pinN)
Reads the differential analog value of two pins (pinP - pinN).
Definition: ADC.cpp:487
void setReference(uint8_t type)
Set the voltage reference you prefer, default is vcc.
Definition: ADC.cpp:173
void enableDMA()
Enable DMA request.
Definition: ADC.cpp:307
int startAnalogTimerDifferential(uint8_t pinP, uint8_t pinN, uint32_t period)
Starts a periodic measurement using the IntervalTimer library.
Definition: ADC.cpp:1003