led_ws2812b: improve set LED speed
This commit is contained in:
parent
cfbe9234b1
commit
9b9751e79d
|
@ -60,20 +60,34 @@ void led_ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue)
|
|||
return;
|
||||
}
|
||||
|
||||
const uint8_t colors[] = {green, red, blue}; // color order for the WS2812B
|
||||
const uint8_t pattern_bit[] = {0x02, 0x10, 0x80, 0x04, 0x20, 0x01, 0x08, 0x40}; // which bit to change in the pattern
|
||||
const uint8_t pattern_byte[] = {2, 2, 2, 1, 1, 0, 0, 0}; // in which byte in the pattern to write the pattern bit
|
||||
for (uint8_t color = 0; color < LENGTH(colors); color++) { // colors are encoded similarly
|
||||
// fill the middle bit (fixed is faster than calculating it)
|
||||
for (uint8_t bit = 0; bit < 8; bit++) { // bit from the color to set/clear
|
||||
if (colors[color] & (1 << bit)) { // setting bit
|
||||
led_ws2812b_data[led * 3 * 3 + color * 3 + pattern_byte[bit]] |= pattern_bit[bit]; // setting bit is pattern
|
||||
} else { // clear bit
|
||||
led_ws2812b_data[led * 3 * 3 + color * 3 + pattern_byte[bit]] &= ~pattern_bit[bit]; // clearing bit is pattern
|
||||
}
|
||||
// convert RGB bit to SPI bit (each bit is encoded in 3 bits)
|
||||
uint32_t red_spi = LED_WS2812B_SPI_TEMPLATE, green_spi = LED_WS2812B_SPI_TEMPLATE, blue_spi = LED_WS2812B_SPI_TEMPLATE;
|
||||
uint32_t bit_spi = 0x2; // the bit to set in the SPI stream
|
||||
for (uint8_t bit = 0; bit < 8; bit++) { // bit from the color to set/clear
|
||||
const uint8_t byte_bit = (1 << bit); // which bit to check
|
||||
if (red & byte_bit) {
|
||||
red_spi |= bit_spi;
|
||||
}
|
||||
if (green & byte_bit) {
|
||||
green_spi |= bit_spi;
|
||||
}
|
||||
if (blue & byte_bit) {
|
||||
blue_spi |= bit_spi;
|
||||
}
|
||||
bit_spi <<= 3; // go to next SPI bit
|
||||
}
|
||||
|
||||
// set calculated pattern in stream (GRB)
|
||||
// we don't stop the DMA, instead we set LSB to MSB for gradient transition
|
||||
led_ws2812b_data[led * 3 * 3 + 0 + 2] = (green_spi >> 0);
|
||||
led_ws2812b_data[led * 3 * 3 + 3 + 2] = (red_spi >> 0);
|
||||
led_ws2812b_data[led * 3 * 3 + 6 + 2] = (blue_spi >> 0);
|
||||
led_ws2812b_data[led * 3 * 3 + 0 + 1] = (green_spi >> 8);
|
||||
led_ws2812b_data[led * 3 * 3 + 3 + 1] = (red_spi >> 8);
|
||||
led_ws2812b_data[led * 3 * 3 + 6 + 1] = (blue_spi >> 8);
|
||||
led_ws2812b_data[led * 3 * 3 + 0 + 0] = (green_spi >> 16);
|
||||
led_ws2812b_data[led * 3 * 3 + 3 + 0] = (red_spi >> 16);
|
||||
led_ws2812b_data[led * 3 * 3 + 6 + 0] = (blue_spi >> 16);
|
||||
}
|
||||
|
||||
void led_ws2812b_setup(void)
|
||||
|
|
Loading…
Reference in New Issue