1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-24 16:46:13 +01:00

Compare commits

...

22 Commits

Author SHA1 Message Date
Asbelos
727e4d32f1 Merge branch 'devel' into devel_lcc 2023-09-08 19:19:52 +01:00
Colin Murdoch
dca023ffd7 Update version.h
Added ONOVERLOAD and AFTEROVERLOAD as 5.1.4
2023-09-07 20:27:25 +01:00
Colin Murdoch
4eef9581fe Merge branch 'devel-plus-onoverload' into devel 2023-09-07 20:23:17 +01:00
Colin Murdoch
ab393047c1 Update MotorDriver.cpp
Replace duplicate call to EXRAIL with single in overload.
2023-09-06 11:20:23 +01:00
Colin Murdoch
1ac104704e Update TrackManager.cpp
Reverse logic in TM::IisPowerOn()
2023-09-05 20:52:18 +01:00
Colin Murdoch
2f8e915b1e Added AFTEROVERLOAD
Added the AFTEROVERLOAD option - as yet untested.
2023-09-05 12:21:09 +01:00
Harald Barth
44d8154223 version number update 2023-08-30 23:57:49 +02:00
Harald Barth
01919b33df Make parser more fool proof 2023-08-30 23:55:39 +02:00
Harald Barth
26ddd27ecf let user disable <D > command in favour for HAL on the Uno platform 2023-08-29 14:27:38 +02:00
Harald Barth
2c64f10da8 Merge branch 'devel' of https://github.com/DCC-EX/CommandStation-EX into devel 2023-08-25 19:14:25 +02:00
Harald Barth
25426d076d version number update 2023-08-25 19:14:03 +02:00
Harald Barth
3453da0671 Bugfix: ESP32 30ms off time 2023-08-25 19:12:47 +02:00
Colin Murdoch
fb226311e5 Update myHal.cpp_example.txt
Added missing ::create to LiquidCrystal HAL definition
2023-08-24 14:54:33 +01:00
Colin Murdoch
6392c74ead Update myHal.cpp_example.txt
Added missing ::create to LiquidCrystal
2023-08-24 14:53:01 +01:00
Harald Barth
25f8852af6 call devel for 5.1.X version number update 2023-08-24 10:09:38 +02:00
Harald Barth
9842ea8a42 Bugfix: execute 30ms off time before rejoin 2023-08-24 10:07:25 +02:00
peteGSX
fa0aa27d46 Add OPCODE list to DCCEXParser.cpp 2023-08-24 10:07:15 +02:00
kempe63
4b2c0702a4 Update version.h
Update version.h for IO_PCA9555 changes
2023-08-18 11:40:34 +01:00
kempe63
e27cceeb74 Update PCA9555.h inconsistencies to IO_MCP23017.h causing IO_PCA9555.h compile error when configure for Mux
Updated Class PCA9555 definition reflecting changes in IO_MCP23017.h to support PCA9548 mux. Checked with PCA9555 base board, compiles and run EXRAIL script with  output driver
2023-08-18 11:30:37 +01:00
Colin Murdoch
247763ac00 Code Corrections
Code corrections
2023-08-12 19:10:35 +01:00
Colin Murdoch
e327e0ae8d Added ONOVERLOAD
Added code changes to create ONOVERLOAD command in EXRAIL
2023-08-12 18:40:48 +01:00
Harald Barth
9f38dae8ba Check bad AT firmware version 2023-08-11 00:07:02 +02:00
15 changed files with 184 additions and 29 deletions

View File

