From 08427abe70f5fe3fe61149d773b122be5821daa9 Mon Sep 17 00:00:00 2001 From: Harald Barth Date: Tue, 30 Aug 2022 09:31:09 +0200 Subject: [PATCH] Workarounds for bugs and functionality not in the Arduino ESP32 package --- ESP32-fixes.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ ESP32-fixes.h | 24 ++++++++++++++++++++ MotorDriver.cpp | 8 +++++++ 3 files changed, 91 insertions(+) create mode 100644 ESP32-fixes.cpp create mode 100644 ESP32-fixes.h diff --git a/ESP32-fixes.cpp b/ESP32-fixes.cpp new file mode 100644 index 0000000..a21a1df --- /dev/null +++ b/ESP32-fixes.cpp @@ -0,0 +1,59 @@ +/* + * © 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 . + */ +#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); + } +} diff --git a/ESP32-fixes.h b/ESP32-fixes.h new file mode 100644 index 0000000..64edaa3 --- /dev/null +++ b/ESP32-fixes.h @@ -0,0 +1,24 @@ +/* + * © 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 . + */ +#pragma once +#include +void DCCEXanalogWriteFrequency(uint8_t pin, uint32_t frequency); +void DCCEXanalogWrite(uint8_t pin, int value); + diff --git a/MotorDriver.cpp b/MotorDriver.cpp index 3bbf6d3..a7a794a 100644 --- a/MotorDriver.cpp +++ b/MotorDriver.cpp @@ -29,6 +29,7 @@ #define ADC_INPUT_MAX_VALUE 1023 // 10 bit ADC #if defined(ARDUINO_ARCH_ESP32) +#include "ESP32-fixes.h" #include #include #include @@ -229,6 +230,9 @@ int MotorDriver::getCurrentRaw() { void MotorDriver::setDCSignal(byte speedcode) { if (brakePin == UNUSED_PIN) return; +#if defined(ARDUINO_ARCH_ESP32) + DCCEXanalogWriteFrequency(brakePin, 100); // set DC PWM frequency to 100Hz XXX May move to setup +#endif // spedcoode is a dcc speed & direction byte tSpeed=speedcode & 0x7F; // DCC Speed with 0,1 stop and speed steps 2 to 127 byte tDir=speedcode & 0x80; @@ -238,7 +242,11 @@ void MotorDriver::setDCSignal(byte speedcode) { else brake = 2 * (128-tSpeed); if (invertBrake) brake=255-brake; +#if defined(ARDUINO_ARCH_ESP32) + DCCEXanalogWrite(brakePin,brake); +#else analogWrite(brakePin,brake); +#endif //DIAG(F("DCSignal %d"), speedcode); if (HAVE_PORTA(fastSignalPin.shadowinout == &PORTA)) { noInterrupts();