diff --git a/CommandDistributor.cpp b/CommandDistributor.cpp
index 6e6fe60..85df03b 100644
--- a/CommandDistributor.cpp
+++ b/CommandDistributor.cpp
@@ -122,7 +122,7 @@ void CommandDistributor::broadcastLoco(byte slot) {
void CommandDistributor::broadcastPower() {
bool main=TrackManager::getMainPower()==POWERMODE::ON;
bool prog=TrackManager::getProgPower()==POWERMODE::ON;
- bool join=DCCWaveform::isJoined();
+ bool join=TrackManager::isJoined();
const FSH * reason=F("");
char state='1';
if (main && prog && join) reason=F(" JOIN");
diff --git a/DCC.cpp b/DCC.cpp
index 5188cda..977a304 100644
--- a/DCC.cpp
+++ b/DCC.cpp
@@ -557,8 +557,7 @@ void DCC::forgetAllLocos() { // removes all speed reminders
byte DCC::loopStatus=0;
void DCC::loop() {
- DCCWaveform::loop(); // power overload checks
- DCCACK::loop(); // maintain prog track ack manager
+ TrackManager::loop(); // power overload checks
issueReminders();
}
diff --git a/DCCACK.cpp b/DCCACK.cpp
index bc115c0..7c159b8 100644
--- a/DCCACK.cpp
+++ b/DCCACK.cpp
@@ -77,10 +77,10 @@ void DCCACK::Setup(int cv, byte byteValueOrBitnum, ackOp const program[], ACK_C
return;
}
- ackManagerRejoin=DCCWaveform::isJoined();
+ ackManagerRejoin=TrackManager::isJoined();
if (ackManagerRejoin ) {
// Change from JOIN must zero resets packet.
- DCCWaveform::setJoin(false);
+ TrackManager::setJoin(false);
DCCWaveform::progTrack.sentResetsSincePacket = 0;
}
@@ -403,7 +403,7 @@ void DCCACK::callback(int value) {
}
// Restore <1 JOIN> to state before BASELINE
if (ackManagerRejoin) {
- DCCWaveform::setJoin(true);
+ TrackManager::setJoin(true);
if (Diag::ACK) DIAG(F("Auto JOIN"));
}
diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp
index 6237e48..4d478cb 100644
--- a/DCCEXParser.cpp
+++ b/DCCEXParser.cpp
@@ -397,7 +397,7 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream)
}
if (main) TrackManager::setMainPower(POWERMODE::ON);
if (prog) TrackManager::setProgPower(POWERMODE::ON);
- DCCWaveform::setJoin(join);
+ TrackManager::setJoin(join);
CommandDistributor::broadcastPower();
return;
@@ -424,10 +424,10 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream)
if (main) TrackManager::setMainPower(POWERMODE::OFF);
if (prog) {
- DCCWaveform::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off
+ TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off
TrackManager::setProgPower(POWERMODE::OFF);
}
- DCCWaveform::setJoin(false);
+ TrackManager::setJoin(false);
CommandDistributor::broadcastPower();
return;
@@ -772,8 +772,8 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[])
#endif
case HASH_KEYWORD_PROGBOOST:
- DCCWaveform::progTrackBoosted=true;
- return true;
+ TrackManager::progTrackBoosted=true;
+ return true;
case HASH_KEYWORD_RESET:
{
diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp
index c51a18e..0258627 100644
--- a/DCCWaveform.cpp
+++ b/DCCWaveform.cpp
@@ -21,7 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see .
*/
-
+#ifndef ARDUINO_ARCH_ESP32
+ // This code is replaced entirely on an ESP32
#include
#include "DCCWaveform.h"
@@ -34,19 +35,38 @@
DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true);
DCCWaveform DCCWaveform::progTrack(PREAMBLE_BITS_PROG, false);
-bool DCCWaveform::progTrackSyncMain=false;
-bool DCCWaveform::progTrackBoosted=false;
-int16_t DCCWaveform::joinRelay=UNUSED_PIN;
+
+// This bitmask has 9 entries as each byte is trasmitted as a zero + 8 bits.
+const byte bitMask[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+
+const byte idlePacket[] = {0xFF, 0x00, 0xFF};
+const byte resetPacket[] = {0x00, 0x00, 0x00};
+
+
+// For each state of the wave nextState=stateTransform[currentState]
+const WAVE_STATE stateTransform[]={
+ /* WAVE_START -> */ WAVE_PENDING,
+ /* WAVE_MID_1 -> */ WAVE_START,
+ /* WAVE_HIGH_0 -> */ WAVE_MID_0,
+ /* WAVE_MID_0 -> */ WAVE_LOW_0,
+ /* WAVE_LOW_0 -> */ WAVE_START,
+ /* WAVE_PENDING (should not happen) -> */ WAVE_PENDING};
+
+// For each state of the wave, signal pin is HIGH or LOW
+const bool signalTransform[]={
+ /* WAVE_START -> */ HIGH,
+ /* WAVE_MID_1 -> */ LOW,
+ /* WAVE_HIGH_0 -> */ HIGH,
+ /* WAVE_MID_0 -> */ LOW,
+ /* WAVE_LOW_0 -> */ LOW,
+ /* WAVE_PENDING (should not happen) -> */ LOW};
void DCCWaveform::begin() {
-
- TrackManager::setPower(POWERMODE::OFF);
DCCTimer::begin(DCCWaveform::interruptHandler);
}
void DCCWaveform::loop() {
- DCCACK::loop();
- TrackManager::loop(DCCACK::isActive() || progTrackSyncMain || progTrackBoosted );
+ // empty placemarker in case ESP32 needs something here
}
#pragma GCC push_options
@@ -55,7 +75,7 @@ void DCCWaveform::interruptHandler() {
// call the timer edge sensitive actions for progtrack and maintrack
// member functions would be cleaner but have more overhead
byte sigMain=signalTransform[mainTrack.state];
- byte sigProg=progTrackSyncMain? sigMain : signalTransform[progTrack.state];
+ byte sigProg=TrackManager::progTrackSyncMain? sigMain : signalTransform[progTrack.state];
// Set the signal state for both tracks
TrackManager::setDCCSignal(sigMain);
@@ -73,18 +93,6 @@ void DCCWaveform::interruptHandler() {
}
#pragma GCC push_options
-void DCCWaveform::setJoinRelayPin(byte joinRelayPin) {
- joinRelay=joinRelayPin;
- if (joinRelay!=UNUSED_PIN) {
- pinMode(joinRelay,OUTPUT);
- digitalWrite(joinRelay,LOW); // LOW is relay disengaged
- }
-}
-
-void DCCWaveform::setJoin(bool joined) {
- progTrackSyncMain=joined;
- if (joinRelay!=UNUSED_PIN) digitalWrite(joinRelay,joined?HIGH:LOW);
-}
// An instance of this class handles the DCC transmissions for one track. (main or prog)
// Interrupts are marshalled via the statics.
@@ -92,9 +100,6 @@ void DCCWaveform::setJoin(bool joined) {
// When the current buffer is exhausted, either the pending buffer (if there is one waiting) or an idle buffer.
-// This bitmask has 9 entries as each byte is trasmitted as a zero + 8 bits.
-const byte bitMask[] = {0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-
DCCWaveform::DCCWaveform( byte preambleBits, bool isMain) {
isMainTrack = isMain;
@@ -110,25 +115,7 @@ DCCWaveform::DCCWaveform( byte preambleBits, bool isMain) {
-// For each state of the wave nextState=stateTransform[currentState]
-const WAVE_STATE DCCWaveform::stateTransform[]={
- /* WAVE_START -> */ WAVE_PENDING,
- /* WAVE_MID_1 -> */ WAVE_START,
- /* WAVE_HIGH_0 -> */ WAVE_MID_0,
- /* WAVE_MID_0 -> */ WAVE_LOW_0,
- /* WAVE_LOW_0 -> */ WAVE_START,
- /* WAVE_PENDING (should not happen) -> */ WAVE_PENDING};
-
-// For each state of the wave, signal pin is HIGH or LOW
-const bool DCCWaveform::signalTransform[]={
- /* WAVE_START -> */ HIGH,
- /* WAVE_MID_1 -> */ LOW,
- /* WAVE_HIGH_0 -> */ HIGH,
- /* WAVE_MID_0 -> */ LOW,
- /* WAVE_LOW_0 -> */ LOW,
- /* WAVE_PENDING (should not happen) -> */ LOW};
-#pragma GCC push_options
#pragma GCC optimize ("-O3")
void DCCWaveform::interrupt2() {
// calculate the next bit to be sent:
@@ -185,8 +172,6 @@ void DCCWaveform::interrupt2() {
}
}
}
-#pragma GCC pop_options
-
// Wait until there is no packet pending, then make this pending
void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repeats) {
@@ -205,7 +190,4 @@ void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repea
packetPending = true;
sentResetsSincePacket=0;
}
-
-#pragma GCC push_options
-#pragma GCC optimize ("-O3")
-#pragma GCC pop_options
+#endif
\ No newline at end of file
diff --git a/DCCWaveform.h b/DCCWaveform.h
index 2ad1c67..667e220 100644
--- a/DCCWaveform.h
+++ b/DCCWaveform.h
@@ -33,19 +33,14 @@ const int PREAMBLE_BITS_MAIN = 16;
const int PREAMBLE_BITS_PROG = 22;
const byte MAX_PACKET_SIZE = 5; // NMRA standard extended packets, payload size WITHOUT checksum.
+
// The WAVE_STATE enum is deliberately numbered because a change of order would be catastrophic
// to the transform array.
enum WAVE_STATE : byte {WAVE_START=0,WAVE_MID_1=1,WAVE_HIGH_0=2,WAVE_MID_0=3,WAVE_LOW_0=4,WAVE_PENDING=5};
-
// NOTE: static functions are used for the overall controller, then
// one instance is created for each track.
-
-
-const byte idlePacket[] = {0xFF, 0x00, 0xFF};
-const byte resetPacket[] = {0x00, 0x00, 0x00};
-
class DCCWaveform {
public:
DCCWaveform( byte preambleBits, bool isMain);
@@ -53,26 +48,12 @@ class DCCWaveform {
static void loop();
static DCCWaveform mainTrack;
static DCCWaveform progTrack;
-
- void beginTrack();
- static void setJoin(bool join);
- static bool isJoined() { return progTrackSyncMain;}
void clearRepeats() {pendingRepeats=0;}
void schedulePacket(const byte buffer[], byte byteCount, byte repeats);
volatile bool packetPending;
- static bool progTrackBoosted; // true when prog track is not current limited
volatile byte sentResetsSincePacket;
- static void setJoinRelayPin(byte joinRelayPin);
- static int16_t joinRelay;
private:
- static bool progTrackSyncMain; // true when prog track is a siding switched to main
-
-// For each state of the wave nextState=stateTransform[currentState]
- static const WAVE_STATE stateTransform[6];
-
-// For each state of the wave, signal pin is HIGH or LOW
- static const bool signalTransform[6];
static void interruptHandler();
void interrupt2();
diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp
index 381d043..e4451a2 100644
--- a/EXRAIL2.cpp
+++ b/EXRAIL2.cpp
@@ -665,7 +665,7 @@ void RMFT2::loop2() {
case OPCODE_POWEROFF:
TrackManager::setPower(POWERMODE::OFF);
- DCCWaveform::setJoin(false);
+ TrackManager::setJoin(false);
CommandDistributor::broadcastPower();
break;
@@ -811,18 +811,18 @@ void RMFT2::loop2() {
case OPCODE_JOIN:
TrackManager::setPower(POWERMODE::ON);
- DCCWaveform::setJoin(true);
+ TrackManager::setJoin(true);
CommandDistributor::broadcastPower();
break;
case OPCODE_POWERON:
TrackManager::setMainPower(POWERMODE::ON);
- DCCWaveform::setJoin(false);
+ TrackManager::setJoin(false);
CommandDistributor::broadcastPower();
break;
case OPCODE_UNJOIN:
- DCCWaveform::setJoin(false);
+ TrackManager::setJoin(false);
CommandDistributor::broadcastPower();
break;
diff --git a/TrackManager.cpp b/TrackManager.cpp
index 17dd754..470e039 100644
--- a/TrackManager.cpp
+++ b/TrackManager.cpp
@@ -41,6 +41,10 @@ MotorDriver * TrackManager::track[MAX_TRACKS];
int16_t TrackManager::trackMode[MAX_TRACKS];
POWERMODE TrackManager::mainPowerGuess=POWERMODE::OFF;
byte TrackManager::lastTrack=0;
+bool TrackManager::progTrackSyncMain=false;
+bool TrackManager::progTrackBoosted=false;
+int16_t TrackManager::joinRelay=UNUSED_PIN;
+
// The setup call is done this way so that the tracks can be in a list
// from the config... the tracks default to NULL in the declaration
@@ -158,7 +162,10 @@ bool TrackManager::parseJ(Print *stream, int16_t params, int16_t p[])
byte TrackManager::nextCycleTrack=MAX_TRACKS;
-void TrackManager::loop(bool dontLimitProg) {
+void TrackManager::loop() {
+ DCCWaveform::loop();
+ DCCACK::loop();
+ bool dontLimitProg=DCCACK::isActive() || progTrackSyncMain || progTrackBoosted;
nextCycleTrack++;
if (nextCycleTrack>lastTrack) nextCycleTrack=0;
if (track[nextCycleTrack]==NULL) return;
@@ -193,3 +200,15 @@ POWERMODE TrackManager::getProgPower() {
return POWERMODE::OFF;
}
+void TrackManager::setJoinRelayPin(byte joinRelayPin) {
+ joinRelay=joinRelayPin;
+ if (joinRelay!=UNUSED_PIN) {
+ pinMode(joinRelay,OUTPUT);
+ digitalWrite(joinRelay,LOW); // LOW is relay disengaged
+ }
+}
+
+void TrackManager::setJoin(bool joined) {
+ progTrackSyncMain=joined;
+ if (joinRelay!=UNUSED_PIN) digitalWrite(joinRelay,joined?HIGH:LOW);
+}
diff --git a/TrackManager.h b/TrackManager.h
index f861edb..18a073f 100644
--- a/TrackManager.h
+++ b/TrackManager.h
@@ -53,10 +53,16 @@ class TrackManager {
static const int16_t MAX_TRACKS=8;
static bool setTrackMode(byte track, int16_t DCaddrOrMode);
static bool parseJ(Print * stream, int16_t params, int16_t p[]);
- static void loop(bool dontLimitProg);
+ static void loop();
static POWERMODE getMainPower() {return mainPowerGuess;}
static POWERMODE getProgPower();
-
+ static void setJoin(bool join);
+ static bool isJoined() { return progTrackSyncMain;}
+ static void setJoinRelayPin(byte joinRelayPin);
+ static int16_t joinRelay;
+ static bool progTrackSyncMain; // true when prog track is a siding switched to main
+ static bool progTrackBoosted; // true when prog track is not current limited
+
private:
static void addTrack(byte t, MotorDriver* driver);
diff --git a/WiThrottle.cpp b/WiThrottle.cpp
index 1ac93f6..fed5078 100644
--- a/WiThrottle.cpp
+++ b/WiThrottle.cpp
@@ -543,7 +543,7 @@ void WiThrottle::getLocoCallback(int16_t locoid) {
itoa(locoid,addcmd+4,10);
stashInstance->multithrottle(stashStream, (byte *)addcmd);
TrackManager::setMainPower(POWERMODE::ON);
- DCCWaveform::setJoin(true); // <1 JOIN> so we can drive loco away
+ TrackManager::setJoin(true); // <1 JOIN> so we can drive loco away
stashStream->commit();
CommandDistributor::broadcastPower();