mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 23:56:13 +01:00
ONBLOCKENTER/EXIT
This commit is contained in:
parent
9d6931c438
commit
8a96791937
|
@ -343,6 +343,15 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'k': // <k blockid cabid> exiting block
|
||||||
|
case 'K': // <K blockid cabid> entering block
|
||||||
|
if (params!=2) break;
|
||||||
|
#ifdef EXRAIL_ACTIVE
|
||||||
|
// without EXrail, valid block commands are ignored
|
||||||
|
RMFT2::blockEvent(p[0],p[1],opcode=='K');
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
case 'w': // WRITE CV on MAIN <w CAB CV VALUE>
|
case 'w': // WRITE CV on MAIN <w CAB CV VALUE>
|
||||||
DCC::writeCVByteMain(p[0], p[1], p[2]);
|
DCC::writeCVByteMain(p[0], p[1], p[2]);
|
||||||
return;
|
return;
|
||||||
|
|
25
EXRAIL2.cpp
25
EXRAIL2.cpp
|
@ -90,6 +90,8 @@ LookList * RMFT2::onDeactivateLookup=NULL;
|
||||||
LookList * RMFT2::onRedLookup=NULL;
|
LookList * RMFT2::onRedLookup=NULL;
|
||||||
LookList * RMFT2::onAmberLookup=NULL;
|
LookList * RMFT2::onAmberLookup=NULL;
|
||||||
LookList * RMFT2::onGreenLookup=NULL;
|
LookList * RMFT2::onGreenLookup=NULL;
|
||||||
|
LookList * RMFT2::onBlockEnterLookup=NULL;
|
||||||
|
LookList * RMFT2::onBlockExitLookup=NULL;
|
||||||
|
|
||||||
#define GET_OPCODE GETFLASH(RMFT2::RouteCode+progCounter)
|
#define GET_OPCODE GETFLASH(RMFT2::RouteCode+progCounter)
|
||||||
#define GET_OPERAND(n) GETFLASHW(RMFT2::RouteCode+progCounter+1+(n*3))
|
#define GET_OPERAND(n) GETFLASHW(RMFT2::RouteCode+progCounter+1+(n*3))
|
||||||
|
@ -153,6 +155,8 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
||||||
onRedLookup=LookListLoader(OPCODE_ONRED);
|
onRedLookup=LookListLoader(OPCODE_ONRED);
|
||||||
onAmberLookup=LookListLoader(OPCODE_ONAMBER);
|
onAmberLookup=LookListLoader(OPCODE_ONAMBER);
|
||||||
onGreenLookup=LookListLoader(OPCODE_ONGREEN);
|
onGreenLookup=LookListLoader(OPCODE_ONGREEN);
|
||||||
|
onBlockEnterLookup=LookListLoader(OPCODE_ONBLOCKENTER);
|
||||||
|
onBlockExitLookup=LookListLoader(OPCODE_ONBLOCKEXIT);
|
||||||
|
|
||||||
// Second pass startup, define any turnouts or servos, set signals red
|
// Second pass startup, define any turnouts or servos, set signals red
|
||||||
// add sequences onRoutines to the lookups
|
// add sequences onRoutines to the lookups
|
||||||
|
@ -923,6 +927,8 @@ void RMFT2::loop2() {
|
||||||
case OPCODE_ONCLOSE: // Turnout event catchers ignored here
|
case OPCODE_ONCLOSE: // Turnout event catchers ignored here
|
||||||
case OPCODE_ONTHROW:
|
case OPCODE_ONTHROW:
|
||||||
case OPCODE_ONACTIVATE: // Activate event catchers ignored here
|
case OPCODE_ONACTIVATE: // Activate event catchers ignored here
|
||||||
|
case OPCODE_ONBLOCKENTER:
|
||||||
|
case OPCODE_ONBLOCKEXIT:
|
||||||
case OPCODE_ONDEACTIVATE:
|
case OPCODE_ONDEACTIVATE:
|
||||||
case OPCODE_ONRED:
|
case OPCODE_ONRED:
|
||||||
case OPCODE_ONAMBER:
|
case OPCODE_ONAMBER:
|
||||||
|
@ -1053,16 +1059,28 @@ void RMFT2::activateEvent(int16_t addr, bool activate) {
|
||||||
else handleEvent(F("DEACTIVATE"),onDeactivateLookup,addr);
|
else handleEvent(F("DEACTIVATE"),onDeactivateLookup,addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) {
|
void RMFT2::blockEvent(int16_t blockId, int16_t locoid, bool enterBlock) {
|
||||||
|
RMFT2 * task=enterBlock
|
||||||
|
? handleEvent(F("BLOCKENTER"),onBlockEnterLookup,blockId)
|
||||||
|
: handleEvent(F("BLOCKEXIT"),onBlockExitLookup,blockId);
|
||||||
|
if (task) {
|
||||||
|
// set task info from locoid
|
||||||
|
byte speed=DCC::getThrottleSpeedByte(locoid);
|
||||||
|
task->speedo=speed & 0x7f;
|
||||||
|
task->forward=speed >> 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RMFT2 * RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) {
|
||||||
int pc= handlers->find(id);
|
int pc= handlers->find(id);
|
||||||
if (pc<0) return;
|
if (pc<0) return NULL;
|
||||||
|
|
||||||
// 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) {
|
||||||
if (task->onEventStartPosition==pc) {
|
if (task->onEventStartPosition==pc) {
|
||||||
DIAG(F("Recursive ON%S(%d)"),reason, id);
|
DIAG(F("Recursive ON%S(%d)"),reason, id);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
task=task->next;
|
task=task->next;
|
||||||
if (task==loopTask) break;
|
if (task==loopTask) break;
|
||||||
|
@ -1070,6 +1088,7 @@ void RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) {
|
||||||
|
|
||||||
task=new RMFT2(pc); // new task starts at this instruction
|
task=new RMFT2(pc); // new task starts at this instruction
|
||||||
task->onEventStartPosition=pc; // flag for recursion detector
|
task->onEventStartPosition=pc; // flag for recursion detector
|
||||||
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RMFT2::printMessage2(const FSH * msg) {
|
void RMFT2::printMessage2(const FSH * msg) {
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
|
||||||
OPCODE_ENDTASK,OPCODE_ENDEXRAIL,
|
OPCODE_ENDTASK,OPCODE_ENDEXRAIL,
|
||||||
OPCODE_SET_TRACK,
|
OPCODE_SET_TRACK,
|
||||||
OPCODE_ONRED,OPCODE_ONAMBER,OPCODE_ONGREEN,
|
OPCODE_ONRED,OPCODE_ONAMBER,OPCODE_ONGREEN,
|
||||||
|
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
|
||||||
|
@ -107,6 +108,8 @@ class LookList {
|
||||||
static void createNewTask(int route, uint16_t cab);
|
static void createNewTask(int route, uint16_t cab);
|
||||||
static void turnoutEvent(int16_t id, bool closed);
|
static void turnoutEvent(int16_t id, bool closed);
|
||||||
static void activateEvent(int16_t addr, bool active);
|
static void activateEvent(int16_t addr, bool active);
|
||||||
|
static void blockEvent(int16_t blockId, int16_t locoid, bool enterBlock);
|
||||||
|
|
||||||
static const int16_t SERVO_SIGNAL_FLAG=0x4000;
|
static const int16_t SERVO_SIGNAL_FLAG=0x4000;
|
||||||
static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000;
|
static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000;
|
||||||
static const int16_t DCC_SIGNAL_FLAG=0x1000;
|
static const int16_t DCC_SIGNAL_FLAG=0x1000;
|
||||||
|
@ -136,7 +139,7 @@ private:
|
||||||
static void setTurnoutHiddenState(Turnout * t);
|
static void setTurnoutHiddenState(Turnout * t);
|
||||||
static LookList* LookListLoader(OPCODE op1,
|
static LookList* LookListLoader(OPCODE op1,
|
||||||
OPCODE op2=OPCODE_ENDEXRAIL,OPCODE op3=OPCODE_ENDEXRAIL);
|
OPCODE op2=OPCODE_ENDEXRAIL,OPCODE op3=OPCODE_ENDEXRAIL);
|
||||||
static void handleEvent(const FSH* reason,LookList* handlers, int16_t id);
|
static RMFT2 * handleEvent(const FSH* reason,LookList* handlers, int16_t id);
|
||||||
static RMFT2 * loopTask;
|
static RMFT2 * loopTask;
|
||||||
static RMFT2 * pausingTask;
|
static RMFT2 * pausingTask;
|
||||||
void delayMe(long millisecs);
|
void delayMe(long millisecs);
|
||||||
|
@ -161,6 +164,8 @@ private:
|
||||||
static LookList * onRedLookup;
|
static LookList * onRedLookup;
|
||||||
static LookList * onAmberLookup;
|
static LookList * onAmberLookup;
|
||||||
static LookList * onGreenLookup;
|
static LookList * onGreenLookup;
|
||||||
|
static LookList * onBlockEnterLookup;
|
||||||
|
static LookList * onBlockExitLookup;
|
||||||
|
|
||||||
|
|
||||||
// Local variables - exist for each instance/task
|
// Local variables - exist for each instance/task
|
||||||
|
|
|
@ -82,6 +82,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
|
||||||
|
@ -192,6 +194,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 ONDEACTIVATE(addr,subaddr)
|
#define ONDEACTIVATE(addr,subaddr)
|
||||||
#define ONDEACTIVATEL(linear)
|
#define ONDEACTIVATEL(linear)
|
||||||
#define ONCLOSE(turnout_id)
|
#define ONCLOSE(turnout_id)
|
||||||
|
|
|
@ -271,6 +271,8 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = {
|
||||||
#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(blockid) OPCODE_ONBLOCKENTER,V(blockid),
|
||||||
|
#define ONBLOCKEXIT(blockid) OPCODE_ONBLOCKEXIT,V(blockid),
|
||||||
#define ONCLOSE(turnout_id) OPCODE_ONCLOSE,V(turnout_id),
|
#define ONCLOSE(turnout_id) OPCODE_ONCLOSE,V(turnout_id),
|
||||||
#define ONDEACTIVATE(addr,subaddr) OPCODE_ONDEACTIVATE,V(addr<<2|subaddr),
|
#define ONDEACTIVATE(addr,subaddr) OPCODE_ONDEACTIVATE,V(addr<<2|subaddr),
|
||||||
#define ONDEACTIVATEL(linear) OPCODE_ONDEACTIVATE,V(linear+3),
|
#define ONDEACTIVATEL(linear) OPCODE_ONDEACTIVATE,V(linear+3),
|
||||||
|
|
22
LCN.cpp
22
LCN.cpp
|
@ -16,13 +16,17 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "defines.h"
|
||||||
#include "LCN.h"
|
#include "LCN.h"
|
||||||
#include "DIAG.h"
|
#include "DIAG.h"
|
||||||
#include "Turnouts.h"
|
#include "Turnouts.h"
|
||||||
#include "Sensors.h"
|
#include "Sensors.h"
|
||||||
|
#include "EXRAIL2.h"
|
||||||
|
|
||||||
int LCN::id = 0;
|
int LCN::id = 0;
|
||||||
|
int LCN::id1 = 0;
|
||||||
|
int LCN::id2 = 0;
|
||||||
|
|
||||||
Stream * LCN::stream=NULL;
|
Stream * LCN::stream=NULL;
|
||||||
bool LCN::firstLoop=true;
|
bool LCN::firstLoop=true;
|
||||||
|
|
||||||
|
@ -46,6 +50,12 @@ void LCN::loop() {
|
||||||
if (ch >= 0 && ch <= '9') { // accumulate id value
|
if (ch >= 0 && ch <= '9') { // accumulate id value
|
||||||
id = 10 * id + ch - '0';
|
id = 10 * id + ch - '0';
|
||||||
}
|
}
|
||||||
|
else if (ch == ',') {
|
||||||
|
// push stack for new number
|
||||||
|
id2=id1;
|
||||||
|
id1=id;
|
||||||
|
id=0;
|
||||||
|
}
|
||||||
else if (ch == 't' || ch == 'T') { // Turnout opcodes
|
else if (ch == 't' || ch == 'T') { // Turnout opcodes
|
||||||
if (Diag::LCN) DIAG(F("LCN IN %d%c"),id,(char)ch);
|
if (Diag::LCN) DIAG(F("LCN IN %d%c"),id,(char)ch);
|
||||||
if (!Turnout::exists(id)) LCNTurnout::create(id);
|
if (!Turnout::exists(id)) LCNTurnout::create(id);
|
||||||
|
@ -64,6 +74,16 @@ void LCN::loop() {
|
||||||
ss->setState(ch == 'S');
|
ss->setState(ch == 'S');
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
|
else if (ch == 'k' || ch == 'K') {
|
||||||
|
// block enter id1 by loco id
|
||||||
|
if (Diag::LCN) DIAG(F("LCN IN %d,%d%c"),id1,id,(char)ch);
|
||||||
|
|
||||||
|
#ifdef EXRAIL_ACTIVE
|
||||||
|
// without EXrail, valid block commands are ignored
|
||||||
|
RMFT2::blockEvent(id1,id,ch=='K');
|
||||||
|
#endif
|
||||||
|
id=0;
|
||||||
|
}
|
||||||
else id = 0; // ignore any other garbage from LCN
|
else id = 0; // ignore any other garbage from LCN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user