From e24b6579fff04e59e5bfde7e222a93165383d5e5 Mon Sep 17 00:00:00 2001 From: Erwin Boskma Date: Sun, 8 Oct 2017 20:02:39 +0200 Subject: [PATCH] Added support for RGBW NeoPixels (#449) --- examples/ws2812_i2s/ws2812_i2s_colour_loop.c | 18 +++++++++++++----- extras/ws2812_i2s/ws2812_i2s.c | 16 +++++++++++----- extras/ws2812_i2s/ws2812_i2s.h | 10 ++++++++-- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/examples/ws2812_i2s/ws2812_i2s_colour_loop.c b/examples/ws2812_i2s/ws2812_i2s_colour_loop.c index 05f47c4..c5b5411 100644 --- a/examples/ws2812_i2s/ws2812_i2s_colour_loop.c +++ b/examples/ws2812_i2s/ws2812_i2s_colour_loop.c @@ -17,7 +17,7 @@ #include "ws2812_i2s/ws2812_i2s.h" -const uint32_t led_number = 60; +const uint32_t led_number = 12; const uint32_t tail_fade_factor = 2; const uint32_t tail_length = 8; @@ -41,7 +41,7 @@ static int fix_index(int index) static ws2812_pixel_t next_colour() { - ws2812_pixel_t colour = {0, 0, 0}; + ws2812_pixel_t colour = {0, 0, 0, 0}; colour.red = rand() % 256; colour.green = rand() % 256; colour.blue = rand() % 256; @@ -54,7 +54,7 @@ static void demo(void *pvParameters) ws2812_pixel_t pixels[led_number]; int head_index = 0; - ws2812_i2s_init(led_number); + ws2812_i2s_init(led_number, PIXEL_RGB); memset(pixels, 0, sizeof(ws2812_pixel_t) * led_number); @@ -69,8 +69,8 @@ static void demo(void *pvParameters) memset(&pixels[fix_index(head_index - tail_length)], 0, sizeof(ws2812_pixel_t)); - ws2812_i2s_update(pixels); - vTaskDelay(20 / portTICK_PERIOD_MS); + ws2812_i2s_update(pixels, PIXEL_RGB); + vTaskDelay(50 / portTICK_PERIOD_MS); } } } @@ -78,6 +78,14 @@ static void demo(void *pvParameters) void user_init(void) { uart_set_baud(0, 115200); + struct sdk_station_config config = { + .ssid = "Loading...", + .password = "morays59924_howitzer", + }; + + /* required to call wifi_set_opmode before station_set_config */ + sdk_wifi_set_opmode(STATION_MODE); + sdk_wifi_station_set_config(&config); xTaskCreate(&demo, "ws2812_i2s", 256, NULL, 10, NULL); } diff --git a/extras/ws2812_i2s/ws2812_i2s.c b/extras/ws2812_i2s/ws2812_i2s.c index 712c894..62dc496 100644 --- a/extras/ws2812_i2s/ws2812_i2s.c +++ b/extras/ws2812_i2s/ws2812_i2s.c @@ -37,7 +37,7 @@ #endif #define MAX_DMA_BLOCK_SIZE 4095 -#define DMA_PIXEL_SIZE 12 // each colour takes 4 bytes +// #define DMA_PIXEL_SIZE 16 // each colour takes 4 bytes /** * Amount of zero data to produce WS2812 reset condition. @@ -117,9 +117,9 @@ static inline void init_descriptors_list(uint8_t *buf, uint32_t total_dma_data_s } } -void ws2812_i2s_init(uint32_t pixels_number) +void ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type) { - dma_buffer_size = pixels_number * DMA_PIXEL_SIZE; + dma_buffer_size = pixels_number * type; dma_block_list_size = dma_buffer_size / MAX_DMA_BLOCK_SIZE; if (dma_buffer_size % MAX_DMA_BLOCK_SIZE) { @@ -156,13 +156,13 @@ const IRAM_DATA int16_t bitpatterns[16] = 0b1110111010001000, 0b1110111010001110, 0b1110111011101000, 0b1110111011101110, }; -void ws2812_i2s_update(ws2812_pixel_t *pixels) +void ws2812_i2s_update(ws2812_pixel_t *pixels, pixeltype_t type) { while (i2s_dma_processing) {}; uint16_t *p_dma_buf = dma_buffer; - for (uint32_t i = 0; i < (dma_buffer_size / DMA_PIXEL_SIZE); i++) { + for (uint32_t i = 0; i < (dma_buffer_size / type); i++) { // green *p_dma_buf++ = bitpatterns[pixels[i].green & 0x0F]; *p_dma_buf++ = bitpatterns[pixels[i].green >> 4]; @@ -174,6 +174,12 @@ void ws2812_i2s_update(ws2812_pixel_t *pixels) // blue *p_dma_buf++ = bitpatterns[pixels[i].blue & 0x0F]; *p_dma_buf++ = bitpatterns[pixels[i].blue >> 4]; + + if(type == PIXEL_RGBW) { + // white + *p_dma_buf++ = bitpatterns[pixels[i].white & 0x0F]; + *p_dma_buf++ = bitpatterns[pixels[i].white >> 4]; + } } i2s_dma_processing = true; diff --git a/extras/ws2812_i2s/ws2812_i2s.h b/extras/ws2812_i2s/ws2812_i2s.h index f6ebc82..16956dc 100644 --- a/extras/ws2812_i2s/ws2812_i2s.h +++ b/extras/ws2812_i2s/ws2812_i2s.h @@ -35,8 +35,14 @@ typedef struct { uint8_t red; uint8_t green; uint8_t blue; + uint8_t white; } ws2812_pixel_t; +typedef enum { + PIXEL_RGB = 12, + PIXEL_RGBW = 16 +} pixeltype_t; + /** * Initialize i2s and dma subsystems to work with ws2812 led strip. * @@ -44,7 +50,7 @@ typedef struct { * * @param pixels_number Number of pixels in the strip. */ -void ws2812_i2s_init(uint32_t pixels_number); +void ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type); /** * Update ws2812 pixels. @@ -52,7 +58,7 @@ void ws2812_i2s_init(uint32_t pixels_number); * @param pixels Array of 'pixels_number' pixels. The array must contain all * the pixels. */ -void ws2812_i2s_update(ws2812_pixel_t *pixels); +void ws2812_i2s_update(ws2812_pixel_t *pixels, pixeltype_t type); #ifdef __cplusplus }