mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +01:00
REjig to L command for LCC
This commit is contained in:
parent
727e4d32f1
commit
1225dabf49
|
@ -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
|
||||||
K, Reserved for future use - Potentially Railcom
|
K, Reserved for future use - Potentially Railcom
|
||||||
l, Loco speedbyte/function map broadcast
|
l, Loco speedbyte/function map broadcast
|
||||||
L,
|
L, Reserved for LCC interface (implemented in EXRAIL)
|
||||||
m,
|
m,
|
||||||
M, Write DCC packet
|
M, Write DCC packet
|
||||||
n,
|
n,
|
||||||
|
@ -775,6 +775,9 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
break; // case J
|
break; // case J
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'L': // LCC interface implemented in EXRAIL parser
|
||||||
|
break; // Will <X> if not intercepted by EXRAIL
|
||||||
|
|
||||||
default: //anything else will diagnose and drop out to <X>
|
default: //anything else will diagnose and drop out to <X>
|
||||||
DIAG(F("Opcode=%c params=%d"), opcode, params);
|
DIAG(F("Opcode=%c params=%d"), opcode, params);
|
||||||
for (int i = 0; i < params; i++)
|
for (int i = 0; i < params; i++)
|
||||||
|
|
47
EXRAIL2.cpp
47
EXRAIL2.cpp
|
@ -180,7 +180,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
||||||
onChangeLookup=LookListLoader(OPCODE_ONCHANGE);
|
onChangeLookup=LookListLoader(OPCODE_ONCHANGE);
|
||||||
onClockLookup=LookListLoader(OPCODE_ONTIME);
|
onClockLookup=LookListLoader(OPCODE_ONTIME);
|
||||||
onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD);
|
onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD);
|
||||||
|
// 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
|
||||||
// add sequences onRoutines to the lookups
|
// add sequences onRoutines to the lookups
|
||||||
|
@ -304,32 +304,28 @@ void RMFT2::ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16
|
||||||
opcode=0;
|
opcode=0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'J':
|
case 'L':
|
||||||
if (paramCount==1 && p[0]==HASH_KEYWORD_S) { //<JS>
|
if (paramCount==0) { //<L> LCC adapter introducing self
|
||||||
LCCSerial=stream;
|
LCCSerial=stream; // now we know where to send events we raise
|
||||||
StringFormatter::send(stream,F("<jS"));
|
|
||||||
|
// loop through all possible sent events
|
||||||
for (int progCounter=0;; SKIPOP) {
|
for (int progCounter=0;; SKIPOP) {
|
||||||
byte opcode=GET_OPCODE;
|
byte opcode=GET_OPCODE;
|
||||||
if (opcode==OPCODE_ENDEXRAIL) break;
|
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("<LS x%h>"),getOperand(progCounter,0));
|
||||||
}
|
}
|
||||||
StringFormatter::send(stream,F(">\n"));
|
|
||||||
opcode=0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (paramCount==1 && p[0]==HASH_KEYWORD_L) { //<JL>
|
|
||||||
// we stream the hex events we wish to listen to
|
|
||||||
// and at the same time build the event index lookup
|
|
||||||
|
|
||||||
LCCSerial=stream;
|
// we stream the hex events we wish to listen to
|
||||||
StringFormatter::send(stream,F("<jL"));
|
// and at the same time build the event index looku.
|
||||||
|
|
||||||
|
|
||||||
int eventIndex=0;
|
int eventIndex=0;
|
||||||
for (int progCounter=0;; SKIPOP) {
|
for (int progCounter=0;; SKIPOP) {
|
||||||
byte opcode=GET_OPCODE;
|
byte opcode=GET_OPCODE;
|
||||||
if (opcode==OPCODE_ENDEXRAIL) break;
|
if (opcode==OPCODE_ENDEXRAIL) break;
|
||||||
if (opcode==OPCODE_ONLCC) {
|
if (opcode==OPCODE_ONLCC) {
|
||||||
onLCCLookup[eventIndex++]=progCounter; // TODO skip...
|
onLCCLookup[eventIndex++]=progCounter; // TODO skip...
|
||||||
StringFormatter::send(stream,F(" %x.%x.%x:%x"),
|
StringFormatter::send(stream,F("<LL x%h%h%h:%h>"),
|
||||||
getOperand(progCounter,1),
|
getOperand(progCounter,1),
|
||||||
getOperand(progCounter,2),
|
getOperand(progCounter,2),
|
||||||
getOperand(progCounter,3),
|
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("<LR>\n")); // Ready to rumble
|
||||||
opcode=0;
|
opcode=0;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
if (paramCount==2 && p[0]==HASH_KEYWORD_E) { //<JE eventid>
|
if (paramCount==1) { // <L eventid> LCC event arrived from adapter
|
||||||
reject=p[1]<0 || p[1]>=countLCCLookup;
|
int16_t eventid=p[0];
|
||||||
if (reject) break;
|
reject=eventid<0 || eventid>=countLCCLookup;
|
||||||
new RMFT2(onLCCLookup[p[1]]);
|
if (!reject) startNonRecursiveTask(F("LCC"),eventid,onLCCLookup[eventid]);
|
||||||
opcode=0;
|
opcode=0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1014,7 +1009,7 @@ void RMFT2::loop2() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_LCC:
|
case OPCODE_LCC:
|
||||||
if (LCCSerial) StringFormatter::send(LCCSerial,F("<%% %x>\n"),(uint16_t)operand);
|
if (LCCSerial) StringFormatter::send(LCCSerial,F("<L x%h>"),(uint16_t)operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPCODE_SERVO: // OPCODE_SERVO,V(vpin),OPCODE_PAD,V(position),OPCODE_PAD,V(profile),OPCODE_PAD,V(duration)
|
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) {
|
void 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) 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
|
// Check we dont already have a task running this handler
|
||||||
RMFT2 * task=loopTask;
|
RMFT2 * task=loopTask;
|
||||||
while(task) {
|
while(task) {
|
||||||
|
|
|
@ -164,6 +164,7 @@ private:
|
||||||
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 void handleEvent(const FSH* reason,LookList* handlers, int16_t id);
|
||||||
static uint16_t getOperand(int progCounter,byte n);
|
static uint16_t getOperand(int progCounter,byte n);
|
||||||
|
static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc);
|
||||||
static RMFT2 * loopTask;
|
static RMFT2 * loopTask;
|
||||||
static RMFT2 * pausingTask;
|
static RMFT2 * pausingTask;
|
||||||
void delayMe(long millisecs);
|
void delayMe(long millisecs);
|
||||||
|
|
|
@ -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 '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 int)va_arg(args, unsigned int), HEX); break;
|
||||||
case 'X': stream->print((unsigned long)va_arg(args, unsigned long), 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':
|
case 'M':
|
||||||
{ // this prints a unsigned long microseconds time in readable format
|
{ // this prints a unsigned long microseconds time in readable format
|
||||||
unsigned long time = va_arg(args, long);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ class StringFormatter
|
||||||
static void lcd2(uint8_t display, byte row, const FSH* input...);
|
static void lcd2(uint8_t display, byte row, const FSH* input...);
|
||||||
static void printEscapes(char * input);
|
static void printEscapes(char * input);
|
||||||
static void printEscape( char c);
|
static void printEscape( char c);
|
||||||
|
static void printHex(Print * stream,uint16_t value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void send2(Print * serial, const FSH* input,va_list args);
|
static void send2(Print * serial, const FSH* input,va_list args);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user