1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-24 08:36:14 +01:00

Compare commits

..

4 Commits

Author SHA1 Message Date
Asbelos
a5ccb2e29e EXRAIL STASH 2023-11-23 14:15:58 +00:00
Asbelos
42e2e69f5f Merge branch 'devel' of https://github.com/DCC-EX/CommandStation-EX into devel 2023-11-23 10:41:40 +00:00
Asbelos
2075bc50e8 EXRAIL basic stash implementation 2023-11-23 10:41:35 +00:00
Asbelos
b478056a9f Fix @ reporting on startup 2023-11-23 09:00:49 +00:00
10 changed files with 125 additions and 10 deletions

View File

@ -365,7 +365,7 @@ void CommandDistributor::setVirtualLCDSerial(Print * stream) {
virtualLCDSerial=stream; virtualLCDSerial=stream;
} }
Print* CommandDistributor::virtualLCDSerial=nullptr; Print* CommandDistributor::virtualLCDSerial=&USB_SERIAL;
byte CommandDistributor::virtualLCDClient=0xFF; byte CommandDistributor::virtualLCDClient=0xFF;
byte CommandDistributor::rememberVLCDClient=0; byte CommandDistributor::rememberVLCDClient=0;

View File

@ -87,7 +87,7 @@ void setup()
DISPLAY_START ( DISPLAY_START (
// This block is still executed for DIAGS if display not in use // This block is still executed for DIAGS if display not in use
LCD(0,F("DCC-EX v%S"),F(VERSION)); LCD(0,F("DCC-EX v" VERSION));
LCD(1,F("Lic GPLv3")); LCD(1,F("Lic GPLv3"));
); );

View File

@ -160,6 +160,7 @@ const int16_t HASH_KEYWORD_C='C';
const int16_t HASH_KEYWORD_G='G'; const int16_t HASH_KEYWORD_G='G';
const int16_t HASH_KEYWORD_H='H'; const int16_t HASH_KEYWORD_H='H';
const int16_t HASH_KEYWORD_I='I'; const int16_t HASH_KEYWORD_I='I';
const int16_t HASH_KEYWORD_M='M';
const int16_t HASH_KEYWORD_O='O'; const int16_t HASH_KEYWORD_O='O';
const int16_t HASH_KEYWORD_P='P'; const int16_t HASH_KEYWORD_P='P';
const int16_t HASH_KEYWORD_R='R'; const int16_t HASH_KEYWORD_R='R';
@ -729,6 +730,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
StringFormatter::send(stream, F("<jA>\n")); StringFormatter::send(stream, F("<jA>\n"));
return; return;
case HASH_KEYWORD_M: // <JM> intercepted by EXRAIL
if (params>1) break; // invalid cant do
// <JM> requests stash size so say none.
StringFormatter::send(stream,F("<jM 0>\n"));
return;
case HASH_KEYWORD_R: // <JR> returns rosters case HASH_KEYWORD_R: // <JR> returns rosters
StringFormatter::send(stream, F("<jR")); StringFormatter::send(stream, F("<jR"));
#ifdef EXRAIL_ACTIVE #ifdef EXRAIL_ACTIVE

View File

@ -54,7 +54,9 @@
xxx; \ xxx; \
t->refresh();} t->refresh();}
#else #else
#define DISPLAY_START(xxx) {} #define DISPLAY_START(xxx) { \
xxx; \
}
#endif #endif
#endif // LCD_Implementation_h #endif // LCD_Implementation_h

View File

