mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-02-19 23:46:02 +01:00
scan ADC pins with id array
This commit is contained in:
parent
e1ec63464c
commit
3e4d6863bb
@ -124,6 +124,8 @@ private:
|
|||||||
static uint16_t usedpins;
|
static uint16_t usedpins;
|
||||||
// cached analog values (malloc:ed to actual number of ADC channels)
|
// cached analog values (malloc:ed to actual number of ADC channels)
|
||||||
static int *analogvals;
|
static int *analogvals;
|
||||||
|
// ids to scan (new way)
|
||||||
|
static byte *idarr;
|
||||||
// friend so that we can call scan() and begin()
|
// friend so that we can call scan() and begin()
|
||||||
friend class DCCWaveform;
|
friend class DCCWaveform;
|
||||||
};
|
};
|
||||||
|
@ -120,12 +120,13 @@ void DCCTimer::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560)
|
#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560)
|
||||||
#define NUM_ADC_INPUTS 15
|
#define NUM_ADC_INPUTS 16
|
||||||
#else
|
#else
|
||||||
#define NUM_ADC_INPUTS 7
|
#define NUM_ADC_INPUTS 8
|
||||||
#endif
|
#endif
|
||||||
uint16_t ADCee::usedpins = 0;
|
uint16_t ADCee::usedpins = 0;
|
||||||
int * ADCee::analogvals = NULL;
|
int * ADCee::analogvals = NULL;
|
||||||
|
byte *ADCee::idarr = NULL;
|
||||||
bool ADCusesHighPort = false;
|
bool ADCusesHighPort = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -135,16 +136,26 @@ bool ADCusesHighPort = false;
|
|||||||
*/
|
*/
|
||||||
int ADCee::init(uint8_t pin) {
|
int ADCee::init(uint8_t pin) {
|
||||||
uint8_t id = pin - A0;
|
uint8_t id = pin - A0;
|
||||||
if (id > NUM_ADC_INPUTS)
|
byte n;
|
||||||
|
if (id >= NUM_ADC_INPUTS)
|
||||||
return -1023;
|
return -1023;
|
||||||
if (id > 7)
|
if (id > 7)
|
||||||
ADCusesHighPort = true;
|
ADCusesHighPort = true;
|
||||||
pinMode(pin, INPUT);
|
pinMode(pin, INPUT);
|
||||||
int value = analogRead(pin);
|
int value = analogRead(pin);
|
||||||
if (analogvals == NULL)
|
if (analogvals == NULL) {
|
||||||
analogvals = (int *)calloc(NUM_ADC_INPUTS+1, sizeof(int));
|
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;
|
analogvals[id] = value;
|
||||||
usedpins |= (1<<id);
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
int16_t ADCee::ADCmax() {
|
int16_t ADCee::ADCmax() {
|
||||||
@ -168,8 +179,7 @@ int ADCee::read(uint8_t pin, bool fromISR) {
|
|||||||
#pragma GCC push_options
|
#pragma GCC push_options
|
||||||
#pragma GCC optimize ("-O3")
|
#pragma GCC optimize ("-O3")
|
||||||
void ADCee::scan() {
|
void ADCee::scan() {
|
||||||
static byte id = 0; // id and mask are the same thing but it is faster to
|
static byte num = 0; // index into id array
|
||||||
static uint16_t mask = 1; // increment and shift instead to calculate mask from id
|
|
||||||
static bool waiting = false;
|
static bool waiting = false;
|
||||||
|
|
||||||
if (waiting) {
|
if (waiting) {
|
||||||
@ -181,45 +191,26 @@ void ADCee::scan() {
|
|||||||
low = ADCL; //must read low before high
|
low = ADCL; //must read low before high
|
||||||
high = ADCH;
|
high = ADCH;
|
||||||
bitSet(ADCSRA, ADIF);
|
bitSet(ADCSRA, ADIF);
|
||||||
analogvals[id] = (high << 8) | low;
|
analogvals[idarr[num]] = (high << 8) | low;
|
||||||
// advance at least one track
|
|
||||||
// for scope debug TrackManager::track[1]->setBrake(0);
|
|
||||||
waiting = false;
|
waiting = false;
|
||||||
id++;
|
|
||||||
mask = mask << 1;
|
|
||||||
if (id == NUM_ADC_INPUTS+1) {
|
|
||||||
id = 0;
|
|
||||||
mask = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!waiting) {
|
if (!waiting) {
|
||||||
if (usedpins == 0) // otherwise we would loop forever
|
// cycle around in-use analogue pins
|
||||||
return;
|
num++;
|
||||||
// look for a valid track to sample or until we are around
|
if (idarr[num] == 255)
|
||||||
while (true) {
|
num = 0;
|
||||||
if (mask & usedpins) {
|
// start new ADC aquire on id
|
||||||
// start new ADC aquire on id
|
|
||||||
#if defined(ADCSRB) && defined(MUX5)
|
#if defined(ADCSRB) && defined(MUX5)
|
||||||
if (ADCusesHighPort) { // if we ever have started to use high pins)
|
if (ADCusesHighPort) { // if we ever have started to use high pins)
|
||||||
if (id > 7) // if we use a high ADC pin
|
if (idarr[num] > 7) // if we use a high ADC pin
|
||||||
bitSet(ADCSRB, MUX5); // set MUX5 bit
|
bitSet(ADCSRB, MUX5); // set MUX5 bit
|
||||||
else
|
else
|
||||||
bitClear(ADCSRB, MUX5);
|
bitClear(ADCSRB, MUX5);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ADMUX=(1<<REFS0)|(id & 0x07); //select AVCC as reference and set MUX
|
|
||||||
bitSet(ADCSRA,ADSC); // start conversion
|
|
||||||
// for scope debug TrackManager::track[1]->setBrake(1);
|
|
||||||
waiting = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
id++;
|
|
||||||
mask = mask << 1;
|
|
||||||
if (id == NUM_ADC_INPUTS+1) {
|
|
||||||
id = 0;
|
|
||||||
mask = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#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
|
#pragma GCC pop_options
|
||||||
|
Loading…
Reference in New Issue
Block a user