From 5742b71ec608e79feaedba1b14322187d960474c Mon Sep 17 00:00:00 2001 From: Asbelos Date: Fri, 16 Feb 2024 12:20:58 +0000 Subject: [PATCH] to EXRAIL DCCX_SIGNAL intercept --- DCCEXParser.cpp | 6 ++++++ EXRAIL2.cpp | 32 ++++++++++++++++++++++++++++++++ EXRAIL2.h | 3 ++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index a3aa1c4..bcd258a 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -390,6 +390,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) if (params!=2) break; if (p[0] != (p[0] & 0x7F)) break; if (p[1] != (p[1] & 0x1F)) break; +#ifdef EXRAIL_ACTIVE + // Ask exrail if this is just changing the aspect on a + // predefined DCCX_SIGNAL. Because this will handle all + // the IFRED and ONRED type issues at the same time. + if (RMFT2::signalAspectEvent(p[0],p[1])) return; +#endif DCC::setExtendedAccessory(p[0],p[1],3); } return; diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 6f0420c..928bc79 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -1146,6 +1146,38 @@ int16_t RMFT2::getSignalSlot(int16_t id) { return (flags[sigslot] & SIGNAL_MASK) == rag; } + +// signalAspectEvent returns true if the aspect is destined +// for a defined DCCX_SIGNAL which will handle all the RAG flags +// and ON* handlers. +// Otherwise false so the parser should send the command directly +bool RMFT2::signalAspectEvent(int16_t address, byte aspect ) { + if (!(compileFeatures & FEATURE_SIGNAL)) return false; + int16_t sigslot=getSignalSlot(address); + if (sigslot<0) return false; // this is not a defined signal + int16_t sigpos=sigslot*8; + VPIN sigid=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos); + VPIN sigtype=sigid & ~SIGNAL_ID_MASK; + if (sigtype!=DCCX_SIGNAL_FLAG) return false; // not a DCCX signal + // Turn an aspect change into a RED/AMBER/GREEN setting + if (aspect==GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+2)) { + doSignal(sigid,SIGNAL_RED); + return true; + } + + if (aspect==GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+4)) { + doSignal(sigid,SIGNAL_AMBER); + return true; + } + + if (aspect==GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+6)) { + doSignal(sigid,SIGNAL_GREEN); + return true; + } + + return false; // aspect is not a defined one +} + void RMFT2::turnoutEvent(int16_t turnoutId, bool closed) { // Hunt for an ONTHROW/ONCLOSE for this turnout if (closed) onCloseLookup->handleEvent(F("CLOSE"),turnoutId); diff --git a/EXRAIL2.h b/EXRAIL2.h index eec2a06..914c822 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -155,6 +155,7 @@ class LookList { static void clockEvent(int16_t clocktime, bool change); static void rotateEvent(int16_t id, bool change); static void powerEvent(int16_t track, bool overload); + static bool signalAspectEvent(int16_t address, byte aspect ); static const int16_t SERVO_SIGNAL_FLAG=0x4000; static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000; static const int16_t DCC_SIGNAL_FLAG=0x1000; @@ -173,7 +174,7 @@ class LookList { static const FSH * getTurntableDescription(int16_t id); static const FSH * getTurntablePositionDescription(int16_t turntableId, uint8_t positionId); static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc); - + private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ;