1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

CODE TIDY

Moved join code out of DCCWaveform to reduce footprint for ESP32 waveform replacement.
This commit is contained in:
Asbelos 2022-03-19 11:22:31 +00:00
parent 4f2dc0934f
commit be186b967b
10 changed files with 74 additions and 87 deletions

View File

@ -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");

View File

@ -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();
}

View File

@ -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"));
}

View File

@ -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:
{

View File

@ -21,7 +21,8 @@
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ARDUINO_ARCH_ESP32
// This code is replaced entirely on an ESP32
#include <Arduino.h>
#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

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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();