@ -351,7 +351,7 @@ void DCCACK::callback(int value) {
switch (callbackState) {
case AFTER_READ:
if (ackManagerRejoin && autoPowerOff) {
if (ackManagerRejoin && !autoPowerOff) {
progDriver->setPower(POWERMODE::OFF);
callbackStart=millis();
callbackState=WAITING_30;

View File

@ -25,6 +25,79 @@
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
/*
List of single character OPCODEs in use for reference.
When determining a new OPCODE for a new feature, refer to this list as the source of truth.
Once a new OPCODE is decided upon, update this list.
Character, Usage
/, |EX-R| interactive commands
-, Remove from reminder table
=, |TM| configuration
!, Emergency stop
@, Reserved for future use - LCD messages to JMRI
#, Request number of supported cabs/locos; heartbeat
+, WiFi AT commands
?, Reserved for future use
0, Track power off
1, Track power on
a, DCC accessory control
A,
b, Write CV bit on main
B, Write CV bit
c, Request current command
C,
d,
D, Diagnostic commands
e, Erase EEPROM
E, Store configuration in EEPROM
f, Loco decoder function control (deprecated)
F, Loco decoder function control
g,
G,
h,
H, Turnout state broadcast
i, Reserved for future use - Turntable object broadcast
I, Reserved for future use - Turntable object command and control
j, Throttle responses
J, Throttle queries
k, Reserved for future use - Potentially Railcom
K, Reserved for future use - Potentially Railcom
l, Loco speedbyte/function map broadcast
L,
m,
M, Write DCC packet
n,
N,
o,
O, Output broadcast
p, Broadcast power state
P, Write DCC packet
q, Sensor deactivated
Q, Sensor activated
r, Broadcast address read on programming track
R, Read CVs
s, Display status
S, Sensor configuration
t, Cab/loco update command
T, Turnout configuration/control
u, Reserved for user commands
U, Reserved for user commands
v,
V, Verify CVs
w, Write CV on main
W, Write CV
x,
X, Invalid command
y,
Y, Output broadcast
z,
Z, Output configuration/control
*/
#include "StringFormatter.h"
#include "DCCEXParser.h"
#include "DCC.h"
@ -378,10 +451,14 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
#ifndef DISABLE_PROG
case 'w': // WRITE CV on MAIN <w CAB CV VALUE>
if (params != 3)
break;
DCC::writeCVByteMain(p[0], p[1], p[2]);
return;
case 'b': // WRITE CV BIT ON MAIN <b CAB CV BIT VALUE>
if (params != 4)
break;
DCC::writeCVBitMain(p[0], p[1], p[2], p[3]);
return;
#endif
@ -412,8 +489,10 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
DCC::setLocoId(p[0],callback_Wloco);
else if (params == 4) // WRITE CV ON PROG <W CV VALUE [CALLBACKNUM] [CALLBACKSUB]>
DCC::writeCVByte(p[0], p[1], callback_W4);
else // WRITE CV ON PROG <W CV VALUE>
else if (params == 2) // WRITE CV ON PROG <W CV VALUE>
DCC::writeCVByte(p[0], p[1], callback_W);
else
break;
return;
case 'V': // VERIFY CV ON PROG <V CV VALUE> <V CV BIT 0|1>
@ -433,7 +512,9 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
}
break;
case 'B': // WRITE CV BIT ON PROG <B CV BIT VALUE CALLBACKNUM CALLBACKSUB>
case 'B': // WRITE CV BIT ON PROG <B CV BIT VALUE CALLBACKNUM CALLBACKSUB> or <B CV BIT VALUE>
if (params != 3 && params != 5)
break;
if (!stashCallback(stream, p, ringStream))
break;
DCC::writeCVBit(p[0], p[1], p[2], callback_B);
@ -565,12 +646,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
case ' ': // < >
StringFormatter::send(stream, F("\n"));
return;
#ifndef DISABLE_DIAG
case 'D': // < >
if (parseD(stream, params, p))
return;
return;
break;
#endif
case '=': // <= Track manager control >
if (TrackManager::parseJ(stream, params, p))
return;

View File

@ -2,7 +2,7 @@
* © 2021 Neil McKechnie
* © 2021-2023 Harald Barth
* © 2020-2023 Chris Harlow
* © 2022 Colin Murdoch
* © 2022-2023 Colin Murdoch
* All rights reserved.
*
* This file is part of CommandStation-EX
@ -97,6 +97,7 @@ LookList * RMFT2::onAmberLookup=NULL;
LookList * RMFT2::onGreenLookup=NULL;
LookList * RMFT2::onChangeLookup=NULL;
LookList * RMFT2::onClockLookup=NULL;
LookList * RMFT2::onOverloadLookup=NULL;
#define GET_OPCODE GETHIGHFLASH(RMFT2::RouteCode,progCounter)
#define SKIPOP progCounter+=3
@ -178,6 +179,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
onGreenLookup=LookListLoader(OPCODE_ONGREEN);
onChangeLookup=LookListLoader(OPCODE_ONCHANGE);
onClockLookup=LookListLoader(OPCODE_ONTIME);
onOverloadLookup=LookListLoader(OPCODE_ONOVERLOAD);
// Second pass startup, define any turnouts or servos, set signals red
@ -198,6 +200,7 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
case OPCODE_AT:
case OPCODE_ATTIMEOUT2:
case OPCODE_AFTER:
case OPCODE_AFTEROVERLOAD:
case OPCODE_IF:
case OPCODE_IFNOT: {
int16_t pin = (int16_t)operand;
@ -735,6 +738,16 @@ void RMFT2::loop2() {
if (millis()-waitAfter < 500 ) return;
break;
case OPCODE_AFTEROVERLOAD: // waits for the power to be turned back on - either by power routine or button
if (!TrackManager::isPowerOn(operand)) {
// reset timer to half a second and keep waiting
waitAfter=millis();
delayMe(50);
return;
}
if (millis()-waitAfter < 500 ) return;
break;
case OPCODE_LATCH:
setFlag(operand,LATCH_FLAG);
break;
@ -1040,6 +1053,7 @@ void RMFT2::loop2() {
case OPCODE_ONGREEN:
case OPCODE_ONCHANGE:
case OPCODE_ONTIME:
case OPCODE_ONOVERLOAD:
break;
@ -1194,6 +1208,16 @@ void RMFT2::clockEvent(int16_t clocktime, bool change) {
}
}
void RMFT2::powerEvent(int16_t track, bool overload) {
// Hunt for an ONOVERLOAD for this item
if (Diag::CMD)
DIAG(F("Looking for Power event on track : %c"), track);
if (overload) {
handleEvent(F("POWER"),onOverloadLookup,track);
}
}
void RMFT2::handleEvent(const FSH* reason,LookList* handlers, int16_t id) {
int pc= handlers->find(id);
if (pc<0) return;

View File

@ -1,7 +1,7 @@
/*
* © 2021 Neil McKechnie
* © 2020-2022 Chris Harlow
* © 2022 Colin Murdoch
* © 2022-2023 Colin Murdoch
* © 2023 Harald Barth
* All rights reserved.
*
@ -35,7 +35,8 @@
enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
OPCODE_FWD,OPCODE_REV,OPCODE_SPEED,OPCODE_INVERT_DIRECTION,
OPCODE_RESERVE,OPCODE_FREE,
OPCODE_AT,OPCODE_AFTER,OPCODE_AUTOSTART,
OPCODE_AT,OPCODE_AFTER,
OPCODE_AFTEROVERLOAD,OPCODE_AUTOSTART,
OPCODE_ATGTE,OPCODE_ATLT,
OPCODE_ATTIMEOUT1,OPCODE_ATTIMEOUT2,
OPCODE_LATCH,OPCODE_UNLATCH,OPCODE_SET,OPCODE_RESET,
@ -63,6 +64,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,
OPCODE_ONCLOCKTIME,
OPCODE_ONTIME,
OPCODE_LCC,OPCODE_ONLCC,
OPCODE_ONOVERLOAD,
// OPcodes below this point are skip-nesting IF operations
// placed here so that they may be skipped as a group
@ -131,6 +133,7 @@ class LookList {
static void activateEvent(int16_t addr, bool active);
static void changeEvent(int16_t id, bool change);
static void clockEvent(int16_t clocktime, bool change);
static void powerEvent(int16_t track, bool overload);
static const int16_t SERVO_SIGNAL_FLAG=0x4000;
static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000;
static const int16_t DCC_SIGNAL_FLAG=0x1000;
@ -190,6 +193,8 @@ private:
static LookList * onGreenLookup;
static LookList * onChangeLookup;
static LookList * onClockLookup;
static LookList * onOverloadLookup;
static const int countLCCLookup;
static int onLCCLookup[];

View File

@ -1,6 +1,6 @@
/*
* © 2020-2022 Chris Harlow. All rights reserved.
* © 2022 Colin Murdoch
* © 2022-2023 Colin Murdoch
* © 2023 Harald Barth
*
* This file is part of CommandStation-EX
@ -27,6 +27,7 @@
#undef ACTIVATE
#undef ACTIVATEL
#undef AFTER
#undef AFTEROVERLOAD
#undef ALIAS
#undef AMBER
#undef ANOUT
@ -95,6 +96,7 @@
#undef ONTIME
#undef ONCLOCKTIME
#undef ONCLOCKMINS
#undef ONOVERLOAD
#undef ONGREEN
#undef ONRED
#undef ONTHROW
@ -154,6 +156,7 @@
#define ACTIVATE(addr,subaddr)
#define ACTIVATEL(addr)
#define AFTER(sensor_id)
#define AFTEROVERLOAD(track_id)
#define ALIAS(name,value...)
#define AMBER(signal_id)
#define ANOUT(vpin,value,param1,param2)
@ -218,6 +221,7 @@
#define ONTIME(value)
#define ONCLOCKTIME(hours,mins)
#define ONCLOCKMINS(mins)
#define ONOVERLOAD(track_id)
#define ONDEACTIVATE(addr,subaddr)
#define ONDEACTIVATEL(linear)
#define ONCLOSE(turnout_id)

View File

@ -1,7 +1,7 @@
/*
* © 2021 Neil McKechnie
* © 2020-2022 Chris Harlow
* © 2022 Colin Murdoch
* © 2022-2023 Colin Murdoch
* © 2023 Harald Barth
* All rights reserved.
*
@ -266,6 +266,7 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
#define ACTIVATE(addr,subaddr) OPCODE_DCCACTIVATE,V(addr<<3 | subaddr<<1 | 1),
#define ACTIVATEL(addr) OPCODE_DCCACTIVATE,V((addr+3)<<1 | 1),
#define AFTER(sensor_id) OPCODE_AT,V(sensor_id),OPCODE_AFTER,V(sensor_id),
#define AFTEROVERLOAD(track_id) OPCODE_AFTEROVERLOAD,V(TRACK_NUMBER_##track_id),
#define ALIAS(name,value...)
#define AMBER(signal_id) OPCODE_AMBER,V(signal_id),
#define ANOUT(vpin,value,param1,param2) OPCODE_SERVO,V(vpin),OPCODE_PAD,V(value),OPCODE_PAD,V(param1),OPCODE_PAD,V(param2),
@ -335,6 +336,7 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
#define ONTIME(value) OPCODE_ONTIME,V(value),
#define ONCLOCKTIME(hours,mins) OPCODE_ONTIME,V((STRIP_ZERO(hours)*60)+STRIP_ZERO(mins)),
#define ONCLOCKMINS(mins) ONCLOCKTIME(25,mins)
#define ONOVERLOAD(track_id) OPCODE_ONOVERLOAD,V(TRACK_NUMBER_##track_id),
#define ONDEACTIVATE(addr,subaddr) OPCODE_ONDEACTIVATE,V(addr<<2|subaddr),
#define ONDEACTIVATEL(linear) OPCODE_ONDEACTIVATE,V(linear+3),
#define ONGREEN(signal_id) OPCODE_ONGREEN,V(signal_id),

View File

@ -1 +1 @@
#define GITHUB_SHA "3bddf4d"
#define GITHUB_SHA "devel-202308302157Z"

View File

@ -29,9 +29,14 @@
// Define symbol IO_NO_HAL to reduce FLASH footprint when HAL features not required
// The HAL is disabled by default on Nano and Uno platforms, because of limited flash space.
#include "defines.h"
#if defined(ARDUINO_AVR_NANO) || defined(ARDUINO_AVR_UNO)
#if defined(DISABLE_DIAG) && defined(DISABLE_EEPROM) && defined(DISABLE_PROG)
#warning you have sacrificed DIAG for HAL
#else
#define IO_NO_HAL
#endif
#endif
// Define symbol IO_SWITCH_OFF_SERVO to set the PCA9685 output to 0 when an
// animation has completed. This switches off the servo motor, preventing

View File

@ -30,8 +30,8 @@
class PCA9555 : public GPIOBase<uint16_t> {
public:
static void create(VPIN vpin, int nPins, uint8_t I2CAddress, int interruptPin=-1) {
new PCA9555(vpin, min(nPins,16), I2CAddress, interruptPin);
static void create(VPIN vpin, uint8_t nPins, I2CAddress i2cAddress, int interruptPin=-1) {
if (checkNoOverlap(vpin, nPins, i2cAddress)) new PCA9555(vpin,nPins, i2cAddress, interruptPin);
}
// Constructor

View File

@ -4,6 +4,7 @@
* © 2021 Fred Decker
* © 2020-2023 Harald Barth
* © 2020-2021 Chris Harlow
* © 2023 Colin Murdoch
* All rights reserved.
*
* This file is part of CommandStation-EX
@ -26,6 +27,7 @@
#include "DCCWaveform.h"
#include "DCCTimer.h"
#include "DIAG.h"
#include "EXRAIL2.h"
unsigned long MotorDriver::globalOverloadStart = 0;
@ -614,6 +616,8 @@ void MotorDriver::checkPowerOverload(bool useProgLimit, byte trackno) {
power_sample_overload_wait *= 2;
if (power_sample_overload_wait > POWER_SAMPLE_RETRY_MAX)
power_sample_overload_wait = POWER_SAMPLE_RETRY_MAX;
DIAG(F("Calling EXRAIL"));
RMFT2::powerEvent(trackno, true); // Tell EXRAIL we have an overload
// power on test
DIAG(F("TRACK %c POWER RESTORE (after %4M)"), trackno + 'A', mslpc);
setPower(POWERMODE::ALERT);

View File

@ -1,6 +1,7 @@
/*
* © 2022 Chris Harlow
* © 2022 Harald Barth
* © 2023 Colin Murdoch
* All rights reserved.
*
* This file is part of DCC++EX
@ -53,7 +54,7 @@ bool TrackManager::progTrackSyncMain=false;
bool TrackManager::progTrackBoosted=false;
int16_t TrackManager::joinRelay=UNUSED_PIN;
#ifdef ARDUINO_ARCH_ESP32
byte TrackManager::tempProgTrack=MAX_TRACKS+1;
byte TrackManager::tempProgTrack=MAX_TRACKS+1; // MAX_TRACKS+1 is the unused flag
#endif
#ifdef ANALOG_READ_INTERRUPT
@ -505,7 +506,12 @@ void TrackManager::setJoin(bool joined) {
}
} else {
if (tempProgTrack != MAX_TRACKS+1) {
// as setTrackMode with TRACK_MODE_PROG defaults to
// power off, we will take the current power state
// of our track and then preserve that state.
POWERMODE tPTmode = track[tempProgTrack]->getPower(); //get current power status of this track
setTrackMode(tempProgTrack, TRACK_MODE_PROG);
track[tempProgTrack]->setPower(tPTmode); //set track status as it was before
tempProgTrack = MAX_TRACKS+1;
}
}
@ -513,3 +519,10 @@ void TrackManager::setJoin(bool joined) {
progTrackSyncMain=joined;
if (joinRelay!=UNUSED_PIN) digitalWrite(joinRelay,joined?HIGH:LOW);
}
bool TrackManager::isPowerOn(byte t) {
if (track[t]->getPower()!=POWERMODE::ON)
return false;
return true;
}

View File

@ -1,6 +1,8 @@
/*
* © 2022 Chris Harlow
* © 2022 Harald Barth
* © 2023 Colin Murdoch
*
* All rights reserved.
*
* This file is part of CommandStation-EX
@ -77,6 +79,7 @@ class TrackManager {
static void reportCurrent(Print* stream);
static void reportObsoleteCurrent(Print* stream);
static void streamTrackState(Print* stream, byte t);
static bool isPowerOn(byte t);
static int16_t joinRelay;
static bool progTrackSyncMain; // true when prog track is a siding switched to main

View File

@ -200,7 +200,21 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password,
// Display the AT version information
StringFormatter::send(wifiStream, F("AT+GMR\r\n"));
checkForOK(2000, true, false); // Makes this visible on the console
if (checkForOK(2000, F("AT version:"), true, false)) {
char version[] = "0.0.0.0";
for (int i=0; i<8;i++) {
while(!wifiStream->available());
version[i]=wifiStream->read();
StringFormatter::printEscape(version[i]);
if ((version[0] == '0') ||
(version[0] == '2' && version[2] == '0') ||
(version[0] == '2' && version[2] == '2' && version[4] == '0' && version[6] == '0')) {
SSid = F("DCCEX_SAYS_BROKEN_FIRMWARE");
forceAP = true;
}
}
}
checkForOK(2000, true, false);
#ifdef DONT_TOUCH_WIFI_CONF
DIAG(F("DONT_TOUCH_WIFI_CONF was set: Using existing config"));

View File

@ -51,7 +51,7 @@ void halSetup() {
// Create a 20x4 LCD display device as display number 2
// (line 0 is written by EX-RAIL 'SCREEN(2, 0, "text")').
// HALDisplay<LiquidCrystal>(2, 0x27, 20, 4);
// HALDisplay<LiquidCrystal>::create(2, 0x27, 20, 4);
//=======================================================================

View File

@ -3,7 +3,7 @@
#include "StringFormatter.h"
#define VERSION "5.0.1LCC"
#define VERSION "5.1.5LCC"
// 5.0.0 - Make 4.2.69 the 5.0.0 release
// 4.2.69 - Bugfix: Make <!> work in DC mode
// 4.2.68 - Rename track mode OFF to NONE