1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-26 17:46:14 +01:00

Signal fixes and DCC_SIGNAL/VIRTUAL_SIGNAL

This commit is contained in:
Asbelos 2022-06-18 12:31:54 +01:00
parent d0e71875e0
commit 6104311ccb
4 changed files with 47 additions and 25 deletions

View File

@ -170,6 +170,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
switch (opcode) { switch (opcode) {
case OPCODE_AT: case OPCODE_AT:
case OPCODE_ATTIMEOUT2:
case OPCODE_AFTER: case OPCODE_AFTER:
case OPCODE_IF: case OPCODE_IF:
case OPCODE_IFNOT: { case OPCODE_IFNOT: {
@ -348,13 +349,14 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
return true; return true;
} }
// all other / commands take 1 parameter 0 to MAX_FLAGS-1 // all other / commands take 1 parameter
if (paramCount!=2 || p[1]<0 || p[1]>=MAX_FLAGS) return false; if (paramCount!=2 ) return false;
switch (p[0]) { switch (p[0]) {
case HASH_KEYWORD_KILL: // Kill taskid|ALL case HASH_KEYWORD_KILL: // Kill taskid|ALL
{ {
RMFT2 * task=loopTask; if ( p[1]<0 || p[1]>=MAX_FLAGS) return false;
RMFT2 * task=loopTask;
while(task) { while(task) {
if (task->taskId==p[1]) { if (task->taskId==p[1]) {
task->kill(F("KILL")); task->kill(F("KILL"));
@ -367,20 +369,16 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
return false; return false;
case HASH_KEYWORD_RESERVE: // force reserve a section case HASH_KEYWORD_RESERVE: // force reserve a section
setFlag(p[1],SECTION_FLAG); return setFlag(p[1],SECTION_FLAG);
return true;
case HASH_KEYWORD_FREE: // force free a section case HASH_KEYWORD_FREE: // force free a section
setFlag(p[1],0,SECTION_FLAG); return setFlag(p[1],0,SECTION_FLAG);
return true;
case HASH_KEYWORD_LATCH: case HASH_KEYWORD_LATCH:
setFlag(p[1], LATCH_FLAG); return setFlag(p[1], LATCH_FLAG);
return true;
case HASH_KEYWORD_UNLATCH: case HASH_KEYWORD_UNLATCH:
setFlag(p[1], 0, LATCH_FLAG); return setFlag(p[1], 0, LATCH_FLAG);
return true;
case HASH_KEYWORD_RED: case HASH_KEYWORD_RED:
doSignal(p[1],SIGNAL_RED); doSignal(p[1],SIGNAL_RED);
@ -926,6 +924,10 @@ void RMFT2::loop2() {
case OPCODE_ONTHROW: case OPCODE_ONTHROW:
case OPCODE_ONACTIVATE: // Activate event catchers ignored here case OPCODE_ONACTIVATE: // Activate event catchers ignored here
case OPCODE_ONDEACTIVATE: case OPCODE_ONDEACTIVATE:
case OPCODE_ONRED:
case OPCODE_ONAMBER:
case OPCODE_ONGREEN:
break; break;
default: default:
@ -942,12 +944,13 @@ void RMFT2::delayMe(long delay) {
delayStart=millis(); delayStart=millis();
} }
void RMFT2::setFlag(VPIN id,byte onMask, byte offMask) { boolean RMFT2::setFlag(VPIN id,byte onMask, byte offMask) {
if (FLAGOVERFLOW(id)) return; // Outside range limit if (FLAGOVERFLOW(id)) return false; // Outside range limit
byte f=flags[id]; byte f=flags[id];
f &= ~offMask; f &= ~offMask;
f |= onMask; f |= onMask;
flags[id]=f; flags[id]=f;
return true;
} }
bool RMFT2::getFlag(VPIN id,byte mask) { bool RMFT2::getFlag(VPIN id,byte mask) {
@ -961,9 +964,9 @@ void RMFT2::kill(const FSH * reason, int operand) {
delete this; delete this;
} }
int16_t RMFT2::getSignalSlot(VPIN id) { int16_t RMFT2::getSignalSlot(int16_t id) {
for (int sigpos=0;;sigpos+=4) { for (int sigpos=0;;sigpos+=4) {
VPIN sigid=GETFLASHW(RMFT2::SignalDefinitions+sigpos); int16_t sigid=GETFLASHW(RMFT2::SignalDefinitions+sigpos);
if (sigid==0) { // end of signal list if (sigid==0) { // end of signal list
DIAG(F("EXRAIL Signal %d not defined"), id); DIAG(F("EXRAIL Signal %d not defined"), id);
return -1; return -1;
@ -976,7 +979,7 @@ int16_t RMFT2::getSignalSlot(VPIN id) {
return sigpos/4; // relative slot in signals table return sigpos/4; // relative slot in signals table
} }
} }
/* static */ void RMFT2::doSignal(VPIN id,char rag) { /* static */ void RMFT2::doSignal(int16_t id,char rag) {
if (diag) DIAG(F(" doSignal %d %x"),id,rag); if (diag) DIAG(F(" doSignal %d %x"),id,rag);
// Schedule any event handler for this signal change. // Schedule any event handler for this signal change.
@ -997,10 +1000,11 @@ int16_t RMFT2::getSignalSlot(VPIN id) {
VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1); VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1);
VPIN amberpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+2); VPIN amberpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+2);
VPIN greenpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+3); VPIN greenpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+3);
if (diag) DIAG(F("signal %d %d %d %d"),sigid,redpin,amberpin,greenpin); if (diag) DIAG(F("signal %d %d %d %d %d"),sigid,id,redpin,amberpin,greenpin);
VPIN sigtype=sigid & ~SIGNAL_ID_MASK;
if (sigid & SERVO_SIGNAL_FLAG) { if (sigtype == SERVO_SIGNAL_FLAG) {
// A servo signal, the pin numbers are actually servo positions // A servo signal, the pin numbers are actually servo positions
// Note, setting a signal to a zero position has no effect. // Note, setting a signal to a zero position has no effect.
int16_t servopos= rag==SIGNAL_RED? redpin: (rag==SIGNAL_GREEN? greenpin : amberpin); int16_t servopos= rag==SIGNAL_RED? redpin: (rag==SIGNAL_GREEN? greenpin : amberpin);
@ -1009,7 +1013,14 @@ int16_t RMFT2::getSignalSlot(VPIN id) {
return; return;
} }
// LED or similar 3 pin signal
if (sigtype== DCC_SIGNAL_FLAG) {
// redpin,amberpin are the DCC addr,subaddr
DCC::setAccessory(redpin,amberpin, rag!=SIGNAL_RED);
return;
}
// LED or similar 3 pin signal, (all pins zero would be a virtual signal)
// If amberpin is zero, synthesise amber from red+green // If amberpin is zero, synthesise amber from red+green
const byte SIMAMBER=0x00; const byte SIMAMBER=0x00;
if (rag==SIGNAL_AMBER && (amberpin==0)) rag=SIMAMBER; // special case this func only if (rag==SIGNAL_AMBER && (amberpin==0)) rag=SIMAMBER; // special case this func only
@ -1021,10 +1032,9 @@ int16_t RMFT2::getSignalSlot(VPIN id) {
if (redpin) IODevice::write(redpin,(rag==SIGNAL_RED || rag==SIMAMBER)^aHigh); if (redpin) IODevice::write(redpin,(rag==SIGNAL_RED || rag==SIMAMBER)^aHigh);
if (amberpin) IODevice::write(amberpin,(rag==SIGNAL_AMBER)^aHigh); if (amberpin) IODevice::write(amberpin,(rag==SIGNAL_AMBER)^aHigh);
if (greenpin) IODevice::write(greenpin,(rag==SIGNAL_GREEN || rag==SIMAMBER)^aHigh); if (greenpin) IODevice::write(greenpin,(rag==SIGNAL_GREEN || rag==SIMAMBER)^aHigh);
return;
} }
/* static */ bool RMFT2::isSignal(VPIN id,char rag) { /* static */ bool RMFT2::isSignal(int16_t id,char rag) {
int16_t sigslot=getSignalSlot(id); int16_t sigslot=getSignalSlot(id);
if (sigslot<0) return false; if (sigslot<0) return false;
return (flags[sigslot] & SIGNAL_MASK) == rag; return (flags[sigslot] & SIGNAL_MASK) == rag;

View File

@ -109,6 +109,7 @@ class LookList {
static void activateEvent(int16_t addr, bool active); static void activateEvent(int16_t addr, bool active);
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 SIGNAL_ID_MASK=0x0FFF; static const int16_t SIGNAL_ID_MASK=0x0FFF;
// Throttle Info Access functions built by exrail macros // Throttle Info Access functions built by exrail macros
@ -126,12 +127,12 @@ private:
static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]);
static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ; static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ;
static void streamFlags(Print* stream); static void streamFlags(Print* stream);
static void setFlag(VPIN id,byte onMask, byte OffMask=0); static bool setFlag(VPIN id,byte onMask, byte OffMask=0);
static bool getFlag(VPIN id,byte mask); static bool getFlag(VPIN id,byte mask);
static int16_t progtrackLocoId; static int16_t progtrackLocoId;
static void doSignal(VPIN id,char rag); static void doSignal(int16_t id,char rag);
static bool isSignal(VPIN id,char rag); static bool isSignal(int16_t id,char rag);
static int16_t getSignalSlot(VPIN id); static int16_t getSignalSlot(int16_t id);
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);

View File

@ -37,6 +37,7 @@
#undef BROADCAST #undef BROADCAST
#undef CALL #undef CALL
#undef CLOSE #undef CLOSE
#undef DCC_SIGNAL
#undef DEACTIVATE #undef DEACTIVATE
#undef DEACTIVATEL #undef DEACTIVATEL
#undef DELAY #undef DELAY
@ -124,6 +125,7 @@
#undef TURNOUT #undef TURNOUT
#undef UNJOIN #undef UNJOIN
#undef UNLATCH #undef UNLATCH
#undef VIRTUAL_SIGNAL
#undef VIRTUAL_TURNOUT #undef VIRTUAL_TURNOUT
#undef WAITFOR #undef WAITFOR
#undef XFOFF #undef XFOFF
@ -144,6 +146,7 @@
#define BROADCAST(msg) #define BROADCAST(msg)
#define CALL(route) #define CALL(route)
#define CLOSE(id) #define CLOSE(id)
#define DCC_SIGNAL(id,add,subaddr)
#define DEACTIVATE(addr,subaddr) #define DEACTIVATE(addr,subaddr)
#define DEACTIVATEL(addr) #define DEACTIVATEL(addr)
#define DELAY(mindelay) #define DELAY(mindelay)
@ -231,6 +234,7 @@
#define TURNOUT(id,addr,subaddr,description...) #define TURNOUT(id,addr,subaddr,description...)
#define UNJOIN #define UNJOIN
#define UNLATCH(sensor_id) #define UNLATCH(sensor_id)
#define VIRTUAL_SIGNAL(id)
#define VIRTUAL_TURNOUT(id,description...) #define VIRTUAL_TURNOUT(id,description...)
#define WAITFOR(pin) #define WAITFOR(pin)
#define XFOFF(cab,func) #define XFOFF(cab,func)

View File

@ -193,6 +193,11 @@ const FSH * RMFT2::getRosterFunctions(int16_t id) {
#define SIGNALH(redpin,amberpin,greenpin) redpin | RMFT2::ACTIVE_HIGH_SIGNAL_FLAG,redpin,amberpin,greenpin, #define SIGNALH(redpin,amberpin,greenpin) redpin | RMFT2::ACTIVE_HIGH_SIGNAL_FLAG,redpin,amberpin,greenpin,
#undef SERVO_SIGNAL #undef SERVO_SIGNAL
#define SERVO_SIGNAL(vpin,redval,amberval,greenval) vpin | RMFT2::SERVO_SIGNAL_FLAG,redval,amberval,greenval, #define SERVO_SIGNAL(vpin,redval,amberval,greenval) vpin | RMFT2::SERVO_SIGNAL_FLAG,redval,amberval,greenval,
#undef DCC_SIGNAL
#define DCC_SIGNAL(id,addr,subaddr) id | RMFT2::DCC_SIGNAL_FLAG,addr,subaddr,0,
#undef VIRTUAL_SIGNAL
#define VIRTUAL_SIGNAL(id) id,0,0,0,
const FLASH int16_t RMFT2::SignalDefinitions[] = { const FLASH int16_t RMFT2::SignalDefinitions[] = {
#include "myAutomation.h" #include "myAutomation.h"
0,0,0,0 }; 0,0,0,0 };
@ -226,6 +231,7 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = {
#define DELAY(ms) ms<30000?OPCODE_DELAYMS:OPCODE_DELAY,V(ms/(ms<30000?1L:100L)), #define DELAY(ms) ms<30000?OPCODE_DELAYMS:OPCODE_DELAY,V(ms/(ms<30000?1L:100L)),
#define DELAYMINS(mindelay) OPCODE_DELAYMINS,V(mindelay), #define DELAYMINS(mindelay) OPCODE_DELAYMINS,V(mindelay),
#define DELAYRANDOM(mindelay,maxdelay) DELAY(mindelay) OPCODE_RANDWAIT,V((maxdelay-mindelay)/100L), #define DELAYRANDOM(mindelay,maxdelay) DELAY(mindelay) OPCODE_RANDWAIT,V((maxdelay-mindelay)/100L),
#define DCC_SIGNAL(id,add,subaddr)
#define DONE OPCODE_ENDTASK,0,0, #define DONE OPCODE_ENDTASK,0,0,
#define DRIVE(analogpin) OPCODE_DRIVE,V(analogpin), #define DRIVE(analogpin) OPCODE_DRIVE,V(analogpin),
#define ELSE OPCODE_ELSE,0,0, #define ELSE OPCODE_ELSE,0,0,
@ -308,6 +314,7 @@ const FLASH int16_t RMFT2::SignalDefinitions[] = {
#define TURNOUT(id,addr,subaddr,description...) OPCODE_TURNOUT,V(id),OPCODE_PAD,V(addr),OPCODE_PAD,V(subaddr), #define TURNOUT(id,addr,subaddr,description...) OPCODE_TURNOUT,V(id),OPCODE_PAD,V(addr),OPCODE_PAD,V(subaddr),
#define UNJOIN OPCODE_UNJOIN,0,0, #define UNJOIN OPCODE_UNJOIN,0,0,
#define UNLATCH(sensor_id) OPCODE_UNLATCH,V(sensor_id), #define UNLATCH(sensor_id) OPCODE_UNLATCH,V(sensor_id),
#define VIRTUAL_SIGNAL(id)
#define VIRTUAL_TURNOUT(id,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(0), #define VIRTUAL_TURNOUT(id,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(0),
#define WAITFOR(pin) OPCODE_WAITFOR,V(pin), #define WAITFOR(pin) OPCODE_WAITFOR,V(pin),
#define XFOFF(cab,func) OPCODE_XFOFF,V(cab),OPCODE_PAD,V(func), #define XFOFF(cab,func) OPCODE_XFOFF,V(cab),OPCODE_PAD,V(func),