mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-07-28 18:03:45 +02:00
Compare commits
6 Commits
v5.4.14-Pr
...
devel-adct
Author | SHA1 | Date | |
---|---|---|---|
|
f6f5c22bbd | ||
|
fc3a28143d | ||
|
96f47bf44f | ||
|
9b04cd791b | ||
|
37b679ae2c | ||
|
3e4d6863bb |
@@ -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;
|
||||
};
|
||||
|
@@ -120,13 +120,14 @@ 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;
|
||||
bool ADCusesHighPort = false;
|
||||
byte *ADCee::idarr = NULL;
|
||||
static bool ADCusesHighPort = false;
|
||||
|
||||
/*
|
||||
* Register a new pin to be scanned
|
||||
@@ -135,16 +136,28 @@ 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));
|
||||
analogvals[id] = value;
|
||||
usedpins |= (1<<id);
|
||||
if (analogvals == NULL) {
|
||||
analogvals = (int *)calloc(NUM_ADC_INPUTS, sizeof(int));
|
||||
for (n=0 ; n < NUM_ADC_INPUTS; n++) // set unreasonable value at startup as marker
|
||||
analogvals[n] = -32768; // 16 bit int min value
|
||||
idarr = (byte *)calloc(NUM_ADC_INPUTS+1, sizeof(byte)); // +1 for terminator value
|
||||
for (n=0 ; n <= NUM_ADC_INPUTS; n++)
|
||||
idarr[n] = 255; // set 255 as end of array marker
|
||||
}
|
||||
analogvals[id] = value; // store before enable by idarr[n]
|
||||
for (n=0 ; n <= NUM_ADC_INPUTS; n++) {
|
||||
if (idarr[n] == 255) {
|
||||
idarr[n] = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
int16_t ADCee::ADCmax() {
|
||||
@@ -156,11 +169,13 @@ int16_t ADCee::ADCmax() {
|
||||
int ADCee::read(uint8_t pin, bool fromISR) {
|
||||
(void)fromISR; // AVR does ignore this arg
|
||||
uint8_t id = pin - A0;
|
||||
if ((usedpins & (1<<id) ) == 0)
|
||||
return -1023;
|
||||
int a;
|
||||
// we do not need to check (analogvals == NULL)
|
||||
// because usedpins would still be 0 in that case
|
||||
return analogvals[id];
|
||||
noInterrupts();
|
||||
a = analogvals[id];
|
||||
interrupts();
|
||||
return a;
|
||||
}
|
||||
/*
|
||||
* Scan function that is called from interrupt
|
||||
@@ -168,8 +183,7 @@ int ADCee::read(uint8_t pin, bool fromISR) {
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("-O3")
|
||||
void ADCee::scan() {
|
||||
static byte id = 0; // id and mask are the same thing but it is faster to
|
||||
static uint16_t mask = 1; // increment and shift instead to calculate mask from id
|
||||
static byte num = 0; // index into id array
|
||||
static bool waiting = false;
|
||||
|
||||
if (waiting) {
|
||||
@@ -181,45 +195,26 @@ void ADCee::scan() {
|
||||
low = ADCL; //must read low before high
|
||||
high = ADCH;
|
||||
bitSet(ADCSRA, ADIF);
|
||||
analogvals[id] = (high << 8) | low;
|
||||
// advance at least one track
|
||||
// for scope debug TrackManager::track[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<<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;
|
||||
}
|
||||
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
|
||||
|
@@ -727,7 +727,7 @@ void RMFT2::loop2() {
|
||||
break;
|
||||
|
||||
case OPCODE_IFRANDOM: // do block on random percentage
|
||||
skipIf=(int16_t)(micros()%100) >= operand;
|
||||
skipIf= ((uint8_t)((uint16_t)micros()>>4)) >= operand;
|
||||
break;
|
||||
|
||||
case OPCODE_IFRESERVE: // do block if we successfully RERSERVE
|
||||
|
@@ -256,7 +256,7 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = {
|
||||
#define IFGTE(sensor_id,value) OPCODE_IFGTE,V(sensor_id),OPCODE_PAD,V(value),
|
||||
#define IFLT(sensor_id,value) OPCODE_IFLT,V(sensor_id),OPCODE_PAD,V(value),
|
||||
#define IFNOT(sensor_id) OPCODE_IFNOT,V(sensor_id),
|
||||
#define IFRANDOM(percent) OPCODE_IFRANDOM,V(percent),
|
||||
#define IFRANDOM(percent) OPCODE_IFRANDOM,V(percent*255/100),
|
||||
#define IFRED(signal_id) OPCODE_IFRED,V(signal_id),
|
||||
#define IFRESERVE(block) OPCODE_IFRESERVE,V(block),
|
||||
#define IFTHROWN(turnout_id) OPCODE_IFTHROWN,V(turnout_id),
|
||||
|
@@ -1 +1 @@
|
||||
#define GITHUB_SHA "devel-202211181919Z"
|
||||
#define GITHUB_SHA "devel-202211242012Z"
|
||||
|
Reference in New Issue
Block a user