From 31ecba08d8b797b3468b04833ac2c3a794602fcc Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Fri, 3 Mar 2023 20:51:32 +0100 Subject: [PATCH 1/5] faultPin can be inverted (from its inverted sense --- MotorDriver.cpp | 11 +++++++++-- MotorDriver.h | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/MotorDriver.cpp b/MotorDriver.cpp index a6a1766..7415b36 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -38,7 +38,7 @@ volatile portreg_t shadowPORTB; volatile portreg_t shadowPORTC; MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin, - byte current_pin, float sense_factor, unsigned int trip_milliamps, byte fault_pin) { + byte current_pin, float sense_factor, unsigned int trip_milliamps, int8_t fault_pin) { powerPin=power_pin; invertPower=power_pin < 0; if (invertPower) { @@ -95,6 +95,9 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i faultPin=fault_pin; if (faultPin != UNUSED_PIN) { + invertFault=fault_pin < 0; + faultPin=invertFault ? 0-fault_pin : fault_pin; + DIAG(F("Fault pin = %d invert %d"), faultPin, invertFault); getFastPin(F("FAULT"),faultPin, 1 /*input*/, fastFaultPin); pinMode(faultPin, INPUT); } @@ -196,8 +199,12 @@ int MotorDriver::getCurrentRaw(bool fromISR) { int current; current = ADCee::read(currentPin, fromISR)-senseOffset; if (current<0) current=0-current; - if ((faultPin != UNUSED_PIN) && isLOW(fastFaultPin) && powerMode==POWERMODE::ON) + if ((faultPin != UNUSED_PIN) && powerMode==POWERMODE::ON) { + if (invertFault && isLOW(fastFaultPin)) return (current == 0 ? -1 : -current); + if (!invertFault && !isLOW(fastFaultPin)) + return (current == 0 ? -1 : -current); + } return current; } diff --git a/MotorDriver.h b/MotorDriver.h index 51f7654..5f36184 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -112,7 +112,7 @@ class MotorDriver { public: MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, int8_t brake_pin, - byte current_pin, float senseFactor, unsigned int tripMilliamps, byte faultPin); + byte current_pin, float senseFactor, unsigned int tripMilliamps, int8_t fault_pin); void setPower( POWERMODE mode); POWERMODE getPower() { return powerMode;} // as the port registers can be shadowed to get syncronized DCC signals @@ -198,6 +198,7 @@ class MotorDriver { bool dualSignal; // true to use signalPin2 bool invertBrake; // brake pin passed as negative means pin is inverted bool invertPower; // power pin passed as negative means pin is inverted + bool invertFault; // fault pin passed as negative means pin is inverted // Raw to milliamp conversion factors avoiding float data types. // Milliamps=rawADCreading * sensefactorInternal / senseScale From 75f274e3b75f4975d8968c7bb621e780b1902fa7 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Thu, 13 Apr 2023 15:27:22 +0800 Subject: [PATCH 2/5] STM32 unsupported board selection error reporting --- DCCTimerSTM32.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/DCCTimerSTM32.cpp b/DCCTimerSTM32.cpp index fcbf286..4f9cbdd 100644 --- a/DCCTimerSTM32.cpp +++ b/DCCTimerSTM32.cpp @@ -1,8 +1,8 @@ /* * © 2023 Neil McKechnie - * © 2022 Paul M. Antoine + * © 2022-23 Paul M. Antoine * © 2021 Mike S - * © 2021 Harald Barth + * © 2021, 2023 Harald Barth * © 2021 Fred Decker * © 2021 Chris Harlow * © 2021 David Cutting @@ -43,11 +43,18 @@ HardwareSerial Serial6(PA12, PA11); // Rx=PA12, Tx=PA11 -- CN10 pins 12 and 14 HardwareSerial Serial1(PA10, PB6); // Rx=PA10 (D2), Tx=PB6 (D10) -- CN10 pins 17 and 9 - F446RE // 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. +// NB: USART3 and USART6 are available but as yet undefined #elif defined(ARDUINO_NUCLEO_F412ZG) || defined(ARDUINO_NUCLEO_F429ZI) || defined(ARDUINO_NUCLEO_F446ZE) // Nucleo-144 boards don't have Serial1 defined by default HardwareSerial Serial1(PG9, PG14); // Rx=PG9, Tx=PG14 -- D0, D1 - F412ZG/F446ZE +// Serial2 is defined to use USART2 by default, but is in fact used as the diag console +// via the debugger on the Nucleo-144. It is therefore unavailable for other DCC-EX uses like WiFi, DFPlayer, etc. +// NB: +// On all of the above, USART3, and USART6 are available but as yet undefined +// On F446ZE and F429ZI, UART4, UART5 are also available but as yet undefined +// On F429ZI, UART7 and UART8 are also available but as yet undefined #else -#warning Serial1 not defined +#error STM32 board selected is not yet explicitly supported - so Serial1 peripheral is not defined #endif /////////////////////////////////////////////////////////////////////////////////////////////// @@ -227,6 +234,9 @@ void DCCTimer::reset() { #define NUM_ADC_INPUTS NUM_ANALOG_INPUTS // TODO: may need to use uint32_t on STMF4xx variants with > 16 analog inputs! +#if defined(ARDUINO_NUCLEO_F446RE) || defined(ARDUINO_NUCLEO_F429ZI) || defined(ARDUINO_NUCLEO_F446ZE) +#warning STM32 board selected not fully supported - only use ADC1 inputs 0-15 for current sensing! +#endif uint16_t ADCee::usedpins = 0; int * ADCee::analogvals = NULL; uint32_t * analogchans = NULL; From d2cc60812d743abcdc90542f37ca0b55e1533393 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Sun, 16 Apr 2023 15:40:27 +0800 Subject: [PATCH 3/5] Merge ESP32-fixes into DCCTimerESP --- DCCTimer.h | 7 ++++-- DCCTimerESP.cpp | 39 +++++++++++++++++++++++++++++++ ESP32-fixes.cpp | 61 ------------------------------------------------- ESP32-fixes.h | 26 --------------------- MotorDriver.cpp | 12 ++++------ 5 files changed, 48 insertions(+), 97 deletions(-) delete mode 100644 ESP32-fixes.cpp delete mode 100644 ESP32-fixes.h diff --git a/DCCTimer.h b/DCCTimer.h index 2214851..7a9d940 100644 --- a/DCCTimer.h +++ b/DCCTimer.h @@ -1,7 +1,7 @@ /* - * © 2022 Paul M. Antoine + * © 2022-2023 Paul M. Antoine * © 2021 Mike S - * © 2021-2022 Harald Barth + * © 2021-2023 Harald Barth * © 2021 Fred Decker * All rights reserved. * @@ -62,6 +62,9 @@ class DCCTimer { static bool isPWMPin(byte pin); static void setPWM(byte pin, bool high); static void clearPWM(); + static void DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency); + static void DCCEXanalogWrite(uint8_t pin, int value); + // Update low ram level. Allow for extra bytes to be specified // by estimation or inspection, that may be used by other // called subroutines. Must be called with interrupts disabled. diff --git a/DCCTimerESP.cpp b/DCCTimerESP.cpp index caaae9d..cf5978e 100644 --- a/DCCTimerESP.cpp +++ b/DCCTimerESP.cpp @@ -150,6 +150,45 @@ int DCCTimer::freeMemory() { void DCCTimer::reset() { ESP.restart(); } + +#include "esp32-hal.h" +#include "soc/soc_caps.h" + + +#ifdef SOC_LEDC_SUPPORT_HS_MODE +#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1) +#else +#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM) +#endif + +static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 }; +static int cnt_channel = LEDC_CHANNELS; + +void DCCTimer::DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency) { + if (pin < SOC_GPIO_PIN_COUNT) { + if (pin_to_channel[pin] != 0) { + ledcSetup(pin_to_channel[pin], frequency, 8); + } + } +} + +void DCCTimer::DCCEXanalogWrite(uint8_t pin, int value) { + if (pin < SOC_GPIO_PIN_COUNT) { + if (pin_to_channel[pin] == 0) { + if (!cnt_channel) { + log_e("No more PWM channels available! All %u already used", LEDC_CHANNELS); + return; + } + pin_to_channel[pin] = --cnt_channel; + ledcAttachPin(pin, cnt_channel); + ledcSetup(cnt_channel, 1000, 8); + } else { + ledcAttachPin(pin, pin_to_channel[pin]); + } + ledcWrite(pin_to_channel[pin], value); + } +} + int ADCee::init(uint8_t pin) { pinMode(pin, ANALOG); adc1_config_width(ADC_WIDTH_BIT_12); diff --git a/ESP32-fixes.cpp b/ESP32-fixes.cpp deleted file mode 100644 index e3c350c..0000000 --- a/ESP32-fixes.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * © 2022 Harald Barth - * 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 . - */ -#ifdef ARDUINO_ARCH_ESP32 -#include -#include "ESP32-fixes.h" - -#include "esp32-hal.h" -#include "soc/soc_caps.h" - - -#ifdef SOC_LEDC_SUPPORT_HS_MODE -#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1) -#else -#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM) -#endif - -static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 }; -static int cnt_channel = LEDC_CHANNELS; - -void DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency) { - if (pin < SOC_GPIO_PIN_COUNT) { - if (pin_to_channel[pin] != 0) { - ledcSetup(pin_to_channel[pin], frequency, 8); - } - } -} - -void DCCEXanalogWrite(uint8_t pin, int value) { - if (pin < SOC_GPIO_PIN_COUNT) { - if (pin_to_channel[pin] == 0) { - if (!cnt_channel) { - log_e("No more PWM channels available! All %u already used", LEDC_CHANNELS); - return; - } - pin_to_channel[pin] = --cnt_channel; - ledcAttachPin(pin, cnt_channel); - ledcSetup(cnt_channel, 1000, 8); - } else { - ledcAttachPin(pin, pin_to_channel[pin]); - } - ledcWrite(pin_to_channel[pin], value); - } -} -#endif diff --git a/ESP32-fixes.h b/ESP32-fixes.h deleted file mode 100644 index 0fd4a7f..0000000 --- a/ESP32-fixes.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * © 2022 Harald Barth - * 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 . - */ -#ifdef ARDUINO_ARCH_ESP32 -#pragma once -#include -void DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency); -void DCCEXanalogWrite(uint8_t pin, int value); -#endif - diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 28ecba6..9f39123 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -1,8 +1,8 @@ /* - * © 2022 Paul M Antoine + * © 2022-2023 Paul M Antoine * © 2021 Mike S * © 2021 Fred Decker - * © 2020-2022 Harald Barth + * © 2020-2023 Harald Barth * © 2020-2021 Chris Harlow * All rights reserved. * @@ -27,10 +27,6 @@ #include "DCCTimer.h" #include "DIAG.h" -#if defined(ARDUINO_ARCH_ESP32) -#include "ESP32-fixes.h" -#endif - bool MotorDriver::commonFaultPin=false; volatile portreg_t shadowPORTA; @@ -286,7 +282,7 @@ void MotorDriver::setDCSignal(byte speedcode) { f = taurustones[ (tSpeed-2)/2 ] ; } } - DCCEXanalogWriteFrequency(brakePin, f); // set DC PWM frequency to 100Hz XXX May move to setup + DCCTimer::DCCEXanalogWriteFrequency(brakePin, f); // set DC PWM frequency to 100Hz XXX May move to setup } #endif if (tSpeed <= 1) brake = 255; @@ -295,7 +291,7 @@ void MotorDriver::setDCSignal(byte speedcode) { if (invertBrake) brake=255-brake; #if defined(ARDUINO_ARCH_ESP32) - DCCEXanalogWrite(brakePin,brake); + DCCTimer::DCCEXanalogWrite(brakePin,brake); #else analogWrite(brakePin,brake); #endif From f465020e93d271aa8027003fa9febe253b703298 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Mon, 17 Apr 2023 23:40:48 +0200 Subject: [PATCH 4/5] Support boards with inverted fault pin --- GITHUB_SHA.h | 2 +- MotorDrivers.h | 14 +++++++++++--- version.h | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 0ac9c5f..f3e8efd 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202304111013Z" +#define GITHUB_SHA "devel-202304172140Z" diff --git a/MotorDrivers.h b/MotorDrivers.h index cc13f54..a355d26 100644 --- a/MotorDrivers.h +++ b/MotorDrivers.h @@ -76,9 +76,13 @@ // analog inputs. Here we use analog inputs A2 and A3 as A0 and A1 are wired in a way so that // they are not useable at the same time as WiFi (what a bummer). The numbers below are the // actual GPIO numbers. In comments the numbers the pins have on an Uno. -#define STANDARD_MOTOR_SHIELD F("STANDARD_MOTOR_SHIELD"), \ - new MotorDriver(25/* 3*/, 19/*12*/, UNUSED_PIN, 13/*9*/, 35/*A2*/, 0.70, 1500, UNUSED_PIN), \ - new MotorDriver(23/*11*/, 18/*13*/, UNUSED_PIN, 12/*8*/, 34/*A3*/, 0.70, 1500, UNUSED_PIN) +#define STANDARD_MOTOR_SHIELD F("STANDARD_MOTOR_SHIELD"), \ + new MotorDriver(25/* 3*/, 19/*12*/, UNUSED_PIN, 13/*9*/, 35/*A2*/, 0.70, 1500, UNUSED_PIN), \ + new MotorDriver(23/*11*/, 18/*13*/, UNUSED_PIN, 12/*8*/, 34/*A3*/, 0.70, 1500, UNUSED_PIN) + +#define EX8874_SHIELD F("EX8874"),\ + new MotorDriver(25/* 3*/, 19/*12*/, UNUSED_PIN, 13/*9*/, 35/*A2*/, 1.17, 5000, -36 /*-A4*/), \ + new MotorDriver(23/*11*/, 18/*13*/, UNUSED_PIN, 12/*8*/, 34/*A3*/, 1.17, 5000, -39 /*-A5*/) #else // STANDARD shield on any Arduino Uno or Mega compatible with the original specification. @@ -116,6 +120,10 @@ new MotorDriver(2, 7, UNUSED_PIN, -9, A0, 10, 2500, 6), \ new MotorDriver(4, 8, UNUSED_PIN, -10, A1, 10, 2500, 12) +#define EX8874_SHIELD F("EX8874"), \ + new MotorDriver( 3, 12, UNUSED_PIN, 9, A0, 4.86, 5000, -A4), \ + new MotorDriver(11, 13, UNUSED_PIN, 8, A1, 4.86, 5000, -A5) + // Firebox Mk1 #define FIREBOX_MK1 F("FIREBOX_MK1"), \ new MotorDriver(3, 6, 7, UNUSED_PIN, A5, 9.766, 5500, UNUSED_PIN), \ diff --git a/version.h b/version.h index 15c6d0b..385c5f2 100644 --- a/version.h +++ b/version.h @@ -4,7 +4,8 @@ #include "StringFormatter.h" -#define VERSION "4.2.45" +#define VERSION "4.2.46" +// 4.2.46 - Support boards with inverted fault pin // 4.2.45 - Add ONCLOCKMINS to FastClock to allow hourly repeat events // 4.2.44 - Add PowerShell installer EX-CommandStation-installer.exe // 4.2.43 - Fix STM32 set right port mode bits for analog From 70fae16ab35077cf6f75da9b72cf67bc0a6fa1e5 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Wed, 19 Apr 2023 11:18:47 +0100 Subject: [PATCH 5/5] Correct response to --- EXRAIL2.cpp | 7 ++++--- version.h | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 31a0de6..374d546 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -265,16 +265,17 @@ void RMFT2::setTurnoutHiddenState(Turnout * t) { char RMFT2::getRouteType(int16_t id) { for (int16_t i=0;;i+=2) { int16_t rid= GETHIGHFLASHW(routeIdList,i); - if (rid==id) return 'R'; if (rid==0) break; + if (rid==id) return 'R'; } for (int16_t i=0;;i+=2) { int16_t rid= GETHIGHFLASHW(automationIdList,i); - if (rid==id) return 'A'; if (rid==0) break; + if (rid==id) return 'A'; } return 'X'; -} +} + // This filter intercepts <> commands to do the following: // - Implement RMFT specific commands/diagnostics // - Reject/modify JMRI commands that would interfere with RMFT processing diff --git a/version.h b/version.h index 385c5f2..f168477 100644 --- a/version.h +++ b/version.h @@ -4,7 +4,8 @@ #include "StringFormatter.h" -#define VERSION "4.2.46" +#define VERSION "4.2.47" +// 4.2.47 - Correct response to // 4.2.46 - Support boards with inverted fault pin // 4.2.45 - Add ONCLOCKMINS to FastClock to allow hourly repeat events // 4.2.44 - Add PowerShell installer EX-CommandStation-installer.exe