mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 23:56:13 +01:00
EXRAIL BLOCKENTER
This commit is contained in:
parent
77de250996
commit
e6bce0850f
97
EXRAIL2.cpp
97
EXRAIL2.cpp
|
@ -87,6 +87,8 @@ LookList * RMFT2::onClockLookup=NULL;
|
||||||
LookList * RMFT2::onRotateLookup=NULL;
|
LookList * RMFT2::onRotateLookup=NULL;
|
||||||
#endif
|
#endif
|
||||||
LookList * RMFT2::onOverloadLookup=NULL;
|
LookList * RMFT2::onOverloadLookup=NULL;
|
||||||
|
LookList * RMFT2::onBlockEnterLookup=NULL;
|
||||||
|
LookList * RMFT2::onBlockExitLookup=NULL;
|
||||||
byte * RMFT2::routeStateArray=nullptr;
|
byte * RMFT2::routeStateArray=nullptr;
|
||||||
const FSH * * RMFT2::routeCaptionArray=nullptr;
|
const FSH * * RMFT2::routeCaptionArray=nullptr;
|
||||||
int16_t * RMFT2::stashArray=nullptr;
|
int16_t * RMFT2::stashArray=nullptr;
|
||||||
|
@ -131,11 +133,11 @@ int16_t LookList::find(int16_t value) {
|
||||||
void LookList::chain(LookList * chain) {
|
void LookList::chain(LookList * chain) {
|
||||||
m_chain=chain;
|
m_chain=chain;
|
||||||
}
|
}
|
||||||
void LookList::handleEvent(const FSH* reason,int16_t id) {
|
void LookList::handleEvent(const FSH* reason,int16_t id, int16_t loco) {
|
||||||
// New feature... create multiple ONhandlers
|
// New feature... create multiple ONhandlers
|
||||||
for (int i=0;i<m_size;i++)
|
for (int i=0;i<m_size;i++)
|
||||||
if (m_lookupArray[i]==id)
|
if (m_lookupArray[i]==id)
|
||||||
RMFT2::startNonRecursiveTask(reason,id,m_resultArray[i]);
|
RMFT2::startNonRecursiveTask(reason,id,m_resultArray[i],loco);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,6 +205,12 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
||||||
onRotateLookup=LookListLoader(OPCODE_ONROTATE);
|
onRotateLookup=LookListLoader(OPCODE_ONROTATE);
|
||||||
#endif
|
#endif
|
||||||
onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD);
|
onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD);
|
||||||
|
|
||||||
|
if (compileFeatures & FEATURE_BLOCK) {
|
||||||
|
onBlockEnterLookup=LookListLoader(OPCODE_ONBLOCKENTER);
|
||||||
|
onBlockExitLookup=LookListLoader(OPCODE_ONBLOCKEXIT);
|
||||||
|
}
|
||||||
|
|
||||||
// onLCCLookup is not the same so not loaded here.
|
// onLCCLookup is not the same so not loaded here.
|
||||||
|
|
||||||
// Second pass startup, define any turnouts or servos, set signals red
|
// Second pass startup, define any turnouts or servos, set signals red
|
||||||
|
@ -379,7 +387,7 @@ char RMFT2::getRouteType(int16_t id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RMFT2::RMFT2(int progCtr) {
|
RMFT2::RMFT2(int progCtr, int16_t _loco) {
|
||||||
progCounter=progCtr;
|
progCounter=progCtr;
|
||||||
|
|
||||||
// get an unused task id from the flags table
|
// get an unused task id from the flags table
|
||||||
|
@ -392,9 +400,7 @@ RMFT2::RMFT2(int progCtr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delayTime=0;
|
delayTime=0;
|
||||||
loco=0;
|
loco=_loco;
|
||||||
speedo=0;
|
|
||||||
forward=true;
|
|
||||||
invert=false;
|
invert=false;
|
||||||
blinkState=not_blink_task;
|
blinkState=not_blink_task;
|
||||||
stackDepth=0;
|
stackDepth=0;
|
||||||
|
@ -412,7 +418,10 @@ RMFT2::RMFT2(int progCtr) {
|
||||||
|
|
||||||
|
|
||||||
RMFT2::~RMFT2() {
|
RMFT2::~RMFT2() {
|
||||||
driveLoco(1); // ESTOP my loco if any
|
// estop my loco if this is not an ONevent
|
||||||
|
// (prevents DONE stopping loco at the end of an
|
||||||
|
// ONBLOCKENTER or ONBLOCKEXIT )
|
||||||
|
if (loco>0 && this->onEventStartPosition==-1) DCC::setThrottle(loco,1,DCC::getThrottleDirection(loco));
|
||||||
setFlag(taskId,0,TASK_FLAG); // we are no longer using this id
|
setFlag(taskId,0,TASK_FLAG); // we are no longer using this id
|
||||||
if (next==this)
|
if (next==this)
|
||||||
loopTask=NULL;
|
loopTask=NULL;
|
||||||
|
@ -428,23 +437,9 @@ RMFT2::~RMFT2() {
|
||||||
void RMFT2::createNewTask(int route, uint16_t cab) {
|
void RMFT2::createNewTask(int route, uint16_t cab) {
|
||||||
int pc=routeLookup->find(route);
|
int pc=routeLookup->find(route);
|
||||||
if (pc<0) return;
|
if (pc<0) return;
|
||||||
RMFT2* task=new RMFT2(pc);
|
new RMFT2(pc,cab);
|
||||||
task->loco=cab;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RMFT2::driveLoco(byte speed) {
|
|
||||||
if (loco<=0) return; // Prevent broadcast!
|
|
||||||
//if (diag) DIAG(F("EXRAIL drive %d %d %d"),loco,speed,forward^invert);
|
|
||||||
/* TODO.....
|
|
||||||
power on appropriate track if DC or main if dcc
|
|
||||||
if (TrackManager::getMainPowerMode()==POWERMODE::OFF) {
|
|
||||||
TrackManager::setMainPower(POWERMODE::ON);
|
|
||||||
}
|
|
||||||
**********/
|
|
||||||
|
|
||||||
DCC::setThrottle(loco,speed, forward^invert);
|
|
||||||
speedo=speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RMFT2::readSensor(uint16_t sensorId) {
|
bool RMFT2::readSensor(uint16_t sensorId) {
|
||||||
// Exrail operands are unsigned but we need the signed version as inserted by the macros.
|
// Exrail operands are unsigned but we need the signed version as inserted by the macros.
|
||||||
|
@ -499,7 +494,7 @@ bool RMFT2::skipIfBlock() {
|
||||||
if (cv & LONG_ADDR_MARKER) { // maker bit indicates long addr
|
if (cv & LONG_ADDR_MARKER) { // maker bit indicates long addr
|
||||||
progtrackLocoId = cv ^ LONG_ADDR_MARKER; // remove marker bit to get real long addr
|
progtrackLocoId = cv ^ LONG_ADDR_MARKER; // remove marker bit to get real long addr
|
||||||
if (progtrackLocoId <= HIGHEST_SHORT_ADDR ) { // out of range for long addr
|
if (progtrackLocoId <= HIGHEST_SHORT_ADDR ) { // out of range for long addr
|
||||||
DIAG(F("Long addr %d <= %d unsupported"), progtrackLocoId, HIGHEST_SHORT_ADDR);
|
DIAG(F("Long addr %d <= %d unsupported\n"), progtrackLocoId, HIGHEST_SHORT_ADDR);
|
||||||
progtrackLocoId = -1;
|
progtrackLocoId = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -507,6 +502,15 @@ bool RMFT2::skipIfBlock() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RMFT2::pause() {
|
||||||
|
if (loco)
|
||||||
|
pauseSpeed=DCC::getThrottleSpeedByte(loco);
|
||||||
|
}
|
||||||
|
void RMFT2::resume() {
|
||||||
|
if (loco)
|
||||||
|
DCC::setThrottle(loco,pauseSpeed & 0x7f, pauseSpeed & 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
void RMFT2::loop() {
|
void RMFT2::loop() {
|
||||||
if (compileFeatures & FEATURE_SENSOR)
|
if (compileFeatures & FEATURE_SENSOR)
|
||||||
EXRAILSensor::checkAll();
|
EXRAILSensor::checkAll();
|
||||||
|
@ -571,18 +575,15 @@ void RMFT2::loop2() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case OPCODE_REV:
|
case OPCODE_REV:
|
||||||
forward = false;
|
if (loco) DCC::setThrottle(loco,operand,invert);
|
||||||
driveLoco(operand);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_FWD:
|
case OPCODE_FWD:
|
||||||
forward = true;
|
if (loco) DCC::setThrottle(loco,operand,!invert);
|
||||||
driveLoco(operand);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case OPCODE_SPEED:
|
case OPCODE_SPEED:
|
||||||
forward=DCC::getThrottleDirection(loco)^invert;
|
if (loco) DCC::setThrottle(loco,operand,DCC::getThrottleDirection(loco));
|
||||||
driveLoco(operand);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_FORGET:
|
case OPCODE_FORGET:
|
||||||
|
@ -594,12 +595,11 @@ void RMFT2::loop2() {
|
||||||
|
|
||||||
case OPCODE_INVERT_DIRECTION:
|
case OPCODE_INVERT_DIRECTION:
|
||||||
invert= !invert;
|
invert= !invert;
|
||||||
driveLoco(speedo);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_RESERVE:
|
case OPCODE_RESERVE:
|
||||||
if (getFlag(operand,SECTION_FLAG)) {
|
if (getFlag(operand,SECTION_FLAG)) {
|
||||||
driveLoco(0);
|
if (loco) DCC::setThrottle(loco,0,DCC::getThrottleDirection(loco));
|
||||||
delayMe(500);
|
delayMe(500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -697,6 +697,10 @@ void RMFT2::loop2() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_PAUSE:
|
case OPCODE_PAUSE:
|
||||||
|
// all tasks save their speed bytes
|
||||||
|
pause();
|
||||||
|
for (RMFT2 * t=next; t!=this;t=t->next) t->pause();
|
||||||
|
|
||||||
DCC::setThrottle(0,1,true); // pause all locos on the track
|
DCC::setThrottle(0,1,true); // pause all locos on the track
|
||||||
pausingTask=this;
|
pausingTask=this;
|
||||||
break;
|
break;
|
||||||
|
@ -741,8 +745,8 @@ void RMFT2::loop2() {
|
||||||
|
|
||||||
case OPCODE_RESUME:
|
case OPCODE_RESUME:
|
||||||
pausingTask=NULL;
|
pausingTask=NULL;
|
||||||
driveLoco(speedo);
|
resume();
|
||||||
for (RMFT2 * t=next; t!=this;t=t->next) if (t->loco >0) t->driveLoco(t->speedo);
|
for (RMFT2 * t=next; t!=this;t=t->next) t->resume();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_IF: // do next operand if sensor set
|
case OPCODE_IF: // do next operand if sensor set
|
||||||
|
@ -853,8 +857,7 @@ void RMFT2::loop2() {
|
||||||
|
|
||||||
case OPCODE_DRIVE:
|
case OPCODE_DRIVE:
|
||||||
{
|
{
|
||||||
byte analogSpeed=IODevice::readAnalogue(operand) *127 / 1024;
|
// Non functional but reserved
|
||||||
if (speedo!=analogSpeed) driveLoco(analogSpeed);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,8 +947,6 @@ void RMFT2::loop2() {
|
||||||
// which is intended so it can be checked
|
// which is intended so it can be checked
|
||||||
// from within EXRAIL
|
// from within EXRAIL
|
||||||
loco=progtrackLocoId;
|
loco=progtrackLocoId;
|
||||||
speedo=0;
|
|
||||||
forward=true;
|
|
||||||
invert=false;
|
invert=false;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -967,16 +968,13 @@ void RMFT2::loop2() {
|
||||||
{
|
{
|
||||||
int newPc=routeLookup->find(getOperand(1));
|
int newPc=routeLookup->find(getOperand(1));
|
||||||
if (newPc<0) break;
|
if (newPc<0) break;
|
||||||
RMFT2* newtask=new RMFT2(newPc); // create new task
|
new RMFT2(newPc,operand); // create new task
|
||||||
newtask->loco=operand;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_SETLOCO:
|
case OPCODE_SETLOCO:
|
||||||
{
|
{
|
||||||
loco=operand;
|
loco=operand;
|
||||||
speedo=0;
|
|
||||||
forward=true;
|
|
||||||
invert=false;
|
invert=false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1110,7 +1108,8 @@ void RMFT2::loop2() {
|
||||||
case OPCODE_ONROTATE:
|
case OPCODE_ONROTATE:
|
||||||
#endif
|
#endif
|
||||||
case OPCODE_ONOVERLOAD:
|
case OPCODE_ONOVERLOAD:
|
||||||
|
case OPCODE_ONBLOCKENTER:
|
||||||
|
case OPCODE_ONBLOCKEXIT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1302,6 +1301,14 @@ void RMFT2::activateEvent(int16_t addr, bool activate) {
|
||||||
else onDeactivateLookup->handleEvent(F("DEACTIVATE"),addr);
|
else onDeactivateLookup->handleEvent(F("DEACTIVATE"),addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RMFT2::blockEvent(int16_t block, int16_t loco, bool entering) {
|
||||||
|
if (compileFeatures & FEATURE_BLOCK) {
|
||||||
|
// Hunt for an ONBLOCKENTER/ONBLOCKEXIT for this accessory
|
||||||
|
if (entering) onBlockEnterLookup->handleEvent(F("BLOCKENTER"),block,loco);
|
||||||
|
else onBlockExitLookup->handleEvent(F("BLOCKEXIT"),block,loco);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RMFT2::changeEvent(int16_t vpin, bool change) {
|
void RMFT2::changeEvent(int16_t vpin, bool change) {
|
||||||
// Hunt for an ONCHANGE for this sensor
|
// Hunt for an ONCHANGE for this sensor
|
||||||
if (change) onChangeLookup->handleEvent(F("CHANGE"),vpin);
|
if (change) onChangeLookup->handleEvent(F("CHANGE"),vpin);
|
||||||
|
@ -1357,7 +1364,7 @@ void RMFT2::killBlinkOnVpin(VPIN pin, uint16_t count) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RMFT2::startNonRecursiveTask(const FSH* reason, int16_t id,int pc) {
|
void RMFT2::startNonRecursiveTask(const FSH* reason, int16_t id,int pc, int16_t loco) {
|
||||||
// Check we dont already have a task running this handler
|
// Check we dont already have a task running this handler
|
||||||
RMFT2 * task=loopTask;
|
RMFT2 * task=loopTask;
|
||||||
while(task) {
|
while(task) {
|
||||||
|
@ -1369,7 +1376,7 @@ void RMFT2::startNonRecursiveTask(const FSH* reason, int16_t id,int pc) {
|
||||||
if (task==loopTask) break;
|
if (task==loopTask) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
task=new RMFT2(pc); // new task starts at this instruction
|
task=new RMFT2(pc,loco); // new task starts at this instruction
|
||||||
task->onEventStartPosition=pc; // flag for recursion detector
|
task->onEventStartPosition=pc; // flag for recursion detector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
EXRAIL2.h
21
EXRAIL2.h
|
@ -75,8 +75,9 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,OPCODE_TOGGLE_TURNOUT,
|
||||||
OPCODE_ROUTE_ACTIVE,OPCODE_ROUTE_INACTIVE,OPCODE_ROUTE_HIDDEN,
|
OPCODE_ROUTE_ACTIVE,OPCODE_ROUTE_INACTIVE,OPCODE_ROUTE_HIDDEN,
|
||||||
OPCODE_ROUTE_DISABLED,
|
OPCODE_ROUTE_DISABLED,
|
||||||
OPCODE_STASH,OPCODE_CLEAR_STASH,OPCODE_CLEAR_ALL_STASH,OPCODE_PICKUP_STASH,
|
OPCODE_STASH,OPCODE_CLEAR_STASH,OPCODE_CLEAR_ALL_STASH,OPCODE_PICKUP_STASH,
|
||||||
OPCODE_ONBUTTON,OPCODE_ONSENSOR,
|
OPCODE_ONBUTTON,OPCODE_ONSENSOR,
|
||||||
OPCODE_NEOPIXEL,
|
OPCODE_NEOPIXEL,
|
||||||
|
OPCODE_ONBLOCKENTER,OPCODE_ONBLOCKEXIT,
|
||||||
// OPcodes below this point are skip-nesting IF operations
|
// OPcodes below this point are skip-nesting IF operations
|
||||||
// placed here so that they may be skipped as a group
|
// placed here so that they may be skipped as a group
|
||||||
// see skipIfBlock()
|
// see skipIfBlock()
|
||||||
|
@ -136,6 +137,7 @@ enum SignalType {
|
||||||
static const byte FEATURE_STASH = 0x08;
|
static const byte FEATURE_STASH = 0x08;
|
||||||
static const byte FEATURE_BLINK = 0x04;
|
static const byte FEATURE_BLINK = 0x04;
|
||||||
static const byte FEATURE_SENSOR = 0x02;
|
static const byte FEATURE_SENSOR = 0x02;
|
||||||
|
static const byte FEATURE_BLOCK = 0x01;
|
||||||
|
|
||||||
|
|
||||||
// Flag bits for status of hardware and TPL
|
// Flag bits for status of hardware and TPL
|
||||||
|
@ -162,7 +164,7 @@ class LookList {
|
||||||
int16_t findPosition(int16_t value); // finds index
|
int16_t findPosition(int16_t value); // finds index
|
||||||
int16_t size();
|
int16_t size();
|
||||||
void stream(Print * _stream);
|
void stream(Print * _stream);
|
||||||
void handleEvent(const FSH* reason,int16_t id);
|
void handleEvent(const FSH* reason,int16_t id, int16_t loco=0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int16_t m_size;
|
int16_t m_size;
|
||||||
|
@ -176,8 +178,7 @@ class LookList {
|
||||||
public:
|
public:
|
||||||
static void begin();
|
static void begin();
|
||||||
static void loop();
|
static void loop();
|
||||||
RMFT2(int progCounter);
|
RMFT2(int progCounter, int16_t cab=0);
|
||||||
RMFT2(int route, uint16_t cab);
|
|
||||||
~RMFT2();
|
~RMFT2();
|
||||||
static void readLocoCallback(int16_t cv);
|
static void readLocoCallback(int16_t cv);
|
||||||
static void createNewTask(int route, uint16_t cab);
|
static void createNewTask(int route, uint16_t cab);
|
||||||
|
@ -187,6 +188,7 @@ class LookList {
|
||||||
static void clockEvent(int16_t clocktime, bool change);
|
static void clockEvent(int16_t clocktime, bool change);
|
||||||
static void rotateEvent(int16_t id, bool change);
|
static void rotateEvent(int16_t id, bool change);
|
||||||
static void powerEvent(int16_t track, bool overload);
|
static void powerEvent(int16_t track, bool overload);
|
||||||
|
static void blockEvent(int16_t block, int16_t loco, bool entering);
|
||||||
static bool signalAspectEvent(int16_t address, byte aspect );
|
static bool signalAspectEvent(int16_t address, byte aspect );
|
||||||
// Throttle Info Access functions built by exrail macros
|
// Throttle Info Access functions built by exrail macros
|
||||||
static const byte rosterNameCount;
|
static const byte rosterNameCount;
|
||||||
|
@ -200,7 +202,7 @@ class LookList {
|
||||||
static const FSH * getRosterFunctions(int16_t id);
|
static const FSH * getRosterFunctions(int16_t id);
|
||||||
static const FSH * getTurntableDescription(int16_t id);
|
static const FSH * getTurntableDescription(int16_t id);
|
||||||
static const FSH * getTurntablePositionDescription(int16_t turntableId, uint8_t positionId);
|
static const FSH * getTurntablePositionDescription(int16_t turntableId, uint8_t positionId);
|
||||||
static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc);
|
static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc, int16_t loco=0);
|
||||||
static bool readSensor(uint16_t sensorId);
|
static bool readSensor(uint16_t sensorId);
|
||||||
static bool isSignal(int16_t id,char rag);
|
static bool isSignal(int16_t id,char rag);
|
||||||
static SIGNAL_DEFINITION getSignalSlot(int16_t slotno);
|
static SIGNAL_DEFINITION getSignalSlot(int16_t slotno);
|
||||||
|
@ -224,7 +226,6 @@ private:
|
||||||
static RMFT2 * loopTask;
|
static RMFT2 * loopTask;
|
||||||
static RMFT2 * pausingTask;
|
static RMFT2 * pausingTask;
|
||||||
void delayMe(long millisecs);
|
void delayMe(long millisecs);
|
||||||
void driveLoco(byte speedo);
|
|
||||||
bool skipIfBlock();
|
bool skipIfBlock();
|
||||||
bool readLoco();
|
bool readLoco();
|
||||||
void loop2();
|
void loop2();
|
||||||
|
@ -233,6 +234,8 @@ private:
|
||||||
void printMessage2(const FSH * msg);
|
void printMessage2(const FSH * msg);
|
||||||
void thrungeString(uint32_t strfar, thrunger mode, byte id=0);
|
void thrungeString(uint32_t strfar, thrunger mode, byte id=0);
|
||||||
uint16_t getOperand(byte n);
|
uint16_t getOperand(byte n);
|
||||||
|
void pause();
|
||||||
|
void resume();
|
||||||
|
|
||||||
static bool diag;
|
static bool diag;
|
||||||
static const HIGHFLASH3 byte RouteCode[];
|
static const HIGHFLASH3 byte RouteCode[];
|
||||||
|
@ -254,6 +257,9 @@ private:
|
||||||
static LookList * onRotateLookup;
|
static LookList * onRotateLookup;
|
||||||
#endif
|
#endif
|
||||||
static LookList * onOverloadLookup;
|
static LookList * onOverloadLookup;
|
||||||
|
static LookList * onBlockEnterLookup;
|
||||||
|
static LookList * onBlockExitLookup;
|
||||||
|
|
||||||
|
|
||||||
static const int countLCCLookup;
|
static const int countLCCLookup;
|
||||||
static int onLCCLookup[];
|
static int onLCCLookup[];
|
||||||
|
@ -278,9 +284,8 @@ private:
|
||||||
byte taskId;
|
byte taskId;
|
||||||
BlinkState blinkState; // includes AT_TIMEOUT flag.
|
BlinkState blinkState; // includes AT_TIMEOUT flag.
|
||||||
uint16_t loco;
|
uint16_t loco;
|
||||||
bool forward;
|
|
||||||
bool invert;
|
bool invert;
|
||||||
byte speedo;
|
byte pauseSpeed;
|
||||||
int onEventStartPosition;
|
int onEventStartPosition;
|
||||||
byte stackDepth;
|
byte stackDepth;
|
||||||
int callStack[MAX_STACK_DEPTH];
|
int callStack[MAX_STACK_DEPTH];
|
||||||
|
|
|
@ -110,6 +110,8 @@
|
||||||
#undef ONACTIVATE
|
#undef ONACTIVATE
|
||||||
#undef ONACTIVATEL
|
#undef ONACTIVATEL
|
||||||
#undef ONAMBER
|
#undef ONAMBER
|
||||||
|
#undef ONBLOCKENTER
|
||||||
|
#undef ONBLOCKEXIT
|
||||||
#undef ONDEACTIVATE
|
#undef ONDEACTIVATE
|
||||||
#undef ONDEACTIVATEL
|
#undef ONDEACTIVATEL
|
||||||
#undef ONCLOSE
|
#undef ONCLOSE
|
||||||
|
@ -281,6 +283,8 @@
|
||||||
#define ONACTIVATE(addr,subaddr)
|
#define ONACTIVATE(addr,subaddr)
|
||||||
#define ONACTIVATEL(linear)
|
#define ONACTIVATEL(linear)
|
||||||
#define ONAMBER(signal_id)
|
#define ONAMBER(signal_id)
|
||||||
|
#define ONBLOCKENTER(blockid)
|
||||||
|
#define ONBLOCKEXIT(blockid)
|
||||||
#define ONTIME(value)
|
#define ONTIME(value)
|
||||||
#define ONCLOCKTIME(hours,mins)
|
#define ONCLOCKTIME(hours,mins)
|
||||||
#define ONCLOCKMINS(mins)
|
#define ONCLOCKMINS(mins)
|
||||||
|
|
|
@ -210,6 +210,14 @@ void RMFT2::ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'K': // <K blockid loco> Block enter
|
||||||
|
case 'k': // <k blockid loco> Block exit
|
||||||
|
if (paramCount!=2) break;
|
||||||
|
blockEvent(p[0],p[1],opcode=='K');
|
||||||
|
opcode=0;
|
||||||
|
break;
|
||||||
|
|
||||||
default: // other commands pass through
|
default: // other commands pass through
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -228,11 +236,9 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StringFormatter::send(stream,F("\nID=%d,PC=%d,LOCO=%d%c,SPEED=%d%c"),
|
StringFormatter::send(stream,F("\nID=%d,PC=%d,LOCO=%d %c"),
|
||||||
(int)(task->taskId),task->progCounter,task->loco,
|
(int)(task->taskId),task->progCounter,task->loco,
|
||||||
task->invert?'I':' ',
|
task->invert?'I':' '
|
||||||
task->speedo,
|
|
||||||
task->forward?'F':'R'
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
task=task->next;
|
task=task->next;
|
||||||
|
@ -276,19 +282,27 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
|
||||||
switch (p[0]) {
|
switch (p[0]) {
|
||||||
case "PAUSE"_hk: // </ PAUSE>
|
case "PAUSE"_hk: // </ PAUSE>
|
||||||
if (paramCount!=1) return false;
|
if (paramCount!=1) return false;
|
||||||
DCC::setThrottle(0,1,true); // pause all locos on the track
|
{ // pause all tasks
|
||||||
|
RMFT2 * task=loopTask;
|
||||||
|
while(task) {
|
||||||
|
task->pause();
|
||||||
|
task=task->next;
|
||||||
|
if (task==loopTask) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCC::setThrottle(0,1,true); // stop all locos on the track
|
||||||
pausingTask=(RMFT2 *)1; // Impossible task address
|
pausingTask=(RMFT2 *)1; // Impossible task address
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case "RESUME"_hk: // </ RESUME>
|
case "RESUME"_hk: // </ RESUME>
|
||||||
if (paramCount!=1) return false;
|
if (paramCount!=1) return false;
|
||||||
pausingTask=NULL;
|
pausingTask=NULL;
|
||||||
{
|
{ // resume all tasks
|
||||||
RMFT2 * task=loopTask;
|
RMFT2 * task=loopTask;
|
||||||
while(task) {
|
while(task) {
|
||||||
if (task->loco) task->driveLoco(task->speedo);
|
task->resume();
|
||||||
task=task->next;
|
task=task->next;
|
||||||
if (task==loopTask) break;
|
if (task==loopTask) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -301,8 +315,7 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
|
||||||
uint16_t cab=(paramCount==2)? 0 : p[1];
|
uint16_t cab=(paramCount==2)? 0 : p[1];
|
||||||
int pc=routeLookup->find(route);
|
int pc=routeLookup->find(route);
|
||||||
if (pc<0) return false;
|
if (pc<0) return false;
|
||||||
RMFT2* task=new RMFT2(pc);
|
new RMFT2(pc,cab);
|
||||||
task->loco=cab;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,10 @@ bool exrailHalSetup() {
|
||||||
#define ONBUTTON(vpin) | FEATURE_SENSOR
|
#define ONBUTTON(vpin) | FEATURE_SENSOR
|
||||||
#undef ONSENSOR
|
#undef ONSENSOR
|
||||||
#define ONSENSOR(vpin) | FEATURE_SENSOR
|
#define ONSENSOR(vpin) | FEATURE_SENSOR
|
||||||
|
#undef ONBLOCKENTER
|
||||||
|
#define ONBLOCKENTER(blockid) | FEATURE_BLOCK
|
||||||
|
#undef ONBLOCKEXIT
|
||||||
|
#define ONBLOCKEXIT(blockid) | FEATURE_BLOCK
|
||||||
|
|
||||||
const byte RMFT2::compileFeatures = 0
|
const byte RMFT2::compileFeatures = 0
|
||||||
#include "myAutomation.h"
|
#include "myAutomation.h"
|
||||||
|
@ -570,6 +574,8 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
|
||||||
#define ONACTIVATE(addr,subaddr) OPCODE_ONACTIVATE,V(addr<<2|subaddr),
|
#define ONACTIVATE(addr,subaddr) OPCODE_ONACTIVATE,V(addr<<2|subaddr),
|
||||||
#define ONACTIVATEL(linear) OPCODE_ONACTIVATE,V(linear+3),
|
#define ONACTIVATEL(linear) OPCODE_ONACTIVATE,V(linear+3),
|
||||||
#define ONAMBER(signal_id) OPCODE_ONAMBER,V(signal_id),
|
#define ONAMBER(signal_id) OPCODE_ONAMBER,V(signal_id),
|
||||||
|
#define ONBLOCKENTER(block_id) OPCODE_ONBLOCKENTER,V(block_id),
|
||||||
|
#define ONBLOCKEXIT(block_id) OPCODE_ONBLOCKEXIT,V(block_id),
|
||||||
#define ONCLOSE(turnout_id) OPCODE_ONCLOSE,V(turnout_id),
|
#define ONCLOSE(turnout_id) OPCODE_ONCLOSE,V(turnout_id),
|
||||||
#define ONLCC(sender,event) OPCODE_ONLCC,V(event),\
|
#define ONLCC(sender,event) OPCODE_ONLCC,V(event),\
|
||||||
OPCODE_PAD,V((((uint64_t)sender)>>32)&0xFFFF),\
|
OPCODE_PAD,V((((uint64_t)sender)>>32)&0xFFFF),\
|
||||||
|
|
Loading…
Reference in New Issue
Block a user