diff --git a/DCCACK.cpp b/DCCACK.cpp index 8c5e8c7..1b339ee 100644 --- a/DCCACK.cpp +++ b/DCCACK.cpp @@ -152,7 +152,7 @@ byte DCCACK::getAck() { return(0); // pending set off but not detected means no ACK. } - +#ifndef DISABLE_PROG void DCCACK::loop() { while (ackManagerProg) { byte opcode=GETFLASH(ackManagerProg); @@ -414,7 +414,7 @@ void DCCACK::callback(int value) { (ackManagerCallback)( value); } } - +#endif void DCCACK::checkAck(byte sentResetsSincePacket) { if (!ackPending) return; diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index bc79927..e4f270f 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -3,7 +3,7 @@ * © 2021 Neil McKechnie * © 2021 Mike S * © 2021 Herb Morton - * © 2020-2022 Harald Barth + * © 2020-2023 Harald Barth * © 2020-2021 M Steve Todd * © 2020-2021 Fred Decker * © 2020-2021 Chris Harlow @@ -54,9 +54,7 @@ // These keywords are used in the <1> command. The number is what you get if you use the keyword as a parameter. // To discover new keyword numbers , use the <$ YOURKEYWORD> command -const int16_t HASH_KEYWORD_PROG = -29718; const int16_t HASH_KEYWORD_MAIN = 11339; -const int16_t HASH_KEYWORD_JOIN = -30750; const int16_t HASH_KEYWORD_CABS = -11981; const int16_t HASH_KEYWORD_RAM = 25982; const int16_t HASH_KEYWORD_CMD = 9962; @@ -64,7 +62,11 @@ const int16_t HASH_KEYWORD_ACK = 3113; const int16_t HASH_KEYWORD_ON = 2657; const int16_t HASH_KEYWORD_DCC = 6436; const int16_t HASH_KEYWORD_SLOW = -17209; +#ifndef DISABLE_PROG +const int16_t HASH_KEYWORD_JOIN = -30750; +const int16_t HASH_KEYWORD_PROG = -29718; const int16_t HASH_KEYWORD_PROGBOOST = -6353; +#endif #ifndef DISABLE_EEPROM const int16_t HASH_KEYWORD_EEPROM = -7168; #endif @@ -371,6 +373,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) return; break; +#ifndef DISABLE_PROG case 'w': // WRITE CV on MAIN DCC::writeCVByteMain(p[0], p[1], p[2]); return; @@ -378,9 +381,12 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) case 'b': // WRITE CV BIT ON MAIN DCC::writeCVBitMain(p[0], p[1], p[2], p[3]); return; +#endif case 'M': // WRITE TRANSPARENT DCC PACKET MAIN +#ifndef DISABLE_PROG case 'P': // WRITE TRANSPARENT DCC PACKET PROG

+#endif // NOTE: this command was parsed in HEX instead of decimal params--; // drop REG if (params<1) break; @@ -395,6 +401,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) } return; +#ifndef DISABLE_PROG case 'W': // WRITE CV ON PROG if (!stashCallback(stream, p, ringStream)) break; @@ -452,6 +459,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) return; } break; +#endif case '1': // POWERON <1 [MAIN|PROG|JOIN]> { @@ -464,17 +472,19 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) prog=true; } if (params==1) { - if (p[0] == HASH_KEYWORD_JOIN) { // <1 JOIN> + if (p[0]==HASH_KEYWORD_MAIN) { // <1 MAIN> + main=true; + } +#ifndef DISABLE_PROG + else if (p[0] == HASH_KEYWORD_JOIN) { // <1 JOIN> main=true; prog=true; join=true; } - else if (p[0]==HASH_KEYWORD_MAIN) { // <1 MAIN> - main=true; - } else if (p[0]==HASH_KEYWORD_PROG) { // <1 PROG> prog=true; } +#endif else break; // will reply } if (main) TrackManager::setMainPower(POWERMODE::ON); @@ -498,9 +508,11 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) if (p[0]==HASH_KEYWORD_MAIN) { // <0 MAIN> main=true; } +#ifndef DISABLE_PROG else if (p[0]==HASH_KEYWORD_PROG) { // <0 PROG> prog=true; } +#endif else break; // will reply } @@ -895,6 +907,7 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[]) StringFormatter::send(stream, F("Free memory=%d\n"), DCCTimer::getMinimumFreeMemory()); break; +#ifndef DISABLE_PROG case HASH_KEYWORD_ACK: // if (params >= 3) { if (p[1] == HASH_KEYWORD_LIMIT) { @@ -915,6 +928,7 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[]) Diag::ACK = onOff; } return true; +#endif case HASH_KEYWORD_CMD: // Diag::CMD = onOff; @@ -937,11 +951,11 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[]) Diag::LCN = onOff; return true; #endif - +#ifndef DISABLE_PROG case HASH_KEYWORD_PROGBOOST: TrackManager::progTrackBoosted=true; return true; - +#endif case HASH_KEYWORD_RESET: DCCTimer::reset(); break; // and if we didnt restart diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 95d608b..cda9c9d 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -705,11 +705,11 @@ void RMFT2::loop2() { DCC::setThrottle(0,1,true); // pause all locos on the track pausingTask=this; break; - + case OPCODE_POM: if (loco) DCC::writeCVByteMain(loco, operand, getOperand(1)); break; - + case OPCODE_POWEROFF: TrackManager::setPower(POWERMODE::OFF); TrackManager::setJoin(false); @@ -884,23 +884,18 @@ void RMFT2::loop2() { while(loopTask) loopTask->kill(F("KILLALL")); return; +#ifndef DISABLE_PROG case OPCODE_JOIN: TrackManager::setPower(POWERMODE::ON); TrackManager::setJoin(true); CommandDistributor::broadcastPower(); break; - - case OPCODE_POWERON: - TrackManager::setMainPower(POWERMODE::ON); - TrackManager::setJoin(false); - CommandDistributor::broadcastPower(); - break; - + case OPCODE_UNJOIN: TrackManager::setJoin(false); CommandDistributor::broadcastPower(); break; - + case OPCODE_READ_LOCO1: // READ_LOCO is implemented as 2 separate opcodes progtrackLocoId=LOCO_ID_WAITING; // Nothing found yet DCC::getLocoId(readLocoCallback); @@ -921,6 +916,13 @@ void RMFT2::loop2() { forward=true; invert=false; break; +#endif + + case OPCODE_POWERON: + TrackManager::setMainPower(POWERMODE::ON); + TrackManager::setJoin(false); + CommandDistributor::broadcastPower(); + break; case OPCODE_START: { diff --git a/EXRAIL2.h b/EXRAIL2.h index 78ed949..4d106e6 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -45,7 +45,10 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE, OPCODE_RED,OPCODE_GREEN,OPCODE_AMBER,OPCODE_DRIVE, OPCODE_SERVO,OPCODE_SIGNAL,OPCODE_TURNOUT,OPCODE_WAITFOR, OPCODE_PAD,OPCODE_FOLLOW,OPCODE_CALL,OPCODE_RETURN, - OPCODE_JOIN,OPCODE_UNJOIN,OPCODE_READ_LOCO1,OPCODE_READ_LOCO2,OPCODE_POM, +#ifndef DISABLE_PROG + OPCODE_JOIN,OPCODE_UNJOIN,OPCODE_READ_LOCO1,OPCODE_READ_LOCO2, +#endif + OPCODE_POM, OPCODE_START,OPCODE_SETLOCO,OPCODE_SENDLOCO,OPCODE_FORGET, OPCODE_PAUSE, OPCODE_RESUME,OPCODE_POWEROFF,OPCODE_POWERON, OPCODE_ONCLOSE, OPCODE_ONTHROW, OPCODE_SERVOTURNOUT, OPCODE_PINTURNOUT, diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index 71b5251..588a417 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -101,7 +101,9 @@ #undef PAUSE #undef PIN_TURNOUT #undef PRINT +#ifndef DISABLE_PROG #undef POM +#endif #undef POWEROFF #undef POWERON #undef READ_LOCO @@ -224,7 +226,9 @@ #define PIN_TURNOUT(id,pin,description...) #define PRINT(msg) #define PARSE(msg) +#ifndef DISABLE_PROG #define POM(cv,value) +#endif #define POWEROFF #define POWERON #define READ_LOCO diff --git a/EXRAILMacros.h b/EXRAILMacros.h index e449fbf..5e81612 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -327,8 +327,10 @@ const HIGHFLASH int16_t RMFT2::SignalDefinitions[] = { #define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id), #define ONCHANGE(sensor_id) OPCODE_ONCHANGE,V(sensor_id), #define PAUSE OPCODE_PAUSE,0,0, -#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 #define POM(cv,value) OPCODE_POM,V(cv),OPCODE_PAD,V(value), +#endif #define POWEROFF OPCODE_POWEROFF,0,0, #define POWERON OPCODE_POWERON,0,0, #define PRINT(msg) OPCODE_PRINT,V(__COUNTER__ - StringMacroTracker2), diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 787fefc..3934c8e 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202305072222Z" +#define GITHUB_SHA "devel-202305091210Z" diff --git a/TrackManager.cpp b/TrackManager.cpp index fcd0c10..9c0f0b0 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -33,8 +33,9 @@ FOR_EACH_TRACK(t) \ if (trackMode[t]==findmode) \ track[t]->function; - +#ifndef DISABLE_PROG const int16_t HASH_KEYWORD_PROG = -29718; +#endif const int16_t HASH_KEYWORD_MAIN = 11339; const int16_t HASH_KEYWORD_OFF = 22479; const int16_t HASH_KEYWORD_DC = 2183; @@ -116,7 +117,11 @@ void TrackManager::Setup(const FSH * shieldname, // Default the first 2 tracks (which may be null) and perform HA waveform check. setTrackMode(0,TRACK_MODE_MAIN); +#ifndef DISABLE_PROG setTrackMode(1,TRACK_MODE_PROG); +#else + setTrackMode(1,TRACK_MODE_MAIN); +#endif // TODO Fault pin config for odd motor boards (example pololu) // MotorDriver::commonFaultPin = ((mainDriver->getFaultPin() == progDriver->getFaultPin()) @@ -198,7 +203,11 @@ bool TrackManager::setTrackMode(byte trackToSet, TRACK_MODE mode, int16_t dcAddr pinMode(p.invpin, OUTPUT); // gpio_reset_pin may reset to input } #endif +#ifndef DISABLE_PROG if (mode==TRACK_MODE_PROG) { +#else + if (false) { +#endif // only allow 1 track to be prog FOR_EACH_TRACK(t) if (trackMode[t]==TRACK_MODE_PROG && t != trackToSet) { @@ -306,8 +315,10 @@ bool TrackManager::parseJ(Print *stream, int16_t params, int16_t p[]) if (params==2 && p[1]==HASH_KEYWORD_MAIN) // <= id MAIN> return setTrackMode(p[0],TRACK_MODE_MAIN); +#ifndef DISABLE_PROG if (params==2 && p[1]==HASH_KEYWORD_PROG) // <= id PROG> return setTrackMode(p[0],TRACK_MODE_PROG); +#endif if (params==2 && p[1]==HASH_KEYWORD_OFF) // <= id OFF> return setTrackMode(p[0],TRACK_MODE_OFF); @@ -332,9 +343,11 @@ void TrackManager::streamTrackState(Print* stream, byte t) { case TRACK_MODE_MAIN: format=F("<= %c MAIN>\n"); break; +#ifndef DISABLE_PROG case TRACK_MODE_PROG: format=F("<= %c PROG>\n"); break; +#endif case TRACK_MODE_OFF: format=F("<= %c OFF>\n"); break; @@ -357,8 +370,10 @@ void TrackManager::streamTrackState(Print* stream, byte t) { byte TrackManager::nextCycleTrack=MAX_TRACKS; void TrackManager::loop() { - DCCWaveform::loop(); - DCCACK::loop(); + DCCWaveform::loop(); +#ifndef DISABLE_PROG + DCCACK::loop(); +#endif bool dontLimitProg=DCCACK::isActive() || progTrackSyncMain || progTrackBoosted; nextCycleTrack++; if (nextCycleTrack>lastTrack) nextCycleTrack=0; diff --git a/config.example.h b/config.example.h index 2a8a11a..728c1dd 100644 --- a/config.example.h +++ b/config.example.h @@ -141,7 +141,7 @@ The configuration file for DCC-EX Command Station // // If you do not need the EEPROM at all, you can disable all the code that saves // data in the EEPROM. You might want to do that if you are in a Arduino UNO -// and want to use the EX-RAIL automation. Otherwise you do not have enough RAM +// and want to use the EXRAIL automation. Otherwise you do not have enough RAM // to do that. Of course, then none of the EEPROM related commands work. // // EEPROM does not work on ESP32. So on ESP32, EEPROM will always be disabled, @@ -149,6 +149,17 @@ The configuration file for DCC-EX Command Station // // #define DISABLE_EEPROM +///////////////////////////////////////////////////////////////////////////////////// +// DISABLE PROG +// +// If you do not need programming capability, you can disable all programming related +// commands. You might want to do that if you are using an Arduino UNO and still want +// to use EXRAIL automation, as the Uno is lacking in RAM and Flash to run both. +// +// Note this disables all programming functionality, including EXRAIL. +// +// #define DISABLE_PROG + ///////////////////////////////////////////////////////////////////////////////////// // REDEFINE WHERE SHORT/LONG ADDR break is. According to NMRA the last short address // is 127 and the first long address is 128. There are manufacturers which have diff --git a/config.h.txt b/config.h.txt deleted file mode 100644 index 98cc3fc..0000000 --- a/config.h.txt +++ /dev/null @@ -1,169 +0,0 @@ -/********************************************************************** - -Config.h -COPYRIGHT (c) 2013-2016 Gregg E. Berman -COPYRIGHT (c) 2020 Fred Decker - -The configuration file for DCC++ EX Command Station - -**********************************************************************/ -///////////////////////////////////////////////////////////////////////////////////// -// NOTE: Before connecting these boards and selecting one in this software -// check the quick install guides!!! Some of these boards require a voltage -// generating resitor on the current sense pin of the device. Failure to select -// the correct resistor could damage the sense pin on your Arduino or destroy -// the device. -// -// DEFINE MOTOR_SHIELD_TYPE BELOW ACCORDING TO THE FOLLOWING TABLE: -// -// STANDARD_MOTOR_SHIELD : Arduino Motor shield Rev3 based on the L298 with 18V 2A per channel -// POLOLU_MOTOR_SHIELD : Pololu MC33926 Motor Driver (not recommended for prog track) -// FUNDUMOTO_SHIELD : Fundumoto Shield, no current sensing (not recommended, no short protection) -// FIREBOX_MK1 : The Firebox MK1 -// FIREBOX_MK1S : The Firebox MK1S -// | -// +-----------------------v -// -// #define STANDARD_MOTOR_SHIELD F("STANDARD_MOTOR_SHIELD"), -// new MotorDriver(3, 12, UNUSED_PIN, 9, A0, 0.488, 1500, UNUSED_PIN), -// new MotorDriver(11, 13, UNUSED_PIN, 8, A1, 0.488, 1500, UNUSED_PIN) - -#define MOTOR_SHIELD_TYPE STANDARD_MOTOR_SHIELD - -///////////////////////////////////////////////////////////////////////////////////// -// -// The IP port to talk to a WIFI or Ethernet shield. -// -#define IP_PORT 2560 - -///////////////////////////////////////////////////////////////////////////////////// -// -// NOTE: Only supported on Arduino Mega -// Set to false if you not even want it on the Arduino Mega -// -//#define ENABLE_WIFI true - -///////////////////////////////////////////////////////////////////////////////////// -// -// DEFINE WiFi Parameters (only in effect if WIFI is on) -// -// If DONT_TOUCH_WIFI_CONF is set, all WIFI config will be done with -// the <+> commands and this sketch will not change anything over -// AT commands and the other WIFI_* defines below do not have any effect. -//#define DONT_TOUCH_WIFI_CONF -// -// WIFI_SSID is the network name IF you want to use your existing home network. -// Do NOT change this if you want to use the WiFi in Access Point (AP) mode. -// -// If you do NOT set the WIFI_SSID, the WiFi chip will first try -// to connect to the previously configured network and if that fails -// fall back to Access Point mode. The SSID of the AP will be -// automatically set to DCCEX_*. -// -// Your SSID may not conain ``"'' (double quote, ASCII 0x22). -#define WIFI_SSID "Your network name" -// -// WIFI_PASSWORD is the network password for your home network or if -// you want to change the password from default AP mode password -// to the AP password you want. -// Your password may not conain ``"'' (double quote, ASCII 0x22). -#define WIFI_PASSWORD "deadcafe" -// -// WIFI_HOSTNAME: You probably don't need to change this -#define WIFI_HOSTNAME "dccex" -// -///////////////////////////////////////////////////////////////////////////////////// -// -// Wifi connect timeout in milliseconds. Default is 14000 (14 seconds). You only need -// to set this if you have an extremely slow Wifi router. -// -#define WIFI_CONNECT_TIMEOUT 14000 - -///////////////////////////////////////////////////////////////////////////////////// -// -// ENABLE_ETHERNET: Set to true if you have an Arduino Ethernet card (wired). This -// is not for Wifi. You will then need the Arduino Ethernet library as well -// -//#define ENABLE_ETHERNET true - - -///////////////////////////////////////////////////////////////////////////////////// -// -// DEFINE STATIC IP ADDRESS *OR* COMMENT OUT TO USE DHCP -// -//#define IP_ADDRESS { 192, 168, 1, 31 } - -///////////////////////////////////////////////////////////////////////////////////// -// -// DEFINE MAC ADDRESS ARRAY FOR ETHERNET COMMUNICATIONS INTERFACE -// -// Uncomment to use with Ethernet Shields -// -// Ethernet Shields do not have have a MAC address in hardware. There may be one on -// a sticker on the Shield that you should use. Otherwise choose one of the ones below -// Be certain that no other device on your network has this same MAC address! -// -// 52:b8:8a:8e:ce:21 -// e3:e9:73:e1:db:0d -// 54:2b:13:52:ac:0c - -// NOTE: This is not used with ESP8266 WiFi modules. - -//#define MAC_ADDRESS { 0x52, 0xB8, 0x8A, 0x8E, 0xCE, 0x21 } // MAC address of your networking card found on the sticker on your card or take one from above - -// -// #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF } - -///////////////////////////////////////////////////////////////////////////////////// -// -// DEFINE LCD SCREEN USAGE BY THE BASE STATION -// -// Note: This feature requires an I2C enabled LCD screen using a Hitachi HD44780 -// controller and a PCF8574 based I2C 'backpack', -// OR an I2C Oled screen based on SSD1306 (128x64 or 128x32) controller, -// OR an I2C Oled screen based on SH1106 (132x64) controller. -// To enable, uncomment one of the lines below - -// define LCD_DRIVER for I2C LCD address 0x3f,16 cols, 2 rows -//#define LCD_DRIVER {SubBus_4,0x27},20,4 - -//OR define OLED_DRIVER width,height in pixels (address auto detected) -#if defined(ARDUINO_ARCH_STM32) -#define OLED_DRIVER 0x3c, 128, 64 -#else -#define OLED_DRIVER {SubBus_0,0x3c}, 128, 32 -#endif - -#define SCROLLMODE 1 - -///////////////////////////////////////////////////////////////////////////////////// -// DISABLE EEPROM -// -// If you do not need the EEPROM at all, you can disable all the code that saves -// data in the EEPROM. You might want to do that if you are in a Arduino UNO -// and want to use the EX-RAIL automation. Otherwise you do not have enough RAM -// to do that. Of course, then none of the EEPROM related commands work. -// -#define DISABLE_EEPROM - - -///////////////////////////////////////////////////////////////////////////////////// -// -// DEFINE TURNOUTS/ACCESSORIES FOLLOW NORM RCN-213 -// -// According to norm RCN-213 a DCC packet with a 1 is closed/straight -// and one with a 0 is thrown/diverging. In DCC++ Classic, and in previous -// versions of DCC++EX, a turnout throw command was implemented in the packet as -// '1' and a close command as '0'. The #define below makes the states -// match with the norm. But we don't want to cause havoc on existent layouts, -// so we define this only for new installations. If you don't want this, -// don't add it to your config.h. -//#define DCC_TURNOUTS_RCN_213 - -// The following #define likewise inverts the behaviour of the command -// for triggering DCC Accessory Decoders, so that generates a -// DCC packet with D=1 (close turnout) and generates D=0 -// (throw turnout). -//#define DCC_ACCESSORY_RCN_213 - -///////////////////////////////////////////////////////////////////////////////////// diff --git a/version.h b/version.h index b2ae424..09aa737 100644 --- a/version.h +++ b/version.h @@ -4,7 +4,8 @@ #include "StringFormatter.h" -#define VERSION "4.2.50" +#define VERSION "4.2.51" +// 4.2.51 - Add DISABLE_PROG to disable programming to save RAM/Flash // 4.2.50 - Fixes: estop all, turnout eeprom, cab ID check // 4.2.49 - Exrail SPEED take notice of external direction change // 4.2.48 - BROADCAST/WITHROTTLE Exrail macros