1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

ONACTIVATE catchers etc

UNTESTED SO FAR
This commit is contained in:
Asbelos 2021-11-25 11:36:05 +00:00
parent ef1719f6fc
commit 92d6a15ee5
4 changed files with 73 additions and 7 deletions

View File

@ -25,6 +25,7 @@
#include "version.h"
#include "FSH.h"
#include "IODevice.h"
#include "RMFT2.h"
// This module is responsible for converting API calls into
// messages to be sent to the waveform generator.
@ -253,6 +254,9 @@ void DCC::setAccessory(int address, byte number, bool activate) {
b[1] = ((((address / 64) % 8) << 4) + (number % 4 << 1) + activate % 2) ^ 0xF8; // second byte is of the form 1AAACDDD, where C should be 1, and the least significant D represent activate/deactivate
DCCWaveform::mainTrack.schedulePacket(b, 2, 4); // Repeat the packet four times
#if defined(RMFT_ACTIVE)
RMFT2::activateEvent(address<<2|number,activate);
#endif
}
//

View File

@ -18,14 +18,15 @@
*/
/* EXRAILPlus planned FEATURE additions
F1. DCC accessory packet opcodes (short and long form)
F2. ONAccessory catchers
F1. [DONE] DCC accessory packet opcodes (short and long form)
F2. [DONE] ONAccessory catchers
F3. Turnout descriptions for Withrottle
F4. Oled announcements (depends on HAL)
F5. Withrottle roster info
F6. Multi-occupancy semaphore
F7. [DONE see AUTOSTART] Self starting sequences
F8. Park/unpark
F9. Analog drive
*/
/* EXRAILPlus planned TRANSPARENT additions
T1. [DONE] RAM based fast lookup for sequences ON* event catchers and signals.
@ -74,6 +75,8 @@ LookList * RMFT2::sequenceLookup=NULL;
LookList * RMFT2::signalLookup=NULL;
LookList * RMFT2::onThrowLookup=NULL;
LookList * RMFT2::onCloseLookup=NULL;
LookList * RMFT2::onActivateLookup=NULL;
LookList * RMFT2::onDeactivateLookup=NULL;
#define GET_OPCODE GETFLASH(RMFT2::RouteCode+progCounter)
#define GET_OPERAND(n) GETFLASHW(RMFT2::RouteCode+progCounter+1+(n*3))
@ -112,6 +115,8 @@ LookList * RMFT2::onCloseLookup=NULL;
int sequenceCount=0; // to allow for seq 0 at start
int onThrowCount=0;
int onCloseCount=0;
int onActivateCount=0;
int onDeactivateCount=0;
int signalCount=0;
// first pass count sizes for fast lookup arrays
@ -137,6 +142,14 @@ LookList * RMFT2::onCloseLookup=NULL;
onCloseCount++;
break;
case OPCODE_ONACTIVATE:
onActivateCount++;
break;
case OPCODE_ONDEACTIVATE:
onDeactivateCount++;
break;
default: // Ignore
break;
}
@ -147,6 +160,8 @@ LookList * RMFT2::onCloseLookup=NULL;
signalLookup=new LookList(signalCount);
onThrowLookup=new LookList(onThrowCount);
onCloseLookup=new LookList(onCloseCount);
onActivateLookup=new LookList(onActivateCount);
onDeactivateLookup=new LookList(onDeactivateCount);
// Second pass startup, define any turnouts or servos, set signals red
// add signals, sequences onRoutines to the lookups
@ -217,6 +232,14 @@ LookList * RMFT2::onCloseLookup=NULL;
onCloseLookup->add(operand,progCounter);
break;
case OPCODE_ONACTIVATE:
onActivateLookup->add(operand,progCounter);
break;
case OPCODE_ONDEACTIVATE:
onDeactivateLookup->add(operand,progCounter);
break;
case OPCODE_AUTOSTART:
// automatically create a task from here at startup.
new RMFT2(progCounter);
@ -660,6 +683,7 @@ void RMFT2::loop2() {
case OPCODE_DRIVE:
{
// IMCOMPLETE TODO PENDING HAL changes for analog read etc
if (readSensor(operand)) break;
byte analogSpeed=IODevice::readAnalogue(GET_OPERAND(1)) *127 / 1024;
if (speedo!=analogSpeed) driveLoco(analogSpeed);
@ -798,7 +822,9 @@ void RMFT2::loop2() {
case OPCODE_SERVOTURNOUT: // Turnout definition ignored at runtime
case OPCODE_PINTURNOUT: // Turnout definition ignored at runtime
case OPCODE_ONCLOSE: // Turnout event catcers ignored here
case OPCODE_ONTHROW: // Turnout definition ignored at runtime
case OPCODE_ONTHROW:
case OPCODE_ONACTIVATE: // Activate event catcers ignored here
case OPCODE_ONDEACTIVATE:
break;
default:
@ -848,9 +874,8 @@ void RMFT2::kill(const FSH * reason, int operand) {
void RMFT2::turnoutEvent(int16_t turnoutId, bool closed) {
// Hunt for an ONTHROW/ONCLOSE for this turnout
// caution hides class progCounter;
int progCounter= (closed?onCloseLookup:onThrowLookup)->find(turnoutId);
if (progCounter<0) return;
int pc= (closed?onCloseLookup:onThrowLookup)->find(turnoutId);
if (pc<0) return;
// Check we dont already have a task running this turnout
RMFT2 * task=loopTask;
@ -864,7 +889,27 @@ void RMFT2::kill(const FSH * reason, int operand) {
}
task->onTurnoutId=turnoutId; // flag for recursion detector
task=new RMFT2(progCounter); // new task starts at this instruction
task=new RMFT2(pc); // new task starts at this instruction
}
void RMFT2::activateEvent(int16_t addr, bool activate) {
// Hunt for an ONACTIVATE/ONDEACTIVATE for this accessory
int pc= (activate?onActivateLookup:onDeactivateLookup)->find(addr);
if (pc<0) return;
// Check we dont already have a task running this address
RMFT2 * task=loopTask;
while(task) {
if (task->onActivateAddr==addr) {
DIAG(F("Recursive ON(DE)ACTIVATE for %d"),addr);
return;
}
task=task->next;
if (task==loopTask) break;
}
task->onActivateAddr=addr; // flag for recursion detector
task=new RMFT2(pc); // new task starts at this instruction
}
void RMFT2::printMessage2(const FSH * msg) {

View File

@ -43,6 +43,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
OPCODE_PAUSE, OPCODE_RESUME,OPCODE_POWEROFF,
OPCODE_ONCLOSE, OPCODE_ONTHROW, OPCODE_SERVOTURNOUT, OPCODE_PINTURNOUT,
OPCODE_PRINT,OPCODE_DCCACTIVATE,
OPCODE_ONACTIVATE,OPCODE_ONDEACTIVATE,
OPCODE_ROUTE,OPCODE_AUTOMATION,OPCODE_SEQUENCE,OPCODE_ENDTASK,OPCODE_ENDEXRAIL
};
@ -81,6 +82,7 @@ class LookList {
static void emitWithrottleRouteList(Print* stream);
static void createNewTask(int route, uint16_t cab);
static void turnoutEvent(int16_t id, bool closed);
static void activateEvent(int16_t addr, bool active);
private:
static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]);
static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ;
@ -112,6 +114,8 @@ private:
static LookList * signalLookup;
static LookList * onThrowLookup;
static LookList * onCloseLookup;
static LookList * onActivateLookup;
static LookList * onDeactivateLookup;
// Local variables - exist for each instance/task
RMFT2 *next; // loop chain
@ -126,6 +130,7 @@ private:
bool invert;
byte speedo;
int16_t onTurnoutId;
int16_t onActivateAddr;
byte stackDepth;
int callStack[MAX_STACK_DEPTH];
};

View File

@ -94,6 +94,10 @@
#define LCN(msg)
#define ONCLOSE(turnout_id)
#define ONTHROW(turnout_id)
#define ONACTIVATE(addr,subaddr)
#define ONDEACTIVATE(addr,subaddr)
#define ONACTIVATEL(linear)
#define ONDEACTIVATEL(linear)
#define PAUSE
#define PRINT(msg)
#define POM(cv,value)
@ -198,6 +202,10 @@ const int StringMacroTracker1=__COUNTER__;
#undef LATCH
#undef LCD
#undef LCN
#undef ONACTIVATE
#undef ONDEACTIVATE
#undef ONACTIVATEL
#undef ONDEACTIVATEL
#undef ONCLOSE
#undef ONTHROW
#undef PAUSE
@ -283,6 +291,10 @@ const int StringMacroTracker1=__COUNTER__;
#define LATCH(sensor_id) OPCODE_LATCH,V(sensor_id),
#define LCD(id,msg) PRINT(msg)
#define LCN(msg) PRINT(msg)
#define ONACTIVATE(addr,subaddr) OPCODE_ONACTIVATE,V(addr<<2|subaddr),
#define ONDEACTIVATE(addr,subaddr) OPCODE_ONDEACTIVATE,V(addr<<2|subaddr),
#define ONACTIVATEL(linear) OPCODE_ONACTIVATE,V(linear+3),
#define ONDEACTIVATEL(linear) OPCODE_ONDEACTIVATE,V(linear+3),
#define ONCLOSE(turnout_id) OPCODE_ONCLOSE,V(turnout_id),
#define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id),
#define PAUSE OPCODE_PAUSE,0,0,