From 264b444fc065ea4bd9f28abe3e1868df403c31d8 Mon Sep 17 00:00:00 2001 From: Sam Guyer Date: Sat, 8 Feb 2020 23:22:09 -0500 Subject: Two changes to improve stability. First, added a min wait that forces calls to show() to be at least 50 microseconds apart. Second, added optional calls to ESP-IDF functions that force flash operations to wait until show() is complete. --- platforms/esp/32/clockless_rmt_esp32.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/platforms/esp/32/clockless_rmt_esp32.h b/platforms/esp/32/clockless_rmt_esp32.h index de5b7c98..bc18589e 100644 --- a/platforms/esp/32/clockless_rmt_esp32.h +++ b/platforms/esp/32/clockless_rmt_esp32.h @@ -58,6 +58,13 @@ * represented by a 32-bit pulse specification, so it is a 32X blow-up * in memory use. * + * NEW: Use of Flash memory on the ESP32 can interfere with the timing + * of pixel output. The ESP-IDF system code disables all other + * code running on *either* core during these operation. To prevent + * this from happening, define this flag. It will force flash + * operations to wait until the show() is done. + * + * #define FASTLED_ESP32_FLASH_LOCK * * Based on public domain code created 19 Nov 2016 by Chris Osborn * http://insentricity.com * @@ -101,6 +108,9 @@ extern "C" { #include "esp_log.h" +extern void spi_flash_op_lock(void); +extern void spi_flash_op_unlock(void); + #ifdef __cplusplus } #endif @@ -200,6 +210,9 @@ class ClocklessController : public CPixelLEDController rmt_item32_t * mBuffer; uint16_t mBufferSize; + // -- Make sure we can't call show() too quickly + CMinWait<50> mWait; + public: void init() @@ -294,6 +307,11 @@ protected: initRMT(); } xSemaphoreTake(gTX_sem, portMAX_DELAY); + +#ifdef FASTLED_ESP32_FLASH_LOCK + // -- Make sure no flash operations happen right now + spi_flash_op_lock(); +#endif } if (FASTLED_RMT_BUILTIN_DRIVER) @@ -321,6 +339,9 @@ protected: channel++; } + // -- Make sure it's been at least 50ms since last show + mWait.wait(); + // -- Start them all for (int i = 0; i < channel; i++) { ClocklessController * pController = static_cast(gControllers[i]); @@ -333,10 +354,17 @@ protected: xSemaphoreTake(gTX_sem, portMAX_DELAY); xSemaphoreGive(gTX_sem); + mWait.mark(); + // -- Reset the counters gNumStarted = 0; gNumDone = 0; gNext = 0; + +#ifdef FASTLED_ESP32_FLASH_LOCK + // -- Release the lock on flash operations + spi_flash_op_unlock(); +#endif } } -- cgit v1.2.3 From c12ba9e2c7c2aa073ed86e8dc2ed2795ced21fcb Mon Sep 17 00:00:00 2001 From: Sam Guyer Date: Mon, 10 Feb 2020 18:53:04 -0500 Subject: Changes the #define to have a value (mek suggestion) --- platforms/esp/32/clockless_rmt_esp32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platforms/esp/32/clockless_rmt_esp32.h b/platforms/esp/32/clockless_rmt_esp32.h index bc18589e..b8cd1f42 100644 --- a/platforms/esp/32/clockless_rmt_esp32.h +++ b/platforms/esp/32/clockless_rmt_esp32.h @@ -64,7 +64,7 @@ * this from happening, define this flag. It will force flash * operations to wait until the show() is done. * - * #define FASTLED_ESP32_FLASH_LOCK + * #define FASTLED_ESP32_FLASH_LOCK 1 * * Based on public domain code created 19 Nov 2016 by Chris Osborn * http://insentricity.com * @@ -308,7 +308,7 @@ protected: } xSemaphoreTake(gTX_sem, portMAX_DELAY); -#ifdef FASTLED_ESP32_FLASH_LOCK +#if FASTLED_ESP32_FLASH_LOCK == 1 // -- Make sure no flash operations happen right now spi_flash_op_lock(); #endif @@ -361,7 +361,7 @@ protected: gNumDone = 0; gNext = 0; -#ifdef FASTLED_ESP32_FLASH_LOCK +#if FASTLED_ESP32_FLASH_LOCK == 1 // -- Release the lock on flash operations spi_flash_op_unlock(); #endif -- cgit v1.2.3