mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-30 03:26:13 +01:00
Trackmanager rework for simpler structure
This commit is contained in:
parent
86ed8ff8a6
commit
582ff890f4
|
@ -248,6 +248,11 @@ void CommandDistributor::broadcastLoco(byte slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandDistributor::broadcastPower() {
|
void CommandDistributor::broadcastPower() {
|
||||||
|
char pstr[] = "? x";
|
||||||
|
for(byte t=0; t<8; t++)
|
||||||
|
if (TrackManager::getPower(t, pstr))
|
||||||
|
broadcastReply(COMMAND_TYPE, F("<p%s>\n"),pstr);
|
||||||
|
|
||||||
bool main=TrackManager::getMainPower()==POWERMODE::ON;
|
bool main=TrackManager::getMainPower()==POWERMODE::ON;
|
||||||
bool prog=TrackManager::getProgPower()==POWERMODE::ON;
|
bool prog=TrackManager::getProgPower()==POWERMODE::ON;
|
||||||
bool join=TrackManager::isJoined();
|
bool join=TrackManager::isJoined();
|
||||||
|
|
147
DCCEXParser.cpp
147
DCCEXParser.cpp
|
@ -553,131 +553,66 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
|
|
||||||
case '1': // POWERON <1 [MAIN|PROG|JOIN]>
|
case '1': // POWERON <1 [MAIN|PROG|JOIN]>
|
||||||
{
|
{
|
||||||
bool main=false;
|
if (params > 1) break;
|
||||||
bool prog=false;
|
if (params==0) { // All
|
||||||
bool join=false;
|
TrackManager::setTrackPower(TRACK_MODE_ALL, POWERMODE::ON);
|
||||||
bool singletrack=false;
|
}
|
||||||
//byte t=0;
|
if (params==1) {
|
||||||
if (params > 1) break;
|
if (p[0]==HASH_KEYWORD_MAIN) { // <1 MAIN>
|
||||||
if (params==0) { // All
|
TrackManager::setTrackPower(TRACK_MODE_MAIN, POWERMODE::ON);
|
||||||
main=true;
|
|
||||||
prog=true;
|
|
||||||
}
|
|
||||||
if (params==1) {
|
|
||||||
if (p[0]==HASH_KEYWORD_MAIN) { // <1 MAIN>
|
|
||||||
main=true;
|
|
||||||
}
|
}
|
||||||
#ifndef DISABLE_PROG
|
#ifndef DISABLE_PROG
|
||||||
else if (p[0] == HASH_KEYWORD_JOIN) { // <1 JOIN>
|
else if (p[0] == HASH_KEYWORD_JOIN) { // <1 JOIN>
|
||||||
main=true;
|
TrackManager::setJoin(true);
|
||||||
prog=true;
|
TrackManager::setTrackPower(TRACK_MODE_MAIN|TRACK_MODE_PROG, POWERMODE::ON);
|
||||||
join=true;
|
|
||||||
}
|
}
|
||||||
else if (p[0]==HASH_KEYWORD_PROG) { // <1 PROG>
|
else if (p[0]==HASH_KEYWORD_PROG) { // <1 PROG>
|
||||||
prog=true;
|
TrackManager::setJoin(false);
|
||||||
|
TrackManager::setTrackPower(TRACK_MODE_PROG, POWERMODE::ON);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H>
|
|
||||||
else if (p[0] >= HASH_KEYWORD_A && p[0] <= HASH_KEYWORD_H) { // <1 A-H>
|
else if (p[0] >= HASH_KEYWORD_A && p[0] <= HASH_KEYWORD_H) { // <1 A-H>
|
||||||
byte t = (p[0] - 'A');
|
byte t = (p[0] - 'A');
|
||||||
//DIAG(F("Processing track - %d "), t);
|
TrackManager::setTrackPower(POWERMODE::ON, t);
|
||||||
if (TrackManager::isProg(t)) {
|
//StringFormatter::send(stream, F("<p1 %c>\n"), t+'A');
|
||||||
main = false;
|
|
||||||
prog = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
main=true;
|
|
||||||
prog=false;
|
|
||||||
}
|
|
||||||
singletrack=true;
|
|
||||||
if (main) TrackManager::setTrackPower(false, false, POWERMODE::ON, t);
|
|
||||||
if (prog) TrackManager::setTrackPower(true, false, POWERMODE::ON, t);
|
|
||||||
|
|
||||||
StringFormatter::send(stream, F("<1 %c>\n"), t+'A');
|
|
||||||
//CommandDistributor::broadcastPower();
|
|
||||||
//TrackManager::streamTrackState(NULL,t);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else break; // will reply <X>
|
else break; // will reply <X>
|
||||||
}
|
}
|
||||||
|
CommandDistributor::broadcastPower();
|
||||||
|
//TrackManager::streamTrackState(NULL,t);
|
||||||
|
|
||||||
if (!singletrack) {
|
return;
|
||||||
TrackManager::setJoin(join);
|
}
|
||||||
if (join) TrackManager::setJoinPower(POWERMODE::ON);
|
|
||||||
else {
|
|
||||||
if (main) TrackManager::setMainPower(POWERMODE::ON);
|
|
||||||
if (prog) TrackManager::setProgPower(POWERMODE::ON);
|
|
||||||
}
|
|
||||||
CommandDistributor::broadcastPower();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
case '0': // POWEROFF <0 [MAIN | PROG] >
|
case '0': // POWEROFF <0 [MAIN | PROG] >
|
||||||
{
|
{
|
||||||
bool main=false;
|
if (params > 1) break;
|
||||||
bool prog=false;
|
if (params==0) { // All
|
||||||
bool singletrack=false;
|
TrackManager::setJoin(false);
|
||||||
//byte t=0;
|
TrackManager::setTrackPower(TRACK_MODE_ALL, POWERMODE::OFF);
|
||||||
if (params > 1) break;
|
}
|
||||||
if (params==0) { // All
|
if (params==1) {
|
||||||
main=true;
|
if (p[0]==HASH_KEYWORD_MAIN) { // <0 MAIN>
|
||||||
prog=true;
|
TrackManager::setJoin(false);
|
||||||
}
|
TrackManager::setTrackPower(TRACK_MODE_MAIN, POWERMODE::OFF);
|
||||||
if (params==1) {
|
}
|
||||||
if (p[0]==HASH_KEYWORD_MAIN) { // <0 MAIN>
|
|
||||||
main=true;
|
|
||||||
}
|
|
||||||
#ifndef DISABLE_PROG
|
#ifndef DISABLE_PROG
|
||||||
else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG>
|
else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG>
|
||||||
prog=true;
|
TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off
|
||||||
|
TrackManager::setTrackPower(TRACK_MODE_PROG, POWERMODE::OFF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//else if (p[0] >= 'A' && p[0] <= 'H') { // <1 A-H>
|
else if (p[0] >= HASH_KEYWORD_A && p[0] <= HASH_KEYWORD_H) { // <1 A-H>
|
||||||
else if (p[0] >= HASH_KEYWORD_A && p[0] <= HASH_KEYWORD_H) { // <1 A-H>
|
byte t = (p[0] - 'A');
|
||||||
byte t = (p[0] - 'A');
|
TrackManager::setJoin(false);
|
||||||
//DIAG(F("Processing track - %d "), t);
|
TrackManager::setTrackPower(POWERMODE::OFF, t);
|
||||||
if (TrackManager::isProg(t)) {
|
//StringFormatter::send(stream, F("<p0 %c>\n"), t+'A');
|
||||||
main = false;
|
|
||||||
prog = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
main=true;
|
|
||||||
prog=false;
|
|
||||||
}
|
|
||||||
singletrack=true;
|
|
||||||
TrackManager::setJoin(false);
|
|
||||||
if (main) TrackManager::setTrackPower(false, false, POWERMODE::OFF, t);
|
|
||||||
if (prog) {
|
|
||||||
TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off
|
|
||||||
TrackManager::setTrackPower(true, false, POWERMODE::OFF, t);
|
|
||||||
}
|
|
||||||
StringFormatter::send(stream, F("<0 %c>\n"), t+'A');
|
|
||||||
//CommandDistributor::broadcastPower();
|
|
||||||
//TrackManager::streamTrackState(NULL, t);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else break; // will reply <X>
|
|
||||||
}
|
}
|
||||||
|
else break; // will reply <X>
|
||||||
if (!singletrack) {
|
}
|
||||||
TrackManager::setJoin(false);
|
CommandDistributor::broadcastPower();
|
||||||
|
return;
|
||||||
if (main) TrackManager::setMainPower(POWERMODE::OFF);
|
}
|
||||||
if (prog) {
|
|
||||||
TrackManager::progTrackBoosted=false; // Prog track boost mode will not outlive prog track off
|
|
||||||
TrackManager::setProgPower(POWERMODE::OFF);
|
|
||||||
}
|
|
||||||
CommandDistributor::broadcastPower();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case '!': // ESTOP ALL <!>
|
case '!': // ESTOP ALL <!>
|
||||||
DCC::setThrottle(0,1,1); // this broadcasts speed 1(estop) and sets all reminders to speed 1.
|
DCC::setThrottle(0,1,1); // this broadcasts speed 1(estop) and sets all reminders to speed 1.
|
||||||
|
|
|
@ -636,10 +636,10 @@ void RMFT2::loop2() {
|
||||||
//byte thistrack=getOperand(1);
|
//byte thistrack=getOperand(1);
|
||||||
switch (operand) {
|
switch (operand) {
|
||||||
case TRACK_POWER_0:
|
case TRACK_POWER_0:
|
||||||
TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), false, POWERMODE::OFF, getOperand(1));
|
TrackManager::setTrackPower(POWERMODE::OFF, getOperand(1));
|
||||||
break;
|
break;
|
||||||
case TRACK_POWER_1:
|
case TRACK_POWER_1:
|
||||||
TrackManager::setTrackPower(TrackManager::isProg(getOperand(1)), false, POWERMODE::ON, getOperand(1));
|
TrackManager::setTrackPower(POWERMODE::ON, getOperand(1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ template<class T> inline T operator& (T a, T b) { return (T)((int)a & (int)b); }
|
||||||
template<class T> inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); }
|
template<class T> inline T operator^ (T a, T b) { return (T)((int)a ^ (int)b); }
|
||||||
enum TRACK_MODE : byte {TRACK_MODE_NONE = 1, TRACK_MODE_MAIN = 2, TRACK_MODE_PROG = 4,
|
enum TRACK_MODE : byte {TRACK_MODE_NONE = 1, TRACK_MODE_MAIN = 2, TRACK_MODE_PROG = 4,
|
||||||
TRACK_MODE_DC = 8, TRACK_MODE_EXT = 16, TRACK_MODE_BOOST = 32,
|
TRACK_MODE_DC = 8, TRACK_MODE_EXT = 16, TRACK_MODE_BOOST = 32,
|
||||||
TRACK_MODE_INV = 64, TRACK_MODE_DCX = 72, TRACK_MODE_AUTOINV = 128};
|
TRACK_MODE_ALL = 62, // only to operate all tracks
|
||||||
|
TRACK_MODE_INV = 64, TRACK_MODE_DCX = 72 /*DC + INV*/, TRACK_MODE_AUTOINV = 128};
|
||||||
|
|
||||||
#define setHIGH(fastpin) *fastpin.inout |= fastpin.maskHIGH
|
#define setHIGH(fastpin) *fastpin.inout |= fastpin.maskHIGH
|
||||||
#define setLOW(fastpin) *fastpin.inout &= fastpin.maskLOW
|
#define setLOW(fastpin) *fastpin.inout &= fastpin.maskLOW
|
||||||
|
|
115
TrackManager.cpp
115
TrackManager.cpp
|
@ -471,51 +471,48 @@ std::vector<MotorDriver *>TrackManager::getMainDrivers() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void TrackManager::setPower2(bool setProg,bool setJoin, POWERMODE mode) {
|
// Set track power for all tracks with this mode
|
||||||
if (!setProg) mainPowerGuess=mode;
|
void TrackManager::setTrackPower(TRACK_MODE trackmode, POWERMODE powermode) {
|
||||||
FOR_EACH_TRACK(t) {
|
FOR_EACH_TRACK(t) {
|
||||||
|
MotorDriver *driver=track[t];
|
||||||
TrackManager::setTrackPower(setProg, setJoin, mode, t);
|
if (trackmode & driver->getMode()) {
|
||||||
|
if (powermode == POWERMODE::ON) {
|
||||||
}
|
if (trackmode & TRACK_MODE_DC) {
|
||||||
return;
|
driver->setBrake(true); // DC starts with brake on
|
||||||
}
|
applyDCSpeed(t); // speed match DCC throttles
|
||||||
|
} else {
|
||||||
void TrackManager::setTrackPower(bool setProg, bool setJoin, POWERMODE mode, byte thistrack) {
|
// toggle brake before turning power on - resets overcurrent error
|
||||||
|
// on the Pololu board if brake is wired to ^D2.
|
||||||
//DIAG(F("SetTrackPower Processing Track %d"), thistrack);
|
driver->setBrake(true);
|
||||||
MotorDriver * driver=track[thistrack];
|
driver->setBrake(false); // DCC runs with brake off
|
||||||
if (!driver) return;
|
}
|
||||||
|
|
||||||
TRACK_MODE tm = track[thistrack]->getMode();
|
|
||||||
if ( (tm & TRACK_MODE_MAIN)
|
|
||||||
&& !setProg ){
|
|
||||||
// toggle brake before turning power on - resets overcurrent error
|
|
||||||
// on the Pololu board if brake is wired to ^D2.
|
|
||||||
// XXX see if we can make this conditional
|
|
||||||
driver->setBrake(true);
|
|
||||||
driver->setBrake(false); // DCC runs with brake off
|
|
||||||
driver->setPower(mode);
|
|
||||||
} else if ( (tm & TRACK_MODE_DC)
|
|
||||||
&& !(setProg || setJoin)){
|
|
||||||
//DIAG(F("Processing track - %d setProg %d"), thistrack, setProg);
|
|
||||||
driver->setBrake(true); // DC starts with brake on
|
|
||||||
applyDCSpeed(thistrack); // speed match DCC throttles
|
|
||||||
driver->setPower(mode);
|
|
||||||
} else if ( (tm & TRACK_MODE_PROG)
|
|
||||||
&& (setProg || setJoin) ){
|
|
||||||
driver->setBrake(true);
|
|
||||||
driver->setBrake(false);
|
|
||||||
driver->setPower(mode);
|
|
||||||
} else if ( (tm & TRACK_MODE_EXT)
|
|
||||||
|| (tm & TRACK_MODE_BOOST)){
|
|
||||||
driver->setBrake(true);
|
|
||||||
driver->setBrake(false);
|
|
||||||
driver->setPower(mode);
|
|
||||||
}
|
}
|
||||||
|
driver->setPower(powermode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackManager::reportPowerChange(Print* stream, byte thistrack) {
|
// Set track power for this track, inependent of mode
|
||||||
|
void TrackManager::setTrackPower(POWERMODE powermode, byte t) {
|
||||||
|
MotorDriver *driver=track[t];
|
||||||
|
TRACK_MODE trackmode = driver->getMode();
|
||||||
|
if (trackmode & TRACK_MODE_DC) {
|
||||||
|
if (powermode == POWERMODE::ON) {
|
||||||
|
driver->setBrake(true); // DC starts with brake on
|
||||||
|
applyDCSpeed(t); // speed match DCC throttles
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (powermode == POWERMODE::ON) {
|
||||||
|
// toggle brake before turning power on - resets overcurrent error
|
||||||
|
// on the Pololu board if brake is wired to ^D2.
|
||||||
|
driver->setBrake(true);
|
||||||
|
driver->setBrake(false); // DCC runs with brake off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
driver->setPower(powermode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackManager::reportPowerChange(Print* stream, byte thistrack) {
|
||||||
// This function is for backward JMRI compatibility only
|
// This function is for backward JMRI compatibility only
|
||||||
// It reports the first track only, as main, regardless of track settings.
|
// It reports the first track only, as main, regardless of track settings.
|
||||||
// <c MeterName value C/V unit min max res warn>
|
// <c MeterName value C/V unit min max res warn>
|
||||||
|
@ -524,12 +521,38 @@ void TrackManager::setTrackPower(bool setProg, bool setJoin, POWERMODE mode, byt
|
||||||
track[0]->raw2mA(track[0]->getCurrentRaw(false)), maxCurrent, maxCurrent);
|
track[0]->raw2mA(track[0]->getCurrentRaw(false)), maxCurrent, maxCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns state of the one and only prog track
|
||||||
POWERMODE TrackManager::getProgPower() {
|
POWERMODE TrackManager::getProgPower() {
|
||||||
FOR_EACH_TRACK(t)
|
FOR_EACH_TRACK(t)
|
||||||
if (track[t]->getMode() & TRACK_MODE_PROG)
|
if (track[t]->getMode() & TRACK_MODE_PROG)
|
||||||
return track[t]->getPower();
|
return track[t]->getPower(); // optimize: there is max one prog track
|
||||||
return POWERMODE::OFF;
|
return POWERMODE::OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns on if all are on. returns off otherwise
|
||||||
|
POWERMODE TrackManager::getMainPower() {
|
||||||
|
POWERMODE result = POWERMODE::OFF;
|
||||||
|
FOR_EACH_TRACK(t) {
|
||||||
|
if (track[t]->getMode() & TRACK_MODE_MAIN) {
|
||||||
|
POWERMODE p = track[t]->getPower();
|
||||||
|
if (p == POWERMODE::OFF)
|
||||||
|
return POWERMODE::OFF; // done and out
|
||||||
|
if (p == POWERMODE::ON)
|
||||||
|
result = POWERMODE::ON;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrackManager::getPower(byte t, char s[]) {
|
||||||
|
if (track[t]) {
|
||||||
|
s[0] = track[t]->getPower() == POWERMODE::ON ? '1' : '0';
|
||||||
|
s[2] = t + 'A';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TrackManager::reportObsoleteCurrent(Print* stream) {
|
void TrackManager::reportObsoleteCurrent(Print* stream) {
|
||||||
// This function is for backward JMRI compatibility only
|
// This function is for backward JMRI compatibility only
|
||||||
|
|
|
@ -62,23 +62,22 @@ class TrackManager {
|
||||||
static void setDCSignal(int16_t cab, byte speedbyte);
|
static void setDCSignal(int16_t cab, byte speedbyte);
|
||||||
static MotorDriver * getProgDriver();
|
static MotorDriver * getProgDriver();
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
static std::vector<MotorDriver *>getMainDrivers();
|
static std::vector<MotorDriver *>getMainDrivers();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void setPower2(bool progTrack,bool joinTrack,POWERMODE mode);
|
|
||||||
static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);}
|
static void setPower(POWERMODE mode) {setMainPower(mode); setProgPower(mode);}
|
||||||
static void setMainPower(POWERMODE mode) {setPower2(false,false,mode);}
|
static void setTrackPower(POWERMODE mode, byte t);
|
||||||
static void setProgPower(POWERMODE mode) {setPower2(true,false,mode);}
|
static void setTrackPower(TRACK_MODE trackmode, POWERMODE powermode);
|
||||||
static void setJoinPower(POWERMODE mode) {setPower2(false,true,mode);}
|
static void setMainPower(POWERMODE mode) {setTrackPower(TRACK_MODE_MAIN, mode);}
|
||||||
static void setTrackPower(bool setProg, bool setJoin, POWERMODE mode, byte thistrack);
|
static void setProgPower(POWERMODE mode) {setTrackPower(TRACK_MODE_PROG, mode);}
|
||||||
|
|
||||||
|
|
||||||
static const int16_t MAX_TRACKS=8;
|
static const int16_t MAX_TRACKS=8;
|
||||||
static bool setTrackMode(byte track, TRACK_MODE mode, int16_t DCaddr=0);
|
static bool setTrackMode(byte track, TRACK_MODE mode, int16_t DCaddr=0);
|
||||||
static bool parseJ(Print * stream, int16_t params, int16_t p[]);
|
static bool parseJ(Print * stream, int16_t params, int16_t p[]);
|
||||||
static void loop();
|
static void loop();
|
||||||
static POWERMODE getMainPower() {return mainPowerGuess;}
|
static POWERMODE getMainPower();
|
||||||
static POWERMODE getProgPower();
|
static POWERMODE getProgPower();
|
||||||
|
static bool getPower(byte t, char s[]);
|
||||||
static void setJoin(bool join);
|
static void setJoin(bool join);
|
||||||
static bool isJoined() { return progTrackSyncMain;}
|
static bool isJoined() { return progTrackSyncMain;}
|
||||||
static void setJoinRelayPin(byte joinRelayPin);
|
static void setJoinRelayPin(byte joinRelayPin);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user