diff --git a/DCCTimer.h b/DCCTimer.h index f87d967..fb8184b 100644 --- a/DCCTimer.h +++ b/DCCTimer.h @@ -91,6 +91,7 @@ private: // gigure out if we have enough memory for advanced features // so define HAS_ENOUGH_MEMORY until proved otherwise. #define HAS_ENOUGH_MEMORY +#define HAS_AVR_WDT #if defined(ARDUINO_AVR_UNO) #define ARDUINO_TYPE "UNO" @@ -114,7 +115,13 @@ private: #define ARDUINO_TYPE "TEENSY40" #elif defined(ARDUINO_TEENSY41) #define ARDUINO_TYPE "TEENSY41" +#elif defined(ARDUINO_ARCH_ESP8266) +#define ARDUINO_TYPE "ESP8266" +#undef HAS_AVR_WDT +#elif defined(ARDUINO_ARCH_ESP32) +#define ARDUINO_TYPE "ESP32" +#undef HAS_AVR_WDT #else -#error CANNOT COMPILE - DCC++ EX ONLY WORKS WITH AN ARDUINO UNO, NANO 328, OR ARDUINO MEGA 1280/2560 +#error CANNOT COMPILE - DCC++ EX ONLY WORKS WITH THE ARCHITECTURES LISTED IN DCCTimer.h #endif #endif diff --git a/DCCTimerESP.cpp b/DCCTimerESP.cpp new file mode 100644 index 0000000..d4b4a2b --- /dev/null +++ b/DCCTimerESP.cpp @@ -0,0 +1,127 @@ +/* + * © 2020-2022 Harald Barth + * + * 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 . + */ + +// ATTENTION: this file only compiles on an ESP8266 and ESP32 +// On ESP32 we do not even use the functions but they are here for completeness sake +// Please refer to DCCTimer.h for general comments about how this class works +// This is to avoid repetition and duplication. + +#ifdef ARDUINO_ARCH_ESP8266 + +#include "DCCTimer.h" +INTERRUPT_CALLBACK interruptHandler=0; + +void DCCTimer::begin(INTERRUPT_CALLBACK callback) { + interruptHandler=callback; + timer1_disable(); + + // There seem to be differnt ways to attach interrupt handler + // ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL); + // ETS_FRC_TIMER1_NMI_INTR_ATTACH(interruptHandler); + // Let us choose the one from the API + timer1_attachInterrupt(interruptHandler); + + // not exactly sure of order: + timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP); + timer1_write(CLOCK_CYCLES); +} +// We do not support to use PWM to make the Waveform on ESP +bool IRAM_ATTR DCCTimer::isPWMPin(byte pin) { + return false; +} +void IRAM_ATTR DCCTimer::setPWM(byte pin, bool high) { +} + +// Fake this as it should not be used +void DCCTimer::getSimulatedMacAddress(byte mac[6]) { + mac[0] = 0xFE; + mac[1] = 0xBE; + mac[2] = 0xEF; + mac[3] = 0xC0; + mac[4] = 0xFF; + mac[5] = 0xEE; +} + +volatile int DCCTimer::minimum_free_memory=__INT_MAX__; + +// Return low memory value... +int DCCTimer::getMinimumFreeMemory() { + noInterrupts(); // Disable interrupts to get volatile value + int retval = minimum_free_memory; + interrupts(); + return retval; +} + +int DCCTimer::freeMemory() { + return ESP.getFreeHeap(); +} +#endif + +//////////////////////////////////////////////////////////////////////// + +#ifdef ARDUINO_ARCH_ESP32 + +#include "DCCTimer.h" +INTERRUPT_CALLBACK interruptHandler=0; + +// https://www.visualmicro.com/page/Timer-Interrupts-Explained.aspx + +portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; + +void DCCTimer::begin(INTERRUPT_CALLBACK callback) { + interruptHandler = callback; + hw_timer_t *timer = NULL; + timer = timerBegin(0, 2, true); // prescaler can be 2 to 65536 so choose 2 + timerAttachInterrupt(timer, interruptHandler, true); + timerAlarmWrite(timer, CLOCK_CYCLES / 6, true); // divide by prescaler*3 (Clockbase is 80Mhz and not F_CPU 240Mhz) + timerAlarmEnable(timer); +} + +// We do not support to use PWM to make the Waveform on ESP +bool IRAM_ATTR DCCTimer::isPWMPin(byte pin) { + return false; +} +void IRAM_ATTR DCCTimer::setPWM(byte pin, bool high) { +} + +// Fake this as it should not be used +void DCCTimer::getSimulatedMacAddress(byte mac[6]) { + mac[0] = 0xFE; + mac[1] = 0xBE; + mac[2] = 0xEF; + mac[3] = 0xC0; + mac[4] = 0xFF; + mac[5] = 0xEE; +} + +volatile int DCCTimer::minimum_free_memory=__INT_MAX__; + +// Return low memory value... +int DCCTimer::getMinimumFreeMemory() { + noInterrupts(); // Disable interrupts to get volatile value + int retval = minimum_free_memory; + interrupts(); + return retval; +} + +int DCCTimer::freeMemory() { + return ESP.getFreeHeap(); +} +#endif + diff --git a/EthernetInterface.h b/EthernetInterface.h index 2a94ac6..e79996d 100644 --- a/EthernetInterface.h +++ b/EthernetInterface.h @@ -31,7 +31,7 @@ #include "defines.h" #include "DCCEXParser.h" #include -#include +//#include #if defined (ARDUINO_TEENSY41) #include //TEENSY Ethernet Treiber #include diff --git a/IO_GPIOBase.h b/IO_GPIOBase.h index 4269a70..3bc75af 100644 --- a/IO_GPIOBase.h +++ b/IO_GPIOBase.h @@ -69,6 +69,10 @@ protected: I2CRB requestBlock; FSH *_deviceName; +#if defined(ARDUINO_ARCH_ESP32) + // workaround: Has somehow no min function for all types + static inline T min(T a, int b) { return a < b ? a : b; }; +#endif }; // Because class GPIOBase is a template, the implementation (below) must be contained within the same @@ -246,4 +250,4 @@ int GPIOBase::_read(VPIN vpin) { return (_portInputState & mask) ? 0 : 1; // Invert state (5v=0, 0v=1) } -#endif \ No newline at end of file +#endif diff --git a/MotorDriver.h b/MotorDriver.h index 0e4af4f..c69f63d 100644 --- a/MotorDriver.h +++ b/MotorDriver.h @@ -29,7 +29,7 @@ #define UNUSED_PIN 127 // inside int8_t #endif -#if defined(__IMXRT1062__) +#if defined(__IMXRT1062__) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) struct FASTPIN { volatile uint32_t *inout; uint32_t maskHIGH; diff --git a/WifiInterface.cpp b/WifiInterface.cpp index 0120074..b7b059e 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -22,7 +22,7 @@ #ifndef ARDUINO_AVR_UNO_WIFI_REV2 // This code is NOT compiled on a unoWifiRev2 processor which uses a different architecture #include "WifiInterface.h" /* config.h included there */ -#include +//#include #include "DIAG.h" #include "StringFormatter.h" diff --git a/WifiInterface.h b/WifiInterface.h index 0a4e477..7c0a433 100644 --- a/WifiInterface.h +++ b/WifiInterface.h @@ -23,7 +23,7 @@ #include "FSH.h" #include "DCCEXParser.h" #include -#include +//#include enum wifiSerialState { WIFI_NOAT, WIFI_DISCONNECTED, WIFI_CONNECTED }; diff --git a/defines.h b/defines.h index 67dbc96..9ce154d 100644 --- a/defines.h +++ b/defines.h @@ -40,7 +40,7 @@ // WIFI_ON: All prereqs for running with WIFI are met // Note: WIFI_CHANNEL may not exist in early config.h files so is added here if needed. -#if (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_ZERO) || defined(TEENSYDUINO)) || defined(ARDUINO_AVR_NANO_EVERY) +#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_ZERO) || defined(TEENSYDUINO) || defined(ARDUINO_AVR_NANO_EVERY) || defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) #define BIG_RAM #endif #if ENABLE_WIFI