1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-07-28 09:53:45 +02:00

Assorted bits (#138)

* LCN

* Prevent deprecated compiler warning

* Implement huge function numbers

* new commands

<! [cab]> forget locos.
<9> ESTOP ALL.
<D RESET> reboot arduino

* Waveform accuracy msg

* Drop post-write verify

* UNUSED_PIN current measure

and callback -2 for cv actions.

* Correct diags

* ESTOP a forget loco

* ESTOP loco on forget

* Avoid compiler warning

* current sensor offset

* Restore <1 JOIN> after prog track operation

* <!> ESTOP <-> FORGET

* Auto current offset detection

* manage current offset and diagnostics

* neater msg at startup

* Add startup message to LCN master

* DCC::setJoinRelayPin

Co-authored-by: Asbelos <asbelos@btinternet.com>
This commit is contained in:
Fred
2021-03-23 10:37:05 -04:00
committed by GitHub
parent f556cc5e1c
commit d7b2cf3d76
17 changed files with 225 additions and 28 deletions

59
DCC.cpp
View File

@@ -47,16 +47,10 @@ const byte FN_GROUP_5=0x10;
FSH* DCC::shieldName=NULL;
byte DCC::joinRelay=UNUSED_PIN;
void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriver* progDriver,
byte joinRelayPin) {
void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriver* progDriver) {
shieldName=(FSH *)motorShieldName;
DIAG(F("<iDCC-EX V-%S / %S / %S G-%S>\n"), F(VERSION), F(ARDUINO_TYPE), shieldName, F(GITHUB_SHA));
joinRelay=joinRelayPin;
if (joinRelay!=UNUSED_PIN) {
pinMode(joinRelay,OUTPUT);
digitalWrite(joinRelay,LOW); // high is relay disengaged
}
// Load stuff from EEprom
(void)EEPROM; // tell compiler not to warn this is unused
EEStore::init();
@@ -64,6 +58,14 @@ void DCC::begin(const FSH * motorShieldName, MotorDriver * mainDriver, MotorDriv
DCCWaveform::begin(mainDriver,progDriver);
}
void DCC::setJoinRelayPin(byte joinRelayPin) {
joinRelay=joinRelayPin;
if (joinRelay!=UNUSED_PIN) {
pinMode(joinRelay,OUTPUT);
digitalWrite(joinRelay,LOW); // LOW is relay disengaged
}
}
void DCC::setThrottle( uint16_t cab, uint8_t tSpeed, bool tDirection) {
byte speedCode = (tSpeed & 0x7F) + tDirection * 128;
setThrottle2(cab, speedCode);
@@ -114,7 +116,28 @@ bool DCC::getThrottleDirection(int cab) {
// Set function to value on or off
void DCC::setFn( int cab, byte functionNumber, bool on) {
if (cab<=0 || functionNumber>28) return;
if (cab<=0 ) return;
if (functionNumber>28) {
//non reminding advanced binary bit set
byte b[5];
byte nB = 0;
if (cab > 127)
b[nB++] = highByte(cab) | 0xC0; // convert train number into a two-byte address
b[nB++] = lowByte(cab);
if (functionNumber <= 127) {
b[nB++] = 0b11011101; // Binary State Control Instruction short form
b[nB++] = functionNumber | (on ? 0x80 : 0);
}
else {
b[nB++] = 0b11000000; // Binary State Control Instruction long form
b[nB++] = (functionNumber & 0x7F) | (on ? 0x80 : 0); // low order bits and state flag
b[nB++] = functionNumber >>8 ; // high order bits
}
DCCWaveform::mainTrack.schedulePacket(b, nB, 4);
return;
}
int reg = lookupSpeedTable(cab);
if (reg<0) return;
@@ -293,7 +316,8 @@ const ackOp FLASH READ_BIT_PROG[] = {
const ackOp FLASH WRITE_BYTE_PROG[] = {
BASELINE,
WB,WACK, // Write
VB,WACK, // validate byte
// VB,WACK, // validate byte, unnecessary after write gave ACK.
// Also, in some cases, like decoder reset, the value read back is not the same as written.
ITC1, // if ok callback (1)
FAIL // callback (-1)
};
@@ -498,12 +522,15 @@ void DCC::setLocoId(int id,ACK_CALLBACK callback) {
ackManagerSetup(id | 0xc000,LONG_LOCO_ID_PROG, callback);
}
void DCC::forgetLoco(int cab) { // removes any speed reminders for this loco
void DCC::forgetLoco(int cab) { // removes any speed reminders for this loco
setThrottle2(cab,1); // ESTOP this loco if still on track
int reg=lookupSpeedTable(cab);
if (reg>=0) speedTable[reg].loco=0;
setThrottle2(cab,1); // ESTOP if this loco still on track
}
void DCC::forgetAllLocos() { // removes all speed reminders
for (int i=0;i<MAX_LOCOS;i++) speedTable[i].loco=0;
setThrottle2(0,1); // ESTOP all locos still on track
for (int i=0;i<MAX_LOCOS;i++) speedTable[i].loco=0;
}
byte DCC::loopStatus=0;
@@ -634,6 +661,7 @@ int DCC::ackManagerWord;
int DCC::ackManagerCv;
byte DCC::ackManagerBitNum;
bool DCC::ackReceived;
bool DCC::ackManagerRejoin;
ACK_CALLBACK DCC::ackManagerCallback;
@@ -667,6 +695,11 @@ void DCC::ackManagerLoop() {
// (typically waiting for a reset counter or ACK waiting, or when all finished.)
switch (opcode) {
case BASELINE:
ackManagerRejoin=DCCWaveform::progTrackSyncMain;
if (!DCCWaveform::progTrack.canMeasureCurrent()) {
callback(-2);
return;
}
setProgTrackSyncMain(false);
if (DCCWaveform::progTrack.getPowerMode() == POWERMODE::OFF) {
if (Diag::ACK) DIAG(F("\nAuto Prog power on"));
@@ -833,6 +866,10 @@ void DCC::callback(int value) {
if (Diag::ACK) DIAG(F("\nAuto Prog power off"));
DCCWaveform::progTrack.doAutoPowerOff();
}
// Restore <1 JOIN> to state before BASELINE
setProgTrackSyncMain(ackManagerRejoin);
if (Diag::ACK) DIAG(F("\nCallback(%d)\n"),value);
(ackManagerCallback)( value);
}