From 83d4930124e9286577e380d71e9731f83d38d0e4 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Fri, 26 Apr 2024 19:04:20 +0800 Subject: [PATCH] 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 };