20#include "driver/rmt_tx.h"
25#define LED_STRIP_RMT_DEFAULT_RESOLUTION 10000000
26#define LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE 4
28#ifndef LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS_MULTIPLIER
29#if CONFIG_IDF_TARGET_ESP32C3
31#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS_MULTIPLIER 2
33#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS_MULTIPLIER 1
38#ifndef LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS
39#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
40#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS (LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS_MULTIPLIER * 64)
42#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS (LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS_MULTIPLIER * 48)
47static const char *TAG =
"led_strip_rmt";
51 rmt_channel_handle_t rmt_chan;
52 rmt_encoder_handle_t strip_encoder;
53 rmt_transmit_config_t tx_conf;
55 uint8_t bytes_per_pixel;
58 bool pixel_buf_allocated_internally;
61static esp_err_t led_strip_rmt_set_pixel(
led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue)
63 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
64 ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG,
"index out of maximum number of LEDs");
67 uint32_t start = index * rmt_strip->bytes_per_pixel;
68 uint8_t *pixel_buf = rmt_strip->pixel_buf;
70 pixel_buf[start + component_fmt.
format.
r_pos] = red & 0xFF;
71 pixel_buf[start + component_fmt.
format.
g_pos] = green & 0xFF;
72 pixel_buf[start + component_fmt.
format.
b_pos] = blue & 0xFF;
80static 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)
82 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
84 ESP_RETURN_ON_FALSE(index < rmt_strip->strip_len, ESP_ERR_INVALID_ARG, TAG,
"index out of maximum number of LEDs");
85 ESP_RETURN_ON_FALSE(component_fmt.
format.
num_components == 4, ESP_ERR_INVALID_ARG, TAG,
"led doesn't have 4 components");
87 uint32_t start = index * rmt_strip->bytes_per_pixel;
88 uint8_t *pixel_buf = rmt_strip->pixel_buf;
90 pixel_buf[start + component_fmt.
format.
r_pos] = red & 0xFF;
91 pixel_buf[start + component_fmt.
format.
g_pos] = green & 0xFF;
92 pixel_buf[start + component_fmt.
format.
b_pos] = blue & 0xFF;
93 pixel_buf[start + component_fmt.
format.
w_pos] = white & 0xFF;
98static esp_err_t led_strip_rmt_refresh_async(
led_strip_t *strip)
100 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
102 ESP_RETURN_ON_ERROR(rmt_enable(rmt_strip->rmt_chan), TAG,
"enable RMT channel failed");
103 ESP_RETURN_ON_ERROR(rmt_transmit(rmt_strip->rmt_chan, rmt_strip->strip_encoder, rmt_strip->pixel_buf,
104 rmt_strip->strip_len * rmt_strip->bytes_per_pixel, &rmt_strip->tx_conf), TAG,
"transmit pixels by RMT failed");
108static esp_err_t led_strip_rmt_wait_for_done(
led_strip_t *strip)
110 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
111 ESP_RETURN_ON_ERROR(rmt_tx_wait_all_done(rmt_strip->rmt_chan, -1), TAG,
"wait for RMT done failed");
112 ESP_RETURN_ON_ERROR(rmt_disable(rmt_strip->rmt_chan), TAG,
"disable RMT channel failed");
116static esp_err_t led_strip_rmt_refresh(
led_strip_t *strip)
118 ESP_RETURN_ON_ERROR(led_strip_rmt_refresh_async(strip), TAG,
"refresh async failed");
119 ESP_RETURN_ON_ERROR(led_strip_rmt_wait_for_done(strip), TAG,
"wait for done failed");
123static esp_err_t led_strip_rmt_clear(
led_strip_t *strip)
125 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
127 memset(rmt_strip->pixel_buf, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel);
128 return led_strip_rmt_refresh(strip);
131static esp_err_t led_strip_rmt_del(
led_strip_t *strip)
133 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
134 ESP_RETURN_ON_ERROR(rmt_del_channel(rmt_strip->rmt_chan), TAG,
"delete RMT channel failed");
135 ESP_RETURN_ON_ERROR(rmt_del_encoder(rmt_strip->strip_encoder), TAG,
"delete strip encoder failed");
136 if (rmt_strip->pixel_buf_allocated_internally) {
137 free(rmt_strip->pixel_buf);
145 led_strip_rmt_obj *rmt_strip = NULL;
146 esp_err_t ret = ESP_OK;
148 ESP_GOTO_ON_FALSE(led_config && rmt_config && ret_strip, ESP_ERR_INVALID_ARG, err, TAG,
"invalid argument");
159 ESP_RETURN_ON_FALSE(mask == 0x07, ESP_ERR_INVALID_ARG, TAG,
"invalid order argument");
163 ESP_RETURN_ON_FALSE(mask == 0x0F, ESP_ERR_INVALID_ARG, TAG,
"invalid order argument");
165 ESP_RETURN_ON_FALSE(
false, ESP_ERR_INVALID_ARG, TAG,
"invalid number of color components: %d", component_fmt.
format.
num_components);
169 rmt_strip = calloc(1,
sizeof(led_strip_rmt_obj));
170 ESP_GOTO_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, err, TAG,
"no mem for rmt strip");
176 rmt_strip->pixel_buf_allocated_internally =
false;
179 rmt_strip->pixel_buf = calloc(led_config->
max_leds * bytes_per_pixel,
sizeof(uint8_t));
180 ESP_GOTO_ON_FALSE(rmt_strip->pixel_buf, ESP_ERR_NO_MEM, err, TAG,
"no mem for pixel buffer");
181 rmt_strip->pixel_buf_allocated_internally =
true;
186 rmt_clock_source_t clk_src = RMT_CLK_SRC_DEFAULT;
190 size_t mem_block_symbols = LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS;
195 rmt_tx_channel_config_t rmt_chan_config = {
198 .mem_block_symbols = mem_block_symbols,
199 .resolution_hz = resolution,
200 .trans_queue_depth = LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE,
204 ESP_GOTO_ON_ERROR(rmt_new_tx_channel(&rmt_chan_config, &rmt_strip->rmt_chan), err, TAG,
"create RMT TX channel failed");
207 .resolution = resolution,
209 .timings = led_config->
timings,
211 ESP_GOTO_ON_ERROR(
rmt_new_led_strip_encoder(&strip_encoder_conf, &rmt_strip->strip_encoder), err, TAG,
"create LED strip encoder failed");
213 rmt_strip->component_fmt = component_fmt;
214 rmt_strip->bytes_per_pixel = bytes_per_pixel;
215 rmt_strip->strip_len = led_config->
max_leds;
216 rmt_strip->tx_conf = (rmt_transmit_config_t){
219 rmt_strip->base.set_pixel = led_strip_rmt_set_pixel;
220 rmt_strip->base.set_pixel_rgbw = led_strip_rmt_set_pixel_rgbw;
221 rmt_strip->base.refresh = led_strip_rmt_refresh;
222 rmt_strip->base.refresh_async = led_strip_rmt_refresh_async;
223 rmt_strip->base.refresh_wait_done = led_strip_rmt_wait_for_done;
224 rmt_strip->base.clear = led_strip_rmt_clear;
225 rmt_strip->base.del = led_strip_rmt_del;
227 *ret_strip = &rmt_strip->base;
231 if (rmt_strip->rmt_chan) {
232 rmt_del_channel(rmt_strip->rmt_chan);
234 if (rmt_strip->strip_encoder) {
235 rmt_del_encoder(rmt_strip->strip_encoder);
237 if (rmt_strip->pixel_buf_allocated_internally) {
238 free(rmt_strip->pixel_buf);
LED strip interface definition.
esp_err_t led_strip_new_rmt_device(const led_strip_config_t *led_config, const led_strip_rmt_config_t *rmt_config, led_strip_handle_t *ret_strip)
Create LED strip based on RMT TX channel.
struct led_strip_rmt_config_t::led_strip_rmt_extra_config flags
rmt_clock_source_t clk_src
LED Strip RMT specific configuration.
esp_err_t rmt_new_led_strip_encoder(const led_strip_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder)
Create RMT encoder for encoding LED strip pixels into RMT symbols.
Type of led strip encoder configuration.
#define LED_STRIP_COLOR_COMPONENT_FMT_GRB
Helper macros to set the color component format.
struct led_strip_t * led_strip_handle_t
Type of LED strip handle.
led_color_component_format_t color_component_format
struct led_strip_config_t::led_strip_extra_flags flags
led_strip_encoder_timings_t timings
struct led_color_component_format_t::format_layout format
uint8_t * external_pixel_buf
LED Strip common configurations The common configurations are not specific to any backend peripheral.
#define FASTLED_UNUSED(x)