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

View file

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

View file

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