From ebdfea049d46ddeeb23ebf46eca284eec690f57c Mon Sep 17 00:00:00 2001 From: Andre Lorbach Date: Fri, 15 Oct 2021 13:15:48 +0200 Subject: esp32: Fix unitialized flags field in init of the RMT driver The flags field was not initialized to 0 (No flags) which caused random failures of the esp32 RMT driver (Depending on what was in the unitialized memory) on newer esp-idf versions. Also added support for debugging output in ESP32 RMT Driver (Disabled by default). related: https://github.com/FastLED/FastLED/issues/1300 --- src/platforms/esp/32/clockless_rmt_esp32.cpp | 18 +++++++++++++----- src/platforms/esp/32/clockless_rmt_esp32.h | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/platforms/esp/32/clockless_rmt_esp32.cpp b/src/platforms/esp/32/clockless_rmt_esp32.cpp index a3a87572..9c89fcb4 100644 --- a/src/platforms/esp/32/clockless_rmt_esp32.cpp +++ b/src/platforms/esp/32/clockless_rmt_esp32.cpp @@ -108,12 +108,14 @@ uint8_t * ESP32RMTController::getPixelBuffer(int size_in_bytes) void ESP32RMTController::init(gpio_num_t pin) { if (gInitialized) return; + esp_err_t espErr = ESP_OK; for (int i = 0; i < gMaxChannel; i += gMemBlocks) { gOnChannel[i] = NULL; // -- RMT configuration for transmission rmt_config_t rmt_tx; + memset(&rmt_tx, 0, sizeof(rmt_config_t)); rmt_tx.channel = rmt_channel_t(i); rmt_tx.rmt_mode = RMT_MODE_TX; rmt_tx.gpio_num = pin; @@ -126,7 +128,8 @@ void ESP32RMTController::init(gpio_num_t pin) rmt_tx.tx_config.idle_output_en = true; // -- Apply the configuration - rmt_config(&rmt_tx); + espErr = rmt_config(&rmt_tx); + FASTLED_DEBUG("rmt_config result: %d", espErr); if (FASTLED_RMT_BUILTIN_DRIVER) { rmt_driver_install(rmt_channel_t(i), 0, 0); @@ -134,7 +137,8 @@ void ESP32RMTController::init(gpio_num_t pin) // -- Set up the RMT to send 32 bits of the pulse buffer and then // generate an interrupt. When we get this interrupt we // fill the other part in preparation (like double-buffering) - rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, PULSES_PER_FILL); + espErr = rmt_set_tx_thr_intr_en(rmt_channel_t(i), true, PULSES_PER_FILL); + FASTLED_DEBUG("rmt_set_tx_thr_intr_en result: %d", espErr); } } @@ -232,6 +236,7 @@ void IRAM_ATTR ESP32RMTController::startNext(int channel) // for it to finish. void IRAM_ATTR ESP32RMTController::startOnChannel(int channel) { + esp_err_t espErr = ESP_OK; // -- Assign this channel and configure the RMT mRMT_channel = rmt_channel_t(channel); @@ -241,9 +246,11 @@ void IRAM_ATTR ESP32RMTController::startOnChannel(int channel) // -- Assign the pin to this channel #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) - rmt_set_gpio(mRMT_channel, RMT_MODE_TX, mPin, false); + espErr = rmt_set_gpio(mRMT_channel, RMT_MODE_TX, mPin, false); + FASTLED_DEBUG("rmt_set_gpio result: %d", espErr); #else - rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin); + espErr = rmt_set_pin(mRMT_channel, RMT_MODE_TX, mPin); + FASTLED_DEBUG("rrmt_set_pin result: %d", espErr); #endif if (FASTLED_RMT_BUILTIN_DRIVER) { @@ -266,7 +273,8 @@ void IRAM_ATTR ESP32RMTController::startOnChannel(int channel) fillNext(false); // -- Turn on the interrupts - rmt_set_tx_intr_en(mRMT_channel, true); + espErr = rmt_set_tx_intr_en(mRMT_channel, true); + FASTLED_DEBUG("rmt_set_tx_intr_en result: %d", espErr); // -- Kick off the transmission tx_start(); diff --git a/src/platforms/esp/32/clockless_rmt_esp32.h b/src/platforms/esp/32/clockless_rmt_esp32.h index 5f522d97..66b04928 100644 --- a/src/platforms/esp/32/clockless_rmt_esp32.h +++ b/src/platforms/esp/32/clockless_rmt_esp32.h @@ -80,6 +80,13 @@ * send the data while the program continues to prepare the next * frame of data. * + * #define FASTLED_RMT_SERIAL_DEBUG 1 + * + * NEW (Oct 2021): If set enabled (Set to 1), output errorcodes to + * Serial for debugging if not ESP_OK. Might be useful to find + * bugs or problems with GPIO PINS. + * + * * Based on public domain code created 19 Nov 2016 by Chris Osborn * http://insentricity.com * * @@ -155,6 +162,16 @@ __attribute__ ((always_inline)) inline static uint32_t __clock_cycles() { //#define FASTLED_RMT_SHOW_TIMER false //#endif +#ifndef FASTLED_RMT_SERIAL_DEBUG +#define FASTLED_RMT_SERIAL_DEBUG 0 +#endif + +#if FASTLED_RMT_SERIAL_DEBUG == 1 +#define FASTLED_DEBUG(format, errcode, ...) if (errcode != ESP_OK) { Serial.printf(PSTR("FASTLED: " format "\n"), errcode, ##__VA_ARGS__); } +#else +#define FASTLED_DEBUG(format, ...) +#endif + // -- Configuration constants #define DIVIDER 2 /* 4, 8 still seem to work, but timings become marginal */ -- cgit v1.2.3