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