Added support for RGBW NeoPixels (#449)

This commit is contained in:
Erwin Boskma 2017-10-08 20:02:39 +02:00 committed by Ruslan V. Uss
parent 68cc1451b2
commit e24b6579ff
3 changed files with 32 additions and 12 deletions

View file

@ -17,7 +17,7 @@
#include "ws2812_i2s/ws2812_i2s.h" #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_fade_factor = 2;
const uint32_t tail_length = 8; const uint32_t tail_length = 8;
@ -41,7 +41,7 @@ static int fix_index(int index)
static ws2812_pixel_t next_colour() 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.red = rand() % 256;
colour.green = rand() % 256; colour.green = rand() % 256;
colour.blue = rand() % 256; colour.blue = rand() % 256;
@ -54,7 +54,7 @@ static void demo(void *pvParameters)
ws2812_pixel_t pixels[led_number]; ws2812_pixel_t pixels[led_number];
int head_index = 0; 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); 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, memset(&pixels[fix_index(head_index - tail_length)], 0,
sizeof(ws2812_pixel_t)); sizeof(ws2812_pixel_t));
ws2812_i2s_update(pixels); ws2812_i2s_update(pixels, PIXEL_RGB);
vTaskDelay(20 / portTICK_PERIOD_MS); vTaskDelay(50 / portTICK_PERIOD_MS);
} }
} }
} }
@ -78,6 +78,14 @@ static void demo(void *pvParameters)
void user_init(void) void user_init(void)
{ {
uart_set_baud(0, 115200); 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); xTaskCreate(&demo, "ws2812_i2s", 256, NULL, 10, NULL);
} }

View file

@ -37,7 +37,7 @@
#endif #endif
#define MAX_DMA_BLOCK_SIZE 4095 #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. * 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; dma_block_list_size = dma_buffer_size / MAX_DMA_BLOCK_SIZE;
if (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, 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) {}; while (i2s_dma_processing) {};
uint16_t *p_dma_buf = dma_buffer; 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 // green
*p_dma_buf++ = bitpatterns[pixels[i].green & 0x0F]; *p_dma_buf++ = bitpatterns[pixels[i].green & 0x0F];
*p_dma_buf++ = bitpatterns[pixels[i].green >> 4]; *p_dma_buf++ = bitpatterns[pixels[i].green >> 4];
@ -174,6 +174,12 @@ void ws2812_i2s_update(ws2812_pixel_t *pixels)
// blue // blue
*p_dma_buf++ = bitpatterns[pixels[i].blue & 0x0F]; *p_dma_buf++ = bitpatterns[pixels[i].blue & 0x0F];
*p_dma_buf++ = bitpatterns[pixels[i].blue >> 4]; *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; i2s_dma_processing = true;

View file

@ -35,8 +35,14 @@ typedef struct {
uint8_t red; uint8_t red;
uint8_t green; uint8_t green;
uint8_t blue; uint8_t blue;
uint8_t white;
} ws2812_pixel_t; } ws2812_pixel_t;
typedef enum {
PIXEL_RGB = 12,
PIXEL_RGBW = 16
} pixeltype_t;
/** /**
* Initialize i2s and dma subsystems to work with ws2812 led strip. * 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. * @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. * 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 * @param pixels Array of 'pixels_number' pixels. The array must contain all
* the pixels. * the pixels.
*/ */
void ws2812_i2s_update(ws2812_pixel_t *pixels); void ws2812_i2s_update(ws2812_pixel_t *pixels, pixeltype_t type);
#ifdef __cplusplus #ifdef __cplusplus
} }