From 4a3d3228a93622d8a7ab48cf1b0000079a51b208 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 7 Jan 2024 22:22:38 +0100 Subject: [PATCH 1/9] ESP32: Use SOC_RMT_MEM_WORDS_PER_CHANNEL to determine if the RMT hardware can handle DCC --- DCCRMT.cpp | 50 +++++++++++++++++++++++++++++++++++--------------- DCCWaveform.h | 8 ++++---- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/DCCRMT.cpp b/DCCRMT.cpp index cbd9af6..afada7b 100644 --- a/DCCRMT.cpp +++ b/DCCRMT.cpp @@ -1,5 +1,5 @@ /* - * © 2021-2022, Harald Barth. + * © 2021-2024, Harald Barth. * * This file is part of DCC-EX * @@ -25,6 +25,18 @@ #include "DCCWaveform.h" // for MAX_PACKET_SIZE #include "soc/gpio_sig_map.h" +// check for right type of ESP32 +#include "soc/soc_caps.h" +#ifndef SOC_RMT_MEM_WORDS_PER_CHANNEL +#error This symobol should be defined +#endif +#if SOC_RMT_MEM_WORDS_PER_CHANNEL < 64 +#warning This is not an ESP32-WROOM but some other unsupported variant +#warning You are outside of the DCC-EX supported hardware +#endif + +static const byte RMT_CHAN_PER_DCC_CHAN = 2; + // Number of bits resulting out of X bytes of DCC payload data // Each byte has one bit extra and at the end we have one EOF marker #define DATA_LEN(X) ((X)*9+1) @@ -75,12 +87,30 @@ void IRAM_ATTR interrupt(rmt_channel_t channel, void *t) { RMTChannel::RMTChannel(pinpair pins, bool isMain) { byte ch; byte plen; + + // Below we check if the DCC packet actually fits into the RMT hardware + // Currently MAX_PACKET_SIZE = 5 so with checksum there are + // MAX_PACKET_SIZE+1 data packets. Each need DATA_LEN (9) bits. + // To that we add the preamble length, the fencepost DCC end bit + // and the RMT EOF marker. + // SOC_RMT_MEM_WORDS_PER_CHANNEL is either 64 (original WROOM) or + // 48 (all other ESP32 like the -C3 or -S2 + // The formula to get the possible MAX_PACKET_SIZE is + // + // ALLOCATED = RMT_CHAN_PER_DCC_CHAN * SOC_RMT_MEM_WORDS_PER_CHANNEL + // MAX_PACKET_SIZE = floor((ALLOCATED - PREAMBLE_LEN - 2)/9 - 1) + // + if (isMain) { ch = 0; plen = PREAMBLE_BITS_MAIN; + static_assert (DATA_LEN(MAX_PACKET_SIZE+1) + PREAMBLE_BITS_MAIN + 2 <= RMT_CHAN_PER_DCC_CHAN * SOC_RMT_MEM_WORDS_PER_CHANNEL, + "Number of DCC packet bits greater than ESP32 RMT memory available"); } else { - ch = 2; + ch = RMT_CHAN_PER_DCC_CHAN; // number == offset plen = PREAMBLE_BITS_PROG; + static_assert (DATA_LEN(MAX_PACKET_SIZE+1) + PREAMBLE_BITS_PROG + 2 <= RMT_CHAN_PER_DCC_CHAN * SOC_RMT_MEM_WORDS_PER_CHANNEL, + "Number of DCC packet bits greater than ESP32 RMT memory available"); } // preamble @@ -115,7 +145,7 @@ RMTChannel::RMTChannel(pinpair pins, bool isMain) { // data: max packet size today is 5 + checksum maxDataLen = DATA_LEN(MAX_PACKET_SIZE+1); // plus checksum data = (rmt_item32_t*)malloc(maxDataLen*sizeof(rmt_item32_t)); - + rmt_config_t config; // Configure the RMT channel for TX bzero(&config, sizeof(rmt_config_t)); @@ -123,20 +153,10 @@ RMTChannel::RMTChannel(pinpair pins, bool isMain) { config.channel = channel = (rmt_channel_t)ch; config.clk_div = RMT_CLOCK_DIVIDER; config.gpio_num = (gpio_num_t)pins.pin; - config.mem_block_num = 2; // With longest DCC packet 11 inc checksum (future expansion) - // number of bits needed is 22preamble + start + - // 11*9 + extrazero + EOT = 124 - // 2 mem block of 64 RMT items should be enough - + config.mem_block_num = RMT_CHAN_PER_DCC_CHAN; + // use config ESP_ERROR_CHECK(rmt_config(&config)); addPin(pins.invpin, true); - /* - // test: config another gpio pin - gpio_num_t gpioNum = (gpio_num_t)(pin-1); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpioNum], PIN_FUNC_GPIO); - gpio_set_direction(gpioNum, GPIO_MODE_OUTPUT); - gpio_matrix_out(gpioNum, RMT_SIG_OUT0_IDX, 0, 0); - */ // NOTE: ESP_INTR_FLAG_IRAM is *NOT* included in this bitmask ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, ESP_INTR_FLAG_LOWMED|ESP_INTR_FLAG_SHARED)); diff --git a/DCCWaveform.h b/DCCWaveform.h index 2202b53..1392288 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -2,7 +2,7 @@ * © 2021 M Steve Todd * © 2021 Mike S * © 2021 Fred Decker - * © 2020-2021 Harald Barth + * © 2020-2024 Harald Barth * © 2020-2021 Chris Harlow * All rights reserved. * @@ -33,9 +33,9 @@ // Number of preamble bits. -const int PREAMBLE_BITS_MAIN = 16; -const int PREAMBLE_BITS_PROG = 22; -const byte MAX_PACKET_SIZE = 5; // NMRA standard extended packets, payload size WITHOUT checksum. +const byte PREAMBLE_BITS_MAIN = 16; +const byte PREAMBLE_BITS_PROG = 22; +const byte MAX_PACKET_SIZE = 5; // NMRA standard extended packets, payload size WITHOUT checksum. // The WAVE_STATE enum is deliberately numbered because a change of order would be catastrophic From 39d0cbb791020e69be0a1da37a4ba7dcdc3a33e5 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Sun, 7 Jan 2024 22:24:15 +0100 Subject: [PATCH 2/9] version 5.2.19 --- 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 4ece558..79fd3fe 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202401030135Z" +#define GITHUB_SHA "devel-202401072123Z" diff --git a/version.h b/version.h index 4ac82a5..ee6bd24 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.18" +#define VERSION "5.2.19" +// 5.2.19 - ESP32: Determine if the RMT hardware can handle DCC // 5.2.18 - Display network IP fix // 5.2.17 - ESP32 simplify network logic // 5.2.16 - Bugfix to allow for devices using the EX-IOExpander protocol to have no analogue or no digital pins From 70a1b9538c303613328cadc554af13d5bb23c9bf Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 8 Jan 2024 13:19:22 +0100 Subject: [PATCH 3/9] Check return of Ethernet.begin() in all code variants --- EthernetInterface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EthernetInterface.cpp b/EthernetInterface.cpp index 5cf531c..7d8d7b0 100644 --- a/EthernetInterface.cpp +++ b/EthernetInterface.cpp @@ -59,15 +59,15 @@ EthernetInterface::EthernetInterface() DCCTimer::getSimulatedMacAddress(mac); connected=false; - #ifdef IP_ADDRESS - Ethernet.begin(mac, IP_ADDRESS); - #else +#ifdef IP_ADDRESS + if (Ethernet.begin(mac, IP_ADDRESS) == 0) +#else if (Ethernet.begin(mac) == 0) +#endif { DIAG(F("Ethernet.begin FAILED")); return; } - #endif if (Ethernet.hardwareStatus() == EthernetNoHardware) { DIAG(F("Ethernet shield not found or W5100")); } From 718e78fca686c4dee836e0e84ab3c9a1556ab054 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 8 Jan 2024 13:20:29 +0100 Subject: [PATCH 4/9] version 5.2.20 --- 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 79fd3fe..1cc285a 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202401072123Z" +#define GITHUB_SHA "devel-202401081219Z" diff --git a/version.h b/version.h index ee6bd24..75c2899 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.19" +#define VERSION "5.2.20" +// 5.2.20 - Check return of Ethernet.begin() // 5.2.19 - ESP32: Determine if the RMT hardware can handle DCC // 5.2.18 - Display network IP fix // 5.2.17 - ESP32 simplify network logic From b51a8fe126d75bddc96ab5e6f1742a0c6be2da61 Mon Sep 17 00:00:00 2001 From: peteGSX <97784652+peteGSX@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:41:29 +1000 Subject: [PATCH 5/9] Add STARTUP_DELAY --- CommandStation-EX.ino | 5 +++++ config.example.h | 8 ++++++++ version.h | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CommandStation-EX.ino b/CommandStation-EX.ino index 205babf..9c94606 100644 --- a/CommandStation-EX.ino +++ b/CommandStation-EX.ino @@ -76,6 +76,11 @@ void setup() DIAG(F("License GPLv3 fsf.org (c) dcc-ex.com")); +// If user has defined a startup delay, delay here before starting IO +#if defined(STARTUP_DELAY) + delay(STARTUP_DELAY) +#endif + // Initialise HAL layer before reading EEprom or setting up MotorDrivers IODevice::begin(); diff --git a/config.example.h b/config.example.h index 89d6c1f..a2e08b2 100644 --- a/config.example.h +++ b/config.example.h @@ -222,6 +222,14 @@ The configuration file for DCC-EX Command Station // We do not support to use the same address, for example 100(long) and 100(short) // at the same time, there must be a border. +///////////////////////////////////////////////////////////////////////////////////// +// Some newer 32bit microcontrollers boot very quickly, so powering on I2C and other +// peripheral devices at the same time may result in the CommandStation booting too +// quickly to detect them. +// To work around this, uncomment the STARTUP_DELAY line below and set a value in +// milliseconds that works for your environment, default is 3000 (3 seconds). +// #define STARTUP_DELAY 3000 + ///////////////////////////////////////////////////////////////////////////////////// // // DEFINE TURNOUTS/ACCESSORIES FOLLOW NORM RCN-213 diff --git a/version.h b/version.h index 75c2899..9f19afe 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.20" +#define VERSION "5.2.21" +// 5.2.21 - Add STARTUP_DELAY config option to delay CS bootup // 5.2.20 - Check return of Ethernet.begin() // 5.2.19 - ESP32: Determine if the RMT hardware can handle DCC // 5.2.18 - Display network IP fix From 5ac26ce505b28c7f0a0a76b2d4e39b6b51b6cc5c Mon Sep 17 00:00:00 2001 From: peteGSX <97784652+peteGSX@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:49:22 +1000 Subject: [PATCH 6/9] Add missing ; and DIAG message --- CommandStation-EX.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CommandStation-EX.ino b/CommandStation-EX.ino index 9c94606..2cd9d33 100644 --- a/CommandStation-EX.ino +++ b/CommandStation-EX.ino @@ -78,7 +78,8 @@ void setup() // If user has defined a startup delay, delay here before starting IO #if defined(STARTUP_DELAY) - delay(STARTUP_DELAY) + DIAG(F("Delaying startup for %dms"), STARTUP_DELAY); + delay(STARTUP_DELAY); #endif // Initialise HAL layer before reading EEprom or setting up MotorDrivers From ca380d11dcaf01459614d2527577a08eb00cb43b Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Wed, 10 Jan 2024 08:15:30 +0100 Subject: [PATCH 7/9] Do not crash on turnouts or turntables without description --- EXRAIL2.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index cc3269b..8a2eadf 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -333,13 +333,15 @@ if (compileFeatures & FEATURE_SIGNAL) { } void RMFT2::setTurnoutHiddenState(Turnout * t) { - // turnout descriptions are in low flash F strings - t->setHidden(GETFLASH(getTurnoutDescription(t->getId()))==0x01); + // turnout descriptions are in low flash F strings + const FSH *desc = getTurnoutDescription(t->getId()); + if (desc) t->setHidden(GETFLASH(desc)==0x01); } #ifndef IO_NO_HAL void RMFT2::setTurntableHiddenState(Turntable * tto) { - tto->setHidden(GETFLASH(getTurntableDescription(tto->getId()))==0x01); + const FSH *desc = getTurntableDescription(tto->getId()); + if (desc) tto->setHidden(GETFLASH(desc)==0x01); } #endif From 27bd4448845e82b8d5d614dcc2d412bbde975c1c Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Wed, 10 Jan 2024 08:18:14 +0100 Subject: [PATCH 8/9] Numbers for automations/routes can be negative --- EXRAIL2Parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXRAIL2Parser.cpp b/EXRAIL2Parser.cpp index b049699..d231342 100644 --- a/EXRAIL2Parser.cpp +++ b/EXRAIL2Parser.cpp @@ -134,7 +134,7 @@ void RMFT2::ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16 return; } if (paramCount==2) { // - uint16_t id=p[1]; + int16_t id=p[1]; StringFormatter::send(stream,F("\n"), id, getRouteType(id), getRouteDescription(id)); From 796d5c47748a4c189f2b04c1e3215f6f54a2c9b2 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Wed, 10 Jan 2024 08:20:14 +0100 Subject: [PATCH 9/9] version 5.2.22 --- 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 1cc285a..a53b57a 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202401081219Z" +#define GITHUB_SHA "devel-202401100719Z" diff --git a/version.h b/version.h index 9f19afe..3c33933 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,8 @@ #include "StringFormatter.h" -#define VERSION "5.2.21" +#define VERSION "5.2.22" +// 5.2.22 - Bugfixes: Empty turnout descriptions ok; negative route numbers valid. // 5.2.21 - Add STARTUP_DELAY config option to delay CS bootup // 5.2.20 - Check return of Ethernet.begin() // 5.2.19 - ESP32: Determine if the RMT hardware can handle DCC