@ -86,6 +86,8 @@ LookList * RMFT2::onRotateLookup=NULL;
LookList * RMFT2::onOverloadLookup=NULL; LookList * RMFT2::onOverloadLookup=NULL;
byte * RMFT2::routeStateArray=nullptr; byte * RMFT2::routeStateArray=nullptr;
const FSH * * RMFT2::routeCaptionArray=nullptr; const FSH * * RMFT2::routeCaptionArray=nullptr;
int16_t * RMFT2::stashArray=nullptr;
int16_t RMFT2::maxStashId=0;
// getOperand instance version, uses progCounter from instance. // getOperand instance version, uses progCounter from instance.
uint16_t RMFT2::getOperand(byte n) { uint16_t RMFT2::getOperand(byte n) {
@ -232,6 +234,12 @@ if (compileFeatures & FEATURE_SIGNAL) {
IODevice::configureInput((VPIN)pin,true); IODevice::configureInput((VPIN)pin,true);
break; break;
} }
case OPCODE_STASH:
case OPCODE_CLEAR_STASH:
case OPCODE_PICKUP_STASH: {
maxStashId=max(maxStashId,((int16_t)operand));
break;
}
case OPCODE_ATGTE: case OPCODE_ATGTE:
case OPCODE_ATLT: case OPCODE_ATLT:
@ -311,8 +319,14 @@ if (compileFeatures & FEATURE_SIGNAL) {
} }
} }
SKIPOP; // include ENDROUTES opcode SKIPOP; // include ENDROUTES opcode
DIAG(F("EXRAIL %db, fl=%d"),progCounter,MAX_FLAGS); if (compileFeatures & FEATURE_STASH) {
// create the stash array from the highest id found
if (maxStashId>0) stashArray=(int16_t*)calloc(maxStashId+1, sizeof(int16_t));
//TODO check EEPROM and fetch stashArray
}
DIAG(F("EXRAIL %db, fl=%d, stash=%d"),progCounter,MAX_FLAGS, maxStashId);
// Removed for 4.2.31 new RMFT2(0); // add the startup route // Removed for 4.2.31 new RMFT2(0); // add the startup route
diag=saved_diag; diag=saved_diag;
@ -935,6 +949,34 @@ void RMFT2::loop2() {
case OPCODE_ROUTE_DISABLED: case OPCODE_ROUTE_DISABLED:
manageRouteState(operand,4); manageRouteState(operand,4);
break; break;
case OPCODE_STASH:
if (compileFeatures & FEATURE_STASH)
stashArray[operand] = invert? -loco : loco;
break;
case OPCODE_CLEAR_STASH:
if (compileFeatures & FEATURE_STASH)
stashArray[operand] = 0;
break;
case OPCODE_CLEAR_ALL_STASH:
if (compileFeatures & FEATURE_STASH)
for (int i=0;i<=maxStashId;i++) stashArray[operand]=0;
break;
case OPCODE_PICKUP_STASH:
if (compileFeatures & FEATURE_STASH) {
int16_t x=stashArray[operand];
if (x>=0) {
loco=x;
invert=false;
break;
}
loco=-x;
invert=true;
}
break;
case OPCODE_ROUTE: case OPCODE_ROUTE:
case OPCODE_AUTOMATION: case OPCODE_AUTOMATION:

View File

@ -70,6 +70,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
OPCODE_ONOVERLOAD, OPCODE_ONOVERLOAD,
OPCODE_ROUTE_ACTIVE,OPCODE_ROUTE_INACTIVE,OPCODE_ROUTE_HIDDEN, OPCODE_ROUTE_ACTIVE,OPCODE_ROUTE_INACTIVE,OPCODE_ROUTE_HIDDEN,
OPCODE_ROUTE_DISABLED, OPCODE_ROUTE_DISABLED,
OPCODE_STASH,OPCODE_CLEAR_STASH,OPCODE_CLEAR_ALL_STASH,OPCODE_PICKUP_STASH,
// 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
@ -102,6 +103,7 @@ enum thrunger: byte {
static const byte FEATURE_LCC = 0x40; static const byte FEATURE_LCC = 0x40;
static const byte FEATURE_ROSTER= 0x20; static const byte FEATURE_ROSTER= 0x20;
static const byte FEATURE_ROUTESTATE= 0x10; static const byte FEATURE_ROUTESTATE= 0x10;
static const byte FEATURE_STASH = 0x08;
// Flag bits for status of hardware and TPL // Flag bits for status of hardware and TPL
@ -229,6 +231,8 @@ private:
static void manageRouteCaption(uint16_t id, const FSH* caption); static void manageRouteCaption(uint16_t id, const FSH* caption);
static byte * routeStateArray; static byte * routeStateArray;
static const FSH ** routeCaptionArray; static const FSH ** routeCaptionArray;
static int16_t * stashArray;
static int16_t maxStashId;
// Local variables - exist for each instance/task // Local variables - exist for each instance/task
RMFT2 *next; // loop chain RMFT2 *next; // loop chain

View File

@ -39,6 +39,8 @@
#undef AUTOSTART #undef AUTOSTART
#undef BROADCAST #undef BROADCAST
#undef CALL #undef CALL
#undef CLEAR_STASH
#undef CLEAR_ALL_STASH
#undef CLOSE #undef CLOSE
#undef DCC_SIGNAL #undef DCC_SIGNAL
#undef DCC_TURNTABLE #undef DCC_TURNTABLE
@ -108,6 +110,7 @@
#undef ONCHANGE #undef ONCHANGE
#undef PARSE #undef PARSE
#undef PAUSE #undef PAUSE
#undef PICKUP_STASH
#undef PIN_TURNOUT #undef PIN_TURNOUT
#undef PRINT #undef PRINT
#ifndef DISABLE_PROG #ifndef DISABLE_PROG
@ -152,6 +155,7 @@
#undef SIGNALH #undef SIGNALH
#undef SPEED #undef SPEED
#undef START #undef START
#undef STASH
#undef STOP #undef STOP
#undef THROW #undef THROW
#undef TT_ADDPOSITION #undef TT_ADDPOSITION
@ -184,7 +188,9 @@
#define AUTOMATION(id,description) #define AUTOMATION(id,description)
#define AUTOSTART #define AUTOSTART
#define BROADCAST(msg) #define BROADCAST(msg)
#define CALL(route) #define CALL(route)
#define CLEAR_STASH(id)
#define CLEAR_ALL_STASH(id)
#define CLOSE(id) #define CLOSE(id)
#define DCC_SIGNAL(id,add,subaddr) #define DCC_SIGNAL(id,add,subaddr)
#define DCC_TURNTABLE(id,home,description) #define DCC_TURNTABLE(id,home,description)
@ -256,6 +262,7 @@
#define PIN_TURNOUT(id,pin,description...) #define PIN_TURNOUT(id,pin,description...)
#define PRINT(msg) #define PRINT(msg)
#define PARSE(msg) #define PARSE(msg)
#define PICKUP_STASH(id)
#ifndef DISABLE_PROG #ifndef DISABLE_PROG
#define POM(cv,value) #define POM(cv,value)
#endif #endif
@ -297,7 +304,8 @@
#define SIGNAL(redpin,amberpin,greenpin) #define SIGNAL(redpin,amberpin,greenpin)
#define SIGNALH(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin)
#define SPEED(speed) #define SPEED(speed)
#define START(route) #define START(route)
#define STASH(id)
#define STOP #define STOP
#define THROW(id) #define THROW(id)
#define TT_ADDPOSITION(turntable_id,position,value,angle,description...) #define TT_ADDPOSITION(turntable_id,position,value,angle,description...)

View File

@ -44,7 +44,9 @@ const int16_t HASH_KEYWORD_ROUTES=-3702;
const int16_t HASH_KEYWORD_RED=26099; const int16_t HASH_KEYWORD_RED=26099;
const int16_t HASH_KEYWORD_AMBER=18713; const int16_t HASH_KEYWORD_AMBER=18713;
const int16_t HASH_KEYWORD_GREEN=-31493; const int16_t HASH_KEYWORD_GREEN=-31493;
const int16_t HASH_KEYWORD_A='A'; const int16_t HASH_KEYWORD_A='A';
const int16_t HASH_KEYWORD_M='M';
// This filter intercepts <> commands to do the following: // This filter intercepts <> commands to do the following:
// - Implement RMFT specific commands/diagnostics // - Implement RMFT specific commands/diagnostics
@ -149,7 +151,33 @@ void RMFT2::ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16
opcode=0; opcode=0;
return; return;
} }
break; break;
case HASH_KEYWORD_M:
// NOTE: we only need to handle valid calls here because
// DCCEXParser has to have code to handle the <J<> cases where
// exrail isnt involved anyway.
// This entire code block is compiled out if STASH macros not used
if (!(compileFeatures & FEATURE_STASH)) return;
if (paramCount==1) { // <JM>
StringFormatter::send(stream,F("<jM %d>\n"),maxStashId);
opcode=0;
break;
}
if (paramCount==2) { // <JM id>
if (p[1]<=0 || p[1]>maxStashId) break;
StringFormatter::send(stream,F("<jM %d %d>\n"),
p[1],stashArray[p[1]]);
opcode=0;
break;
}
if (paramCount==3) { // <JM id cab>
if (p[1]<=0 || p[1]>maxStashId) break;
stashArray[p[1]]=p[2];
opcode=0;
break;
}
break;
default: default:
break; break;
} }
@ -195,6 +223,15 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) {
sigid & SIGNAL_ID_MASK); sigid & SIGNAL_ID_MASK);
} }
} }
if (compileFeatures & FEATURE_STASH) {
for (int i=1;i<=maxStashId;i++) {
if (stashArray[i])
StringFormatter::send(stream,F("\nSTASH[%d] Loco=%d"),
i, stashArray[i]);
}
}
StringFormatter::send(stream,F(" *>\n")); StringFormatter::send(stream,F(" *>\n"));
return true; return true;
} }

