Skip to content

Commit 564c20f

Browse files
committed
Refactor ESP32 timer handling for core version compatibility
compat with the recent Arduino framework crankyoldgit#2144 Signed-off-by: hldh214 <[email protected]>
1 parent bce5c0b commit 564c20f

File tree

1 file changed

+50
-26
lines changed

1 file changed

+50
-26
lines changed

src/IRrecv.cpp

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,24 @@ static ETSTimer timer;
5656
} // namespace _IRrecv
5757
#endif // ESP8266
5858
#if defined(ESP32)
59+
#if ( defined(ESP_ARDUINO_VERSION) && \
60+
(ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)) )
61+
#define _ESP32_ARDUINO_CORE_V3PLUS
62+
#endif // ESP_ARDUINO_VERSION >= 3
5963
// We need a horrible timer hack for ESP32 Arduino framework < v2.0.0
60-
#if !defined(_ESP32_IRRECV_TIMER_HACK)
64+
#if !defined(_ESP32_ARDUINO_CORE_V2PLUS)
6165
// Version check
6266
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
6367
// No need for the hack if we are running version >= 2.0.0
64-
#define _ESP32_IRRECV_TIMER_HACK false
68+
#define _ESP32_ARDUINO_CORE_V2PLUS false
6569
#else // Version check
6670
// If no ESP_ARDUINO_VERSION_MAJOR is defined, or less than 2, then we are
6771
// using an old ESP32 core, so we need the hack.
68-
#define _ESP32_IRRECV_TIMER_HACK true
72+
#define _ESP32_ARDUINO_CORE_V2PLUS true
6973
#endif // Version check
70-
#endif // !defined(_ESP32_IRRECV_TIMER_HACK)
74+
#endif // !defined(_ESP32_ARDUINO_CORE_V2PLUS)
7175

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

136140
namespace _IRrecv {
137-
static hw_timer_t * timer = NULL;
141+
static hw_timer_t *timer = NULL;
138142
} // namespace _IRrecv
139143
#endif // ESP32
140144
using _IRrecv::timer;
@@ -225,26 +229,31 @@ static void USE_IRAM_ATTR gpio_intr() {
225229
#if defined(ESP32)
226230
// Reset the timeout.
227231
//
228-
#if _ESP32_IRRECV_TIMER_HACK
229-
// The following three lines of code are the equiv of:
232+
#if _ESP32_ARDUINO_CORE_V2PLUS
233+
// The following three lines of code are the equivalent of:
230234
// `timerWrite(timer, 0);`
231235
// We can't call that routine safely from inside an ISR as that procedure
232236
// is not stored in IRAM. Hence, we do it manually so that it's covered by
233237
// USE_IRAM_ATTR in this ISR.
234238
// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1350
235239
// @see https://github.com/espressif/arduino-esp32/blob/6b0114366baf986c155e8173ab7c22bc0c5fcedc/cores/esp32/esp32-hal-timer.c#L106-L110
236-
timer->dev->load_high = (uint32_t) 0;
237-
timer->dev->load_low = (uint32_t) 0;
240+
timer->dev->load_high = static_cast<uint32_t>(0);
241+
timer->dev->load_low = static_cast<uint32_t>(0);
238242
timer->dev->reload = 1;
239243
// The next line is the same, but instead replaces:
240244
// `timerAlarmEnable(timer);`
241245
// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1350
242246
// @see https://github.com/espressif/arduino-esp32/blob/6b0114366baf986c155e8173ab7c22bc0c5fcedc/cores/esp32/esp32-hal-timer.c#L176-L178
243247
timer->dev->config.alarm_en = 1;
244-
#else // _ESP32_IRRECV_TIMER_HACK
248+
#elif defined(_ESP32_ARDUINO_CORE_V3PLUS)
249+
// For ESP32 core version 3.x, replace `timerAlarmEnable`
250+
timerWrite(timer, 0);
251+
uint64_t alarm_value = 50000; // Example value (50ms)
252+
timerAlarm(timer, alarm_value, false, 0);
253+
#else // !_ESP32_ARDUINO_CORE_V3PLUS
245254
timerWrite(timer, 0);
246255
timerAlarmEnable(timer);
247-
#endif // _ESP32_IRRECV_TIMER_HACK
256+
#endif // _ESP32_ARDUINO_CORE_V2PLUS
248257
#endif // ESP32
249258
}
250259
#endif // UNIT_TEST
@@ -358,21 +367,33 @@ void IRrecv::enableIRIn(const bool pullup) {
358367
}
359368
#if defined(ESP32)
360369
// Initialise the ESP32 timer.
370+
#if defined(_ESP32_ARDUINO_CORE_V3PLUS)
371+
// Use newer timerBegin signature for ESP32 core version 3.x
372+
timer = timerBegin(1000000); // Initialize with 1MHz (1us per tick)
373+
#else // _ESP32_ARDUINO_CORE_V3PLUS
361374
// 80MHz / 80 = 1 uSec granularity.
362375
timer = timerBegin(_timer_num, 80, true);
376+
#endif // _ESP32_ARDUINO_CORE_V3PLUS
377+
378+
// Ensure the timer is successfully initialized
363379
#ifdef DEBUG
364380
if (timer == NULL) {
365381
DPRINT("FATAL: Unable enable system timer: ");
366382
DPRINTLN((uint16_t)_timer_num);
367383
}
368384
#endif // DEBUG
369385
assert(timer != NULL); // Check we actually got the timer.
370-
// Set the timer so it only fires once, and set it's trigger in uSeconds.
386+
// Set the timer so it only fires once, and set its trigger in microseconds.
387+
#if defined(_ESP32_ARDUINO_CORE_V3PLUS)
388+
timerWrite(timer, 0); // Reset the timer for ESP32 core version 3.x
389+
timerAttachInterrupt(timer, &read_timeout);
390+
#else // _ESP32_ARDUINO_CORE_V3PLUS
371391
timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE);
372392
// Note: Interrupt needs to be attached before it can be enabled or disabled.
373393
// Note: EDGE (true) is not supported, use LEVEL (false). Ref: #1713
374394
// See: https://github.com/espressif/arduino-esp32/blob/caef4006af491130136b219c1205bdcf8f08bf2b/cores/esp32/esp32-hal-timer.c#L224-L227
375395
timerAttachInterrupt(timer, &read_timeout, false);
396+
#endif // _ESP32_ARDUINO_CORE_V3PLUS
376397
#endif // ESP32
377398

