From 9cfcebc3a6a8d913d3b15ceea10e7e3ef4a798b5 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 6 Oct 2023 21:56:43 +0200 Subject: [PATCH 01/14] [Build] Add compatibility with C++20 --- examples/IRMQTTServer/IRMQTTServer.ino | 4 ++ src/IRrecv.cpp | 76 +++++++++++++++++++++---- src/IRrecv.h | 79 ++++++++++++++++++++++---- src/IRremoteESP8266.h | 3 + src/IRutils.cpp | 4 ++ test/IRrecv_test.cpp | 4 ++ 6 files changed, 150 insertions(+), 20 deletions(-) diff --git a/examples/IRMQTTServer/IRMQTTServer.ino b/examples/IRMQTTServer/IRMQTTServer.ino index 35a528107..78045c50a 100644 --- a/examples/IRMQTTServer/IRMQTTServer.ino +++ b/examples/IRMQTTServer/IRMQTTServer.ino @@ -443,7 +443,11 @@ char Hostname[kHostnameLength + 1] = "ir_server"; // Default hostname. uint16_t *codeArray; uint32_t lastReconnectAttempt = 0; // MQTT last attempt reconnection number bool boot = true; +#if __cplusplus >= 202002L +atomic lockIr = false; // Primitive locking for gating the IR LED. +#else volatile bool lockIr = false; // Primitive locking for gating the IR LED. +#endif uint32_t sendReqCounter = 0; bool lastSendSucceeded = false; // Store the success status of the last send. uint32_t lastSendTime = 0; diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 173526104..544da42c5 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -144,7 +144,11 @@ namespace _IRrecv { // Namespace extension #if defined(ESP32) portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; #endif // ESP32 +#if __cplusplus >= 202002L +atomic params; +#else volatile irparams_t params; +#endif irparams_t *params_save; // A copy of the interrupt state while decoding. } // namespace _IRrecv @@ -437,7 +441,13 @@ void IRrecv::resume(void) { /// i.e. In kStopState. /// @param[in] src Pointer to an irparams_t structure to copy from. /// @param[out] dst Pointer to an irparams_t structure to copy to. -void IRrecv::copyIrParams(volatile irparams_t *src, irparams_t *dst) { +void IRrecv::copyIrParams( + #if __cplusplus >= 202002L + atomic *src + #else + volatile irparams_t *src + #endif + , irparams_t *dst) { // Typecast src and dst addresses to (char *) char *csrc = (char *)src; // NOLINT(readability/casting) char *cdst = (char *)dst; // NOLINT(readability/casting) @@ -1449,7 +1459,12 @@ bool IRrecv::decodeHash(decode_results *results) { /// @return A match_result_t structure containing the success (or not), the /// data value, and how many buffer entries were used. match_result_t IRrecv::matchData( - volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, + #if __cplusplus >= 202002L + atomic *data_ptr + #else + volatile uint16_t *data_ptr + #endif + , const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance, const int16_t excess, const bool MSBfirst, const bool expectlastspace) { @@ -1509,7 +1524,13 @@ match_result_t IRrecv::matchData( /// true is Most Significant Bit First Order, false is Least Significant First /// @param[in] expectlastspace Do we expect a space at the end of the message? /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, +uint16_t IRrecv::matchBytes( + #if __cplusplus >= 202002L + atomic *data_ptr + #else + volatile uint16_t *data_ptr + #endif + , uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -1561,7 +1582,12 @@ uint16_t IRrecv::matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, /// @param[in] MSBfirst Bit order to save the data in. (Def: true) /// true is Most Significant Bit First Order, false is Least Significant First /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr, +uint16_t IRrecv::_matchGeneric( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint64_t *result_bits_ptr, uint8_t *result_bytes_ptr, const bool use_bits, @@ -1663,7 +1689,12 @@ uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr, /// @param[in] MSBfirst Bit order to save the data in. (Def: true) /// true is Most Significant Bit First Order, false is Least Significant First /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, +uint16_t IRrecv::matchGeneric( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1710,7 +1741,12 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, /// @param[in] MSBfirst Bit order to save the data in. (Def: true) /// true is Most Significant Bit First Order, false is Least Significant First /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, +uint16_t IRrecv::matchGeneric( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1757,7 +1793,12 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, /// @return If successful, how many buffer entries were used. Otherwise 0. /// @note Parameters one + zero add up to the total time for a bit. /// e.g. mark(one) + space(zero) is a `1`, mark(zero) + space(one) is a `0`. -uint16_t IRrecv::matchGenericConstBitTime(volatile uint16_t *data_ptr, +uint16_t IRrecv::matchGenericConstBitTime( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1844,7 +1885,12 @@ uint16_t IRrecv::matchGenericConstBitTime(volatile uint16_t *data_ptr, /// @return If successful, how many buffer entries were used. Otherwise 0. /// @see https://en.wikipedia.org/wiki/Manchester_code /// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf -uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, +uint16_t IRrecv::matchManchester( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile const uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1951,7 +1997,12 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, /// @see https://en.wikipedia.org/wiki/Manchester_code /// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf /// @todo Clean up and optimise this. It is just "get it working code" atm. -uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr, +uint16_t IRrecv::matchManchesterData( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile const uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -2072,7 +2123,12 @@ uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr, #if UNIT_TEST /// Unit test helper to get access to the params structure. -volatile irparams_t *IRrecv::_getParamsPtr(void) { +#if __cplusplus >= 202002L +atomic +#else +volatile irparams_t +#endif + *IRrecv::_getParamsPtr(void) { return ¶ms; } #endif // UNIT_TEST diff --git a/src/IRrecv.h b/src/IRrecv.h index 7adf5eb1b..87c8cefd6 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -111,7 +111,11 @@ class decode_results { uint8_t state[kStateSizeMax]; // Multi-byte results. }; uint16_t bits; // Number of bits in decoded value + #if __cplusplus >= 202002L + atomic *rawbuf; // Raw intervals in .5 us ticks + #else volatile uint16_t *rawbuf; // Raw intervals in .5 us ticks + #endif uint16_t rawlen; // Number of records in rawbuf. bool overflow; bool repeat; // Is the result a repeat code? @@ -171,11 +175,23 @@ class IRrecv { uint16_t _unknown_threshold; #endif #ifdef UNIT_TEST - volatile irparams_t *_getParamsPtr(void); + #if __cplusplus >= 202002L + atomic + #else + volatile irparams_t + #endif + *_getParamsPtr(void); #endif // UNIT_TEST // These are called by decode uint8_t _validTolerance(const uint8_t percentage); - void copyIrParams(volatile irparams_t *src, irparams_t *dst); + void copyIrParams( + #if __cplusplus >= 202002L + atomic + #else + volatile irparams_t + #endif + *src, + irparams_t *dst); uint16_t compare(const uint16_t oldval, const uint16_t newval); uint32_t ticksLow(const uint32_t usecs, const uint8_t tolerance = kUseDefTol, @@ -186,7 +202,12 @@ class IRrecv { bool matchAtLeast(const uint32_t measured, const uint32_t desired, const uint8_t tolerance = kUseDefTol, const uint16_t delta = 0); - uint16_t _matchGeneric(volatile uint16_t *data_ptr, + uint16_t _matchGeneric( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, @@ -204,14 +225,26 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - match_result_t matchData(volatile uint16_t *data_ptr, const uint16_t nbits, + match_result_t matchData( + #if __cplusplus >= 202002L + atomic *data_ptr + #else + volatile uint16_t *data_ptr + #endif + , const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true, const bool expectlastspace = true); - uint16_t matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, + uint16_t matchBytes( + #if __cplusplus >= 202002L + atomic *data_ptr + #else + volatile uint16_t *data_ptr + #endif + , uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -219,7 +252,12 @@ class IRrecv { const int16_t excess = kMarkExcess, const bool MSBfirst = true, const bool expectlastspace = true); - uint16_t matchGeneric(volatile uint16_t *data_ptr, + uint16_t matchGeneric( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, @@ -230,7 +268,13 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - uint16_t matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, + uint16_t matchGeneric( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif + uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, @@ -241,7 +285,12 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr, + uint16_t matchGenericConstBitTime( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -255,7 +304,12 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - uint16_t matchManchesterData(volatile const uint16_t *data_ptr, + uint16_t matchManchesterData( + #if __cplusplus >= 202002L + atomic *data_ptr, + #else + volatile const uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -265,7 +319,12 @@ class IRrecv { const int16_t excess = kMarkExcess, const bool MSBfirst = true, const bool GEThomas = true); - uint16_t matchManchester(volatile const uint16_t *data_ptr, + uint16_t matchManchester( + #if __cplusplus >= 202002L + atomic uint16_t *data_ptr, + #else + volatile const uint16_t *data_ptr, + #endif uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 949de1ecf..33e71af2c 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -51,6 +51,9 @@ #include #include #endif // UNIT_TEST +#if __cplusplus >= 202002L +#include +#endif // Library Version Information // Major version number (X.x.x) diff --git a/src/IRutils.cpp b/src/IRutils.cpp index e9af0b28f..05dd55d03 100644 --- a/src/IRutils.cpp +++ b/src/IRutils.cpp @@ -1397,7 +1397,11 @@ namespace irutils { /// issue has been found. uint8_t lowLevelSanityCheck(void) { const uint64_t kExpectedBitFieldResult = 0x8000012340000039ULL; + #if __cplusplus >= 202002L + atomic EndianTest = 0x12345678; + #else volatile uint32_t EndianTest = 0x12345678; + #endif const uint8_t kBitFieldError = 0b01; const uint8_t kEndiannessError = 0b10; uint8_t result = 0; diff --git a/test/IRrecv_test.cpp b/test/IRrecv_test.cpp index 2d32847d3..2470d3f31 100644 --- a/test/IRrecv_test.cpp +++ b/test/IRrecv_test.cpp @@ -48,7 +48,11 @@ TEST(TestIRrecv, DecodeHeapOverflow) { IRrecv irrecv(1); irrecv.enableIRIn(); ASSERT_EQ(kRawBuf, irrecv.getBufSize()); + #if __cplusplus >= 202002L + atomic *params_ptr = irrecv._getParamsPtr(); + #else volatile irparams_t *params_ptr = irrecv._getParamsPtr(); + #endif // replace the buffer with a slightly bigger one to see if we go past the end // accidentally. params_ptr->rawbuf = new uint16_t[kRawBuf + 10]; From c763e13d09f9d670f183932cb827c1599bdd1f1a Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 13:22:18 +0200 Subject: [PATCH 02/14] [Build] ESP32 builds both IDF 4.x and IDF 5.x --- platformio.ini | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 76c2f3b40..34470ab31 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,5 +18,10 @@ board = nodemcuv2 board = d1_mini [env:esp32dev] -platform = espressif32 +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.09.01/platform-espressif32.zip +board = esp32dev + +# Experimental IDF 5.x support +[env:esp32devIDF5x] +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip board = esp32dev From f24076a594bc6f2da540a8381d212ad32ccd4163 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 13:23:57 +0200 Subject: [PATCH 03/14] [Build] C++20 Use typedefs to switch compilation (volatile vs atomic where needed) --- examples/IRMQTTServer/IRMQTTServer.ino | 6 +- src/IRrecv.cpp | 102 +++++++++---------------- src/IRrecv.h | 86 +++++---------------- src/IRremoteESP8266.h | 9 +++ src/IRutils.cpp | 6 +- test/IRrecv_test.cpp | 6 +- 6 files changed, 63 insertions(+), 152 deletions(-) diff --git a/examples/IRMQTTServer/IRMQTTServer.ino b/examples/IRMQTTServer/IRMQTTServer.ino index 78045c50a..e6ca7f493 100644 --- a/examples/IRMQTTServer/IRMQTTServer.ino +++ b/examples/IRMQTTServer/IRMQTTServer.ino @@ -443,11 +443,7 @@ char Hostname[kHostnameLength + 1] = "ir_server"; // Default hostname. uint16_t *codeArray; uint32_t lastReconnectAttempt = 0; // MQTT last attempt reconnection number bool boot = true; -#if __cplusplus >= 202002L -atomic lockIr = false; // Primitive locking for gating the IR LED. -#else -volatile bool lockIr = false; // Primitive locking for gating the IR LED. -#endif +atomic_bool lockIr = false; // Primitive locking for gating the IR LED. uint32_t sendReqCounter = 0; bool lastSendSucceeded = false; // Store the success status of the last send. uint32_t lastSendTime = 0; diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 544da42c5..d96af8a6f 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -144,11 +144,7 @@ namespace _IRrecv { // Namespace extension #if defined(ESP32) portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; #endif // ESP32 -#if __cplusplus >= 202002L -atomic params; -#else -volatile irparams_t params; -#endif +atomic_irparams_t params; irparams_t *params_save; // A copy of the interrupt state while decoding. } // namespace _IRrecv @@ -246,8 +242,13 @@ static void USE_IRAM_ATTR gpio_intr() { // @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 +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); + timerAttachInterrupt(timer, &read_timeout); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerWrite(timer, 0); timerAlarmEnable(timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // _ESP32_IRRECV_TIMER_HACK #endif // ESP32 } @@ -363,7 +364,11 @@ void IRrecv::enableIRIn(const bool pullup) { #if defined(ESP32) // Initialise the ESP32 timer. // 80MHz / 80 = 1 uSec granularity. +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timer = timerBegin(80); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timer = timerBegin(_timer_num, 80, true); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #ifdef DEBUG if (timer == NULL) { DPRINT("FATAL: Unable enable system timer: "); @@ -371,12 +376,17 @@ void IRrecv::enableIRIn(const bool pullup) { } #endif // DEBUG assert(timer != NULL); // Check we actually got the timer. +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); + timerAttachInterrupt(timer, &read_timeout); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 // Set the timer so it only fires once, and set it's trigger in uSeconds. 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 // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 // Initialise state machine variables @@ -402,9 +412,13 @@ void IRrecv::disableIRIn(void) { os_timer_disarm(&timer); #endif // ESP8266 #if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerEnd(timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); timerDetachInterrupt(timer); timerEnd(timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 detachInterrupt(params.recvpin); #endif // UNIT_TEST @@ -430,7 +444,11 @@ void IRrecv::resume(void) { params.rawlen = 0; params.overflow = false; #if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerEnd(timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_enable((gpio_num_t)params.recvpin); #endif // ESP32 } @@ -441,13 +459,7 @@ void IRrecv::resume(void) { /// i.e. In kStopState. /// @param[in] src Pointer to an irparams_t structure to copy from. /// @param[out] dst Pointer to an irparams_t structure to copy to. -void IRrecv::copyIrParams( - #if __cplusplus >= 202002L - atomic *src - #else - volatile irparams_t *src - #endif - , irparams_t *dst) { +void IRrecv::copyIrParams(atomic_irparams_t *src, irparams_t *dst) { // Typecast src and dst addresses to (char *) char *csrc = (char *)src; // NOLINT(readability/casting) char *cdst = (char *)dst; // NOLINT(readability/casting) @@ -513,7 +525,7 @@ void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) { results->rawbuf[i - 2] = results->rawbuf[i]; if (offset > 1) { // There is a previous pair we can add to. // Merge this pair into into the previous space. - results->rawbuf[offset - 1] += addition; + results->rawbuf[offset - 1] = results->rawbuf[offset - 1] + addition; } results->rawlen -= 2; // Adjust the length. } else { @@ -1459,12 +1471,7 @@ bool IRrecv::decodeHash(decode_results *results) { /// @return A match_result_t structure containing the success (or not), the /// data value, and how many buffer entries were used. match_result_t IRrecv::matchData( - #if __cplusplus >= 202002L - atomic *data_ptr - #else - volatile uint16_t *data_ptr - #endif - , const uint16_t nbits, const uint16_t onemark, + atomic_uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance, const int16_t excess, const bool MSBfirst, const bool expectlastspace) { @@ -1524,13 +1531,7 @@ match_result_t IRrecv::matchData( /// true is Most Significant Bit First Order, false is Least Significant First /// @param[in] expectlastspace Do we expect a space at the end of the message? /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::matchBytes( - #if __cplusplus >= 202002L - atomic *data_ptr - #else - volatile uint16_t *data_ptr - #endif - , uint8_t *result_ptr, +uint16_t IRrecv::matchBytes(atomic_uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -1582,12 +1583,7 @@ uint16_t IRrecv::matchBytes( /// @param[in] MSBfirst Bit order to save the data in. (Def: true) /// true is Most Significant Bit First Order, false is Least Significant First /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::_matchGeneric( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif +uint16_t IRrecv::_matchGeneric(atomic_uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_bytes_ptr, const bool use_bits, @@ -1689,12 +1685,7 @@ uint16_t IRrecv::_matchGeneric( /// @param[in] MSBfirst Bit order to save the data in. (Def: true) /// true is Most Significant Bit First Order, false is Least Significant First /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::matchGeneric( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif +uint16_t IRrecv::matchGeneric(atomic_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1741,12 +1732,7 @@ uint16_t IRrecv::matchGeneric( /// @param[in] MSBfirst Bit order to save the data in. (Def: true) /// true is Most Significant Bit First Order, false is Least Significant First /// @return If successful, how many buffer entries were used. Otherwise 0. -uint16_t IRrecv::matchGeneric( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif +uint16_t IRrecv::matchGeneric(atomic_uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1793,12 +1779,7 @@ uint16_t IRrecv::matchGeneric( /// @return If successful, how many buffer entries were used. Otherwise 0. /// @note Parameters one + zero add up to the total time for a bit. /// e.g. mark(one) + space(zero) is a `1`, mark(zero) + space(one) is a `0`. -uint16_t IRrecv::matchGenericConstBitTime( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif +uint16_t IRrecv::matchGenericConstBitTime(atomic_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1885,12 +1866,7 @@ uint16_t IRrecv::matchGenericConstBitTime( /// @return If successful, how many buffer entries were used. Otherwise 0. /// @see https://en.wikipedia.org/wiki/Manchester_code /// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf -uint16_t IRrecv::matchManchester( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile const uint16_t *data_ptr, - #endif +uint16_t IRrecv::matchManchester(atomic_const_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -1997,12 +1973,7 @@ uint16_t IRrecv::matchManchester( /// @see https://en.wikipedia.org/wiki/Manchester_code /// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf /// @todo Clean up and optimise this. It is just "get it working code" atm. -uint16_t IRrecv::matchManchesterData( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile const uint16_t *data_ptr, - #endif +uint16_t IRrecv::matchManchesterData(atomic_const_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -2123,12 +2094,7 @@ uint16_t IRrecv::matchManchesterData( #if UNIT_TEST /// Unit test helper to get access to the params structure. -#if __cplusplus >= 202002L -atomic -#else -volatile irparams_t -#endif - *IRrecv::_getParamsPtr(void) { +atomic_irparams_t *IRrecv::_getParamsPtr(void) { return ¶ms; } #endif // UNIT_TEST diff --git a/src/IRrecv.h b/src/IRrecv.h index 87c8cefd6..e681b91f0 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -86,6 +86,12 @@ typedef struct { uint8_t timeout; // Nr. of milliSeconds before we give up. } irparams_t; +#if __cplusplus >= 202002L +typedef volatile irparams_t atomic_irparams_t; +#else +typedef volatile irparams_t atomic_irparams_t; +#endif + /// Results from a data match typedef struct { bool success; // Was the match successful? @@ -111,11 +117,7 @@ class decode_results { uint8_t state[kStateSizeMax]; // Multi-byte results. }; uint16_t bits; // Number of bits in decoded value - #if __cplusplus >= 202002L - atomic *rawbuf; // Raw intervals in .5 us ticks - #else - volatile uint16_t *rawbuf; // Raw intervals in .5 us ticks - #endif + atomic_uint16_t *rawbuf; // Raw intervals in .5 us ticks uint16_t rawlen; // Number of records in rawbuf. bool overflow; bool repeat; // Is the result a repeat code? @@ -175,23 +177,11 @@ class IRrecv { uint16_t _unknown_threshold; #endif #ifdef UNIT_TEST - #if __cplusplus >= 202002L - atomic - #else - volatile irparams_t - #endif - *_getParamsPtr(void); + atomic_irparams_t *_getParamsPtr(void); #endif // UNIT_TEST // These are called by decode uint8_t _validTolerance(const uint8_t percentage); - void copyIrParams( - #if __cplusplus >= 202002L - atomic - #else - volatile irparams_t - #endif - *src, - irparams_t *dst); + void copyIrParams(atomic_irparams_t *src, irparams_t *dst); uint16_t compare(const uint16_t oldval, const uint16_t newval); uint32_t ticksLow(const uint32_t usecs, const uint8_t tolerance = kUseDefTol, @@ -202,12 +192,7 @@ class IRrecv { bool matchAtLeast(const uint32_t measured, const uint32_t desired, const uint8_t tolerance = kUseDefTol, const uint16_t delta = 0); - uint16_t _matchGeneric( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif + uint16_t _matchGeneric(atomic_uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, @@ -225,26 +210,14 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - match_result_t matchData( - #if __cplusplus >= 202002L - atomic *data_ptr - #else - volatile uint16_t *data_ptr - #endif - , const uint16_t nbits, + match_result_t matchData(atomic_uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true, const bool expectlastspace = true); - uint16_t matchBytes( - #if __cplusplus >= 202002L - atomic *data_ptr - #else - volatile uint16_t *data_ptr - #endif - , uint8_t *result_ptr, + uint16_t matchBytes(atomic_uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -252,12 +225,7 @@ class IRrecv { const int16_t excess = kMarkExcess, const bool MSBfirst = true, const bool expectlastspace = true); - uint16_t matchGeneric( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif + uint16_t matchGeneric(atomic_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, @@ -268,12 +236,7 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - uint16_t matchGeneric( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif + uint16_t matchGeneric(atomic_uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, @@ -285,12 +248,7 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - uint16_t matchGenericConstBitTime( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile uint16_t *data_ptr, - #endif + uint16_t matchGenericConstBitTime(atomic_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -304,12 +262,7 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); - uint16_t matchManchesterData( - #if __cplusplus >= 202002L - atomic *data_ptr, - #else - volatile const uint16_t *data_ptr, - #endif + uint16_t matchManchesterData(atomic_const_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, @@ -319,12 +272,7 @@ class IRrecv { const int16_t excess = kMarkExcess, const bool MSBfirst = true, const bool GEThomas = true); - uint16_t matchManchester( - #if __cplusplus >= 202002L - atomic uint16_t *data_ptr, - #else - volatile const uint16_t *data_ptr, - #endif + uint16_t matchManchester(atomic_const_uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 33e71af2c..6698a0731 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -53,6 +53,15 @@ #endif // UNIT_TEST #if __cplusplus >= 202002L #include +typedef std::atomic< bool > atomic_bool; +typedef volatile uint16_t atomic_uint16_t; +typedef volatile const uint16_t atomic_const_uint16_t; +typedef volatile uint32_t atomic_uint32_t; +#else +typedef volatile bool atomic_bool; +typedef volatile uint16_t atomic_uint16_t; +typedef volatile const uint16_t atomic_const_uint16_t; +typedef volatile uint32_t atomic_uint32_t; #endif // Library Version Information diff --git a/src/IRutils.cpp b/src/IRutils.cpp index 05dd55d03..e096f88c5 100644 --- a/src/IRutils.cpp +++ b/src/IRutils.cpp @@ -1397,11 +1397,7 @@ namespace irutils { /// issue has been found. uint8_t lowLevelSanityCheck(void) { const uint64_t kExpectedBitFieldResult = 0x8000012340000039ULL; - #if __cplusplus >= 202002L - atomic EndianTest = 0x12345678; - #else - volatile uint32_t EndianTest = 0x12345678; - #endif + atomic_uint32_t EndianTest = 0x12345678; const uint8_t kBitFieldError = 0b01; const uint8_t kEndiannessError = 0b10; uint8_t result = 0; diff --git a/test/IRrecv_test.cpp b/test/IRrecv_test.cpp index 2470d3f31..25a8e4e0a 100644 --- a/test/IRrecv_test.cpp +++ b/test/IRrecv_test.cpp @@ -48,11 +48,7 @@ TEST(TestIRrecv, DecodeHeapOverflow) { IRrecv irrecv(1); irrecv.enableIRIn(); ASSERT_EQ(kRawBuf, irrecv.getBufSize()); - #if __cplusplus >= 202002L - atomic *params_ptr = irrecv._getParamsPtr(); - #else - volatile irparams_t *params_ptr = irrecv._getParamsPtr(); - #endif + atomic_irparams_t *params_ptr = irrecv._getParamsPtr(); // replace the buffer with a slightly bigger one to see if we go past the end // accidentally. params_ptr->rawbuf = new uint16_t[kRawBuf + 10]; From 02740c258d7d15d04c65529378e3e36b7307875a Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 13:30:51 +0200 Subject: [PATCH 04/14] [Linter] Fix complaint about spaces :-| --- src/IRrecv.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index d96af8a6f..c56105e99 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -379,7 +379,7 @@ void IRrecv::enableIRIn(const bool pullup) { #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); timerAttachInterrupt(timer, &read_timeout); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 // Set the timer so it only fires once, and set it's trigger in uSeconds. timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE); // Note: Interrupt needs to be attached before it can be enabled or disabled. @@ -414,11 +414,11 @@ void IRrecv::disableIRIn(void) { #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerEnd(timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); timerDetachInterrupt(timer); timerEnd(timer); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 detachInterrupt(params.recvpin); #endif // UNIT_TEST @@ -446,9 +446,9 @@ void IRrecv::resume(void) { #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerEnd(timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_enable((gpio_num_t)params.recvpin); #endif // ESP32 } From f4234172690c1878a7bca3e4293f2f1c437ac369 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 13:44:45 +0200 Subject: [PATCH 05/14] [Linter] Fix more complaints about spaces :-| --- src/IRrecv.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index c56105e99..5908416c2 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -245,7 +245,7 @@ static void USE_IRAM_ATTR gpio_intr() { #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); timerAttachInterrupt(timer, &read_timeout); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerWrite(timer, 0); timerAlarmEnable(timer); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 @@ -366,7 +366,7 @@ void IRrecv::enableIRIn(const bool pullup) { // 80MHz / 80 = 1 uSec granularity. #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timer = timerBegin(80); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timer = timerBegin(_timer_num, 80, true); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #ifdef DEBUG @@ -379,7 +379,7 @@ void IRrecv::enableIRIn(const bool pullup) { #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); timerAttachInterrupt(timer, &read_timeout); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 // Set the timer so it only fires once, and set it's trigger in uSeconds. timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE); // Note: Interrupt needs to be attached before it can be enabled or disabled. @@ -414,7 +414,7 @@ void IRrecv::disableIRIn(void) { #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerEnd(timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); timerDetachInterrupt(timer); timerEnd(timer); @@ -446,7 +446,7 @@ void IRrecv::resume(void) { #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerEnd(timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_enable((gpio_num_t)params.recvpin); From dda8b06f1aa9e28bcb554dac1b15752b6f4b5aa1 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 15:24:24 +0200 Subject: [PATCH 06/14] [Build] esp32dev build restore standard espressif32 platform --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 34470ab31..1c2a4f1cd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,10 +18,10 @@ board = nodemcuv2 board = d1_mini [env:esp32dev] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.09.01/platform-espressif32.zip +platform = espressif32 @ ^6.4.0 board = esp32dev # Experimental IDF 5.x support [env:esp32devIDF5x] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.10/platform-espressif32.zip board = esp32dev From 1eeac0a5f3e7c72a7577b9f5406760cbc9cd4672 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 15:25:56 +0200 Subject: [PATCH 07/14] [Build] C++20 Adjust typedefs and code to avoid deprecation warnings --- src/IRrecv.cpp | 2 +- src/IRremoteESP8266.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 5908416c2..82b474dc1 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -215,7 +215,7 @@ static void USE_IRAM_ATTR gpio_intr() { else params.rawbuf[rawlen] = (now - start) / kRawTick; } - params.rawlen++; + params.rawlen = params.rawlen + 1; // C++20 fix start = now; diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 6698a0731..6d5497b05 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -56,7 +56,7 @@ typedef std::atomic< bool > atomic_bool; typedef volatile uint16_t atomic_uint16_t; typedef volatile const uint16_t atomic_const_uint16_t; -typedef volatile uint32_t atomic_uint32_t; +typedef std::atomic atomic_uint32_t; #else typedef volatile bool atomic_bool; typedef volatile uint16_t atomic_uint16_t; From 591a589eda5159d1fffd8a5be8fc557f5a728d5a Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 16:10:17 +0200 Subject: [PATCH 08/14] [Build] esp32devIDF5x build restore Arduino 2.0.14 platform --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 1c2a4f1cd..6cc589c9a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -23,5 +23,5 @@ board = esp32dev # Experimental IDF 5.x support [env:esp32devIDF5x] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.10/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip board = esp32dev From c00fc860a46a0e5c88c17bb7379fe64b9c770f71 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 17:02:10 +0200 Subject: [PATCH 09/14] [Build] esp32devIDF5x build enable Arduino 3.0.0 alpha1 platform by switching interrupts off/on instead of (missing) low-level IDF calls --- platformio.ini | 2 +- src/IRrecv.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 6cc589c9a..1c2a4f1cd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -23,5 +23,5 @@ board = esp32dev # Experimental IDF 5.x support [env:esp32devIDF5x] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.10/platform-espressif32.zip board = esp32dev diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 82b474dc1..d34f77a31 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -431,7 +431,11 @@ void IRrecv::pause(void) { params.rawlen = 0; params.overflow = false; #if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + noInterrupts(); // Bluntly switch off (and on), not sure if we really want this... +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_disable((gpio_num_t)params.recvpin); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 } @@ -446,10 +450,11 @@ void IRrecv::resume(void) { #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerEnd(timer); + interrupts(); // Back on #else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_enable((gpio_num_t)params.recvpin); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 } From 9301ff05e4a9f9eb07ade982b5fcc557822a2bdd Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 17:36:23 +0200 Subject: [PATCH 10/14] [Build] Remove unneeded duplicate typedefs --- src/IRrecv.h | 4 ---- src/IRremoteESP8266.h | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/IRrecv.h b/src/IRrecv.h index e681b91f0..c777758cc 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -86,11 +86,7 @@ typedef struct { uint8_t timeout; // Nr. of milliSeconds before we give up. } irparams_t; -#if __cplusplus >= 202002L typedef volatile irparams_t atomic_irparams_t; -#else -typedef volatile irparams_t atomic_irparams_t; -#endif /// Results from a data match typedef struct { diff --git a/src/IRremoteESP8266.h b/src/IRremoteESP8266.h index 6d5497b05..b1140f259 100644 --- a/src/IRremoteESP8266.h +++ b/src/IRremoteESP8266.h @@ -54,15 +54,13 @@ #if __cplusplus >= 202002L #include typedef std::atomic< bool > atomic_bool; -typedef volatile uint16_t atomic_uint16_t; -typedef volatile const uint16_t atomic_const_uint16_t; typedef std::atomic atomic_uint32_t; #else typedef volatile bool atomic_bool; -typedef volatile uint16_t atomic_uint16_t; -typedef volatile const uint16_t atomic_const_uint16_t; typedef volatile uint32_t atomic_uint32_t; #endif +typedef volatile uint16_t atomic_uint16_t; +typedef volatile const uint16_t atomic_const_uint16_t; // Library Version Information // Major version number (X.x.x) From 79fff9656515b25bd0cd7255f0b7af510cdb1027 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 17:37:56 +0200 Subject: [PATCH 11/14] [Linter] Fix complaint about comment line-length :-| --- src/IRrecv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index d34f77a31..7d70250c1 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -432,7 +432,7 @@ void IRrecv::pause(void) { params.overflow = false; #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - noInterrupts(); // Bluntly switch off (and on), not sure if we really want this... + noInterrupts(); // Bluntly switch off, not sure if we really want this... #else // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_disable((gpio_num_t)params.recvpin); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 From e11d2a8b3a89f9beecbabf7498bd6d7780968c4e Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 7 Oct 2023 17:47:10 +0200 Subject: [PATCH 12/14] [Build] Add correct include to get `gpio_intr_enable` and `gpio_intr_disable`, thnx Jason2866! --- src/IRrecv.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 7d70250c1..7cba44091 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -21,6 +21,12 @@ extern "C" { #include "IRremoteESP8266.h" #include "IRutils.h" +#if defined(ESP32) +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) +#include +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 +#endif + #ifdef UNIT_TEST #undef ICACHE_RAM_ATTR #define ICACHE_RAM_ATTR @@ -431,11 +437,7 @@ void IRrecv::pause(void) { params.rawlen = 0; params.overflow = false; #if defined(ESP32) -#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - noInterrupts(); // Bluntly switch off, not sure if we really want this... -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 gpio_intr_disable((gpio_num_t)params.recvpin); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #endif // ESP32 } @@ -450,11 +452,10 @@ void IRrecv::resume(void) { #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) timerEnd(timer); - interrupts(); // Back on #else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); - gpio_intr_enable((gpio_num_t)params.recvpin); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 + gpio_intr_enable((gpio_num_t)params.recvpin); #endif // ESP32 } From c359dc32854f326b261028b77628f2842b1be27b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 19 Oct 2023 21:12:53 +0200 Subject: [PATCH 13/14] Add comment why code was changed --- src/IRrecv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 7cba44091..9cc14450e 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -530,7 +530,7 @@ void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) { for (uint16_t i = offset + 2; i <= results->rawlen && i < kBufSize; i++) results->rawbuf[i - 2] = results->rawbuf[i]; if (offset > 1) { // There is a previous pair we can add to. - // Merge this pair into into the previous space. + // Merge this pair into into the previous space. // C++20 fix applied results->rawbuf[offset - 1] = results->rawbuf[offset - 1] + addition; } results->rawlen -= 2; // Adjust the length. From db98aa001b8302ee827d1cd23367eb43480ba5ee Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 2 Nov 2023 21:22:16 +0100 Subject: [PATCH 14/14] [Lib] Add latest ESP32 fixes by @s-hadinger, add extra NULL safeguard, update Platform build --- platformio.ini | 4 ++-- src/IRrecv.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/platformio.ini b/platformio.ini index 1c2a4f1cd..eacdd4f1d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -23,5 +23,5 @@ board = esp32dev # Experimental IDF 5.x support [env:esp32devIDF5x] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.10/platform-espressif32.zip -board = esp32dev +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.12/platform-espressif32.zip +board = esp32dev diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 9cc14450e..c7202534d 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -249,8 +249,8 @@ static void USE_IRAM_ATTR gpio_intr() { timer->dev->config.alarm_en = 1; #else // _ESP32_IRRECV_TIMER_HACK #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); - timerAttachInterrupt(timer, &read_timeout); + timerWrite(timer, 0); + timerStart(timer); #else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerWrite(timer, 0); timerAlarmEnable(timer); @@ -344,9 +344,6 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, /// timers or interrupts used. IRrecv::~IRrecv(void) { disableIRIn(); -#if defined(ESP32) - if (timer != NULL) timerEnd(timer); // Cleanup the ESP32 timeout timer. -#endif // ESP32 delete[] params.rawbuf; if (params_save != NULL) { delete[] params_save->rawbuf; @@ -371,9 +368,9 @@ void IRrecv::enableIRIn(const bool pullup) { // Initialise the ESP32 timer. // 80MHz / 80 = 1 uSec granularity. #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - timer = timerBegin(80); + timer = timerBegin(1000000); // 1 MHz #else // ESP_ARDUINO_VERSION_MAJOR >= 3 - timer = timerBegin(_timer_num, 80, true); + timer = timerBegin(_timer_num, 80, true); // 1 MHz : 80 MHz with divider 80 #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 #ifdef DEBUG if (timer == NULL) { @@ -383,8 +380,8 @@ void IRrecv::enableIRIn(const bool pullup) { #endif // DEBUG assert(timer != NULL); // Check we actually got the timer. #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); timerAttachInterrupt(timer, &read_timeout); + timerAlarm(timer, MS_TO_USEC(params.timeout), ONCE, 0); #else // ESP_ARDUINO_VERSION_MAJOR >= 3 // Set the timer so it only fires once, and set it's trigger in uSeconds. timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE); @@ -418,13 +415,16 @@ void IRrecv::disableIRIn(void) { os_timer_disarm(&timer); #endif // ESP8266 #if defined(ESP32) + if (timer == NULL) { return; } // Call only once (defensive) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerDetachInterrupt(timer); timerEnd(timer); #else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); timerDetachInterrupt(timer); timerEnd(timer); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3 + timer = NULL; // Cleanup the ESP32 timeout timer. #endif // ESP32 detachInterrupt(params.recvpin); #endif // UNIT_TEST @@ -451,7 +451,7 @@ void IRrecv::resume(void) { params.overflow = false; #if defined(ESP32) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - timerEnd(timer); + timerStop(timer); #else // ESP_ARDUINO_VERSION_MAJOR >= 3 timerAlarmDisable(timer); #endif // ESP_ARDUINO_VERSION_MAJOR >= 3