mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-25 00:56:13 +01:00
Compare commits
5 Commits
8a69403dda
...
d5dad767a4
Author | SHA1 | Date | |
---|---|---|---|
|
d5dad767a4 | ||
|
56fcb4e5f7 | ||
|
7783837545 | ||
|
0266936875 | ||
|
befb41ce98 |
15
DCCTimer.h
15
DCCTimer.h
|
@ -105,9 +105,14 @@ private:
|
||||||
// that an offset can be initialized.
|
// that an offset can be initialized.
|
||||||
class ADCee {
|
class ADCee {
|
||||||
public:
|
public:
|
||||||
// init does add the pin to the list of scanned pins (if this
|
// begin is called for any setup that must be done before
|
||||||
|
// **init** can be called. On some architectures this involves ADC
|
||||||
|
// initialisation and clock routing, sampling times etc.
|
||||||
|
static void begin();
|
||||||
|
// init adds the pin to the list of scanned pins (if this
|
||||||
// platform's implementation scans pins) and returns the first
|
// platform's implementation scans pins) and returns the first
|
||||||
// read value. It is called before the regular scan is started.
|
// read value (which is why it required begin to have been called first!)
|
||||||
|
// It must be called before the regular scan is started.
|
||||||
static int init(uint8_t pin);
|
static int init(uint8_t pin);
|
||||||
// read does read the pin value from the scanned cache or directly
|
// read does read the pin value from the scanned cache or directly
|
||||||
// if this is a platform that does not scan. fromISR is a hint if
|
// if this is a platform that does not scan. fromISR is a hint if
|
||||||
|
@ -116,19 +121,15 @@ public:
|
||||||
static int read(uint8_t pin, bool fromISR=false);
|
static int read(uint8_t pin, bool fromISR=false);
|
||||||
// returns possible max value that the ADC can return
|
// returns possible max value that the ADC can return
|
||||||
static int16_t ADCmax();
|
static int16_t ADCmax();
|
||||||
// begin is called for any setup that must be done before
|
|
||||||
// scan can be called.
|
|
||||||
static void begin();
|
|
||||||
private:
|
private:
|
||||||
// On platforms that scan, it is called from waveform ISR
|
// On platforms that scan, it is called from waveform ISR
|
||||||
// only on a regular basis.
|
// only on a regular basis.
|
||||||
static void scan();
|
static void scan();
|
||||||
// bit array of used pins (max 16)
|
// bit array of used pins (max 16)
|
||||||
static uint16_t usedpins;
|
static uint16_t usedpins;
|
||||||
|
static uint8_t highestPin;
|
||||||
// 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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* © 2021 Mike S
|
* © 2021 Mike S
|
||||||
* © 2021-2022 Harald Barth
|
* © 2021-2023 Harald Barth
|
||||||
* © 2021 Fred Decker
|
* © 2021 Fred Decker
|
||||||
* © 2021 Chris Harlow
|
* © 2021 Chris Harlow
|
||||||
* © 2021 David Cutting
|
* © 2021 David Cutting
|
||||||
|
@ -29,6 +29,9 @@
|
||||||
#include <avr/boot.h>
|
#include <avr/boot.h>
|
||||||
#include <avr/wdt.h>
|
#include <avr/wdt.h>
|
||||||
#include "DCCTimer.h"
|
#include "DCCTimer.h"
|
||||||
|
#ifdef DEBUG_ADC
|
||||||
|
#include "TrackManager.h"
|
||||||
|
#endif
|
||||||
INTERRUPT_CALLBACK interruptHandler=0;
|
INTERRUPT_CALLBACK interruptHandler=0;
|
||||||
|
|
||||||
// Arduino nano, uno, mega etc
|
// Arduino nano, uno, mega etc
|
||||||
|
@ -128,8 +131,8 @@ void DCCTimer::reset() {
|
||||||
#define NUM_ADC_INPUTS 8
|
#define NUM_ADC_INPUTS 8
|
||||||
#endif
|
#endif
|
||||||
uint16_t ADCee::usedpins = 0;
|
uint16_t ADCee::usedpins = 0;
|
||||||
|
uint8_t ADCee::highestPin = 0;
|
||||||
int * ADCee::analogvals = NULL;
|
int * ADCee::analogvals = NULL;
|
||||||
byte *ADCee::idarr = NULL;
|
|
||||||
static bool ADCusesHighPort = false;
|
static bool ADCusesHighPort = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -139,28 +142,17 @@ static 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;
|
||||||
byte n;
|
|
||||||
if (id >= NUM_ADC_INPUTS)
|
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, sizeof(int));
|
analogvals = (int *)calloc(NUM_ADC_INPUTS, sizeof(int));
|
||||||
for (n=0 ; n < NUM_ADC_INPUTS; n++) // set unreasonable value at startup as marker
|
analogvals[id] = value;
|
||||||
analogvals[n] = -32768; // 16 bit int min value
|
usedpins |= (1<<id);
|
||||||
idarr = (byte *)calloc(NUM_ADC_INPUTS+1, sizeof(byte)); // +1 for terminator value
|
if (id > highestPin) highestPin = id;
|
||||||
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;
|
return value;
|
||||||
}
|
}
|
||||||
int16_t ADCee::ADCmax() {
|
int16_t ADCee::ADCmax() {
|
||||||
|
@ -170,14 +162,14 @@ int16_t ADCee::ADCmax() {
|
||||||
* Read function ADCee::read(pin) to get value instead of analogRead(pin)
|
* Read function ADCee::read(pin) to get value instead of analogRead(pin)
|
||||||
*/
|
*/
|
||||||
int ADCee::read(uint8_t pin, bool fromISR) {
|
int ADCee::read(uint8_t pin, bool fromISR) {
|
||||||
(void)fromISR; // AVR does ignore this arg
|
|
||||||
uint8_t id = pin - A0;
|
uint8_t id = pin - A0;
|
||||||
int a;
|
if ((usedpins & (1<<id) ) == 0)
|
||||||
|
return -1023;
|
||||||
// we do not need to check (analogvals == NULL)
|
// we do not need to check (analogvals == NULL)
|
||||||
// because usedpins would still be 0 in that case
|
// because usedpins would still be 0 in that case
|
||||||
noInterrupts();
|
if (!fromISR) noInterrupts();
|
||||||
a = analogvals[id];
|
int a = analogvals[id];
|
||||||
interrupts();
|
if (!fromISR) interrupts();
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -186,7 +178,8 @@ 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 num = 0; // index into id array
|
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 bool waiting = false;
|
static bool waiting = false;
|
||||||
|
|
||||||
if (waiting) {
|
if (waiting) {
|
||||||
|
@ -198,26 +191,49 @@ 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[idarr[num]] = (high << 8) | low;
|
analogvals[id] = (high << 8) | low;
|
||||||
|
// advance at least one track
|
||||||
|
#ifdef DEBUG_ADC
|
||||||
|
if (id == 1) TrackManager::track[1]->setBrake(0);
|
||||||
|
#endif
|
||||||
waiting = false;
|
waiting = false;
|
||||||
|
id++;
|
||||||
|
mask = mask << 1;
|
||||||
|
if (id > highestPin) { // the 1 has been shifted out
|
||||||
|
id = 0;
|
||||||
|
mask = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!waiting) {
|
if (!waiting) {
|
||||||
// cycle around in-use analogue pins
|
if (usedpins == 0) // otherwise we would loop forever
|
||||||
num++;
|
return;
|
||||||
if (idarr[num] == 255)
|
// look for a valid track to sample or until we are around
|
||||||
num = 0;
|
while (true) {
|
||||||
|
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 (idarr[num] > 7) // if we use a high ADC pin
|
if (id > 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
|
#endif
|
||||||
ADMUX = (1 << REFS0) | (idarr[num] & 0x07); // select AVCC as reference and set MUX
|
ADMUX=(1<<REFS0)|(id & 0x07); //select AVCC as reference and set MUX
|
||||||
bitSet(ADCSRA, ADSC); // start conversion
|
bitSet(ADCSRA,ADSC); // start conversion
|
||||||
|
#ifdef DEBUG_ADC
|
||||||
|
if (id == 1) TrackManager::track[1]->setBrake(1);
|
||||||
|
#endif
|
||||||
waiting = true;
|
waiting = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
id++;
|
||||||
|
mask = mask << 1;
|
||||||
|
if (id > highestPin) {
|
||||||
|
id = 0;
|
||||||
|
mask = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma GCC pop_options
|
#pragma GCC pop_options
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#ifdef ARDUINO_ARCH_STM32
|
#ifdef ARDUINO_ARCH_STM32
|
||||||
|
|
||||||
#include "DCCTimer.h"
|
#include "DCCTimer.h"
|
||||||
|
#ifdef DEBUG_ADC
|
||||||
|
#include "TrackManager.h"
|
||||||
|
#endif
|
||||||
|
#include "DIAG.h"
|
||||||
|
|
||||||
#if defined(ARDUINO_NUCLEO_F411RE)
|
#if defined(ARDUINO_NUCLEO_F411RE)
|
||||||
// Nucleo-64 boards don't have Serial1 defined by default
|
// Nucleo-64 boards don't have Serial1 defined by default
|
||||||
|
@ -307,6 +311,8 @@ int ADCee::init(uint8_t pin) {
|
||||||
analogchans[id] = adcchan; // Keep track of which ADC channel is used for reading this pin
|
analogchans[id] = adcchan; // Keep track of which ADC channel is used for reading this pin
|
||||||
usedpins |= (1 << id); // This pin is now ready
|
usedpins |= (1 << id); // This pin is now ready
|
||||||
|
|
||||||
|
DIAG(F("ADCee::init(): value=%d, channel=%d, id=%d"), value, adcchan, id);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,11 +346,13 @@ void ADCee::scan() {
|
||||||
// found value
|
// found value
|
||||||
analogvals[id] = ADC1->DR;
|
analogvals[id] = ADC1->DR;
|
||||||
// advance at least one track
|
// advance at least one track
|
||||||
// for scope debug TrackManager::track[1]->setBrake(0);
|
#ifdef DEBUG_ADC
|
||||||
|
if (id == 1) TrackManager::track[1]->setBrake(0);
|
||||||
|
#endif
|
||||||
waiting = false;
|
waiting = false;
|
||||||
id++;
|
id++;
|
||||||
mask = mask << 1;
|
mask = mask << 1;
|
||||||
if (id == NUM_ADC_INPUTS+1) {
|
if (mask == 0) { // the 1 has been shifted out
|
||||||
id = 0;
|
id = 0;
|
||||||
mask = 1;
|
mask = 1;
|
||||||
}
|
}
|
||||||
|
@ -358,13 +366,15 @@ void ADCee::scan() {
|
||||||
// start new ADC aquire on id
|
// start new ADC aquire on id
|
||||||
ADC1->SQR3 = analogchans[id]; //1st conversion in regular sequence
|
ADC1->SQR3 = analogchans[id]; //1st conversion in regular sequence
|
||||||
ADC1->CR2 |= (1 << 30); //Start 1st conversion SWSTART
|
ADC1->CR2 |= (1 << 30); //Start 1st conversion SWSTART
|
||||||
// for scope debug TrackManager::track[1]->setBrake(1);
|
#ifdef DEBUG_ADC
|
||||||
|
if (id == 1) TrackManager::track[1]->setBrake(1);
|
||||||
|
#endif
|
||||||
waiting = true;
|
waiting = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
id++;
|
id++;
|
||||||
mask = mask << 1;
|
mask = mask << 1;
|
||||||
if (id == NUM_ADC_INPUTS+1) {
|
if (mask == 0) { // the 1 has been shifted out
|
||||||
id = 0;
|
id = 0;
|
||||||
mask = 1;
|
mask = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define GITHUB_SHA "devel-202306031954Z"
|
#define GITHUB_SHA "devel-202306182208Z"
|
||||||
|
|
|
@ -108,8 +108,13 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPin=current_pin;
|
currentPin=current_pin;
|
||||||
if (currentPin!=UNUSED_PIN)
|
if (currentPin!=UNUSED_PIN) {
|
||||||
ADCee::init(currentPin);
|
int ret = ADCee::init(currentPin);
|
||||||
|
if (ret < -1010) { // XXX give value a name later
|
||||||
|
DIAG(F("ADCee::init error %d, disable current pin %d"), ret, currentPin);
|
||||||
|
currentPin = UNUSED_PIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
senseOffset=0; // value can not be obtained until waveform is activated
|
senseOffset=0; // value can not be obtained until waveform is activated
|
||||||
|
|
||||||
if (fault_pin != UNUSED_PIN) {
|
if (fault_pin != UNUSED_PIN) {
|
||||||
|
|
|
@ -86,6 +86,13 @@ class TrackManager {
|
||||||
static bool progTrackSyncMain; // true when prog track is a siding switched to main
|
static bool progTrackSyncMain; // true when prog track is a siding switched to main
|
||||||
static bool progTrackBoosted; // true when prog track is not current limited
|
static bool progTrackBoosted; // true when prog track is not current limited
|
||||||
|
|
||||||
|
#ifdef DEBUG_ADC
|
||||||
|
public:
|
||||||
|
#else
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
static MotorDriver* track[MAX_TRACKS];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void addTrack(byte t, MotorDriver* driver);
|
static void addTrack(byte t, MotorDriver* driver);
|
||||||
static byte lastTrack;
|
static byte lastTrack;
|
||||||
|
@ -93,7 +100,6 @@ class TrackManager {
|
||||||
static POWERMODE mainPowerGuess;
|
static POWERMODE mainPowerGuess;
|
||||||
static void applyDCSpeed(byte t);
|
static void applyDCSpeed(byte t);
|
||||||
|
|
||||||
static MotorDriver* track[MAX_TRACKS];
|
|
||||||
static TRACK_MODE trackMode[MAX_TRACKS];
|
static TRACK_MODE trackMode[MAX_TRACKS];
|
||||||
static int16_t trackDCAddr[MAX_TRACKS]; // dc address if TRACK_MODE_DC or TRACK_MODE_DCX
|
static int16_t trackDCAddr[MAX_TRACKS]; // dc address if TRACK_MODE_DC or TRACK_MODE_DCX
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
|
|
||||||
#define VERSION "4.2.54"
|
#define VERSION "4.2.55"
|
||||||
|
// 4.2.55 - Optimize analog read for AVR
|
||||||
// 4.2.54 - EX8874 shield in config.example.h
|
// 4.2.54 - EX8874 shield in config.example.h
|
||||||
// - Fix: Better warnings for pin number errors
|
// - Fix: Better warnings for pin number errors
|
||||||
// - Fix: Default roster list possible in Withrottle and <jR>
|
// - Fix: Default roster list possible in Withrottle and <jR>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user