Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Esp32 Core version 3 #2144

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
62 changes: 46 additions & 16 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,24 @@ static ETSTimer timer;
} // namespace _IRrecv
#endif // ESP8266
#if defined(ESP32)
#if ( defined(ESP_ARDUINO_VERSION) && \
(ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)) )
#define _ESP32_ARDUINO_CORE_V3PLUS
#endif // ESP_ARDUINO_VERSION >= 3
// We need a horrible timer hack for ESP32 Arduino framework < v2.0.0
#if !defined(_ESP32_IRRECV_TIMER_HACK)
#if !defined(_ESP32_ARDUINO_CORE_V2PLUS)
// Version check
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
// No need for the hack if we are running version >= 2.0.0
#define _ESP32_IRRECV_TIMER_HACK false
#define _ESP32_ARDUINO_CORE_V2PLUS false
#else // Version check
// If no ESP_ARDUINO_VERSION_MAJOR is defined, or less than 2, then we are
// using an old ESP32 core, so we need the hack.
#define _ESP32_IRRECV_TIMER_HACK true
#define _ESP32_ARDUINO_CORE_V2PLUS true
#endif // Version check
#endif // !defined(_ESP32_IRRECV_TIMER_HACK)
#endif // !defined(_ESP32_ARDUINO_CORE_V2PLUS)

#if _ESP32_IRRECV_TIMER_HACK
#if _ESP32_ARDUINO_CORE_V2PLUS
// Required structs/types from:
// https://github.com/espressif/arduino-esp32/blob/6b0114366baf986c155e8173ab7c22bc0c5fcedc/cores/esp32/esp32-hal-timer.c#L28-L58
// These are needed to be able to directly manipulate the timer registers from
Expand Down Expand Up @@ -131,10 +135,10 @@ typedef struct hw_timer_s {
uint8_t timer;
portMUX_TYPE lock;
} hw_timer_t;
#endif // _ESP32_IRRECV_TIMER_HACK / End of Horrible Hack.
#endif // _ESP32_ARDUINO_CORE_V2PLUS / End of Horrible Hack.

namespace _IRrecv {
static hw_timer_t * timer = NULL;
static hw_timer_t *timer = NULL;
} // namespace _IRrecv
#endif // ESP32
using _IRrecv::timer;
Expand Down Expand Up @@ -225,26 +229,31 @@ static void USE_IRAM_ATTR gpio_intr() {
#if defined(ESP32)
// Reset the timeout.
//
#if _ESP32_IRRECV_TIMER_HACK
// The following three lines of code are the equiv of:
#if _ESP32_ARDUINO_CORE_V2PLUS
// The following three lines of code are the equivalent of:
// `timerWrite(timer, 0);`
// We can't call that routine safely from inside an ISR as that procedure
// is not stored in IRAM. Hence, we do it manually so that it's covered by
// USE_IRAM_ATTR in this ISR.
// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1350
// @see https://github.com/espressif/arduino-esp32/blob/6b0114366baf986c155e8173ab7c22bc0c5fcedc/cores/esp32/esp32-hal-timer.c#L106-L110
timer->dev->load_high = (uint32_t) 0;
timer->dev->load_low = (uint32_t) 0;
timer->dev->load_high = static_cast<uint32_t>(0);
timer->dev->load_low = static_cast<uint32_t>(0);
timer->dev->reload = 1;
// The next line is the same, but instead replaces:
// `timerAlarmEnable(timer);`
// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1350
// @see https://github.com/espressif/arduino-esp32/blob/6b0114366baf986c155e8173ab7c22bc0c5fcedc/cores/esp32/esp32-hal-timer.c#L176-L178
timer->dev->config.alarm_en = 1;
#else // _ESP32_IRRECV_TIMER_HACK
#elif defined(_ESP32_ARDUINO_CORE_V3PLUS)
// For ESP32 core version 3.x, replace `timerAlarmEnable`
timerWrite(timer, 0);
uint64_t alarm_value = 50000; // Example value (50ms)
timerAlarm(timer, alarm_value, false, 0);
#else // !_ESP32_ARDUINO_CORE_V3PLUS
timerWrite(timer, 0);
timerAlarmEnable(timer);
#endif // _ESP32_IRRECV_TIMER_HACK
#endif // _ESP32_ARDUINO_CORE_V2PLUS
#endif // ESP32
}
#endif // UNIT_TEST
Expand Down Expand Up @@ -358,21 +367,33 @@ void IRrecv::enableIRIn(const bool pullup) {
}
#if defined(ESP32)
// Initialise the ESP32 timer.
#if defined(_ESP32_ARDUINO_CORE_V3PLUS)
// Use newer timerBegin signature for ESP32 core version 3.x
timer = timerBegin(1000000); // Initialize with 1MHz (1us per tick)
#else // _ESP32_ARDUINO_CORE_V3PLUS
// 80MHz / 80 = 1 uSec granularity.
timer = timerBegin(_timer_num, 80, true);
#endif // _ESP32_ARDUINO_CORE_V3PLUS

// Ensure the timer is successfully initialized
#ifdef DEBUG
if (timer == NULL) {
DPRINT("FATAL: Unable enable system timer: ");
DPRINTLN((uint16_t)_timer_num);
}
#endif // DEBUG
assert(timer != NULL); // Check we actually got the timer.
// Set the timer so it only fires once, and set it's trigger in uSeconds.
// Set the timer so it only fires once, and set its trigger in microseconds.
#if defined(_ESP32_ARDUINO_CORE_V3PLUS)
timerWrite(timer, 0); // Reset the timer for ESP32 core version 3.x
timerAttachInterrupt(timer, &read_timeout);
#else // _ESP32_ARDUINO_CORE_V3PLUS
timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE);
// Note: Interrupt needs to be attached before it can be enabled or disabled.
// Note: EDGE (true) is not supported, use LEVEL (false). Ref: #1713
// See: https://github.com/espressif/arduino-esp32/blob/caef4006af491130136b219c1205bdcf8f08bf2b/cores/esp32/esp32-hal-timer.c#L224-L227
timerAttachInterrupt(timer, &read_timeout, false);
#endif // _ESP32_ARDUINO_CORE_V3PLUS
#endif // ESP32

// Initialise state machine variables
Expand All @@ -396,8 +417,11 @@ void IRrecv::disableIRIn(void) {
#ifndef UNIT_TEST
#if defined(ESP8266)
os_timer_disarm(&timer);
#endif // ESP8266
#if defined(ESP32)
#elif defined(_ESP32_ARDUINO_CORE_V3PLUS)
timerWrite(timer, 0); // Reset the timer
timerDetachInterrupt(timer);
timerEnd(timer);
#elif defined(ESP32)
timerAlarmDisable(timer);
timerDetachInterrupt(timer);
timerEnd(timer);
Expand Down Expand Up @@ -426,7 +450,13 @@ void IRrecv::resume(void) {
params.rawlen = 0;
params.overflow = false;
#if defined(ESP32)
// Check for ESP32 core version and handle timer functions differently
#if defined(_ESP32_ARDUINO_CORE_V3PLUS)
timerWrite(timer, 0); // Reset the timer (no need for timerAlarmDisable)
#else // _ESP32_ARDUINO_CORE_V3PLUS
timerAlarmDisable(timer);
#endif // _ESP32_ARDUINO_CORE_V3PLUS
// Re-enable GPIO interrupt in both versions
gpio_intr_enable((gpio_num_t)params.recvpin);
#endif // ESP32
}
Expand Down
Loading