mirror of
https://github.com/bbulkow/FastLED-idf.git
synced 2025-08-04 13:15:23 +02:00
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
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
#ifndef __INC_FL_DELAY_H
|
||||
#define __INC_FL_DELAY_H
|
||||
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
#include "FastLED.h"
|
||||
|
||||
///@file fastled_delay.h
|
||||
@@ -11,18 +16,29 @@ FASTLED_NAMESPACE_BEGIN
|
||||
/// 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
|
||||
/// this should make sure that chipsets that have
|
||||
template<int WAIT> class CMinWait {
|
||||
uint16_t mLastMicros;
|
||||
uint64_t mLastMicros;
|
||||
public:
|
||||
CMinWait() { mLastMicros = 0; }
|
||||
|
||||
void wait() {
|
||||
uint16_t diff;
|
||||
do {
|
||||
diff = (micros() & 0xFFFF) - mLastMicros;
|
||||
} while(diff < WAIT);
|
||||
// how long I been waiting
|
||||
uint64_t waited = esp_timer_get_time() - mLastMicros;
|
||||
// fast path, waited long enough
|
||||
if (waited >= WAIT) return;
|
||||
// delay vs spin
|
||||
if ((WAIT - waited) > (portTICK_PERIOD_MS * 1000)) {
|
||||
int tickDelay = ((WAIT - waited) / 1000) / portTICK_PERIOD_MS;
|
||||
//printf("cMinWait: %llu micros means delay %d ticks\n",(WAIT - waited),tickDelay);
|
||||
vTaskDelay( tickDelay );
|
||||
}
|
||||
else { /*buzz is only other option outch */
|
||||
do {
|
||||
waited = esp_timer_get_time() - mLastMicros;
|
||||
} while( waited > WAIT);
|
||||
}
|
||||
}
|
||||
|
||||
void mark() { mLastMicros = micros() & 0xFFFF; }
|
||||
void mark() { mLastMicros = esp_timer_get_time(); }
|
||||
};
|
||||
|
||||
|
||||
|
@@ -205,7 +205,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
|
||||
PixelController<RGB_ORDER> * mPixels;
|
||||
|
||||
// -- Make sure we can't call show() too quickly
|
||||
CMinWait<50> mWait;
|
||||
CMinWait<55> mWait;
|
||||
|
||||
public:
|
||||
|
||||
|
@@ -31,7 +31,7 @@ static intr_handle_t gRMT_intr_handle = NULL;
|
||||
static xSemaphoreHandle gTX_sem = NULL;
|
||||
|
||||
// -- Make sure we can't call show() too quickly (fastled library)
|
||||
CMinWait<50> gWait;
|
||||
CMinWait<55> gWait;
|
||||
|
||||
static bool gInitialized = false;
|
||||
|
||||
@@ -355,7 +355,12 @@ void ESP32RMTController::showPixels()
|
||||
// -- This Take always succeeds immediately
|
||||
xSemaphoreTake(gTX_sem, portMAX_DELAY);
|
||||
|
||||
// -- First, fill all the available channels
|
||||
// -- Make sure it's been at least 50us since last show
|
||||
// this is very conservative if you have multiple channels,
|
||||
// arguably there should be a wait on the startnext of each LED string
|
||||
gWait.wait();
|
||||
|
||||
// -- First, fill all the available channels and start them
|
||||
int channel = 0;
|
||||
while ( (channel < FASTLED_RMT_MAX_CHANNELS) && (gNext < gNumControllers) ) {
|
||||
|
||||
@@ -364,9 +369,6 @@ void ESP32RMTController::showPixels()
|
||||
channel++;
|
||||
}
|
||||
|
||||
// -- Make sure it's been at least 50us since last show
|
||||
gWait.wait();
|
||||
|
||||
// -- Wait here while the data is sent. The interrupt handler
|
||||
// will keep refilling the RMT buffers until it is all
|
||||
// done; then it gives the semaphore back.
|
||||
|
Reference in New Issue
Block a user