From 1225dabf49934ee84d1751666b58b8b8edd3793d Mon Sep 17 00:00:00 2001 From: Asbelos Date: Mon, 18 Sep 2023 12:06:59 +0100 Subject: [PATCH] REjig to L command for LCC --- DCCEXParser.cpp | 5 ++++- EXRAIL2.cpp | 53 +++++++++++++++++++++------------------------ EXRAIL2.h | 1 + StringFormatter.cpp | 14 +++++++++++- StringFormatter.h | 1 + 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 53cb5ce..1614376 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -67,7 +67,7 @@ Once a new OPCODE is decided upon, update this list. k, Reserved for future use - Potentially Railcom K, Reserved for future use - Potentially Railcom l, Loco speedbyte/function map broadcast - L, + L, Reserved for LCC interface (implemented in EXRAIL) m, M, Write DCC packet n, @@ -775,6 +775,9 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) break; // case J } + case 'L': // LCC interface implemented in EXRAIL parser + break; // Will if not intercepted by EXRAIL + default: //anything else will diagnose and drop out to DIAG(F("Opcode=%c params=%d"), opcode, params); for (int i = 0; i < params; i++) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index e5509b9..c6274a5 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -180,7 +180,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) { onChangeLookup=LookListLoader(OPCODE_ONCHANGE); onClockLookup=LookListLoader(OPCODE_ONTIME); onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD); - + // onLCCLookup is not the same so not loaded here. // Second pass startup, define any turnouts or servos, set signals red // add sequences onRoutines to the lookups @@ -304,32 +304,28 @@ void RMFT2::ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16 opcode=0; break; - case 'J': - if (paramCount==1 && p[0]==HASH_KEYWORD_S) { // - LCCSerial=stream; - StringFormatter::send(stream,F(" LCC adapter introducing self + LCCSerial=stream; // now we know where to send events we raise + + // loop through all possible sent events for (int progCounter=0;; SKIPOP) { byte opcode=GET_OPCODE; if (opcode==OPCODE_ENDEXRAIL) break; - if (opcode==OPCODE_LCC) StringFormatter::send(stream,F(" %x"),getOperand(progCounter,0)); + if (opcode==OPCODE_LCC) StringFormatter::send(stream,F(""),getOperand(progCounter,0)); } - StringFormatter::send(stream,F(">\n")); - opcode=0; - return; - } - if (paramCount==1 && p[0]==HASH_KEYWORD_L) { // - // we stream the hex events we wish to listen to - // and at the same time build the event index lookup - LCCSerial=stream; - StringFormatter::send(stream,F(""), getOperand(progCounter,1), getOperand(progCounter,2), getOperand(progCounter,3), @@ -337,16 +333,15 @@ void RMFT2::ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16 ); } } - StringFormatter::send(stream,F(">\n")); + StringFormatter::send(stream,F("\n")); // Ready to rumble opcode=0; - return; + break; } - if (paramCount==2 && p[0]==HASH_KEYWORD_E) { // - reject=p[1]<0 || p[1]>=countLCCLookup; - if (reject) break; - new RMFT2(onLCCLookup[p[1]]); - opcode=0; - return; + if (paramCount==1) { // LCC event arrived from adapter + int16_t eventid=p[0]; + reject=eventid<0 || eventid>=countLCCLookup; + if (!reject) startNonRecursiveTask(F("LCC"),eventid,onLCCLookup[eventid]); + opcode=0; } break; @@ -1014,7 +1009,7 @@ void RMFT2::loop2() { break; case OPCODE_LCC: - if (LCCSerial) StringFormatter::send(LCCSerial,F("<%% %x>\n"),(uint16_t)operand); + if (LCCSerial) StringFormatter::send(LCCSerial,F(""),(uint16_t)operand); break; case OPCODE_SERVO: // OPCODE_SERVO,V(vpin),OPCODE_PAD,V(position),OPCODE_PAD,V(profile),OPCODE_PAD,V(duration) @@ -1220,8 +1215,10 @@ void RMFT2::powerEvent(int16_t track, bool overload) { void RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) { int pc= handlers->find(id); - if (pc<0) return; - + if (pc>=0) startNonRecursiveTask(reason,id,pc); +} + +void RMFT2::startNonRecursiveTask(const FSH* reason, int16_t id,int pc) { // Check we dont already have a task running this handler RMFT2 * task=loopTask; while(task) { diff --git a/EXRAIL2.h b/EXRAIL2.h index f43d7d4..908c13e 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -164,6 +164,7 @@ private: OPCODE op2=OPCODE_ENDEXRAIL,OPCODE op3=OPCODE_ENDEXRAIL); static void handleEvent(const FSH* reason,LookList* handlers, int16_t id); static uint16_t getOperand(int progCounter,byte n); + static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc); static RMFT2 * loopTask; static RMFT2 * pausingTask; void delayMe(long millisecs); diff --git a/StringFormatter.cpp b/StringFormatter.cpp index c475ef0..8b2d69c 100644 --- a/StringFormatter.cpp +++ b/StringFormatter.cpp @@ -117,6 +117,7 @@ void StringFormatter::send2(Print * stream,const FSH* format, va_list args) { case 'o': stream->print(va_arg(args, int), OCT); break; case 'x': stream->print((unsigned int)va_arg(args, unsigned int), HEX); break; case 'X': stream->print((unsigned long)va_arg(args, unsigned long), HEX); break; + case 'h': printHex(stream,(unsigned int)va_arg(args, unsigned int)); break; case 'M': { // this prints a unsigned long microseconds time in readable format unsigned long time = va_arg(args, long); @@ -218,4 +219,15 @@ void StringFormatter::printPadded(Print* stream, long value, byte width, bool fo if (!formatLeft) stream->print(value, DEC); } - +const char FLASH Hexpattern[]="0123456789ABCDEF"; +// printHex prints the full 2 byte hex with leading zeros, unlike print(value,HEX) +void StringFormatter::printHex(Print * stream,uint16_t value) { + char result[5]; + for (int i=3;i>=0;i--) { + result[i]=GETFLASH(Hexpattern+(value & 0xFF)); + value>>=4; + } + result[4]='\0'; + stream->print(result); +} + \ No newline at end of file diff --git a/StringFormatter.h b/StringFormatter.h index 6923c10..1231d54 100644 --- a/StringFormatter.h +++ b/StringFormatter.h @@ -49,6 +49,7 @@ class StringFormatter static void lcd2(uint8_t display, byte row, const FSH* input...); static void printEscapes(char * input); static void printEscape( char c); + static void printHex(Print * stream,uint16_t value); private: static void send2(Print * serial, const FSH* input,va_list args);