diff --git a/lib/led_ws2812b.c b/lib/led_ws2812b.c index 3c1cb43..4d17849 100644 --- a/lib/led_ws2812b.c +++ b/lib/led_ws2812b.c @@ -34,7 +34,7 @@ #include // Cortex M3 utilities #include "led_ws2812b.h" // LED WS2812b library API -#include "global.h" // global definitions +#include "global.h" // common methods /** peripheral configuration */ /** @defgroup led_ws2812b_spi SPI peripheral used to control the WS2812b LEDs @@ -72,12 +72,11 @@ * The first SPI bit is the high start of the WS2812b bit frame. * The second SPI bit determines if the WS2812b bit is a 0 or 1. * The third SPI bit is the last part of the WS2812b bit frame, which is always low. - * Only the first 24 bits (3*8) are used. - * The binary pattern is 0b10010010010010010010010000000000 + * The binary pattern is 0b100100100100100100100100 */ -#define WS2812B_SPI_TEMPLATE 0x92492400 +#define WS2812B_SPI_TEMPLATE 0x924924 -uint8_t ws2812b_data[WS2812B_LEDS*3*3+40*3/8] = {0}; /**< data encoded to be shifted out by SPI for the WS2812b, pulse the 50us reset */ +uint8_t ws2812b_data[WS2812B_LEDS*3*3+40*3/8+1] = {0}; /**< data encoded to be shifted out by SPI for the WS2812b, plus the 50us reset (~40 data bits) */ static volatile bool transmit_flag = false; /**< flag set in software when transmission started, clear by interrupt when transmission completed */ void ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue) @@ -91,18 +90,18 @@ void ws2812b_set_rgb(uint16_t led, uint8_t red, uint8_t green, uint8_t blue) __WFI(); } - uint8_t colors[] = {green, red, blue}; - - // generate the pattern - for (uint8_t color=0; color>bit)&0x1)<<(bit*3+9); // encode the data bits in the pattern + 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>24); - ws2812b_data[led*3*3+color*3+1] = (bits_color>>16); - ws2812b_data[led*3*3+color*3+2] = (bits_color>>8); } } @@ -167,9 +166,15 @@ void ws2812b_setup(void) dma_set_priority(WS2812B_DMA, WS2812B_DMA_CH, DMA_CCR_PL_HIGH); // set priority to high since time is crucial for the peripheral nvic_enable_irq(WS2812B_DMA_IRQ); // enable interrupts for this DMA channel - // reset color - for (uint16_t led=0; led>16); + ws2812b_data[i*3+1] = (uint8_t)(WS2812B_SPI_TEMPLATE>>8); + ws2812b_data[i*3+2] = (uint8_t)(WS2812B_SPI_TEMPLATE>>0); + } + // fill remaining with with 0 to encode the reset code + for (uint16_t i=WS2812B_LEDS*3*3; i