diff --git a/DCCTimer.h b/DCCTimer.h index ed87e1f..2567a69 100644 --- a/DCCTimer.h +++ b/DCCTimer.h @@ -124,6 +124,8 @@ private: static uint16_t usedpins; // cached analog values (malloc:ed to actual number of ADC channels) static int *analogvals; + // ids to scan (new way) + static byte *idarr; // friend so that we can call scan() and begin() friend class DCCWaveform; }; diff --git a/DCCTimerAVR.cpp b/DCCTimerAVR.cpp index 5ff0e52..471ee24 100644 --- a/DCCTimerAVR.cpp +++ b/DCCTimerAVR.cpp @@ -120,12 +120,13 @@ void DCCTimer::reset() { } #if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) -#define NUM_ADC_INPUTS 15 +#define NUM_ADC_INPUTS 16 #else -#define NUM_ADC_INPUTS 7 +#define NUM_ADC_INPUTS 8 #endif uint16_t ADCee::usedpins = 0; int * ADCee::analogvals = NULL; +byte *ADCee::idarr = NULL; bool ADCusesHighPort = false; /* @@ -135,16 +136,26 @@ bool ADCusesHighPort = false; */ int ADCee::init(uint8_t pin) { uint8_t id = pin - A0; - if (id > NUM_ADC_INPUTS) + byte n; + if (id >= NUM_ADC_INPUTS) return -1023; if (id > 7) ADCusesHighPort = true; pinMode(pin, INPUT); int value = analogRead(pin); - if (analogvals == NULL) - analogvals = (int *)calloc(NUM_ADC_INPUTS+1, sizeof(int)); + if (analogvals == NULL) { + analogvals = (int *)calloc(NUM_ADC_INPUTS, sizeof(int)); + idarr = (byte *)calloc(NUM_ADC_INPUTS+1, sizeof(byte)); + for (n=0 ; n <= NUM_ADC_INPUTS; n++) + idarr[n] = 255; + } + for (n=0 ; n <= NUM_ADC_INPUTS; n++) { + if (idarr[n] == 255) { + idarr[n] = id; + break; + } + } analogvals[id] = value; - usedpins |= (1<setBrake(0); + analogvals[idarr[num]] = (high << 8) | low; waiting = false; - id++; - mask = mask << 1; - if (id == NUM_ADC_INPUTS+1) { - id = 0; - mask = 1; - } } if (!waiting) { - if (usedpins == 0) // otherwise we would loop forever - return; - // look for a valid track to sample or until we are around - while (true) { - if (mask & usedpins) { - // start new ADC aquire on id + // cycle around in-use analogue pins + num++; + if (idarr[num] == 255) + num = 0; + // start new ADC aquire on id #if defined(ADCSRB) && defined(MUX5) - if (ADCusesHighPort) { // if we ever have started to use high pins) - if (id > 7) // if we use a high ADC pin - bitSet(ADCSRB, MUX5); // set MUX5 bit - else - bitClear(ADCSRB, MUX5); - } -#endif - ADMUX=(1<setBrake(1); - waiting = true; - return; - } - id++; - mask = mask << 1; - if (id == NUM_ADC_INPUTS+1) { - id = 0; - mask = 1; - } + if (ADCusesHighPort) { // if we ever have started to use high pins) + if (idarr[num] > 7) // if we use a high ADC pin + bitSet(ADCSRB, MUX5); // set MUX5 bit + else + bitClear(ADCSRB, MUX5); } +#endif + ADMUX = (1 << REFS0) | (idarr[num] & 0x07); // select AVCC as reference and set MUX + bitSet(ADCSRA, ADSC); // start conversion + waiting = true; } } #pragma GCC pop_options