@@ -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;
@@ -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