add ws2812 optimisations to not send if there are no changes

This commit is contained in:
Xelus22 2025-01-26 00:50:15 +11:00
parent ca737d4496
commit 7a198c349d
4 changed files with 13 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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