Skip to content

Commit 47f83d4

Browse files
committed
Delay code written for Arduino was no longer quite right and prone to overflow
On ESP32 we can use 64bits and the native libraries and it's OK
1 parent 162a962 commit 47f83d4

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

components/FastLED-idf/fastled_delay.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#ifndef __INC_FL_DELAY_H
22
#define __INC_FL_DELAY_H
33

4+
5+
#include "freertos/FreeRTOS.h"
6+
#include "freertos/task.h"
7+
#include "esp_timer.h"
8+
49
#include "FastLED.h"
510

611
///@file fastled_delay.h
@@ -11,18 +16,29 @@ FASTLED_NAMESPACE_BEGIN
1116
/// Class to ensure that a minimum amount of time has kicked since the last time run - and delay if not enough time has passed yet
1217
/// this should make sure that chipsets that have
1318
template<int WAIT> class CMinWait {
14-
uint16_t mLastMicros;
19+
uint64_t mLastMicros;
1520
public:
1621
CMinWait() { mLastMicros = 0; }
1722

1823
void wait() {
19-
uint16_t diff;
20-
do {
21-
diff = (micros() & 0xFFFF) - mLastMicros;
22-
} while(diff < WAIT);
24+
// how long I been waiting
25+
uint64_t waited = esp_timer_get_time() - mLastMicros;
26+
// fast path, waited long enough
27+
if (waited >= WAIT) return;
28+
// delay vs spin
29+
if ((WAIT - waited) > (portTICK_PERIOD_MS * 1000)) {
30+
int tickDelay = ((WAIT - waited) / 1000) / portTICK_PERIOD_MS;
31+
//printf("cMinWait: %llu micros means delay %d ticks\n",(WAIT - waited),tickDelay);
32+
vTaskDelay( tickDelay );
33+
}
34+
else { /*buzz is only other option outch */
35+
do {
36+
waited = esp_timer_get_time() - mLastMicros;
37+
} while( waited > WAIT);
38+
}
2339
}
2440

25-
void mark() { mLastMicros = micros() & 0xFFFF; }
41+
void mark() { mLastMicros = esp_timer_get_time(); }
2642
};
2743

2844

components/FastLED-idf/platforms/esp/32/clockless_i2s_esp32.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
205205
PixelController<RGB_ORDER> * mPixels;
206206

207207
// -- Make sure we can't call show() too quickly
208-
CMinWait<50> mWait;
208+
CMinWait<55> mWait;
209209

210210
public:
211211

components/FastLED-idf/platforms/esp/32/clockless_rmt_esp32.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static intr_handle_t gRMT_intr_handle = NULL;
3131
static xSemaphoreHandle gTX_sem = NULL;
3232

3333
// -- Make sure we can't call show() too quickly (fastled library)
34-
CMinWait<50> gWait;
34+
CMinWait<55> gWait;
3535

3636
static bool gInitialized = false;
3737

@@ -355,7 +355,12 @@ void ESP32RMTController::showPixels()
355355
// -- This Take always succeeds immediately
356356
xSemaphoreTake(gTX_sem, portMAX_DELAY);
357357

358-
// -- First, fill all the available channels
358+
// -- Make sure it's been at least 50us since last show
359+
// this is very conservative if you have multiple channels,
360+
// arguably there should be a wait on the startnext of each LED string
361+
gWait.wait();
362+
363+
// -- First, fill all the available channels and start them
359364
int channel = 0;
360365
while ( (channel < FASTLED_RMT_MAX_CHANNELS) && (gNext < gNumControllers) ) {
361366

@@ -364,9 +369,6 @@ void ESP32RMTController::showPixels()
364369
channel++;
365370
}
366371

367-
// -- Make sure it's been at least 50us since last show
368-
gWait.wait();
369-
370372
// -- Wait here while the data is sent. The interrupt handler
371373
// will keep refilling the RMT buffers until it is all
372374
// done; then it gives the semaphore back.

0 commit comments

Comments
 (0)