diff --git a/src/NeoPixelesp8266.c b/src/NeoPixelesp8266.c index 99b0efd..6de8525 100644 --- a/src/NeoPixelesp8266.c +++ b/src/NeoPixelesp8266.c @@ -28,12 +28,17 @@ License along with NeoPixel. If not, see #include #if defined(ARDUINO_ARCH_ESP8266) -#include +# include +# if (ARDUINO_ESP8266_MAJOR < 3) +# define INRAM ICACHE_RAM_ATTR +# else +# define INRAM IRAM_ATTR +# endif #endif // ESP32 doesn't define ICACHE_RAM_ATTR -#ifndef ICACHE_RAM_ATTR -#define ICACHE_RAM_ATTR IRAM_ATTR +#ifndef INRAM +# define INRAM IRAM_ATTR #endif inline uint32_t _getCycleCount() @@ -53,7 +58,7 @@ inline uint32_t _getCycleCount() # define CYCLES_800 (F_CPU / 900000) // 1.25us per bit #endif -void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, size_t count, uint8_t pin) +void INRAM send_pixels_800(uint8_t* pixels, size_t count, uint8_t pin) { const uint32_t pinRegister = _BV(pin); uint8_t mask; diff --git a/src/wsLED.cpp b/src/wsLED.cpp index 9d9f2d7..42ff905 100644 --- a/src/wsLED.cpp +++ b/src/wsLED.cpp @@ -11,11 +11,17 @@ # define T0H 14 // 0 bit high time # define T1H 52 // 1 bit high time # define TL 52 // low time for either bit +# define INRAM IRAM_ATTR #endif #if defined(ARDUINO_ARCH_ESP8266) // due to linker overriding the ICACHE_RAM_ATTR for cpp files, these methods are // moved into a C file so the attribute will be applied correctly -extern "C" void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixel, size_t count, uint8_t pin); +#if (ARDUINO_ESP8266_MAJOR < 3) +# define INRAM ICACHE_RAM_ATTR +#else +# define INRAM IRAM_ATTR +#endif +extern "C" void INRAM send_pixels_800(uint8_t* pixel, size_t count, uint8_t pin); #endif // TODO: Proverit ESP32 s https://github.com/adafruit/Adafruit_NeoPixel/blob/master/esp.c // ... a s https://github.com/Freenove/Freenove_WS2812_Lib_for_ESP32 @@ -30,12 +36,18 @@ static const uint16_t LB[] PROGMEM = { 0x12d , 0x12a , 0x126 , 0x123 , 0x11f , 0x11c , 0x11a , 0x117 , 0x115 , 0x112 , 0x110 , 0x10e , 0x10c , 0x10b , 0x109 , 0x108 , 0x107 , 0x105 , 0x104 , 0x203 , 0x102 , 0x201 , 0x2900 }; -static void ICACHE_RAM_ATTR ledTrampoline(wsLED *ptr) +static void INRAM ledTrampoline(wsLED *ptr) { ptr->rtLed(); } +inline bool wsLED::canShow(void) +{ + + return (micros() - _endtime) >= 70L; +} + void wsLED::show(void) { uint8_t color[3]; @@ -45,6 +57,8 @@ void wsLED::show(void) uint16_t c = (uint16_t)_color[i] * (1 + (uint16_t)_scale); color[i] = (uint8_t)(c >> 8); } + while (!canShow()) + __asm__ volatile ("nop"); #if defined(ARDUINO_ARCH_ESP32) uint32_t bits_to_send = ((uint32_t)color[0] << 16) | ((uint32_t)color[1] << 8) | (uint32_t)color[2]; uint32_t mask = 1 << (BITS_PER_LED_CMD - 1); @@ -61,16 +75,21 @@ void wsLED::show(void) send_pixels_800(color, 1, _pin); interrupts(); #endif + _endtime = micros(); } -wsLED::wsLED(int pin, int order) : _pin(pin), _order(order), _ledState(LED_STOP) -{ -} +wsLED::wsLED(int pin, int order) + : _pin(pin) + , _order(order) + , _ledState(LED_STOP) +{} -wsLED::wsLED(void) : _pin(NOT_A_PIN), _order(RGB), _ledState(LED_STOP) -{ -} +wsLED::wsLED(void) + : _pin(NOT_A_PIN) + , _order(RGB) + , _ledState(LED_STOP) +{} void wsLED::begin(int pin) { @@ -118,7 +137,7 @@ void wsLED::setColor(LEDRGB color) _color[_order & 7] = color.b; } -void ICACHE_RAM_ATTR wsLED::rtLed(void) +void INRAM wsLED::rtLed(void) { uint32_t timing; diff --git a/src/wsLED.h b/src/wsLED.h index 9275aa0..67c38a9 100644 --- a/src/wsLED.h +++ b/src/wsLED.h @@ -148,9 +148,11 @@ protected: rmt_item32_t led_data_buffer[LED_BUFFER_ITEMS]; SemaphoreHandle_t _mutex; #endif + uint32_t _endtime; void show(void); void setColor(LEDRGB color); + bool canShow(void); #if defined(ARDUINO_ARCH_ESP32) portMUX_TYPE _mux = portMUX_INITIALIZER_UNLOCKED; #endif