View File

@ -113,6 +113,15 @@ void exrailHalSetup() {
#undef ROUTE_CAPTION #undef ROUTE_CAPTION
#define ROUTE_CAPTION(id,caption) | FEATURE_ROUTESTATE #define ROUTE_CAPTION(id,caption) | FEATURE_ROUTESTATE
#undef CLEAR_STASH
#define CLEAR_STASH(id) | FEATURE_STASH
#undef CLEAR_ALL_STASH
#define CLEAR_ALL_STASH | FEATURE_STASH
#undef PICKUP_STASH
#define PICKUP_STASH(id) | FEATURE_STASH
#undef STASH
#define STASH(id) | FEATURE_STASH
const byte RMFT2::compileFeatures = 0 const byte RMFT2::compileFeatures = 0
#include "myAutomation.h" #include "myAutomation.h"
; ;
@ -353,6 +362,8 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
#define AUTOSTART OPCODE_AUTOSTART,0,0, #define AUTOSTART OPCODE_AUTOSTART,0,0,
#define BROADCAST(msg) PRINT(msg) #define BROADCAST(msg) PRINT(msg)
#define CALL(route) OPCODE_CALL,V(route), #define CALL(route) OPCODE_CALL,V(route),
#define CLEAR_STASH(id) OPCODE_CLEAR_STASH,V(id),
#define CLEAR_ALL_STASH OPCODE_CLEAR_ALL_STASH,V(0),
#define CLOSE(id) OPCODE_CLOSE,V(id), #define CLOSE(id) OPCODE_CLOSE,V(id),
#ifndef IO_NO_HAL #ifndef IO_NO_HAL
#define DCC_TURNTABLE(id,home,description...) OPCODE_DCCTURNTABLE,V(id),OPCODE_PAD,V(home), #define DCC_TURNTABLE(id,home,description...) OPCODE_DCCTURNTABLE,V(id),OPCODE_PAD,V(home),
@ -435,6 +446,7 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
#define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id), #define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id),
#define ONCHANGE(sensor_id) OPCODE_ONCHANGE,V(sensor_id), #define ONCHANGE(sensor_id) OPCODE_ONCHANGE,V(sensor_id),
#define PAUSE OPCODE_PAUSE,0,0, #define PAUSE OPCODE_PAUSE,0,0,
#define PICKUP_STASH(id) OPCODE_PICKUP_STASH,V(id),
#define PIN_TURNOUT(id,pin,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(pin), #define PIN_TURNOUT(id,pin,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(pin),
#ifndef DISABLE_PROG #ifndef DISABLE_PROG
#define POM(cv,value) OPCODE_POM,V(cv),OPCODE_PAD,V(value), #define POM(cv,value) OPCODE_POM,V(cv),OPCODE_PAD,V(value),
@ -482,6 +494,7 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
#define SIGNALH(redpin,amberpin,greenpin) #define SIGNALH(redpin,amberpin,greenpin)
#define SPEED(speed) OPCODE_SPEED,V(speed), #define SPEED(speed) OPCODE_SPEED,V(speed),
#define START(route) OPCODE_START,V(route), #define START(route) OPCODE_START,V(route),
#define STASH(id) OPCODE_STASH,V(id),
#define STOP OPCODE_SPEED,V(0), #define STOP OPCODE_SPEED,V(0),
#define THROW(id) OPCODE_THROW,V(id), #define THROW(id) OPCODE_THROW,V(id),
#ifndef IO_NO_HAL #ifndef IO_NO_HAL

View File

@ -3,7 +3,9 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "5.2.8" #define VERSION "5.2.9"
// 5.2.9 - Bugfix LCD startup with no LCD, uses <@
// 5.2.9 - EXRAIL STASH feature
// 5.2.8 - Bugfix: Do not turn off all tracks on change // 5.2.8 - Bugfix: Do not turn off all tracks on change
// give better power messages // give better power messages
// 5.2.7 - Bugfix: EXRAIL ling segment // 5.2.7 - Bugfix: EXRAIL ling segment