Added support for RGBW NeoPixels (#449)
This commit is contained in:
		
							parent
							
								
									68cc1451b2
								
							
						
					
					
						commit
						e24b6579ff
					
				
					 3 changed files with 32 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue