@@ -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
136140namespace _IRrecv {
137- static hw_timer_t * timer = NULL ;
141+ static hw_timer_t *timer = NULL ;
138142} // namespace _IRrecv
139143#endif // ESP32
140144using _IRrecv::timer;
@@ -215,7 +219,7 @@ static void USE_IRAM_ATTR gpio_intr() {
215219 else
216220 params.rawbuf [rawlen] = (now - start) / kRawTick ;
217221 }
218- params.rawlen ++;
222+ params.rawlen = params. rawlen + 1 ; // C++20 fix
219223
220224 start = now;
221225
@@ -225,8 +229,8 @@ 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
@@ -241,10 +245,15 @@ static void USE_IRAM_ATTR gpio_intr() {
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
@@ -366,21 +375,33 @@ void IRrecv::enableIRIn(const bool pullup) {
366375 }
367376#if defined(ESP32)
368377 // Initialise the ESP32 timer.
378+ #if defined(_ESP32_ARDUINO_CORE_V3PLUS)
379+ // Use newer timerBegin signature for ESP32 core version 3.x
380+ timer = timerBegin (1000000 ); // Initialize with 1MHz (1us per tick)
381+ #else // _ESP32_ARDUINO_CORE_V3PLUS
369382 // 80MHz / 80 = 1 uSec granularity.
370383 timer = timerBegin (_timer_num, 80 , true );
384+ #endif // _ESP32_ARDUINO_CORE_V3PLUS
385+
386+ // Ensure the timer is successfully initialized
371387#ifdef IR_DEBUG
372388 if (timer == NULL ) {
373389 DPRINT (" FATAL: Unable enable system timer: " );
374390 DPRINTLN ((uint16_t )_timer_num);
375391 }
376392#endif // IR_DEBUG
377393 assert (timer != NULL ); // Check we actually got the timer.
378- // Set the timer so it only fires once, and set it's trigger in uSeconds.
394+ // Set the timer so it only fires once, and set its trigger in microseconds.
395+ #if defined(_ESP32_ARDUINO_CORE_V3PLUS)
396+ timerWrite (timer, 0 ); // Reset the timer for ESP32 core version 3.x
397+ timerAttachInterrupt (timer, &read_timeout);
398+ #else // _ESP32_ARDUINO_CORE_V3PLUS
379399 timerAlarmWrite (timer, MS_TO_USEC (params.timeout ), ONCE);
380400 // Note: Interrupt needs to be attached before it can be enabled or disabled.
381401 // Note: EDGE (true) is not supported, use LEVEL (false). Ref: #1713
382402 // See: https://github.com/espressif/arduino-esp32/blob/caef4006af491130136b219c1205bdcf8f08bf2b/cores/esp32/esp32-hal-timer.c#L224-L227
383403 timerAttachInterrupt (timer, &read_timeout, false );
404+ #endif // _ESP32_ARDUINO_CORE_V3PLUS
384405#endif // ESP32
385406
386407 // Initialise state machine variables
@@ -404,8 +425,11 @@ void IRrecv::disableIRIn(void) {
404425#ifndef UNIT_TEST
405426#if defined(ESP8266)
406427 os_timer_disarm (&timer);
407- #endif // ESP8266
408- #if defined(ESP32)
428+ #elif defined(_ESP32_ARDUINO_CORE_V3PLUS)
429+ timerWrite (timer, 0 ); // Reset the timer
430+ timerDetachInterrupt (timer);
431+ timerEnd (timer);
432+ #elif defined(ESP32)
409433 timerAlarmDisable (timer);
410434 timerDetachInterrupt (timer);
411435 timerEnd (timer);
@@ -434,7 +458,13 @@ void IRrecv::resume(void) {
434458 params.rawlen = 0 ;
435459 params.overflow = false ;
436460#if defined(ESP32)
461+ // Check for ESP32 core version and handle timer functions differently
462+ #if defined(_ESP32_ARDUINO_CORE_V3PLUS)
463+ timerWrite (timer, 0 ); // Reset the timer (no need for timerAlarmDisable)
464+ #else // _ESP32_ARDUINO_CORE_V3PLUS
437465 timerAlarmDisable (timer);
466+ #endif // _ESP32_ARDUINO_CORE_V3PLUS
467+ // Re-enable GPIO interrupt in both versions
438468 gpio_intr_enable ((gpio_num_t )params.recvpin );
439469#endif // ESP32
440470}
@@ -510,8 +540,8 @@ void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) {
510540 for (uint16_t i = offset + 2 ; i <= results->rawlen && i < kBufSize ; i++)
511541 results->rawbuf [i - 2 ] = results->rawbuf [i];
512542 if (offset > 1 ) { // There is a previous pair we can add to.
513- // Merge this pair into into the previous space.
514- results->rawbuf [offset - 1 ] += addition;
543+ // Merge this pair into into the previous space. // C++20 fix applied
544+ results->rawbuf [offset - 1 ] = results-> rawbuf [offset - 1 ] + addition;
515545 }
516546 results->rawlen -= 2 ; // Adjust the length.
517547 } else {
0 commit comments