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;
37 const uint8_t ADC::ledPin = 13;
39 ADC::ADC_Config ADC::adc_config;
40 uint8_t ADC::adcWasInUse;
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[]= {
46 34, 0, 0, 36, 23, 14, 20, 21, 16, 17, 0, 0, 19, 18,
47 15, 22, 0, 0, 0, 35, 0, 37, 39, 0, 0, 0, 38};
50 ADC::AnalogTimer *ADC::analogTimer[];
56 ADC::ISR ADC::analogTimerCallback[] = {
57 ADC::analogTimerCallback0,
58 ADC::analogTimerCallback1,
59 ADC::analogTimerCallback2
68 analog_config_bits = 0;
69 analog_max_val = 1024;
70 analog_num_average = 4;
71 analog_reference_internal = 0;
72 var_enableInterrupts = 0;
77 analogTimer[i] =
new AnalogTimer;
97 delete analogTimer[i];
105 void ADC::analog_init(uint32_t config)
111 if (analog_reference_internal) {
112 ADC0_SC2 |= ADC_SC2_REFSEL(1);
114 ADC0_SC2 |= ADC_SC2_REFSEL(0);
128 void ADC::calibrate() {
129 ADC0_SC3 |= ADC_SC3_CAL;
139 void ADC::wait_for_cal(
void)
143 while (ADC0_SC3 & ADC_SC3_CAL) {
151 sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
152 sum = (sum / 2) | 0x8000;
157 sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
158 sum = (sum / 2) | 0x8000;
177 if (!analog_reference_internal) {
178 analog_reference_internal = 1;
179 if (calibrating) ADC0_SC3 = 0;
184 if (analog_reference_internal) {
185 analog_reference_internal = 0;
186 if (calibrating) ADC0_SC3 = 0;
205 }
else if (bits > 16) {
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) {
217 analog_config_bits = config;
220 if ( (analog_config_bits == 8) || (analog_config_bits == 9) ) {
221 ADC0_CFG1 = ADC0_CFG1_24MHZ + ADC_CFG1_MODE(0);
222 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
223 analog_max_val = 256;
224 }
else if ( (analog_config_bits == 10 )|| (analog_config_bits == 11) ) {
225 ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
226 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
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;
230 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
231 analog_max_val = 4096;
233 ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
234 ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
235 analog_max_val = 65536;
240 if (calibrating) ADC0_SC3 = 0;
249 return analog_config_bits;
256 return analog_max_val;
266 if (calibrating) wait_for_cal();
269 ADC0_SC3 &= !ADC_SC3_AVGE;
270 }
else if (num <= 4) {
272 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(0);
273 }
else if (num <= 8) {
275 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(1);
276 }
else if (num <= 16) {
278 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(2);
281 ADC0_SC3 |= ADC_SC3_AVGE + ADC_SC3_AVGS(3);
283 analog_num_average = num;
291 var_enableInterrupts = 1;
292 NVIC_ENABLE_IRQ(IRQ_ADC0);
299 var_enableInterrupts = 0;
300 NVIC_DISABLE_IRQ(IRQ_ADC0);
308 ADC0_SC2 |= ADC_SC2_DMAEN;
315 ADC0_SC2 &= !ADC_SC2_DMAEN;
325 ADC0_SC2 |= ADC_SC2_ACFE | greaterThan*ADC_SC2_ACFGT;
326 ADC0_CV1 = compValue;
338 if(insideRange && inclusive) {
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) {
343 ADC0_CV2 = lowerLimit;
344 ADC0_CV1 = upperLimit;
345 ADC0_SC2 |= ADC_SC2_ACFE | ADC_SC2_ACREN;
346 }
else if(!insideRange && inclusive) {
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) {
351 ADC0_CV1 = lowerLimit;
352 ADC0_CV2 = upperLimit;
353 ADC0_SC2 |= ADC_SC2_ACFE | ADC_SC2_ACREN;
361 ADC0_SC2 &= !ADC_SC2_ACFE;
374 if (pin >= 14 && pin <= 39) {
377 }
else if (pin >= 34) {
384 if (calibrating) wait_for_cal();
390 uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2, savedRes;
398 savedSC1A = ADC0_SC1A;
399 savedCFG1 = ADC0_CFG1;
410 ADC0_SC3 &= !ADC_SC3_ADCO;
418 if( (res==9) || (res==11) || (res==13) ) {
424 ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN;
430 if ((ADC0_SC1A & ADC_SC1_COCO)) {
439 if(res==16 && ((savedSC1A & ADC_SC1_DIFF) >> 5) ) {
443 ADC0_CFG1 = savedCFG1;
444 ADC0_SC2 = savedSC2 & 0x7F;
445 ADC0_SC3 = savedSC3 & 0xF;
446 ADC0_SC1A = savedSC1A & 0x7F;
450 }
else if( ((ADC0_SC2 & ADC_SC2_ADACT) == 0) && ((ADC0_SC1A & ADC_SC1_COCO) == 0) ) {
459 if(res==16 && ((savedSC1A & ADC_SC1_DIFF) >> 5) ) {
463 ADC0_CFG1 = savedCFG1;
464 ADC0_SC2 = savedSC2 & 0x7F;
465 ADC0_SC3 = savedSC3 & 0xF;
466 ADC0_SC1A = savedSC1A & 0x7F;
493 if (calibrating) wait_for_cal();
499 uint32_t savedSC1A, savedSC2, savedSC3, savedCFG1, savedCFG2, savedRes;
507 savedSC1A = ADC0_SC1A;
508 savedCFG1 = ADC0_CFG1;
509 savedCFG2 = ADC0_CFG2;
514 ADC0_SC3 &= !ADC_SC3_ADCO;
520 if( (res==8) || (res==10) || (res==12) ) {
530 if ( (pinP == A10) && (pinN == A11) ) {
532 ADC0_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN;
534 }
else if ( (pinP == A12) && (pinN == A13) ) {
536 ADC0_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN;
545 if ((ADC0_SC1A & ADC_SC1_COCO)) {
558 ADC0_CFG1 = savedCFG1;
559 ADC0_CFG2 = savedCFG2;
560 ADC0_SC2 = savedSC2 & 0x7F;
561 ADC0_SC3 = savedSC3 & 0xF;
562 ADC0_SC1A = savedSC1A & 0x7F;
566 if (result & (1<<15)) {
567 result |= 0xFFFF0000;
570 }
else if( ((ADC0_SC2 & ADC_SC2_ADACT) == 0) && ((ADC0_SC1A & ADC_SC1_COCO) == 0) ) {
583 ADC0_CFG1 = savedCFG1;
584 ADC0_CFG2 = savedCFG2;
585 ADC0_SC2 = savedSC2 & 0x7F;
586 ADC0_SC3 = savedSC3 & 0xF;
587 ADC0_SC1A = savedSC1A & 0x7F;
609 if (pin >= 14 && pin <= 39) {
612 }
else if (pin >= 34) {
619 if (calibrating) wait_for_cal();
624 adc_config.diffRes = 0;
625 if( (res==9) || (res==11) || (res==13) ) {
627 adc_config.diffRes = 1;
629 analog_max_val = 65536;
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;
651 ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN;
667 if (calibrating) wait_for_cal();
672 adc_config.diffRes = 0;
673 if( (res==8) || (res==10) || (res==12) ) {
675 adc_config.diffRes = 1;
677 analog_max_val = 32768;
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;
698 if ( (pinP == A10) && (pinN == A11) ) {
700 ADC0_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN;
702 }
else if ( (pinP == A12) && (pinN == A13) ) {
704 ADC0_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN;
729 if( (res==9) || (res==11) || (res==13) ) {
732 analog_max_val = 65536;
736 if (calibrating) wait_for_cal();
741 }
else if (pin >= 34 && pin <= 39) {
750 ADC0_SC3 |= ADC_SC3_ADCO;
752 ADC0_SC1A = channel2sc1a[pin] + var_enableInterrupts*ADC_SC1_AIEN;
766 if( (res==8) || (res==10) || (res==12) ) {
769 analog_max_val = 32768;
777 if (calibrating) wait_for_cal();
781 ADC0_SC3 |= ADC_SC3_ADCO;
785 if ( (pinP == A10) && (pinN == A11) ) {
787 ADC0_SC1A = ADC_SC1_DIFF + 0x0 + var_enableInterrupts*ADC_SC1_AIEN;
789 }
else if ( (pinP == A12) && (pinN == A13) ) {
791 ADC0_SC1A = ADC_SC1_DIFF + 0x3 + var_enableInterrupts*ADC_SC1_AIEN;
807 int16_t result = ADC0_RA;
808 if (result & (1<<15)) {
809 result |= 0xFFFF0000;
827 void ADC::voidFunction(){
return;}
832 void ADC::ADC_callback() {
834 digitalWriteFast(ledPin, HIGH);
838 int pin = sc1a2channel[ADC0_SC1A & 0x1F];
845 digitalWriteFast(ledPin, LOW);
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;
866 digitalWriteFast(ledPin, LOW);
874 void ADC::analogTimerCallback0() {
876 digitalWriteFast(ledPin, HIGH);
879 uint8_t pin = analogTimer[0]->pinNumber;
880 if(analogTimer[0]->isDiff) {
883 }
else if(pin == A12) {
891 digitalWriteFast(ledPin, LOW);
897 void ADC::analogTimerCallback1() {
899 digitalWriteFast(ledPin, HIGH);
902 uint8_t pin = analogTimer[1]->pinNumber;
903 if(analogTimer[1]->isDiff) {
906 }
else if(pin == A12) {
914 digitalWriteFast(ledPin, LOW);
920 void ADC::analogTimerCallback2() {
922 digitalWriteFast(ledPin, HIGH);
925 uint8_t pin = analogTimer[2]->pinNumber;
926 if(analogTimer[2]->isDiff) {
929 }
else if(pin == A12) {
937 digitalWriteFast(ledPin, LOW);
949 if (pin < 14 || pin > 39) {
955 if( (res==9) || (res==11) || (res==13) ) {
962 if(analogTimer[i]->pinNumber==-1) {
964 }
else if(analogTimer[i]->pinNumber==pin) {
968 if( i == (MAX_ANALOG_TIMERS) ) {
972 analogTimer[i]->pinNumber = pin;
975 analogTimer[i]->timer =
new IntervalTimer;
979 analogTimer[i]->period = period;
987 int result = analogTimer[i]->timer->begin(analogTimerCallback[i], period);
1006 if ( (pinP != A10) && (pinP != A12) ) {
1012 if( (res==8) || (res==10) || (res==12) ) {
1019 if(analogTimer[i]->pinNumber==-1) {
1021 }
else if(analogTimer[i]->pinNumber==pinP) {
1025 if( i == (MAX_ANALOG_TIMERS) ) {
1029 analogTimer[i]->pinNumber = pinP;
1032 analogTimer[i]->timer =
new IntervalTimer;
1035 analogTimer[i]->period = period;
1036 analogTimer[i]->isDiff =
true;
1044 int result = analogTimer[i]->timer->begin(analogTimerCallback[i], period);
1063 analogTimer[i]->timer->end();
1064 analogTimer[i]->pinNumber = -1;
1066 delete analogTimer[i]->timer;
1067 delete analogTimer[i]->buffer;
1091 return analogTimer[i]->buffer->read();
1104 return analogTimer[i]->buffer->isEmpty();
1114 return (ADC0_SC2 & ADC_SC2_ADACT) >> 7;
1125 return (ADC0_SC1A & ADC_SC1_COCO) >> 7;
1130 return (ADC0_SC1A & ADC_SC1_DIFF) >> 5;
1134 return (ADC0_SC3 & ADC_SC3_ADCO) >> 3;
static bool isConverting()
Is the ADC converting at the moment?
void startContinuous(uint8_t pin)
Starts continuous conversion on the pin.
void disableCompare()
Disable the compare function.
bool isTimerLastValue(uint8_t pin)
Is the oldest value also the last one?
static int startSingleRead(uint8_t pin)
Starts an analog measurement on the pin and enables interrupts.
void enableCompare(int16_t compValue, int greaterThan)
Enable the compare function to a single value.
static bool isDifferential()
Is the ADC in differential mode?
static void(* analogTimer_ADC_Callback)(void)
Points to the function that takes care of the analogTimers.
static int startSingleDifferential(uint8_t pinP, uint8_t pinN)
Start a differential conversion between two pins (pinP - pinN) and enables interrupts.
static bool isContinuous()
Is the ADC in continuous mode?
#define MAX_ANALOG_TIMERS
uint32_t getMaxValue()
Returns the maximum value for a measurement.
static int analogRead(uint8_t pin)
Returns the analog value of the pin.
int getTimerValue(uint8_t pin)
Returns the oldest value of the ring buffer where the periodic measurements go.
#define ADC_ERROR_DIFF_VALUE
void setAveraging(uint8_t num)
Set the number of averages.
void stopContinuous()
Stops continuous conversion.
static void setResolution(uint8_t bits)
Change the resolution of the measurement.
static int readSingle()
Reads the analog value of a single conversion.
void enableCompareRange(int16_t lowerLimit, int16_t upperLimit, int insideRange, int inclusive)
Enable the compare function to a range.
static bool isComplete()
Is an ADC conversion ready?
void disableDMA()
Disable ADC DMA request.
void __attribute__((weak)) adc0_isr(void)
void startContinuousDifferential(uint8_t pinP, uint8_t pinN)
Starts continuous conversion between the pins (pinP-pinN).
static void enableInterrupts()
Enable interrupts.
static uint8_t getResolution()
Returns the resolution of the ADC.
static int analogReadContinuous()
Reads the analog value of a continuous conversion.
#define ANALOG_TIMER_ERROR
void stopAnalogTimer(uint8_t pin)
Stops the periodic measurement.
int startAnalogTimer(uint8_t pin, uint32_t period)
Starts a periodic measurement using the IntervalTimer library.
static void disableInterrupts()
Disable interrupts.
static int analogReadDifferential(uint8_t pinP, uint8_t pinN)
Reads the differential analog value of two pins (pinP - pinN).
void setReference(uint8_t type)
Set the voltage reference you prefer, default is vcc.
void enableDMA()
Enable DMA request.
int startAnalogTimerDifferential(uint8_t pinP, uint8_t pinN, uint32_t period)
Starts a periodic measurement using the IntervalTimer library.