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:
Brian Bulkowski
2020-09-21 18:52:32 -07:00
parent 162a962a02
commit 47f83d4689
3 changed files with 30 additions and 12 deletions

View File

@@ -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(); }
};

View File

@@ -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:

View File

@@ -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.