Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Guyer <sam.guyer@gmail.com>2020-08-22 05:23:45 +0300
committerSam Guyer <sam.guyer@gmail.com>2020-08-22 05:25:35 +0300
commitc8bd7832d030427bb6059a5bcc10ded3b9eeaa79 (patch)
tree93e09d71cf34f5394ac4214d55527137b730c468 /src
parent8c8fc6090e07cec2f6faafabc197f4b94cf0fb7e (diff)
Added logic to time the interval between buffer fills, and bail out if the interval is more than +50% of what is expected
Diffstat (limited to 'src')
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.cpp25
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.h8
2 files changed, 27 insertions, 6 deletions
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.cpp b/src/platforms/esp/32/clockless_rmt_esp32.cpp
index 20d2b217..907e37bf 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.cpp
+++ b/src/platforms/esp/32/clockless_rmt_esp32.cpp
@@ -32,9 +32,13 @@ CMinWait<50> gWait;
static bool gInitialized = false;
+// -- Bailout metric
+// Keep track of how long it's been between buffer fills, and
+// bail out on showing them if there's a big gap
+static uint32_t gLastFill[8];
+
// -- SZG: For debugging purposes
#if FASTLED_ESP32_SHOWTIMING == 1
-static uint32_t gLastFill[8];
static int gTooSlow[8];
static uint32_t gTotalTime[8];
#endif
@@ -67,6 +71,13 @@ ESP32RMTController::ESP32RMTController(int DATA_PIN, int T1, int T2, int T3)
gControllers[gNumControllers] = this;
gNumControllers++;
+ // -- Expected number of CPU cycles between buffer fills
+ mCyclesPerFill = (T1 + T2 + T3) * PULSES_PER_FILL;
+
+ // -- If there is ever an interval greater than 1.5 times
+ // the expected time, then bail out.
+ mMaxCyclesPerFill = mCyclesPerFill + mCyclesPerFill/2;
+
mPin = gpio_num_t(DATA_PIN);
}
@@ -274,9 +285,9 @@ void ESP32RMTController::startOnChannel(int channel)
void ESP32RMTController::tx_start()
{
rmt_tx_start(mRMT_channel, true);
+ gLastFill[mRMT_channel] = __clock_cycles();
#if FASTLED_ESP32_SHOWTIMING == 1
- gLastFill[mRMT_channel] = __clock_cycles();
gTooSlow[mRMT_channel] = 0;
gTotalTime[mRMT_channel] = 0;
#endif
@@ -323,9 +334,7 @@ void ESP32RMTController::doneOnChannel(rmt_channel_t channel, void * arg)
// next half of the RMT buffer with data.
void IRAM_ATTR ESP32RMTController::interruptHandler(void *arg)
{
-#if FASTLED_ESP32_SHOWTIMING == 1
uint32_t now = __clock_cycles();
-#endif
// -- The basic structure of this code is borrowed from the
// interrupt handler in esp-idf/components/driver/rmt.c
@@ -342,10 +351,14 @@ void IRAM_ATTR ESP32RMTController::interruptHandler(void *arg)
if (intr_st & BIT(tx_next_bit)) {
// -- More to send on this channel
RMT.int_clr.val |= BIT(tx_next_bit);
- pController->fillNext();
+ uint32_t delta = (now - gLastFill[channel]);
+ if (delta > pController->getMaxCyclesPerFill()) {
+ doneOnChannel(rmt_channel_t(channel), 0);
+ } else {
+ pController->fillNext();
+ }
#if FASTLED_ESP32_SHOWTIMING == 1
- uint32_t delta = (now - gLastFill[channel]);
if (delta > C_NS(50500)) {
gTooSlow[channel]++;
}
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.h b/src/platforms/esp/32/clockless_rmt_esp32.h
index 604bd3d1..e8ee0f9c 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.h
+++ b/src/platforms/esp/32/clockless_rmt_esp32.h
@@ -192,6 +192,11 @@ private:
rmt_item32_t mZero;
rmt_item32_t mOne;
+ // -- Total expected time to send 32 bits
+ // Each strip should get an interrupt roughly at this interval
+ uint32_t mCyclesPerFill;
+ uint32_t mMaxCyclesPerFill;
+
// -- Pixel data
uint32_t * mPixelData;
int mSize;
@@ -215,6 +220,9 @@ public:
// member variables.
ESP32RMTController(int DATA_PIN, int T1, int T2, int T3);
+ // -- Get max cycles per fill
+ uint32_t IRAM_ATTR getMaxCyclesPerFill() const { return mMaxCyclesPerFill; }
+
// -- Get or create the pixel data buffer
uint32_t * getPixelBuffer(int size_in_bytes);