Merge pull request #1256 from sascha432/FastLED_master
Fix for ESP8266 board sdk 3.0.0, was glitching LEDs due to by NMI
This commit is contained in:
commit
5cc17b2be8
@ -28,7 +28,7 @@ public:
|
||||
virtual int size() { return CLEDController::size() * LANES; }
|
||||
|
||||
virtual void showPixels(PixelController<RGB_ORDER, LANES, PORT_MASK> & pixels) {
|
||||
// mWait.wait();
|
||||
mWait.wait();
|
||||
/*uint32_t clocks = */
|
||||
int cnt=FASTLED_INTERRUPT_RETRY_COUNT;
|
||||
while(!showRGBInternal(pixels) && cnt--) {
|
||||
@ -45,7 +45,7 @@ public:
|
||||
// MS_COUNTER += (1 + (microsTaken / 1000));
|
||||
// #endif
|
||||
|
||||
// mWait.mark();
|
||||
mWait.mark();
|
||||
}
|
||||
|
||||
template<int PIN> static void initPin() {
|
||||
|
@ -16,7 +16,7 @@ __attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
|
||||
|
||||
#define FASTLED_HAS_CLOCKLESS 1
|
||||
|
||||
template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
|
||||
template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 85>
|
||||
class ClocklessController : public CPixelLEDController<RGB_ORDER> {
|
||||
typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
|
||||
typedef typename FastPin<DATA_PIN>::port_t data_t;
|
||||
@ -36,7 +36,7 @@ public:
|
||||
protected:
|
||||
|
||||
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
|
||||
// mWait.wait();
|
||||
mWait.wait();
|
||||
int cnt = FASTLED_INTERRUPT_RETRY_COUNT;
|
||||
while((showRGBInternal(pixels)==0) && cnt--) {
|
||||
#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
|
||||
@ -46,13 +46,13 @@ protected:
|
||||
delayMicroseconds(WAIT_TIME);
|
||||
os_intr_lock();
|
||||
}
|
||||
// mWait.mark();
|
||||
mWait.mark();
|
||||
}
|
||||
|
||||
#define _ESP_ADJ (0)
|
||||
#define _ESP_ADJ2 (0)
|
||||
|
||||
template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & last_mark, register uint32_t b) {
|
||||
template<int BITS> __attribute__ ((always_inline)) inline static bool writeBits(register uint32_t & last_mark, register uint32_t b) {
|
||||
b <<= 24; b = ~b;
|
||||
for(register uint32_t i = BITS; i > 0; --i) {
|
||||
while((__clock_cycles() - last_mark) < (T1+T2+T3));
|
||||
@ -65,7 +65,17 @@ protected:
|
||||
|
||||
while((__clock_cycles() - last_mark) < (T1+T2));
|
||||
FastPin<DATA_PIN>::lo();
|
||||
|
||||
// even with interrupts disabled, the NMI interupt seems to cause
|
||||
// timing issues here. abort the frame if one bit took to long. if the
|
||||
// last of the 24 bits has been sent already, it is too late
|
||||
// this fixes the flickering first pixel that started to occur with
|
||||
// framework version 3.0.0
|
||||
if ((__clock_cycles() - last_mark) >= (T1 + T2 + T3 - 5)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
|
||||
@ -75,38 +85,56 @@ protected:
|
||||
pixels.preStepFirstByteDithering();
|
||||
register uint32_t b = pixels.loadAndScale0();
|
||||
pixels.preStepFirstByteDithering();
|
||||
os_intr_lock();
|
||||
uint32_t start = __clock_cycles();
|
||||
uint32_t last_mark = start;
|
||||
while(pixels.has(1)) {
|
||||
// Write first byte, read next byte
|
||||
writeBits<8+XTRA0>(last_mark, b);
|
||||
b = pixels.loadAndScale1();
|
||||
uint32_t start;
|
||||
{
|
||||
struct Lock {
|
||||
Lock() {
|
||||
os_intr_lock();
|
||||
}
|
||||
~Lock() {
|
||||
os_intr_unlock();
|
||||
}
|
||||
};
|
||||
|
||||
// Write second byte, read 3rd byte
|
||||
writeBits<8+XTRA0>(last_mark, b);
|
||||
b = pixels.loadAndScale2();
|
||||
start = __clock_cycles();
|
||||
uint32_t last_mark = start;
|
||||
while(pixels.has(1)) {
|
||||
// Write first byte, read next byte
|
||||
if (writeBits<8+XTRA0>(last_mark, b)) {
|
||||
return 0;
|
||||
}
|
||||
b = pixels.loadAndScale1();
|
||||
|
||||
// Write third byte, read 1st byte of next pixel
|
||||
writeBits<8+XTRA0>(last_mark, b);
|
||||
b = pixels.advanceAndLoadAndScale0();
|
||||
// Write second byte, read 3rd byte
|
||||
if (writeBits<8+XTRA0>(last_mark, b)) {
|
||||
return 0;
|
||||
}
|
||||
b = pixels.loadAndScale2();
|
||||
|
||||
#if (FASTLED_ALLOW_INTERRUPTS == 1)
|
||||
os_intr_unlock();
|
||||
#endif
|
||||
// Write third byte, read 1st byte of next pixel
|
||||
if (writeBits<8+XTRA0>(last_mark, b)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixels.stepDithering();
|
||||
#if (FASTLED_ALLOW_INTERRUPTS == 1)
|
||||
os_intr_unlock();
|
||||
#endif
|
||||
|
||||
#if (FASTLED_ALLOW_INTERRUPTS == 1)
|
||||
os_intr_lock();
|
||||
// if interrupts took longer than 45µs, punt on the current frame
|
||||
if((int32_t)(__clock_cycles()-last_mark) > 0) {
|
||||
if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) { sei(); return 0; }
|
||||
}
|
||||
#endif
|
||||
};
|
||||
b = pixels.advanceAndLoadAndScale0();
|
||||
pixels.stepDithering();
|
||||
|
||||
#if (FASTLED_ALLOW_INTERRUPTS == 1)
|
||||
os_intr_lock();
|
||||
// if interrupts took longer than 45µs, punt on the current frame
|
||||
if((int32_t)(__clock_cycles()-last_mark) > 0) {
|
||||
if((int32_t)(__clock_cycles()-last_mark) > (T1+T2+T3+((WAIT_TIME-INTERRUPT_THRESHOLD)*CLKS_PER_US))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
os_intr_unlock();
|
||||
#ifdef FASTLED_DEBUG_COUNT_FRAME_RETRIES
|
||||
++_frame_cnt;
|
||||
#endif
|
||||
|
7
workspace.code-workspace
Normal file
7
workspace.code-workspace
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user