@@ -22,18 +22,36 @@ typedef struct {
22
22
rmt_channel_handle_t rmt_chan ;
23
23
rmt_encoder_handle_t strip_encoder ;
24
24
uint32_t strip_len ;
25
+ uint8_t bytes_per_pixel ;
25
26
uint8_t pixel_buf [];
26
27
} led_strip_rmt_obj ;
27
28
28
29
static esp_err_t led_strip_rmt_set_pixel (led_strip_t * strip , uint32_t index , uint32_t red , uint32_t green , uint32_t blue )
29
30
{
30
31
led_strip_rmt_obj * rmt_strip = __containerof (strip , led_strip_rmt_obj , base );
31
32
ESP_RETURN_ON_FALSE (index < rmt_strip -> strip_len , ESP_ERR_INVALID_ARG , TAG , "index out of maximum number of LEDs" );
32
- uint32_t start = index * 3 ;
33
+ uint32_t start = index * rmt_strip -> bytes_per_pixel ;
33
34
// In thr order of GRB, as LED strip like WS2812 sends out pixels in this order
34
35
rmt_strip -> pixel_buf [start + 0 ] = green & 0xFF ;
35
36
rmt_strip -> pixel_buf [start + 1 ] = red & 0xFF ;
36
37
rmt_strip -> pixel_buf [start + 2 ] = blue & 0xFF ;
38
+ if (rmt_strip -> bytes_per_pixel > 3 ) {
39
+ rmt_strip -> pixel_buf [start + 3 ] = 0 ;
40
+ }
41
+ return ESP_OK ;
42
+ }
43
+
44
+ static esp_err_t led_strip_rmt_set_pixel_rgbw (led_strip_t * strip , uint32_t index , uint32_t red , uint32_t green , uint32_t blue , uint32_t white )
45
+ {
46
+ led_strip_rmt_obj * rmt_strip = __containerof (strip , led_strip_rmt_obj , base );
47
+ ESP_RETURN_ON_FALSE (index < rmt_strip -> strip_len , ESP_ERR_INVALID_ARG , TAG , "index out of maximum number of LEDs" );
48
+ ESP_RETURN_ON_FALSE (rmt_strip -> bytes_per_pixel == 4 , ESP_ERR_INVALID_ARG , TAG , "wrong LED pixel format, expected 4 bytes per pixel" );
49
+ uint8_t * buf_start = rmt_strip -> pixel_buf + index * 4 ;
50
+ // SK6812 component order is GRBW
51
+ * buf_start = green & 0xFF ;
52
+ * ++ buf_start = red & 0xFF ;
53
+ * ++ buf_start = blue & 0xFF ;
54
+ * ++ buf_start = white & 0xFF ;
37
55
return ESP_OK ;
38
56
}
39
57
@@ -46,7 +64,7 @@ static esp_err_t led_strip_rmt_refresh(led_strip_t *strip)
46
64
47
65
ESP_RETURN_ON_ERROR (rmt_enable (rmt_strip -> rmt_chan ), TAG , "enable RMT channel failed" );
48
66
ESP_RETURN_ON_ERROR (rmt_transmit (rmt_strip -> rmt_chan , rmt_strip -> strip_encoder , rmt_strip -> pixel_buf ,
49
- rmt_strip -> strip_len * 3 , & tx_conf ), TAG , "transmit pixels by RMT failed" );
67
+ rmt_strip -> strip_len * rmt_strip -> bytes_per_pixel , & tx_conf ), TAG , "transmit pixels by RMT failed" );
50
68
ESP_RETURN_ON_ERROR (rmt_tx_wait_all_done (rmt_strip -> rmt_chan , -1 ), TAG , "flush RMT channel failed" );
51
69
ESP_RETURN_ON_ERROR (rmt_disable (rmt_strip -> rmt_chan ), TAG , "disable RMT channel failed" );
52
70
return ESP_OK ;
@@ -56,7 +74,7 @@ static esp_err_t led_strip_rmt_clear(led_strip_t *strip)
56
74
{
57
75
led_strip_rmt_obj * rmt_strip = __containerof (strip , led_strip_rmt_obj , base );
58
76
// Write zero to turn off all leds
59
- memset (rmt_strip -> pixel_buf , 0 , rmt_strip -> strip_len * 3 );
77
+ memset (rmt_strip -> pixel_buf , 0 , rmt_strip -> strip_len * rmt_strip -> bytes_per_pixel );
60
78
return led_strip_rmt_refresh (strip );
61
79
}
62
80
@@ -74,7 +92,14 @@ esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const l
74
92
led_strip_rmt_obj * rmt_strip = NULL ;
75
93
esp_err_t ret = ESP_OK ;
76
94
ESP_GOTO_ON_FALSE (led_config && rmt_config && ret_strip , ESP_ERR_INVALID_ARG , err , TAG , "invalid argument" );
77
- rmt_strip = calloc (1 , sizeof (led_strip_rmt_obj ) + led_config -> max_leds * 3 );
95
+ ESP_GOTO_ON_FALSE (led_config -> led_pixel_format <= LED_PIXEL_FORMAT_GRBW , ESP_ERR_INVALID_ARG , err , TAG , "invalid led_pixel_format" );
96
+ uint8_t bytes_per_pixel ;
97
+ if (led_config -> led_pixel_format == LED_PIXEL_FORMAT_GRBW ) {
98
+ bytes_per_pixel = 4 ;
99
+ } else {
100
+ bytes_per_pixel = 3 ;
101
+ }
102
+ rmt_strip = calloc (1 , sizeof (led_strip_rmt_obj ) + led_config -> max_leds * bytes_per_pixel );
78
103
ESP_GOTO_ON_FALSE (rmt_strip , ESP_ERR_NO_MEM , err , TAG , "no mem for rmt strip" );
79
104
uint32_t resolution = rmt_config -> resolution_hz ? rmt_config -> resolution_hz : LED_STRIP_RMT_DEFAULT_RESOLUTION ;
80
105
@@ -96,12 +121,15 @@ esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const l
96
121
97
122
led_strip_encoder_config_t strip_encoder_conf = {
98
123
.resolution = resolution ,
124
+ .led_model = led_config -> led_model
99
125
};
100
126
ESP_GOTO_ON_ERROR (rmt_new_led_strip_encoder (& strip_encoder_conf , & rmt_strip -> strip_encoder ), err , TAG , "create LED strip encoder failed" );
101
127
102
128
129
+ rmt_strip -> bytes_per_pixel = bytes_per_pixel ;
103
130
rmt_strip -> strip_len = led_config -> max_leds ;
104
131
rmt_strip -> base .set_pixel = led_strip_rmt_set_pixel ;
132
+ rmt_strip -> base .set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw ;
105
133
rmt_strip -> base .refresh = led_strip_rmt_refresh ;
106
134
rmt_strip -> base .clear = led_strip_rmt_clear ;
107
135
rmt_strip -> base .del = led_strip_rmt_del ;
0 commit comments