diff --git a/platforms/avr/drivers/ws2812_bitbang.c b/platforms/avr/drivers/ws2812_bitbang.c index 183690c9674..23bab5256ca 100644 --- a/platforms/avr/drivers/ws2812_bitbang.c +++ b/platforms/avr/drivers/ws2812_bitbang.c @@ -152,6 +152,7 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t } ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; +bool ws2812_dirty = false; void ws2812_init(void) { DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN); @@ -161,6 +162,7 @@ void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { ws2812_leds[index].r = red; ws2812_leds[index].g = green; ws2812_leds[index].b = blue; + ws2812_dirty = true; #if defined(WS2812_RGBW) ws2812_rgb_to_rgbw(&ws2812_leds[index]); #endif @@ -173,6 +175,7 @@ void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { } void ws2812_flush(void) { + if (!ws2812_dirty) return; uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN); uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN); diff --git a/platforms/avr/drivers/ws2812_i2c.c b/platforms/avr/drivers/ws2812_i2c.c index e6b922f4bfe..7ab92b61d13 100644 --- a/platforms/avr/drivers/ws2812_i2c.c +++ b/platforms/avr/drivers/ws2812_i2c.c @@ -17,6 +17,7 @@ #endif ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; +bool ws2812_dirty = false; void ws2812_init(void) { i2c_init(); @@ -26,6 +27,7 @@ void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { ws2812_leds[index].r = red; ws2812_leds[index].g = green; ws2812_leds[index].b = blue; + ws2812_dirty = true; } void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { @@ -35,5 +37,6 @@ void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { } void ws2812_flush(void) { + if (!ws2812_dirty) return; i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), WS2812_I2C_TIMEOUT); } diff --git a/platforms/chibios/drivers/ws2812_bitbang.c b/platforms/chibios/drivers/ws2812_bitbang.c index a88c5ff619d..93fbb6db7ec 100644 --- a/platforms/chibios/drivers/ws2812_bitbang.c +++ b/platforms/chibios/drivers/ws2812_bitbang.c @@ -77,6 +77,7 @@ void sendByte(uint8_t byte) { } ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; +bool ws2812_dirty = false; void ws2812_init(void) { palSetLineMode(WS2812_DI_PIN, WS2812_OUTPUT_MODE); @@ -86,6 +87,7 @@ void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { ws2812_leds[index].r = red; ws2812_leds[index].g = green; ws2812_leds[index].b = blue; + ws2812_dirty = true; #if defined(WS2812_RGBW) ws2812_rgb_to_rgbw(&ws2812_leds[index]); #endif @@ -98,6 +100,7 @@ void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { } void ws2812_flush(void) { + if (!ws2812_dirty) return; // this code is very time dependent, so we need to disable interrupts chSysLock(); diff --git a/platforms/chibios/drivers/ws2812_spi.c b/platforms/chibios/drivers/ws2812_spi.c index d1792b871bf..4ccea138887 100644 --- a/platforms/chibios/drivers/ws2812_spi.c +++ b/platforms/chibios/drivers/ws2812_spi.c @@ -165,6 +165,7 @@ static void set_led_color_rgb(ws2812_led_t color, int pos) { } ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; +bool ws2812_dirty = false; void ws2812_init(void) { palSetLineMode(WS2812_DI_PIN, WS2812_MOSI_OUTPUT_MODE); @@ -188,8 +189,7 @@ void ws2812_init(void) { 0, WS2812_SPI_DIVISOR # else - WS2812_SPI_DIVISOR_CR1_BR_X, - 0 + WS2812_SPI_DIVISOR_CR1_BR_X, 0 # endif #else // HAL_SPI_V2 @@ -228,6 +228,7 @@ void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { ws2812_leds[index].r = red; ws2812_leds[index].g = green; ws2812_leds[index].b = blue; + ws2812_dirty = true; #if defined(WS2812_RGBW) ws2812_rgb_to_rgbw(&ws2812_leds[index]); #endif @@ -248,6 +249,7 @@ void ws2812_flush(void) { // Instead spiSend can be used to send synchronously (or the thread logic can be added back). #ifndef WS2812_SPI_USE_CIRCULAR_BUFFER # ifdef WS2812_SPI_SYNC + if (!ws2812_dirty) return; spiSend(&WS2812_SPI_DRIVER, ARRAY_SIZE(txbuf), txbuf); # else spiStartSend(&WS2812_SPI_DRIVER, ARRAY_SIZE(txbuf), txbuf);