diff --git a/DCCTimer.cpp b/DCCTimer.cpp index 063a6ae..6b204fe 100644 --- a/DCCTimer.cpp +++ b/DCCTimer.cpp @@ -169,7 +169,26 @@ bool IRAM_ATTR DCCTimer::isPWMPin(byte pin) { void IRAM_ATTR DCCTimer::setPWM(byte pin, bool high) { } +#elif defined(ARDUINO_ARCH_ESP32) +// 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 / 2, true); // divide by prescaler + 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) { +} #else // Arduino nano, uno, mega etc diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index df599de..dbabc19 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -66,7 +66,9 @@ void IRAM_ATTR DCCWaveform::loop(bool ackManagerActive) { if (ackflag) { progTrack.checkAck(); // reset flag AFTER check is done + portENTER_CRITICAL(&timerMux); ackflag = 0; + portEXIT_CRITICAL(&timerMux); } #endif } @@ -88,8 +90,11 @@ void IRAM_ATTR DCCWaveform::interruptHandler() { if (progTrack.state==WAVE_PENDING) progTrack.interrupt2(); #ifdef SLOW_ANALOG_READ - else if (progTrack.ackPending && ackflag == 0) // We need AND we are not already checking + else if (progTrack.ackPending && ackflag == 0) { // We need AND we are not already checking + portENTER_CRITICAL(&timerMux); ackflag = 1; + portEXIT_CRITICAL(&timerMux); + } #else else if (progTrack.ackPending) progTrack.checkAck(); diff --git a/defines.h b/defines.h index afb18e8..a79ddca 100644 --- a/defines.h +++ b/defines.h @@ -26,6 +26,17 @@ #define SLOW_ANALOG_READ #endif +//////////////////////////////////////////////////////////////////////////////// +// +#if defined (ARDUINO_ARCH_ESP32) +#define ESP_FAMILY +#define SLOW_ANALOG_READ +#else +#define portENTER_CRITICAL(A) do {} while (0) +#define portEXIT_CRITICAL(A) do {} while (0) +#endif + + //////////////////////////////////////////////////////////////////////////////// // // WIFI_ON: All prereqs for running with WIFI are met