378399
// Initialise state machine variables
@@ -396,8 +417,11 @@ void IRrecv::disableIRIn(void) {
396417
#ifndef UNIT_TEST
397418
#if defined(ESP8266)
398419
os_timer_disarm(&timer);
399-
#endif // ESP8266
400-
#if defined(ESP32)
420+
#elif defined(_ESP32_ARDUINO_CORE_V3PLUS)
421+
timerWrite(timer, 0); // Reset the timer
422+
timerDetachInterrupt(timer);
423+
timerEnd(timer);
424+
#elif defined(ESP32)
401425
timerAlarmDisable(timer);
402426
timerDetachInterrupt(timer);
403427
timerEnd(timer);
@@ -426,7 +450,13 @@ void IRrecv::resume(void) {
426450
params.rawlen = 0;
427451
params.overflow = false;
428452
#if defined(ESP32)
453+
// Check for ESP32 core version and handle timer functions differently
454+
#if defined(_ESP32_ARDUINO_CORE_V3PLUS)
455+
timerWrite(timer, 0); // Reset the timer (no need for timerAlarmDisable)
456+
#else // _ESP32_ARDUINO_CORE_V3PLUS
429457
timerAlarmDisable(timer);
458+
#endif // _ESP32_ARDUINO_CORE_V3PLUS
459+
// Re-enable GPIO interrupt in both versions
430460
gpio_intr_enable((gpio_num_t)params.recvpin);
431461
#endif // ESP32
432462
}
@@ -693,16 +723,6 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
693723
DPRINTLN("Attempting Fujitsu A/C decode");
694724
if (decodeFujitsuAC(results, offset)) return true;
695725
#endif
696-
#if DECODE_FUJITSU_AC264
697-
// FujitsuAC264 should be checked before FujitsuAC
698-
// Fujitsu A/C needs to precede Panasonic and Denon as it has a short
699-
// message which looks exactly the same as a Panasonic/Denon message.
700-
DPRINTLN("Attempting Fujitsu A/C264 decode");
701-
if (decodeFujitsuAC264(results, offset, kFujitsuAc264Bits) ||
702-
decodeFujitsuAC264(results, offset, kFujitsuAc264BitsMiddle) ||
703-
decodeFujitsuAC264(results, offset, kFujitsuAc264BitsShort))
704-
return true;
705-
#endif
706726
#if DECODE_DENON
707727
// Denon needs to precede Panasonic as it is a special case of Panasonic.
708728
DPRINTLN("Attempting Denon decode");
@@ -1195,6 +1215,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
11951215
DPRINTLN("Attempting York decode");
11961216
if (decodeYork(results, offset, kYorkBits)) return true;
11971217
#endif // DECODE_YORK
1218+
#if DECODE_BLUESTARHEAVY
1219+
DPRINTLN("Attempting BluestarHeavy decode");
1220+
if (decodeBluestarHeavy(results, offset, kBluestarHeavyBits)) return true;
1221+
#endif // DECODE_BLUESTARHEAVY
11981222
// Typically new protocols are added above this line.
11991223
}
12001224
#if DECODE_HASH

0 commit comments

Comments
 (0)