From 91e60b371667763135207e2ac5ea707f7558f8d7 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Fri, 12 Apr 2024 17:25:00 +0800 Subject: [PATCH 01/22] HALDisplay bug fix --- IO_HALDisplay.h | 11 +++++++---- version.h | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/IO_HALDisplay.h b/IO_HALDisplay.h index f2ca3af..24ffde7 100644 --- a/IO_HALDisplay.h +++ b/IO_HALDisplay.h @@ -1,7 +1,9 @@ /* - * © 2023, Neil McKechnie. All rights reserved. + * © 2024, Paul Antoine + * © 2023, Neil McKechnie + * All rights reserved. * - * This file is part of DCC++EX API + * This file is part of DCC-EX API * * This is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -112,13 +114,14 @@ protected: // Fill buffer with spaces memset(_buffer, ' ', _numCols*_numRows); - _displayDriver->clearNative(); - // Add device to list of HAL devices (not necessary but allows // status to be displayed using and device to be // reinitialised using ). IODevice::addDevice(this); + // Moved after addDevice() to ensure I2CManager.begin() has been called fisrt + _displayDriver->clearNative(); + // Also add this display to list of display handlers DisplayInterface::addDisplay(displayNo); diff --git a/version.h b/version.h index 3eaf199..e871738 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.47" +#define VERSION "5.2.48" +// 5.2.48 - Bugfix: HALDisplay was generating I2C traffic prior to I2C being initialised // 5.2.47 - EXRAIL additions: // STEALTH_GLOBAL // BLINK From 4aa97e1731e108651d372c947772485d3974cf10 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sat, 13 Apr 2024 08:12:35 +0100 Subject: [PATCH 02/22] Squashed commit of the following: commit 3fc90c916c54ceae4364f79a4b9a2001bc75fcd5 Merge: 132e2d0 91e60b3 Author: Asbelos Date: Fri Apr 12 15:08:49 2024 +0100 Merge branch 'devel' into devel_chris commit 132e2d0de2c6e72b1a3d85520936fb7cddd8d739 Author: Asbelos Date: Fri Apr 12 15:07:31 2024 +0100 Revert "Merge branch 'master' into devel_chris" This reverts commit 23845f2df2035333c43b4aa05d76e9f7600efe29, reversing changes made to 76755993f146a1deaf46993d22e850b899dcf603. commit 23845f2df2035333c43b4aa05d76e9f7600efe29 Merge: 7675599 28d60d4 Author: Asbelos Date: Fri Apr 12 14:38:22 2024 +0100 Merge branch 'master' into devel_chris commit 76755993f146a1deaf46993d22e850b899dcf603 Author: Asbelos Date: Fri Apr 12 14:37:34 2024 +0100 ONSENSOR/ONBUTTON commit 8987d622e60fb27174203ce47b49462a01ecb61c Author: Asbelos Date: Tue Apr 9 20:44:47 2024 +0100 doc note commit 8f0a5c1ec0fde18dbb262311a1ef5ef79d571807 Author: Asbelos Date: Thu Apr 4 09:45:58 2024 +0100 Exrail notes commit 94083b9ab8a2322c39b7087c522730569194b732 Merge: 72ef199 02bf50b Author: Asbelos Date: Thu Apr 4 09:08:26 2024 +0100 Merge branch 'devel' into devel_chris commit 72ef199315d1c7717331864abb11730890fd3162 Author: Asbelos Date: Thu Apr 4 09:06:50 2024 +0100 TOGGLE_TURNOUT commit e69b777a2f62104dd8b74ba688b950fa92919d54 Author: Asbelos Date: Wed Apr 3 15:17:40 2024 +0100 BLINK command commit c7ed47400d5d89c0b8425ec12b1828e710fb23ec Author: Asbelos Date: Tue Apr 2 10:12:45 2024 +0100 FTOGGLE,XFTOGGLE commit 7a93cf7be856afd30f6976a483b1db4bfc4073a1 Author: Asbelos Date: Fri Mar 29 13:21:35 2024 +0000 EXRAIL STEALTH_GLOBAL commit 28d60d49849c8fc4b0ff0f933222c052ba7c90aa Author: Peter Akers Date: Fri Feb 16 18:02:40 2024 +1000 Update README.md commit 3b162996ad42546486b812e22d3ed6daee857d19 Author: peteGSX Date: Sun Jan 21 07:13:53 2024 +1000 EX-IO fixes in version commit fb414a7a506f078d2a075d65c7b171ae4399ef63 Author: Harald Barth Date: Thu Jan 18 08:20:33 2024 +0100 Bugfix: allocate enough bytes for digital pins. Add more sanity checks when allocating memory commit 818e05b4253a1a0980abb3a0bbef38a8c662bb1a Author: Harald Barth Date: Wed Jan 10 08:37:54 2024 +0100 version 5.0.8 commit c5168f030fa64330a1f0e09d6637a3817fe5e067 Author: Harald Barth Date: Wed Jan 10 08:15:30 2024 +0100 Do not crash on turnouts without description commit 387ea019bdc483667bcbcf45205a56330d615aee Author: Harald Barth Date: Mon Nov 6 22:11:56 2023 +0100 version 5.0.7 commit a981f83bb9c376d01245c328c5de7d7bf25ebfb2 Author: Harald Barth Date: Mon Nov 6 22:11:31 2023 +0100 Only flag 2.2.0.0-dev as broken, not 2.2.0.0 commit 749a859db551113567faae3248c575dbf6440ece Author: Asbelos Date: Wed Nov 1 20:13:05 2023 +0000 Bugfix TURNOUTL commit 659c58b30766a7b8dd2b4d2677d90663af8fefcf Author: Harald Barth Date: Sat Oct 28 19:20:33 2023 +0200 version 5.0.5 commit 0b9ec7460ba461d5602b6e06843d6be8468f385f Author: Harald Barth Date: Sat Oct 28 19:18:59 2023 +0200 Bugfix version detection logic and better message --- EXRAIL2.cpp | 10 +++ EXRAIL2.h | 2 +- EXRAIL2MacroReset.h | 4 ++ EXRAILMacros.h | 2 + EXRAILSensor.cpp | 104 ++++++++++++++++++++++++++++++ EXRAILSensor.h | 50 ++++++++++++++ Release_Notes/EXRAIL additions.md | 38 +++++++++++ 7 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 EXRAILSensor.cpp create mode 100644 EXRAILSensor.h create mode 100644 Release_Notes/EXRAIL additions.md diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 9293c96..adea99e 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -54,6 +54,7 @@ #include "TrackManager.h" #include "Turntables.h" #include "IODevice.h" +#include "EXRAILSensor.h" // One instance of RMFT clas is used for each "thread" in the automation. @@ -251,6 +252,12 @@ if (compileFeatures & FEATURE_SIGNAL) { break; } + case OPCODE_ONSENSOR: + new EXRAILSensor(operand,progCounter+3,true ); + break; + case OPCODE_ONBUTTON: + new EXRAILSensor(operand,progCounter+3,false ); + break; case OPCODE_TURNOUT: { VPIN id=operand; int addr=getOperand(progCounter,1); @@ -480,6 +487,7 @@ bool RMFT2::skipIfBlock() { } void RMFT2::loop() { + EXRAILSensor::checkAll(); // Round Robin call to a RMFT task each time if (loopTask==NULL) return; @@ -1084,6 +1092,8 @@ void RMFT2::loop2() { case OPCODE_ONGREEN: case OPCODE_ONCHANGE: case OPCODE_ONTIME: + case OPCODE_ONBUTTON: + case OPCODE_ONSENSOR: #ifndef IO_NO_HAL case OPCODE_DCCTURNTABLE: // Turntable definition ignored at runtime case OPCODE_EXTTTURNTABLE: // Turntable definition ignored at runtime diff --git a/EXRAIL2.h b/EXRAIL2.h index 7075f26..1042d53 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -73,7 +73,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,OPCODE_TOGGLE_TURNOUT, OPCODE_ROUTE_ACTIVE,OPCODE_ROUTE_INACTIVE,OPCODE_ROUTE_HIDDEN, OPCODE_ROUTE_DISABLED, OPCODE_STASH,OPCODE_CLEAR_STASH,OPCODE_CLEAR_ALL_STASH,OPCODE_PICKUP_STASH, - + OPCODE_ONBUTTON,OPCODE_ONSENSOR, // OPcodes below this point are skip-nesting IF operations // placed here so that they may be skipped as a group // see skipIfBlock() diff --git a/EXRAIL2MacroReset.h b/EXRAIL2MacroReset.h index ce242ea..c799ddf 100644 --- a/EXRAIL2MacroReset.h +++ b/EXRAIL2MacroReset.h @@ -114,6 +114,8 @@ #undef ONGREEN #undef ONRED #undef ONROTATE +#undef ONBUTTON +#undef ONSENSOR #undef ONTHROW #undef ONCHANGE #undef PARSE @@ -279,6 +281,8 @@ #define ONROTATE(turntable_id) #define ONTHROW(turnout_id) #define ONCHANGE(sensor_id) +#define ONSENSOR(sensor_id) +#define ONBUTTON(sensor_id) #define PAUSE #define PIN_TURNOUT(id,pin,description...) #define PRINT(msg) diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 7db52dc..508540a 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -553,6 +553,8 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup]; #endif #define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id), #define ONCHANGE(sensor_id) OPCODE_ONCHANGE,V(sensor_id), +#define ONSENSOR(sensor_id) OPCODE_ONSENSOR,V(sensor_id), +#define ONBUTTON(sensor_id) OPCODE_ONBUTTON,V(sensor_id), #define PAUSE OPCODE_PAUSE,0,0, #define PICKUP_STASH(id) OPCODE_PICKUP_STASH,V(id), #define PIN_TURNOUT(id,pin,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(pin), diff --git a/EXRAILSensor.cpp b/EXRAILSensor.cpp new file mode 100644 index 0000000..b0a5fa0 --- /dev/null +++ b/EXRAILSensor.cpp @@ -0,0 +1,104 @@ +/* + * © 2024 Chris Harlow + * All rights reserved. + * + * This file is part of CommandStation-EX + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * It is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CommandStation. If not, see . + */ + +/********************************************************************** +EXRAILSensor represents a sensor that should be monitored in order +to call an exrail ONBUTTON or ONCHANGE handler. +These are created at EXRAIL startup and thus need no delete or listing +capability. +The basic logic is similar to that found in the Sensor class +except that on the relevant change an EXRAIL thread is started. +**********************************************************************/ + +#include "EXRAILSensor.h" +#include "EXRAIL2.h" + +void EXRAILSensor::checkAll() { + if (firstSensor == NULL) return; // No sensors to be scanned + if (readingSensor == NULL) { + // Not currently scanning sensor list + unsigned long thisTime = micros(); + if (thisTime - lastReadCycle < cycleInterval) return; + // Required time has elapsed since last read cycle started, + // so initiate new scan through the sensor list + readingSensor = firstSensor; + lastReadCycle = thisTime; + } + + // Loop until either end of list is encountered or we pause for some reason + byte sensorCount = 0; + + while (readingSensor != NULL) { + bool pause=readingSensor->check(); + // Move to next sensor in list. + readingSensor = readingSensor->nextSensor; + // Currently process max of 16 sensors per entry. + // Performance measurements taken during development indicate that, with 128 sensors configured + // on 8x 16-pin MCP23017 GPIO expanders with polling (no change notification), all inputs can be read from the devices + // within 1.4ms (400Mhz I2C bus speed), and a full cycle of checking 128 sensors for changes takes under a millisecond. + if (pause || (++sensorCount)>=16) return; + } +} + +bool EXRAILSensor::check() { + // check for debounced change in this sensor + inputState = IODevice::read(pin); + + // Check if changed since last time, and process changes. + if (inputState == active) {// no change + latchDelay = minReadCount; // Reset counter + return false; // no change + } + + // Change detected ... has it stayed changed for long enough + if (latchDelay > 0) { + latchDelay--; + return false; + } + + // change validated, act on it. + active = inputState; + latchDelay = minReadCount; // Reset debounce counter + if (onChange || active) { + new RMFT2(progCounter); + return true; // Don't check any more sensors on this entry + } + return false; +} + +EXRAILSensor::EXRAILSensor(VPIN _pin, int _progCounter, bool _onChange) { + // Add to the start of the list + //DIAG(F("ONthing vpin=%d at %d"), _pin, _progCounter); + nextSensor = firstSensor; + firstSensor = this; + + pin=_pin; + progCounter=_progCounter; + onChange=_onChange; + + IODevice::configureInput(pin, true); + active = IODevice::read(pin); + inputState = active; + latchDelay = minReadCount; +} + +EXRAILSensor *EXRAILSensor::firstSensor=NULL; +EXRAILSensor *EXRAILSensor::readingSensor=NULL; +unsigned long EXRAILSensor::lastReadCycle=0; diff --git a/EXRAILSensor.h b/EXRAILSensor.h new file mode 100644 index 0000000..b5b00c6 --- /dev/null +++ b/EXRAILSensor.h @@ -0,0 +1,50 @@ +/* + * © 2024 Chris Harlow + * All rights reserved. + * + * This file is part of CommandStation-EX + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * It is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CommandStation. If not, see . + */ + +#ifndef EXRAILSensor_h +#define EXRAILSensor_h +#include "IODevice.h" +class EXRAILSensor { + static EXRAILSensor * firstSensor; + static EXRAILSensor * readingSensor; + static unsigned long lastReadCycle; + + public: + static void checkAll(); + + EXRAILSensor(VPIN _pin, int _progCounter, bool _onChange); + bool check(); + + private: + static const unsigned int cycleInterval = 10000; // min time between consecutive reads of each sensor in microsecs. + // should not be less than device scan cycle time. + static const byte minReadCount = 4; // number of additional scans before acting on change + // E.g. 1 means that a change is ignored for one scan and actioned on the next. + // Max value is 63 + + EXRAILSensor* nextSensor; + VPIN pin; + int progCounter; + bool active; + bool inputState; + bool onChange; + byte latchDelay; +}; +#endif \ No newline at end of file diff --git a/Release_Notes/EXRAIL additions.md b/Release_Notes/EXRAIL additions.md new file mode 100644 index 0000000..690ff0a --- /dev/null +++ b/Release_Notes/EXRAIL additions.md @@ -0,0 +1,38 @@ + +BLINK(vpin, onMs,offMs) + +which will start a vpin blinking until such time as it is SET, RESET or set by a signal operation such as RED, AMBER, GREEN. + +BLINK returns immediately, the blinking is autonomous. + +This means a signal that always blinks amber could be done like this: +``` +SIGNAL(30,31,32) +ONAMBER(30) BLINK(31,500,500) DONE +``` +The RED or GREEN calls will turn off the amber blink automatically. + +Alternatively a signal that has normal AMBER and flashing AMBER could be like this: + +#define FLASHAMBER(signal) \ + AMBER(signal) \ + BLINK(signal+1,500,500) + + (Caution: this issumes that the amber pin is redpin+1) + + == + + FTOGGLE(function) + Toggles the current loco function (see FON and FOFF) + + XFTOGGLE(loco,function) + Toggles the function on given loco. (See XFON, XFOFF) + + TOGGLE_TURNOUT(id) + Toggles the turnout (see CLOSE, THROW) + + STEALTH_GLOBAL(code) + ADVANCED C++ users only. + Inserts code such as static variables and functions that + may be utilised by multiple STEALTH operations. + \ No newline at end of file From 7dafe0383d21491bbefb1a9ce3562396aefb421c Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sat, 13 Apr 2024 09:14:55 +0100 Subject: [PATCH 03/22] EXRAIL ONBUTTON --- Release_Notes/EXRAIL additions.md | 38 ------------------------------- Release_Notes/Exrail mods.txt | 21 +++++++++++++++++ version.h | 4 +++- 3 files changed, 24 insertions(+), 39 deletions(-) delete mode 100644 Release_Notes/EXRAIL additions.md diff --git a/Release_Notes/EXRAIL additions.md b/Release_Notes/EXRAIL additions.md deleted file mode 100644 index 690ff0a..0000000 --- a/Release_Notes/EXRAIL additions.md +++ /dev/null @@ -1,38 +0,0 @@ - -BLINK(vpin, onMs,offMs) - -which will start a vpin blinking until such time as it is SET, RESET or set by a signal operation such as RED, AMBER, GREEN. - -BLINK returns immediately, the blinking is autonomous. - -This means a signal that always blinks amber could be done like this: -``` -SIGNAL(30,31,32) -ONAMBER(30) BLINK(31,500,500) DONE -``` -The RED or GREEN calls will turn off the amber blink automatically. - -Alternatively a signal that has normal AMBER and flashing AMBER could be like this: - -#define FLASHAMBER(signal) \ - AMBER(signal) \ - BLINK(signal+1,500,500) - - (Caution: this issumes that the amber pin is redpin+1) - - == - - FTOGGLE(function) - Toggles the current loco function (see FON and FOFF) - - XFTOGGLE(loco,function) - Toggles the function on given loco. (See XFON, XFOFF) - - TOGGLE_TURNOUT(id) - Toggles the turnout (see CLOSE, THROW) - - STEALTH_GLOBAL(code) - ADVANCED C++ users only. - Inserts code such as static variables and functions that - may be utilised by multiple STEALTH operations. - \ No newline at end of file diff --git a/Release_Notes/Exrail mods.txt b/Release_Notes/Exrail mods.txt index 68f57b7..6f8287f 100644 --- a/Release_Notes/Exrail mods.txt +++ b/Release_Notes/Exrail mods.txt @@ -1,3 +1,24 @@ +// 5.2.49 + +Which is a more efficient than the AT/AFTER/IF methods +of handling buttons and switches, especially on MIMIC panels. + +ONBUTTON(vpin) + handles debounce and starts a task if a button is used to + short a pin to ground. + + for example: + ONBUTTON(30) TOGGLE_TURNOUT(30) DONE + +ONSENSOR(vpin) + handles debounce and starts a task if the pin changes. + You may want to check the pin state with an IF ... + +Note the ONBUTTON and ONSENSOR are not generally useful +for track sensors and running trains, because you dont know which +train triggered the sensor. + +// 5.2.47 BLINK(vpin, onMs,offMs) diff --git a/version.h b/version.h index e871738..395630a 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,9 @@ #include "StringFormatter.h" -#define VERSION "5.2.48" +#define VERSION "5.2.49" +// 5.2.49 - EXRAIL additions: +// ONBUTTON, ONSENSOR // 5.2.48 - Bugfix: HALDisplay was generating I2C traffic prior to I2C being initialised // 5.2.47 - EXRAIL additions: // STEALTH_GLOBAL From ebe8f62cf05d560a33553086a26f20af923acce1 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sat, 13 Apr 2024 10:16:26 +0100 Subject: [PATCH 04/22] ONBUTTON/ONSENSOR use latch --- EXRAIL2.cpp | 9 ++++++--- EXRAIL2.h | 5 +++-- EXRAILMacros.h | 4 ++++ EXRAILSensor.cpp | 2 +- version.h | 3 ++- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index adea99e..6b1b05e 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -253,11 +253,13 @@ if (compileFeatures & FEATURE_SIGNAL) { } case OPCODE_ONSENSOR: + if (compileFeatures & FEATURE_SENSOR) new EXRAILSensor(operand,progCounter+3,true ); - break; + break; case OPCODE_ONBUTTON: + if (compileFeatures & FEATURE_SENSOR) new EXRAILSensor(operand,progCounter+3,false ); - break; + break; case OPCODE_TURNOUT: { VPIN id=operand; int addr=getOperand(progCounter,1); @@ -487,7 +489,8 @@ bool RMFT2::skipIfBlock() { } void RMFT2::loop() { - EXRAILSensor::checkAll(); + if (compileFeatures & FEATURE_SENSOR) + EXRAILSensor::checkAll(); // Round Robin call to a RMFT task each time if (loopTask==NULL) return; diff --git a/EXRAIL2.h b/EXRAIL2.h index 1042d53..794eb86 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -115,6 +115,7 @@ enum BlinkState: byte { static const byte FEATURE_ROUTESTATE= 0x10; static const byte FEATURE_STASH = 0x08; static const byte FEATURE_BLINK = 0x04; + static const byte FEATURE_SENSOR = 0x02; // Flag bits for status of hardware and TPL @@ -185,7 +186,8 @@ class LookList { static const FSH * getTurntableDescription(int16_t id); static const FSH * getTurntablePositionDescription(int16_t turntableId, uint8_t positionId); static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc); - + static bool readSensor(uint16_t sensorId); + private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ; @@ -208,7 +210,6 @@ private: static RMFT2 * pausingTask; void delayMe(long millisecs); void driveLoco(byte speedo); - bool readSensor(uint16_t sensorId); bool skipIfBlock(); bool readLoco(); void loop2(); diff --git a/EXRAILMacros.h b/EXRAILMacros.h index 508540a..e9e2f77 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -210,6 +210,10 @@ bool exrailHalSetup() { #define STASH(id) | FEATURE_STASH #undef BLINK #define BLINK(vpin,onDuty,offDuty) | FEATURE_BLINK +#undef ONBUTTON +#define ONBUTTON(vpin) | FEATURE_SENSOR +#undef ONSENSOR +#define ONSENSOR(vpin) | FEATURE_SENSOR const byte RMFT2::compileFeatures = 0 #include "myAutomation.h" diff --git a/EXRAILSensor.cpp b/EXRAILSensor.cpp index b0a5fa0..218b970 100644 --- a/EXRAILSensor.cpp +++ b/EXRAILSensor.cpp @@ -59,7 +59,7 @@ void EXRAILSensor::checkAll() { bool EXRAILSensor::check() { // check for debounced change in this sensor - inputState = IODevice::read(pin); + inputState = RMFT2::readSensor(pin); // Check if changed since last time, and process changes. if (inputState == active) {// no change diff --git a/version.h b/version.h index 395630a..0b8c1a6 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.49" +#define VERSION "5.2.50" +// 5.2.50 - EXRAIL ONBUTTON/ONSENSOR observe LATCH // 5.2.49 - EXRAIL additions: // ONBUTTON, ONSENSOR // 5.2.48 - Bugfix: HALDisplay was generating I2C traffic prior to I2C being initialised From c382bd33bc65dc8f8185abbf746bc1fe02f50b9b Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 21 Apr 2024 19:03:24 +0200 Subject: [PATCH 05/22] Distinguish between sighandle and sigid --- EXRAIL2.cpp | 38 +++++++++++++++++++++----------------- EXRAIL2Parser.cpp | 11 ++++++----- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 6b1b05e..b811145 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -205,15 +205,16 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) { // Second pass startup, define any turnouts or servos, set signals red // add sequences onRoutines to the lookups -if (compileFeatures & FEATURE_SIGNAL) { - onRedLookup=LookListLoader(OPCODE_ONRED); - onAmberLookup=LookListLoader(OPCODE_ONAMBER); - onGreenLookup=LookListLoader(OPCODE_ONGREEN); - for (int sigslot=0;;sigslot++) { - VPIN sigid=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); - if (sigid==0) break; // end of signal list - doSignal(sigid & SIGNAL_ID_MASK, SIGNAL_RED); - } + if (compileFeatures & FEATURE_SIGNAL) { + onRedLookup=LookListLoader(OPCODE_ONRED); + onAmberLookup=LookListLoader(OPCODE_ONAMBER); + onGreenLookup=LookListLoader(OPCODE_ONGREEN); + for (int sigslot=0;;sigslot++) { + int16_t sighandle=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); + if (sighandle==0) break; // end of signal list + VPIN sigid = sighandle & SIGNAL_ID_MASK; + doSignal(sigid, SIGNAL_RED); + } } int progCounter; @@ -1143,16 +1144,17 @@ void RMFT2::kill(const FSH * reason, int operand) { int16_t RMFT2::getSignalSlot(int16_t id) { for (int sigslot=0;;sigslot++) { - int16_t sigid=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); - if (sigid==0) { // end of signal list + int16_t sighandle=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); + if (sighandle==0) { // end of signal list DIAG(F("EXRAIL Signal %d not defined"), id); return -1; } + VPIN sigid = sighandle & SIGNAL_ID_MASK; // sigid is the signal id used in RED/AMBER/GREEN macro // for a LED signal it will be same as redpin // but for a servo signal it will also have SERVO_SIGNAL_FLAG set. - if ((sigid & SIGNAL_ID_MASK)!= id) continue; // keep looking + if (sigid != id) continue; // keep looking return sigslot; // relative slot in signals table } } @@ -1175,13 +1177,14 @@ int16_t RMFT2::getSignalSlot(int16_t id) { // Correct signal definition found, get the rag values int16_t sigpos=sigslot*8; - VPIN sigid=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos); + int16_t sighandle=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos); VPIN redpin=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+2); VPIN amberpin=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+4); VPIN greenpin=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+6); //if (diag) DIAG(F("signal %d %d %d %d %d"),sigid,id,redpin,amberpin,greenpin); - VPIN sigtype=sigid & ~SIGNAL_ID_MASK; + VPIN sigtype=sighandle & ~SIGNAL_ID_MASK; + VPIN sigid = sighandle & SIGNAL_ID_MASK; if (sigtype == SERVO_SIGNAL_FLAG) { // A servo signal, the pin numbers are actually servo positions @@ -1204,7 +1207,7 @@ int16_t RMFT2::getSignalSlot(int16_t id) { byte value=redpin; if (rag==SIGNAL_AMBER) value=amberpin; if (rag==SIGNAL_GREEN) value=greenpin; - DCC::setExtendedAccessory(sigid & SIGNAL_ID_MASK,value); + DCC::setExtendedAccessory(sigid, value); return; } @@ -1255,8 +1258,9 @@ bool RMFT2::signalAspectEvent(int16_t address, byte aspect ) { int16_t sigslot=getSignalSlot(address); if (sigslot<0) return false; // this is not a defined signal int16_t sigpos=sigslot*8; - VPIN sigid=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos); - VPIN sigtype=sigid & ~SIGNAL_ID_MASK; + int16_t sighandle=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos); + VPIN sigtype=sighandle & ~SIGNAL_ID_MASK; + VPIN sigid = sighandle & SIGNAL_ID_MASK; if (sigtype!=DCCX_SIGNAL_FLAG) return false; // not a DCCX signal // Turn an aspect change into a RED/AMBER/GREEN setting if (aspect==GETHIGHFLASHW(RMFT2::SignalDefinitions,sigpos+2)) { diff --git a/EXRAIL2Parser.cpp b/EXRAIL2Parser.cpp index 95375bb..4023633 100644 --- a/EXRAIL2Parser.cpp +++ b/EXRAIL2Parser.cpp @@ -214,12 +214,13 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) { // do the signals // flags[n] represents the state of the nth signal in the table for (int sigslot=0;;sigslot++) { - VPIN sigid=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); - if (sigid==0) break; // end of signal list - byte flag=flags[sigslot] & SIGNAL_MASK; // obtain signal flags for this id + int16_t sighandle=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); + if (sighandle==0) break; // end of signal list + VPIN sigid = sighandle & SIGNAL_ID_MASK; + byte flag=flags[sigslot] & SIGNAL_MASK; // obtain signal flags for this id StringFormatter::send(stream,F("\n%S[%d]"), - (flag == SIGNAL_RED)? F("RED") : (flag==SIGNAL_GREEN) ? F("GREEN") : F("AMBER"), - sigid & SIGNAL_ID_MASK); + (flag == SIGNAL_RED)? F("RED") : (flag==SIGNAL_GREEN) ? F("GREEN") : F("AMBER"), + sigid); } } From 3af2f6779221e9ab8008efe94b88acce22b811d9 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 21 Apr 2024 19:41:30 +0200 Subject: [PATCH 06/22] version 5.2.51 --- GITHUB_SHA.h | 2 +- version.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index a9ab348..ab13219 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202404061747Z" +#define GITHUB_SHA "devel-202404211704Z" diff --git a/version.h b/version.h index 0b8c1a6..19b046c 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.50" +#define VERSION "5.2.51" +// 5.2.51 - Bugfix for SIGNAL: Distinguish between sighandle and sigid // 5.2.50 - EXRAIL ONBUTTON/ONSENSOR observe LATCH // 5.2.49 - EXRAIL additions: // ONBUTTON, ONSENSOR From b4e7982099ee2a56f80a077a293425ef1f297112 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 22 Apr 2024 08:12:08 +0200 Subject: [PATCH 07/22] remove forgotten #define DIAG_IO --- Turnouts.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Turnouts.cpp b/Turnouts.cpp index 83603fc..ca5f890 100644 --- a/Turnouts.cpp +++ b/Turnouts.cpp @@ -123,7 +123,6 @@ return true; } -#define DIAG_IO // Static setClosed function is invoked from close(), throw() etc. to perform the // common parts of the turnout operation. Code which is specific to a turnout // type should be placed in the virtual function setClosedInternal(bool) which is From 83d4930124e9286577e380d71e9731f83d38d0e4 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Fri, 26 Apr 2024 19:04:20 +0800 Subject: [PATCH 08/22] Fix F446ZE ADCee support and add STM32 ports G and H --- DCCTimer.h | 4 +++- DCCTimerSTM32.cpp | 22 ++++++++++++++++++---- MotorDriver.cpp | 36 +++++++++++++++++++++++++++++++++++- MotorDriver.h | 19 ++++++++++++++++++- 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/DCCTimer.h b/DCCTimer.h index 44c85f2..c3fcaf1 100644 --- a/DCCTimer.h +++ b/DCCTimer.h @@ -1,5 +1,5 @@ /* - * © 2022-2023 Paul M. Antoine + * © 2022-2024 Paul M. Antoine * © 2021 Mike S * © 2021-2023 Harald Barth * © 2021 Fred Decker @@ -135,6 +135,8 @@ private: #if defined (ARDUINO_ARCH_STM32) // bit array of used pins (max 32) static uint32_t usedpins; + static uint32_t * analogchans; // Array of channel numbers to be scanned + static ADC_TypeDef * * adcchans; // Array to capture which ADC is each input channel on #else // bit array of used pins (max 16) static uint16_t usedpins; diff --git a/DCCTimerSTM32.cpp b/DCCTimerSTM32.cpp index 0c1d5d6..7a13919 100644 --- a/DCCTimerSTM32.cpp +++ b/DCCTimerSTM32.cpp @@ -1,6 +1,6 @@ /* * © 2023 Neil McKechnie - * © 2022-2023 Paul M. Antoine + * © 2022-2024 Paul M. Antoine * © 2021 Mike S * © 2021, 2023 Harald Barth * © 2021 Fred Decker @@ -34,6 +34,7 @@ #include "TrackManager.h" #endif #include "DIAG.h" +#include #if defined(ARDUINO_NUCLEO_F401RE) || defined(ARDUINO_NUCLEO_F411RE) // Nucleo-64 boards don't have additional serial ports defined by default @@ -363,9 +364,9 @@ void DCCTimer::DCCEXanalogWrite(uint8_t pin, int value, bool invert) { uint32_t ADCee::usedpins = 0; // Max of 32 ADC input channels! uint8_t ADCee::highestPin = 0; // Highest pin to scan int * ADCee::analogvals = NULL; // Array of analog values last captured -uint32_t * analogchans = NULL; // Array of channel numbers to be scanned +uint32_t * ADCee::analogchans = NULL; // Array of channel numbers to be scanned // bool adc1configured = false; -ADC_TypeDef * * adcchans = NULL; // Array to capture which ADC is each input channel on +ADC_TypeDef * * ADCee::adcchans = NULL; // Array to capture which ADC is each input channel on int16_t ADCee::ADCmax() { @@ -383,9 +384,10 @@ int ADCee::init(uint8_t pin) { uint32_t adcchan = STM_PIN_CHANNEL(pinmap_function(stmpin, PinMap_ADC)); // find ADC input channel ADC_TypeDef *adc = (ADC_TypeDef *)pinmap_find_peripheral(stmpin, PinMap_ADC); // find which ADC this pin is on ADC1/2/3 etc. int adcnum = 1; + // All variants have ADC1 if (adc == ADC1) DIAG(F("ADCee::init(): found pin %d on ADC1"), pin); -// Checking for ADC2 and ADC3 being defined helps cater for more variants later + // Checking for ADC2 and ADC3 being defined helps cater for more variants #if defined(ADC2) else if (adc == ADC2) { @@ -432,6 +434,18 @@ int ADCee::init(uint8_t pin) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOFEN; //Power up PORTF gpioBase = GPIOF; break; +#endif +#if defined(GPIOG) + case 0x06: + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN; //Power up PORTG + gpioBase = GPIOG; + break; +#endif +#if defined(GPIOH) + case 0x07: + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOHEN; //Power up PORTH + gpioBase = GPIOH; + break; #endif default: return -1023; // some silly value as error diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 66d1b71..da9d3ee 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -1,5 +1,5 @@ /* - * © 2022-2023 Paul M Antoine + * © 2022-2024 Paul M Antoine * © 2021 Mike S * © 2021 Fred Decker * © 2020-2023 Harald Barth @@ -38,6 +38,8 @@ volatile portreg_t shadowPORTC; volatile portreg_t shadowPORTD; volatile portreg_t shadowPORTE; volatile portreg_t shadowPORTF; +volatile portreg_t shadowPORTG; +volatile portreg_t shadowPORTH; #endif MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, int16_t brake_pin, @@ -88,6 +90,16 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i fastSignalPin.shadowinout = fastSignalPin.inout; fastSignalPin.inout = &shadowPORTF; } + if (HAVE_PORTG(fastSignalPin.inout == &PORTG)) { + DIAG(F("Found PORTG pin %d"),signalPin); + fastSignalPin.shadowinout = fastSignalPin.inout; + fastSignalPin.inout = &shadowPORTG; + } + if (HAVE_PORTH(fastSignalPin.inout == &PORTH)) { + DIAG(F("Found PORTH pin %d"),signalPin); + fastSignalPin.shadowinout = fastSignalPin.inout; + fastSignalPin.inout = &shadowPORTF; + } signalPin2=signal_pin2; if (signalPin2!=UNUSED_PIN) { @@ -126,6 +138,16 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i fastSignalPin2.shadowinout = fastSignalPin2.inout; fastSignalPin2.inout = &shadowPORTF; } + if (HAVE_PORTG(fastSignalPin2.inout == &PORTG)) { + DIAG(F("Found PORTG pin %d"),signalPin2); + fastSignalPin2.shadowinout = fastSignalPin2.inout; + fastSignalPin2.inout = &shadowPORTG; + } + if (HAVE_PORTH(fastSignalPin2.inout == &PORTH)) { + DIAG(F("Found PORTH pin %d"),signalPin2); + fastSignalPin2.shadowinout = fastSignalPin2.inout; + fastSignalPin2.inout = &shadowPORTH; + } } else dualSignal=false; @@ -393,6 +415,18 @@ void MotorDriver::setDCSignal(byte speedcode, uint8_t frequency /*default =0*/) setSignal(tDir); HAVE_PORTF(PORTF=shadowPORTF); interrupts(); + } else if (HAVE_PORTG(fastSignalPin.shadowinout == &PORTG)) { + noInterrupts(); + HAVE_PORTG(shadowPORTG=PORTG); + setSignal(tDir); + HAVE_PORTG(PORTG=shadowPORTG); + interrupts(); + } else if (HAVE_PORTH(fastSignalPin.shadowinout == &PORTH)) { + noInterrupts(); + HAVE_PORTH(shadowPORTH=PORTH); + setSignal(tDir); + HAVE_PORTH(PORTH=shadowPORTH); + interrupts(); } else { noInterrupts(); setSignal(tDir); diff --git a/MotorDriver.h b/MotorDriver.h index a6ed1f6..3438c05 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -1,5 +1,5 @@ /* - * © 2022-2023 Paul M. Antoine + * © 2022-2024 Paul M. Antoine * © 2021 Mike S * © 2021 Fred Decker * © 2020 Chris Harlow @@ -26,6 +26,7 @@ #include "FSH.h" #include "IODevice.h" #include "DCCTimer.h" +#include // use powers of two so we can do logical and/or on the track modes in if clauses. // RACK_MODE_DCX is (TRACK_MODE_DC|TRACK_MODE_INV) @@ -83,6 +84,14 @@ enum TRACK_MODE : byte {TRACK_MODE_NONE = 1, TRACK_MODE_MAIN = 2, TRACK_MODE_PRO #define PORTF GPIOF->ODR #define HAVE_PORTF(X) X #endif +#if defined(GPIOG) +#define PORTG GPIOG->ODR +#define HAVE_PORTG(X) X +#endif +#if defined(GPIOH) +#define PORTH GPIOH->ODR +#define HAVE_PORTH(X) X +#endif #endif // if macros not defined as pass-through we define @@ -106,6 +115,12 @@ enum TRACK_MODE : byte {TRACK_MODE_NONE = 1, TRACK_MODE_MAIN = 2, TRACK_MODE_PRO #ifndef HAVE_PORTF #define HAVE_PORTF(X) byte TOKENPASTE2(Unique_, __LINE__) __attribute__((unused)) =0 #endif +#ifndef HAVE_PORTG +#define HAVE_PORTG(X) byte TOKENPASTE2(Unique_, __LINE__) __attribute__((unused)) =0 +#endif +#ifndef HAVE_PORTH +#define HAVE_PORTH(X) byte TOKENPASTE2(Unique_, __LINE__) __attribute__((unused)) =0 +#endif // Virtualised Motor shield 1-track hardware Interface @@ -145,6 +160,8 @@ extern volatile portreg_t shadowPORTC; extern volatile portreg_t shadowPORTD; extern volatile portreg_t shadowPORTE; extern volatile portreg_t shadowPORTF; +extern volatile portreg_t shadowPORTG; +extern volatile portreg_t shadowPORTH; enum class POWERMODE : byte { OFF, ON, OVERLOAD, ALERT }; From 742b100f65e3f7182e3e52917e84d4ef64e0cb22 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Thu, 2 May 2024 09:48:18 +0100 Subject: [PATCH 09/22] Comments only --- DCCEXParser.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index b9ac3a9..431093f 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -70,8 +70,8 @@ Once a new OPCODE is decided upon, update this list. L, Reserved for LCC interface (implemented in EXRAIL) m, message to throttles broadcast M, Write DCC packet - n, - N, + n, Reserved for SensorCam + N, Reserved for Sensorcam o, O, Output broadcast p, Broadcast power state @@ -91,10 +91,10 @@ Once a new OPCODE is decided upon, update this list. w, Write CV on main W, Write CV x, - X, Invalid command - y, + X, Invalid command response + y, Y, Output broadcast - z, + z, Direct output Z, Output configuration/control */ From 76ad3ee48d769a653981fb2e8b46fa6b7f91887f Mon Sep 17 00:00:00 2001 From: pmantoine Date: Tue, 7 May 2024 11:10:39 +0800 Subject: [PATCH 10/22] STM32 bug fixes, port usage --- version.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/version.h b/version.h index 19b046c..0677dec 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,9 @@ #include "StringFormatter.h" -#define VERSION "5.2.51" +#define VERSION "5.2.52" +// 5.2.52 - Bugfix for ADCee() to handle ADC2 and ADC3 channel inputs on F446ZE and others +// - Add support for ports G and H on STM32 for ADCee() and MotorDriver pins/shadow regs // 5.2.51 - Bugfix for SIGNAL: Distinguish between sighandle and sigid // 5.2.50 - EXRAIL ONBUTTON/ONSENSOR observe LATCH // 5.2.49 - EXRAIL additions: From 16214fad66fbfa217356a510192d93c12b042c54 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Tue, 7 May 2024 11:13:19 +0800 Subject: [PATCH 11/22] EX-Fastclock bugfix for address check --- IO_EXFastclock.h | 1 + version.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/IO_EXFastclock.h b/IO_EXFastclock.h index 5ed237e..11aaea7 100644 --- a/IO_EXFastclock.h +++ b/IO_EXFastclock.h @@ -51,6 +51,7 @@ static void create(I2CAddress i2cAddress) { // Start by assuming we will find the clock // Check if specified I2C address is responding (blocking operation) // Returns I2C_STATUS_OK (0) if OK, or error code. + I2CManager.begin(); uint8_t _checkforclock = I2CManager.checkAddress(i2cAddress); DIAG(F("Clock check result - %d"), _checkforclock); // XXXX change thistosave2 bytes diff --git a/version.h b/version.h index 0677dec..443475b 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.52" +#define VERSION "5.2.53" +// 5.2.53 - Bugfix for EX-Fastclock, call I2CManager.begin() before checking I2C address // 5.2.52 - Bugfix for ADCee() to handle ADC2 and ADC3 channel inputs on F446ZE and others // - Add support for ports G and H on STM32 for ADCee() and MotorDriver pins/shadow regs // 5.2.51 - Bugfix for SIGNAL: Distinguish between sighandle and sigid From bd11cfbf8b8a8030d1eb58d462c5b639cde32d5f Mon Sep 17 00:00:00 2001 From: pmantoine Date: Tue, 7 May 2024 11:29:49 +0800 Subject: [PATCH 12/22] Bugfix EXRAIL active high signal handling --- EXRAIL2.cpp | 2 +- version.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index b811145..96763d5 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -1218,7 +1218,7 @@ int16_t RMFT2::getSignalSlot(int16_t id) { if (rag==SIGNAL_AMBER && (amberpin==0)) rag=SIMAMBER; // special case this func only // Manage invert (HIGH on) pins - bool aHigh=sigid & ACTIVE_HIGH_SIGNAL_FLAG; + bool aHigh=sighandle & ACTIVE_HIGH_SIGNAL_FLAG; // set the three pins if (redpin) { diff --git a/version.h b/version.h index 443475b..3260ebb 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.53" +#define VERSION "5.2.54" +// 5.2.54 - Bugfix for EXRAIL signal handling for active high // 5.2.53 - Bugfix for EX-Fastclock, call I2CManager.begin() before checking I2C address // 5.2.52 - Bugfix for ADCee() to handle ADC2 and ADC3 channel inputs on F446ZE and others // - Add support for ports G and H on STM32 for ADCee() and MotorDriver pins/shadow regs From 1449dc7bac4d375c630a5bd51515d0008b3913df Mon Sep 17 00:00:00 2001 From: pmantoine Date: Tue, 7 May 2024 15:12:37 +0800 Subject: [PATCH 13/22] EXRAIL move isSignal to public for STEALTH --- EXRAIL2.h | 2 +- version.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/EXRAIL2.h b/EXRAIL2.h index 794eb86..8750e41 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -187,6 +187,7 @@ class LookList { static const FSH * getTurntablePositionDescription(int16_t turntableId, uint8_t positionId); static void startNonRecursiveTask(const FSH* reason, int16_t id,int pc); static bool readSensor(uint16_t sensorId); + static bool isSignal(int16_t id,char rag); private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); @@ -196,7 +197,6 @@ private: static bool getFlag(VPIN id,byte mask); static int16_t progtrackLocoId; static void doSignal(int16_t id,char rag); - static bool isSignal(int16_t id,char rag); static int16_t getSignalSlot(int16_t id); static void setTurnoutHiddenState(Turnout * t); #ifndef IO_NO_HAL diff --git a/version.h b/version.h index 3260ebb..bcf6470 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.54" +#define VERSION "5.2.55" +// 5.2.55 - Move EXRAIL isSignal() to public to allow use in STEALTH call // 5.2.54 - Bugfix for EXRAIL signal handling for active high // 5.2.53 - Bugfix for EX-Fastclock, call I2CManager.begin() before checking I2C address // 5.2.52 - Bugfix for ADCee() to handle ADC2 and ADC3 channel inputs on F446ZE and others From a610e83f6ec4e1c943d06f63b913ec802f1723e2 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Tue, 7 May 2024 18:20:37 +0800 Subject: [PATCH 14/22] Bugfix and refactor for EXRAIL getSignalSlot --- EXRAIL2.cpp | 30 ++++++++++++++++++------------ version.h | 3 ++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 96763d5..38fd394 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -1,4 +1,5 @@ /* + * © 2024 Paul M. Antoine * © 2021 Neil McKechnie * © 2021-2023 Harald Barth * © 2020-2023 Chris Harlow @@ -1143,20 +1144,25 @@ void RMFT2::kill(const FSH * reason, int operand) { } int16_t RMFT2::getSignalSlot(int16_t id) { - for (int sigslot=0;;sigslot++) { - int16_t sighandle=GETHIGHFLASHW(RMFT2::SignalDefinitions,sigslot*8); - if (sighandle==0) { // end of signal list - DIAG(F("EXRAIL Signal %d not defined"), id); - return -1; - } - VPIN sigid = sighandle & SIGNAL_ID_MASK; + + if (id > 0) { + int sigslot = 0; + int16_t sighandle = 0; + // Trundle down the signal list until we reach the end + while ((sighandle = GETHIGHFLASHW(RMFT2::SignalDefinitions, sigslot * 8)) != 0) + { // sigid is the signal id used in RED/AMBER/GREEN macro // for a LED signal it will be same as redpin - // but for a servo signal it will also have SERVO_SIGNAL_FLAG set. - - if (sigid != id) continue; // keep looking - return sigslot; // relative slot in signals table - } + // but for a servo signal it will also have SERVO_SIGNAL_FLAG set. + VPIN sigid = sighandle & SIGNAL_ID_MASK; + if (sigid == (VPIN)id) + return sigslot; // found it + sigslot++; // keep looking + }; + } + // We did not find the signal + DIAG(F("EXRAIL Signal %d not defined"), id); + return -1; } /* static */ void RMFT2::doSignal(int16_t id,char rag) { diff --git a/version.h b/version.h index bcf6470..eafba6c 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.55" +#define VERSION "5.2.56" +// 5.2.56 - Bugfix and refactor for EXRAIL getSignalSlot // 5.2.55 - Move EXRAIL isSignal() to public to allow use in STEALTH call // 5.2.54 - Bugfix for EXRAIL signal handling for active high // 5.2.53 - Bugfix for EX-Fastclock, call I2CManager.begin() before checking I2C address From 86310aea4f331dd2cf3d4a727643e085f59e1800 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Thu, 9 May 2024 15:18:00 +0200 Subject: [PATCH 15/22] getSignalSlot minor typo (and indent/comments) fix --- EXRAIL2.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 38fd394..f401eba 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -1145,7 +1145,7 @@ void RMFT2::kill(const FSH * reason, int operand) { int16_t RMFT2::getSignalSlot(int16_t id) { - if (id > 0) { + if (id >= 0) { int sigslot = 0; int16_t sighandle = 0; // Trundle down the signal list until we reach the end @@ -1155,14 +1155,14 @@ int16_t RMFT2::getSignalSlot(int16_t id) { // for a LED signal it will be same as redpin // but for a servo signal it will also have SERVO_SIGNAL_FLAG set. VPIN sigid = sighandle & SIGNAL_ID_MASK; - if (sigid == (VPIN)id) - return sigslot; // found it - sigslot++; // keep looking + if (sigid == (VPIN)id) // cast to keep compiler happy but id is positive + return sigslot; // found it + sigslot++; // keep looking }; } - // We did not find the signal + // If we got here, we did not find the signal DIAG(F("EXRAIL Signal %d not defined"), id); - return -1; + return -1; } /* static */ void RMFT2::doSignal(int16_t id,char rag) { From 91818ed80c2d01d70634bf3746fcbb887b126397 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Thu, 9 May 2024 17:06:33 +0200 Subject: [PATCH 16/22] apply mode by binart bit match and not by equality --- TrackManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TrackManager.cpp b/TrackManager.cpp index d66b999..512452d 100644 --- a/TrackManager.cpp +++ b/TrackManager.cpp @@ -35,7 +35,7 @@ #define APPLY_BY_MODE(findmode,function) \ FOR_EACH_TRACK(t) \ - if (track[t]->getMode()==findmode) \ + if (track[t]->getMode() & findmode) \ track[t]->function; MotorDriver * TrackManager::track[MAX_TRACKS] = { NULL }; @@ -398,7 +398,7 @@ bool TrackManager::parseEqualSign(Print *stream, int16_t params, int16_t p[]) if (params==2 && p[1]=="AUTO"_hk) // <= id AUTO> return setTrackMode(p[0], track[p[0]]->getMode() | TRACK_MODE_AUTOINV); - if (params==2 && p[1]=="INV"_hk) // <= id AUTO> + if (params==2 && p[1]=="INV"_hk) // <= id INV> return setTrackMode(p[0], track[p[0]]->getMode() | TRACK_MODE_INV); if (params==3 && p[1]=="DC"_hk && p[2]>0) // <= id DC cab> From 6689a1d35fc2927f0e5aa1da99525cc8b2b0bf82 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Thu, 9 May 2024 17:11:09 +0200 Subject: [PATCH 17/22] version 5.2.57 --- GITHUB_SHA.h | 2 +- version.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index ab13219..8fd0549 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202404211704Z" +#define GITHUB_SHA "devel-202404091507Z" diff --git a/version.h b/version.h index eafba6c..dc6dfc3 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.56" +#define VERSION "5.2.57" +// 5.2.57 - Bugfix autoreverse: Apply mode by binart bit match and not by equality // 5.2.56 - Bugfix and refactor for EXRAIL getSignalSlot // 5.2.55 - Move EXRAIL isSignal() to public to allow use in STEALTH call // 5.2.54 - Bugfix for EXRAIL signal handling for active high From 66791b19f53bf2470d22c36fd28768f41d71455c Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sat, 11 May 2024 07:43:24 +0200 Subject: [PATCH 18/22] remove stupid comment --- DCCTimerAVR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCCTimerAVR.cpp b/DCCTimerAVR.cpp index cb9e685..2806b07 100644 --- a/DCCTimerAVR.cpp +++ b/DCCTimerAVR.cpp @@ -186,7 +186,7 @@ int DCCTimer::freeMemory() { void DCCTimer::reset() { wdt_enable( WDTO_15MS); // set Arduino watchdog timer for 15ms - delay(50); // wait for the prescaller time to expire + delay(50); // wait for it to happen } From 86291cbec41ca4b9f53a73a6212d21fa9198c239 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sat, 11 May 2024 07:45:28 +0200 Subject: [PATCH 19/22] signal id of 0 does not work --- EXRAIL2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index f401eba..6980f03 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -1145,7 +1145,7 @@ void RMFT2::kill(const FSH * reason, int operand) { int16_t RMFT2::getSignalSlot(int16_t id) { - if (id >= 0) { + if (id > 0) { int sigslot = 0; int16_t sighandle = 0; // Trundle down the signal list until we reach the end From 2172d2e1754fd9dbe87cf2c8c80a3ddab0bf9185 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sat, 11 May 2024 08:46:25 +0200 Subject: [PATCH 20/22] make WDT time longer to work around bootloader bug --- DCCTimerAVR.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DCCTimerAVR.cpp b/DCCTimerAVR.cpp index 2806b07..656ba7e 100644 --- a/DCCTimerAVR.cpp +++ b/DCCTimerAVR.cpp @@ -185,8 +185,10 @@ int DCCTimer::freeMemory() { } void DCCTimer::reset() { - wdt_enable( WDTO_15MS); // set Arduino watchdog timer for 15ms - delay(50); // wait for it to happen + // 250ms chosen to circumwent bootloader bug which + // hangs at too short timepout (like 15ms) + wdt_enable( WDTO_250MS); // set Arduino watchdog timer for 250ms + delay(500); // wait for it to happen } From 06b8995861f0dfac3300f9171dc6657cc0c754e1 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Tue, 21 May 2024 20:04:11 +0100 Subject: [PATCH 21/22] ALIAS(named pins) --- EXRAILMacros.h | 2 +- version.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/EXRAILMacros.h b/EXRAILMacros.h index e9e2f77..827c1d2 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -75,7 +75,7 @@ // Pass 1 Implements aliases #include "EXRAIL2MacroReset.h" #undef ALIAS -#define ALIAS(name,value...) const int name= 1##value##0 ==10 ? -__COUNTER__ : value##0/10; +#define ALIAS(name,value...) const int name= #value[0] ? value+0: -__COUNTER__ ; #include "myAutomation.h" // Pass 1d Detect sequence duplicates. diff --git a/version.h b/version.h index dc6dfc3..e5e0241 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.57" +#define VERSION "5.2.58" +// 5.2.58 - EXRAIL ALIAS allows named pins // 5.2.57 - Bugfix autoreverse: Apply mode by binart bit match and not by equality // 5.2.56 - Bugfix and refactor for EXRAIL getSignalSlot // 5.2.55 - Move EXRAIL isSignal() to public to allow use in STEALTH call From 449a5f1670ae12000020fcbf72e1a4ee6bac7511 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Wed, 22 May 2024 07:16:25 +0800 Subject: [PATCH 22/22] STM32 updates for serial ports etc. --- DCCTimerSTM32.cpp | 17 +++++++++++++++-- WifiInterface.cpp | 3 ++- version.h | 4 +++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/DCCTimerSTM32.cpp b/DCCTimerSTM32.cpp index 7a13919..0917455 100644 --- a/DCCTimerSTM32.cpp +++ b/DCCTimerSTM32.cpp @@ -36,7 +36,20 @@ #include "DIAG.h" #include -#if defined(ARDUINO_NUCLEO_F401RE) || defined(ARDUINO_NUCLEO_F411RE) +#if defined(ARDUINO_NUCLEO_F401RE) +// Nucleo-64 boards don't have additional serial ports defined by default +// Serial1 is available on the F401RE, but not hugely convenient. +// Rx pin on PB7 is useful, but all the Tx pins map to Arduino digital pins, specifically: +// PA9 == D8 +// PB6 == D10 +// of which D8 is needed by the standard and EX8874 motor shields. D10 would be used if a second +// EX8874 is stacked. So only disable this if using a second motor shield. +HardwareSerial Serial1(PB7, PB6); // Rx=PB7, Tx=PB6 -- CN7 pin 17 and CN10 pin 17 +// Serial2 is defined to use USART2 by default, but is in fact used as the diag console +// via the debugger on the Nucleo-64. It is therefore unavailable for other DCC-EX uses like WiFi, DFPlayer, etc. +// Let's define Serial6 as an additional serial port (the only other option for the F401RE) +HardwareSerial Serial6(PA12, PA11); // Rx=PA12, Tx=PA11 -- CN10 pins 12 and 14 - F401RE +#elif defined(ARDUINO_NUCLEO_F411RE) // Nucleo-64 boards don't have additional serial ports defined by default HardwareSerial Serial1(PB7, PA15); // Rx=PB7, Tx=PA15 -- CN7 pins 17 and 21 - F411RE // Serial2 is defined to use USART2 by default, but is in fact used as the diag console @@ -54,7 +67,7 @@ HardwareSerial Serial3(PC11, PC10); // Rx=PC11, Tx=PC10 -- USART3 - F446RE HardwareSerial Serial5(PD2, PC12); // Rx=PD2, Tx=PC12 -- UART5 - F446RE // On the F446RE, Serial4 and Serial6 also use pins we can't readily map while using the Arduino pins #elif defined(ARDUINO_NUCLEO_F412ZG) || defined(ARDUINO_NUCLEO_F413ZH) || defined(ARDUINO_NUCLEO_F446ZE) || \ - defined(ARDUINO_NUCLEO_F429ZI) || defined(ARDUINO_NUCLEO_F439ZI) + defined(ARDUINO_NUCLEO_F429ZI) || defined(ARDUINO_NUCLEO_F439ZI) || defined(ARDUINO_NUCLEO_F4X9ZI) // Nucleo-144 boards don't have Serial1 defined by default HardwareSerial Serial6(PG9, PG14); // Rx=PG9, Tx=PG14 -- USART6 HardwareSerial Serial5(PD2, PC12); // Rx=PD2, Tx=PC12 -- UART5 diff --git a/WifiInterface.cpp b/WifiInterface.cpp index 87d5437..fcf9932 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -1,4 +1,5 @@ /* + * © 2022-2024 Paul M. Antoine * © 2021 Fred Decker * © 2020-2022 Harald Barth * © 2020-2022 Chris Harlow @@ -70,7 +71,7 @@ Stream * WifiInterface::wifiStream; #define SERIAL3 Serial5 #elif defined(ARDUINO_NUCLEO_F413ZH) || defined(ARDUINO_NUCLEO_F429ZI) \ || defined(ARDUINO_NUCLEO_F446ZE) || defined(ARDUINO_NUCLEO_F412ZG) \ - || defined(ARDUINO_NUCLEO_F439ZI) + || defined(ARDUINO_NUCLEO_F439ZI) || defined(ARDUINO_NUCLEO_F4X9ZI) #define NUM_SERIAL 2 #define SERIAL1 Serial6 #else diff --git a/version.h b/version.h index e5e0241..2079a1e 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,9 @@ #include "StringFormatter.h" -#define VERSION "5.2.58" +#define VERSION "5.2.59" +// 5.2.59 - STM32 bugfix correct Serial1 definition for Nucleo-F401RE +// - STM32 add support for ARDUINO_NUCLEO_F4X9ZI type to span F429/F439 in upcoming STM32duino release v2.8 as a result of our PR // 5.2.58 - EXRAIL ALIAS allows named pins // 5.2.57 - Bugfix autoreverse: Apply mode by binart bit match and not by equality // 5.2.56 - Bugfix and refactor for EXRAIL getSignalSlot