mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 21:01:25 +01:00
Reduced RAM/PROGMEM and CPU for signals.
This commit is contained in:
parent
230a119cd0
commit
7017c6bbf5
70
RMFT2.cpp
70
RMFT2.cpp
@ -77,7 +77,6 @@ RMFT2 * RMFT2::pausingTask=NULL; // Task causing a PAUSE.
|
|||||||
byte RMFT2::flags[MAX_FLAGS];
|
byte RMFT2::flags[MAX_FLAGS];
|
||||||
|
|
||||||
LookList * RMFT2::sequenceLookup=NULL;
|
LookList * RMFT2::sequenceLookup=NULL;
|
||||||
LookList * RMFT2::signalLookup=NULL;
|
|
||||||
LookList * RMFT2::onThrowLookup=NULL;
|
LookList * RMFT2::onThrowLookup=NULL;
|
||||||
LookList * RMFT2::onCloseLookup=NULL;
|
LookList * RMFT2::onCloseLookup=NULL;
|
||||||
LookList * RMFT2::onActivateLookup=NULL;
|
LookList * RMFT2::onActivateLookup=NULL;
|
||||||
@ -122,17 +121,12 @@ LookList * RMFT2::onDeactivateLookup=NULL;
|
|||||||
int onCloseCount=0;
|
int onCloseCount=0;
|
||||||
int onActivateCount=0;
|
int onActivateCount=0;
|
||||||
int onDeactivateCount=0;
|
int onDeactivateCount=0;
|
||||||
int signalCount=0;
|
|
||||||
|
|
||||||
// first pass count sizes for fast lookup arrays
|
// first pass count sizes for fast lookup arrays
|
||||||
for (progCounter=0;; SKIPOP) {
|
for (progCounter=0;; SKIPOP) {
|
||||||
byte opcode=GET_OPCODE;
|
byte opcode=GET_OPCODE;
|
||||||
if (opcode==OPCODE_ENDEXRAIL) break;
|
if (opcode==OPCODE_ENDEXRAIL) break;
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case OPCODE_SIGNAL:
|
|
||||||
signalCount++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPCODE_ROUTE:
|
case OPCODE_ROUTE:
|
||||||
case OPCODE_AUTOMATION:
|
case OPCODE_AUTOMATION:
|
||||||
case OPCODE_SEQUENCE:
|
case OPCODE_SEQUENCE:
|
||||||
@ -162,14 +156,23 @@ LookList * RMFT2::onDeactivateLookup=NULL;
|
|||||||
|
|
||||||
// create lookups
|
// create lookups
|
||||||
sequenceLookup=new LookList(sequenceCount);
|
sequenceLookup=new LookList(sequenceCount);
|
||||||
signalLookup=new LookList(signalCount);
|
|
||||||
onThrowLookup=new LookList(onThrowCount);
|
onThrowLookup=new LookList(onThrowCount);
|
||||||
onCloseLookup=new LookList(onCloseCount);
|
onCloseLookup=new LookList(onCloseCount);
|
||||||
onActivateLookup=new LookList(onActivateCount);
|
onActivateLookup=new LookList(onActivateCount);
|
||||||
onDeactivateLookup=new LookList(onDeactivateCount);
|
onDeactivateLookup=new LookList(onDeactivateCount);
|
||||||
|
|
||||||
// Second pass startup, define any turnouts or servos, set signals red
|
// Second pass startup, define any turnouts or servos, set signals red
|
||||||
// add signals, sequences onRoutines to the lookups
|
// add sequences onRoutines to the lookups
|
||||||
|
for (int sigpos=0;;sigpos+=3) {
|
||||||
|
VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos);
|
||||||
|
if (redpin==0) break; // end of signal list
|
||||||
|
VPIN amberpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1);
|
||||||
|
VPIN greenpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+2);
|
||||||
|
IODevice::write(redpin,true);
|
||||||
|
if (amberpin) IODevice::write(amberpin,false);
|
||||||
|
IODevice::write(greenpin,false);
|
||||||
|
}
|
||||||
|
|
||||||
for (progCounter=0;; SKIPOP){
|
for (progCounter=0;; SKIPOP){
|
||||||
byte opcode=GET_OPCODE;
|
byte opcode=GET_OPCODE;
|
||||||
if (opcode==OPCODE_ENDEXRAIL) break;
|
if (opcode==OPCODE_ENDEXRAIL) break;
|
||||||
@ -186,18 +189,6 @@ LookList * RMFT2::onDeactivateLookup=NULL;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case OPCODE_SIGNAL: {
|
|
||||||
VPIN red=operand;
|
|
||||||
VPIN amber=GET_OPERAND(1);
|
|
||||||
VPIN green=GET_OPERAND(2);
|
|
||||||
IODevice::write(red,true);
|
|
||||||
if (amber) IODevice::write(amber,false);
|
|
||||||
IODevice::write(green,false);
|
|
||||||
signalLookup->add(red,progCounter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OPCODE_TURNOUT: {
|
case OPCODE_TURNOUT: {
|
||||||
VPIN id=operand;
|
VPIN id=operand;
|
||||||
int addr=GET_OPERAND(1);
|
int addr=GET_OPERAND(1);
|
||||||
@ -256,9 +247,9 @@ LookList * RMFT2::onDeactivateLookup=NULL;
|
|||||||
}
|
}
|
||||||
SKIPOP; // include ENDROUTES opcode
|
SKIPOP; // include ENDROUTES opcode
|
||||||
|
|
||||||
DIAG(F("EXRAIL %db, fl=%d seq=%d, sig=%d, onT=%d, onC=%d"),
|
DIAG(F("EXRAIL %db, fl=%d seq=%d, onT=%d, onC=%d"),
|
||||||
progCounter,MAX_FLAGS,
|
progCounter,MAX_FLAGS,
|
||||||
sequenceCount, signalCount, onThrowCount, onCloseCount);
|
sequenceCount, onThrowCount, onCloseCount);
|
||||||
|
|
||||||
new RMFT2(0); // add the startup route
|
new RMFT2(0); // add the startup route
|
||||||
}
|
}
|
||||||
@ -871,7 +862,6 @@ void RMFT2::loop2() {
|
|||||||
|
|
||||||
case OPCODE_AUTOSTART: // Handled only during begin process
|
case OPCODE_AUTOSTART: // Handled only during begin process
|
||||||
case OPCODE_PAD: // Just a padding for previous opcode needing >1 operad byte.
|
case OPCODE_PAD: // Just a padding for previous opcode needing >1 operad byte.
|
||||||
case OPCODE_SIGNAL: // Signal definition ignore at run time
|
|
||||||
case OPCODE_TURNOUT: // Turnout definition ignored at runtime
|
case OPCODE_TURNOUT: // Turnout definition ignored at runtime
|
||||||
case OPCODE_SERVOTURNOUT: // Turnout definition ignored at runtime
|
case OPCODE_SERVOTURNOUT: // Turnout definition ignored at runtime
|
||||||
case OPCODE_PINTURNOUT: // Turnout definition ignored at runtime
|
case OPCODE_PINTURNOUT: // Turnout definition ignored at runtime
|
||||||
@ -913,19 +903,27 @@ void RMFT2::kill(const FSH * reason, int operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void RMFT2::doSignal(VPIN id,bool red, bool amber, bool green) {
|
/* static */ void RMFT2::doSignal(VPIN id,bool red, bool amber, bool green) {
|
||||||
// CAUTION: hides class member progCounter
|
//if (diag) DIAG(F(" dosignal %d"),id);
|
||||||
int progCounter=signalLookup->find(id);
|
for (int sigpos=0;;sigpos+=3) {
|
||||||
if (progCounter<0) return;
|
VPIN redpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos);
|
||||||
VPIN redpin=GET_OPERAND(0);
|
//if (diag) DIAG(F("red=%d"),redpin);
|
||||||
if (redpin!=id) return; // something wrong in lookup
|
if (redpin==0) {
|
||||||
VPIN amberpin=GET_OPERAND(1);
|
DIAG(F("EXRAIL Signal %d not defined"), id);
|
||||||
VPIN greenpin=GET_OPERAND(2);
|
return; // signal not found
|
||||||
// If amberpin is zero, synthesise amber from red+green
|
}
|
||||||
IODevice::write(redpin,red || (amber && (amberpin==0)));
|
if (redpin==id) {
|
||||||
if (amberpin) IODevice::write(amberpin,amber);
|
VPIN amberpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+1);
|
||||||
if (greenpin) IODevice::write(greenpin,green || (amber && (amberpin==0)));
|
VPIN greenpin=GETFLASHW(RMFT2::SignalDefinitions+sigpos+2);
|
||||||
|
//if (diag) DIAG(F("signal %d %d %d"),redpin,amberpin,greenpin);
|
||||||
|
// If amberpin is zero, synthesise amber from red+green
|
||||||
|
IODevice::write(redpin,red || (amber && (amberpin==0)));
|
||||||
|
if (amberpin) IODevice::write(amberpin,amber);
|
||||||
|
if (greenpin) IODevice::write(greenpin,green || (amber && (amberpin==0)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RMFT2::turnoutEvent(int16_t turnoutId, bool closed) {
|
void RMFT2::turnoutEvent(int16_t turnoutId, bool closed) {
|
||||||
// Hunt for an ONTHROW/ONCLOSE for this turnout
|
// Hunt for an ONTHROW/ONCLOSE for this turnout
|
||||||
int pc= (closed?onCloseLookup:onThrowLookup)->find(turnoutId);
|
int pc= (closed?onCloseLookup:onThrowLookup)->find(turnoutId);
|
||||||
|
14
RMFT2.h
14
RMFT2.h
@ -22,7 +22,7 @@
|
|||||||
#include "IODevice.h"
|
#include "IODevice.h"
|
||||||
|
|
||||||
// The following are the operation codes (or instructions) for a kind of virtual machine.
|
// The following are the operation codes (or instructions) for a kind of virtual machine.
|
||||||
// Each instruction is normally 2 bytes long with an operation code followed by a parameter.
|
// Each instruction is normally 3 bytes long with an operation code followed by a parameter.
|
||||||
// In cases where more than one parameter is required, the first parameter is followed by one
|
// In cases where more than one parameter is required, the first parameter is followed by one
|
||||||
// or more OPCODE_PAD instructions with the subsequent parameters. This wastes a byte but makes
|
// or more OPCODE_PAD instructions with the subsequent parameters. This wastes a byte but makes
|
||||||
// searching easier as a parameter can never be confused with an opcode.
|
// searching easier as a parameter can never be confused with an opcode.
|
||||||
@ -53,9 +53,11 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
|
|||||||
|
|
||||||
|
|
||||||
// Flag bits for status of hardware and TPL
|
// Flag bits for status of hardware and TPL
|
||||||
static const byte SECTION_FLAG = 0x01;
|
static const byte SECTION_FLAG = 0x80;
|
||||||
static const byte LATCH_FLAG = 0x02;
|
static const byte LATCH_FLAG = 0x40;
|
||||||
static const byte TASK_FLAG = 0x04;
|
static const byte TASK_FLAG = 0x20;
|
||||||
|
static const byte SPARE_FLAG = 0x10;
|
||||||
|
static const byte COUNTER_MASK= 0x0F;
|
||||||
|
|
||||||
static const byte MAX_STACK_DEPTH=4;
|
static const byte MAX_STACK_DEPTH=4;
|
||||||
|
|
||||||
@ -95,7 +97,7 @@ private:
|
|||||||
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 void 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,bool red, bool amber, bool green);
|
static void doSignal(VPIN id,bool red, bool amber, bool green);
|
||||||
static void emitRouteDescription(Print * stream, char type, int id, const FSH * description);
|
static void emitRouteDescription(Print * stream, char type, int id, const FSH * description);
|
||||||
@ -116,9 +118,9 @@ private:
|
|||||||
|
|
||||||
static bool diag;
|
static bool diag;
|
||||||
static const FLASH byte RouteCode[];
|
static const FLASH byte RouteCode[];
|
||||||
|
static const FLASH int16_t SignalDefinitions[];
|
||||||
static byte flags[MAX_FLAGS];
|
static byte flags[MAX_FLAGS];
|
||||||
static LookList * sequenceLookup;
|
static LookList * sequenceLookup;
|
||||||
static LookList * signalLookup;
|
|
||||||
static LookList * onThrowLookup;
|
static LookList * onThrowLookup;
|
||||||
static LookList * onCloseLookup;
|
static LookList * onCloseLookup;
|
||||||
static LookList * onActivateLookup;
|
static LookList * onActivateLookup;
|
||||||
|
11
RMFTMacros.h
11
RMFTMacros.h
@ -140,11 +140,18 @@ const FSH * RMFT2::getRosterFunctions(int16_t cabid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass 8 Signal definitions
|
||||||
|
#include "RMFT2MacroReset.h"
|
||||||
|
#undef SIGNAL
|
||||||
|
#define SIGNAL(redpin,amberpin,greenpin) redpin,amberpin,greenpin,
|
||||||
|
const FLASH int16_t RMFT2::SignalDefinitions[] = {
|
||||||
|
#include "myAutomation.h"
|
||||||
|
0,0,0 };
|
||||||
|
|
||||||
// Last Pass : create main routes table
|
// Last Pass : create main routes table
|
||||||
// Only undef the macros, not dummy them.
|
// Only undef the macros, not dummy them.
|
||||||
#define RMFT2_UNDEF_ONLY
|
#define RMFT2_UNDEF_ONLY
|
||||||
#include "RMFT2MacroReset.h"
|
#include "RMFT2MacroReset.h"
|
||||||
|
|
||||||
// Define internal helper macros.
|
// Define internal helper macros.
|
||||||
// Everything we generate here has to be compile-time evaluated to
|
// Everything we generate here has to be compile-time evaluated to
|
||||||
// a constant.
|
// a constant.
|
||||||
@ -227,7 +234,7 @@ const FSH * RMFT2::getRosterFunctions(int16_t cabid) {
|
|||||||
#define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) OPCODE_SERVOTURNOUT,V(id),OPCODE_PAD,V(pin),OPCODE_PAD,V(activeAngle),OPCODE_PAD,V(inactiveAngle),OPCODE_PAD,V(PCA9685::ProfileType::profile),
|
#define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) OPCODE_SERVOTURNOUT,V(id),OPCODE_PAD,V(pin),OPCODE_PAD,V(activeAngle),OPCODE_PAD,V(inactiveAngle),OPCODE_PAD,V(PCA9685::ProfileType::profile),
|
||||||
#define SET(pin) OPCODE_SET,V(pin),
|
#define SET(pin) OPCODE_SET,V(pin),
|
||||||
#define SETLOCO(loco) OPCODE_SETLOCO,V(loco),
|
#define SETLOCO(loco) OPCODE_SETLOCO,V(loco),
|
||||||
#define SIGNAL(redpin,amberpin,greenpin) OPCODE_SIGNAL,V(redpin),OPCODE_PAD,V(amberpin),OPCODE_PAD,V(greenpin),
|
#define SIGNAL(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 STOP OPCODE_SPEED,V(0),
|
#define STOP OPCODE_SPEED,V(0),
|
||||||
|
Loading…
Reference in New Issue
Block a user