From e2d8ebd78464a51016f1b6794787208f95bd653a Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Fri, 4 Mar 2022 21:39:25 +1000 Subject: [PATCH 1/5] ESP32-C3: Use different default receive pin to avoid reboot. Seems `14` was a poor default for the ESP-C3. Using it causes a reboot. Using `10` for the input GPIO avoids the crash. Fixes #1751 --- examples/DumbIRRepeater/DumbIRRepeater.ino | 5 +++++ examples/IRrecvDemo/IRrecvDemo.ino | 5 +++++ examples/IRrecvDumpV2/IRrecvDumpV2.ino | 5 +++++ examples/IRrecvDumpV3/IRrecvDumpV3.ino | 5 +++++ examples/SmartIRRepeater/SmartIRRepeater.ino | 5 +++++ 5 files changed, 25 insertions(+) diff --git a/examples/DumbIRRepeater/DumbIRRepeater.ino b/examples/DumbIRRepeater/DumbIRRepeater.ino index d3ddbdb6a..abcf4b682 100644 --- a/examples/DumbIRRepeater/DumbIRRepeater.ino +++ b/examples/DumbIRRepeater/DumbIRRepeater.ino @@ -57,7 +57,12 @@ // The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5) // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. +#ifndef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 14; +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#endif // ARDUINO_ESP32C3_DEV // GPIO to use to control the IR LED circuit. Recommended: 4 (D2). const uint16_t kIrLedPin = 4; diff --git a/examples/IRrecvDemo/IRrecvDemo.ino b/examples/IRrecvDemo/IRrecvDemo.ino index 2ae2e1410..016497ccc 100644 --- a/examples/IRrecvDemo/IRrecvDemo.ino +++ b/examples/IRrecvDemo/IRrecvDemo.ino @@ -24,7 +24,12 @@ // An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU // board). // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. +#ifndef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 14; +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#endif // ARDUINO_ESP32C3_DEV IRrecv irrecv(kRecvPin); diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index 70dbdba42..c80d4335f 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -38,7 +38,12 @@ // An IR detector/demodulator is connected to GPIO pin 14 // e.g. D5 on a NodeMCU board. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. +#ifndef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 14; +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#endif // ARDUINO_ESP32C3_DEV // The Serial connection baud rate. // i.e. Status message will be sent to the PC at this baud rate. diff --git a/examples/IRrecvDumpV3/IRrecvDumpV3.ino b/examples/IRrecvDumpV3/IRrecvDumpV3.ino index 0948ae5e9..926220e0e 100644 --- a/examples/IRrecvDumpV3/IRrecvDumpV3.ino +++ b/examples/IRrecvDumpV3/IRrecvDumpV3.ino @@ -45,7 +45,12 @@ // An IR detector/demodulator is connected to GPIO pin 14 // e.g. D5 on a NodeMCU board. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. +#ifndef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 14; +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#endif // ARDUINO_ESP32C3_DEV // The Serial connection baud rate. // i.e. Status message will be sent to the PC at this baud rate. diff --git a/examples/SmartIRRepeater/SmartIRRepeater.ino b/examples/SmartIRRepeater/SmartIRRepeater.ino index d35c4cef6..2ed35e9e7 100644 --- a/examples/SmartIRRepeater/SmartIRRepeater.ino +++ b/examples/SmartIRRepeater/SmartIRRepeater.ino @@ -60,7 +60,12 @@ // The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5) // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. +#ifndef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 14; +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#endif // ARDUINO_ESP32C3_DEV // GPIO to use to control the IR LED circuit. Recommended: 4 (D2). const uint16_t kIrLedPin = 4; From ca226a5d647c0a901f79c6d6d37446809ae24a65 Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Sat, 5 Mar 2022 16:17:27 +1000 Subject: [PATCH 2/5] Change from ifndef to ifdef Per review feedback. --- examples/DumbIRRepeater/DumbIRRepeater.ino | 6 +++--- examples/IRrecvDemo/IRrecvDemo.ino | 6 +++--- examples/IRrecvDumpV2/IRrecvDumpV2.ino | 6 +++--- examples/IRrecvDumpV3/IRrecvDumpV3.ino | 6 +++--- examples/SmartIRRepeater/SmartIRRepeater.ino | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/DumbIRRepeater/DumbIRRepeater.ino b/examples/DumbIRRepeater/DumbIRRepeater.ino index abcf4b682..2d3f1a8b3 100644 --- a/examples/DumbIRRepeater/DumbIRRepeater.ino +++ b/examples/DumbIRRepeater/DumbIRRepeater.ino @@ -58,10 +58,10 @@ // The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5) // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. -#ifndef ARDUINO_ESP32C3_DEV -const uint16_t kRecvPin = 14; -#else // ARDUINO_ESP32C3_DEV +#ifdef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 14; #endif // ARDUINO_ESP32C3_DEV // GPIO to use to control the IR LED circuit. Recommended: 4 (D2). diff --git a/examples/IRrecvDemo/IRrecvDemo.ino b/examples/IRrecvDemo/IRrecvDemo.ino index 016497ccc..743d32c4e 100644 --- a/examples/IRrecvDemo/IRrecvDemo.ino +++ b/examples/IRrecvDemo/IRrecvDemo.ino @@ -25,10 +25,10 @@ // board). // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. -#ifndef ARDUINO_ESP32C3_DEV -const uint16_t kRecvPin = 14; -#else // ARDUINO_ESP32C3_DEV +#ifdef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 14; #endif // ARDUINO_ESP32C3_DEV IRrecv irrecv(kRecvPin); diff --git a/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/examples/IRrecvDumpV2/IRrecvDumpV2.ino index c80d4335f..f0bebff12 100644 --- a/examples/IRrecvDumpV2/IRrecvDumpV2.ino +++ b/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -39,10 +39,10 @@ // e.g. D5 on a NodeMCU board. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. -#ifndef ARDUINO_ESP32C3_DEV -const uint16_t kRecvPin = 14; -#else // ARDUINO_ESP32C3_DEV +#ifdef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 14; #endif // ARDUINO_ESP32C3_DEV // The Serial connection baud rate. diff --git a/examples/IRrecvDumpV3/IRrecvDumpV3.ino b/examples/IRrecvDumpV3/IRrecvDumpV3.ino index 926220e0e..6bc054a3c 100644 --- a/examples/IRrecvDumpV3/IRrecvDumpV3.ino +++ b/examples/IRrecvDumpV3/IRrecvDumpV3.ino @@ -46,10 +46,10 @@ // e.g. D5 on a NodeMCU board. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. -#ifndef ARDUINO_ESP32C3_DEV -const uint16_t kRecvPin = 14; -#else // ARDUINO_ESP32C3_DEV +#ifdef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 14; #endif // ARDUINO_ESP32C3_DEV // The Serial connection baud rate. diff --git a/examples/SmartIRRepeater/SmartIRRepeater.ino b/examples/SmartIRRepeater/SmartIRRepeater.ino index 2ed35e9e7..10554735d 100644 --- a/examples/SmartIRRepeater/SmartIRRepeater.ino +++ b/examples/SmartIRRepeater/SmartIRRepeater.ino @@ -61,10 +61,10 @@ // The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5) // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot. -#ifndef ARDUINO_ESP32C3_DEV -const uint16_t kRecvPin = 14; -#else // ARDUINO_ESP32C3_DEV +#ifdef ARDUINO_ESP32C3_DEV const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop. +#else // ARDUINO_ESP32C3_DEV +const uint16_t kRecvPin = 14; #endif // ARDUINO_ESP32C3_DEV // GPIO to use to control the IR LED circuit. Recommended: 4 (D2). From 03e1f067ebef4205f3334ec83fa13e6888b9017a Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Sun, 6 Mar 2022 07:24:28 +1000 Subject: [PATCH 3/5] [BUG] Ensure ESP32 system timer is valid before use. * Add debug messages & a runtime assert to ensure we correctly allocated a system timer in `IRrecv::enableIRIn()`. * Limit the max number of the system timer to the appropriate size for the ESP32. ESP32-C3's only have two system timers (0-1), the rest have 4 (0-3). * Done in such a way it should be correct for future ESP32 models. Ref: https://docs.espressif.com/projects/arduino-esp32/en/latest/api/timer.html Fixes #1751 --- src/IRrecv.cpp | 14 +++++++++++--- src/IRrecv.h | 7 +++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index 5626db2c7..e87981a86 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -261,13 +261,14 @@ static void USE_IRAM_ATTR gpio_intr() { /// capturing data. (Default: kTimeoutMs) /// @param[in] save_buffer Use a second (save) buffer to decode from. /// (Default: false) -/// @param[in] timer_num Nr. of the ESP32 timer to use (0 to 3) (ESP32 Only) +/// @param[in] timer_num Nr. of the ESP32 timer to use. (0 to 3) (ESP32 Only) +/// or (0 to 1) (ESP32-C3) #if defined(ESP32) IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, const uint8_t timeout, const bool save_buffer, const uint8_t timer_num) { - // There are only 4 timers. 0 to 3. - _timer_num = std::min(timer_num, (uint8_t)3); + // Ensure we use a valid timer number. + _timer_num = std::min(timer_num, (uint8_t)(SOC_TIMER_GROUP_TOTAL_TIMERS - 1)); #else // ESP32 /// @cond IGNORE /// Class constructor @@ -353,6 +354,13 @@ void IRrecv::enableIRIn(const bool pullup) { // Initialise the ESP32 timer. // 80MHz / 80 = 1 uSec granularity. timer = timerBegin(_timer_num, 80, true); +#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. timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE); // Note: Interrupt needs to be attached before it can be enabled or disabled. diff --git a/src/IRrecv.h b/src/IRrecv.h index f9ff4b0ef..9c428488c 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -52,8 +52,11 @@ const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1)); const uint32_t kFnvPrime32 = 16777619UL; const uint32_t kFnvBasis32 = 2166136261UL; -// Which of the ESP32 timers to use by default. (0-3) -const uint8_t kDefaultESP32Timer = 3; +#ifdef ESP32 +// Which of the ESP32 timers to use by default. +// (3 for most ESP32s, 1 for ESP32-C3s) +const uint8_t kDefaultESP32Timer = SOC_TIMER_GROUP_TOTAL_TIMERS - 1; +#endif // ESP32 #if DECODE_AC // Hitachi AC is the current largest state size. From 14cd7eee268e46b313025cc41d7a23c6e2dbd82e Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Sun, 6 Mar 2022 07:52:38 +1000 Subject: [PATCH 4/5] Handle when `SOC_TIMER_GROUP_TOTAL_TIMERS` is not defined. Fixes a compile error on older/normal ESP32 Arduino framework/cores. For #1751 --- src/IRrecv.cpp | 9 ++++++++- src/IRrecv.h | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index e87981a86..a4926e772 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -268,7 +268,14 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, const uint8_t timeout, const bool save_buffer, const uint8_t timer_num) { // Ensure we use a valid timer number. - _timer_num = std::min(timer_num, (uint8_t)(SOC_TIMER_GROUP_TOTAL_TIMERS - 1)); + _timer_num = std::min(timer_num, + (uint8_t)( +#ifdef SOC_TIMER_GROUP_TOTAL_TIMERS + SOC_TIMER_GROUP_TOTAL_TIMERS - 1 +#else // SOC_TIMER_GROUP_TOTAL_TIMERS + 3 +#endif // SOC_TIMER_GROUP_TOTAL_TIMERS + )); #else // ESP32 /// @cond IGNORE /// Class constructor diff --git a/src/IRrecv.h b/src/IRrecv.h index 9c428488c..425fc4b24 100644 --- a/src/IRrecv.h +++ b/src/IRrecv.h @@ -55,7 +55,11 @@ const uint32_t kFnvBasis32 = 2166136261UL; #ifdef ESP32 // Which of the ESP32 timers to use by default. // (3 for most ESP32s, 1 for ESP32-C3s) +#ifdef SOC_TIMER_GROUP_TOTAL_TIMERS const uint8_t kDefaultESP32Timer = SOC_TIMER_GROUP_TOTAL_TIMERS - 1; +#else // SOC_TIMER_GROUP_TOTAL_TIMERS +const uint8_t kDefaultESP32Timer = 3; +#endif // SOC_TIMER_GROUP_TOTAL_TIMERS #endif // ESP32 #if DECODE_AC From 07af7e8bd062c5af3a14432d309ed541eeb7f090 Mon Sep 17 00:00:00 2001 From: crankyoldgit Date: Sun, 6 Mar 2022 07:55:10 +1000 Subject: [PATCH 5/5] Fix linter issue. --- src/IRrecv.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/IRrecv.cpp b/src/IRrecv.cpp index a4926e772..6debda635 100644 --- a/src/IRrecv.cpp +++ b/src/IRrecv.cpp @@ -271,11 +271,10 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, _timer_num = std::min(timer_num, (uint8_t)( #ifdef SOC_TIMER_GROUP_TOTAL_TIMERS - SOC_TIMER_GROUP_TOTAL_TIMERS - 1 + SOC_TIMER_GROUP_TOTAL_TIMERS - 1)); #else // SOC_TIMER_GROUP_TOTAL_TIMERS - 3 + 3)); #endif // SOC_TIMER_GROUP_TOTAL_TIMERS - )); #else // ESP32 /// @cond IGNORE /// Class constructor