ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
led_strip_rmt_dev_idf4.c File Reference
#include <stdlib.h>
#include <string.h>
#include <sys/cdefs.h>
#include "esp_log.h"
#include "esp_check.h"
#include "driver/rmt.h"
#include "led_strip.h"
#include "led_strip_interface.h"
Include dependency graph for led_strip_rmt_dev_idf4.c:

Go to the source code of this file.

Data Structures

struct  led_strip_rmt_obj

Macros

#define WS2812_T0H_NS   (300)
#define WS2812_T0L_NS   (900)
#define WS2812_T1H_NS   (900)
#define WS2812_T1L_NS   (300)
#define SK6812_T0H_NS   (300)
#define SK6812_T0L_NS   (900)
#define SK6812_T1H_NS   (600)
#define SK6812_T1L_NS   (600)
#define LED_STRIP_RESET_MS   (10)
#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS   48

Functions

static void ws2812_rmt_adapter (const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num)
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)
static esp_err_t led_strip_rmt_refresh (led_strip_t *strip)
static esp_err_t led_strip_rmt_clear (led_strip_t *strip)
static esp_err_t led_strip_rmt_del (led_strip_t *strip)
esp_err_t led_strip_new_rmt_device (const led_strip_config_t *led_config, const led_strip_rmt_config_t *dev_config, led_strip_handle_t *ret_strip)
 Create LED strip based on RMT TX channel.

Variables

static const char * TAG = "led_strip_rmt"
static uint32_t led_t0h_ticks = 0
static uint32_t led_t1h_ticks = 0
static uint32_t led_t0l_ticks = 0
static uint32_t led_t1l_ticks = 0

Macro Definition Documentation

◆ LED_STRIP_RESET_MS

#define LED_STRIP_RESET_MS   (10)

Definition at line 27 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_rmt_refresh().

◆ LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS

#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS   48

Definition at line 33 of file led_strip_rmt_dev_idf4.c.

◆ SK6812_T0H_NS

#define SK6812_T0H_NS   (300)

Definition at line 22 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ SK6812_T0L_NS

#define SK6812_T0L_NS   (900)

Definition at line 23 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ SK6812_T1H_NS

#define SK6812_T1H_NS   (600)

Definition at line 24 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ SK6812_T1L_NS

#define SK6812_T1L_NS   (600)

Definition at line 25 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ WS2812_T0H_NS

#define WS2812_T0H_NS   (300)

Definition at line 17 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ WS2812_T0L_NS

#define WS2812_T0L_NS   (900)

Definition at line 18 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ WS2812_T1H_NS

#define WS2812_T1H_NS   (900)

Definition at line 19 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

◆ WS2812_T1L_NS

#define WS2812_T1L_NS   (300)

Definition at line 20 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device().

Function Documentation

◆ led_strip_new_rmt_device()

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.

Parameters
led_configLED strip configuration
rmt_configRMT specific configuration
ret_stripReturned LED strip handle
Returns
  • ESP_OK: create LED strip handle successfully
  • ESP_ERR_INVALID_ARG: create LED strip handle failed because of invalid argument
  • ESP_ERR_NO_MEM: create LED strip handle failed because of out of memory
  • ESP_FAIL: create LED strip handle failed because some other error

Definition at line 121 of file led_strip_rmt_dev_idf4.c.

122{
123 led_strip_rmt_obj *rmt_strip = NULL;
124 esp_err_t ret = ESP_OK;
125 ESP_RETURN_ON_FALSE(led_config && dev_config && ret_strip, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
126 ESP_RETURN_ON_FALSE(led_config->led_pixel_format < LED_PIXEL_FORMAT_INVALID, ESP_ERR_INVALID_ARG, TAG, "invalid led_pixel_format");
127 ESP_RETURN_ON_FALSE(dev_config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, TAG, "DMA is not supported");
128
129 uint8_t bytes_per_pixel = 3;
130 if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRBW) {
131 bytes_per_pixel = 4;
132 } else if (led_config->led_pixel_format == LED_PIXEL_FORMAT_GRB) {
133 bytes_per_pixel = 3;
134 } else {
135 assert(false);
136 }
137
138 // allocate memory for led_strip object
139 rmt_strip = calloc(1, sizeof(led_strip_rmt_obj) + led_config->max_leds * bytes_per_pixel);
140 ESP_RETURN_ON_FALSE(rmt_strip, ESP_ERR_NO_MEM, TAG, "request memory for les_strip failed");
141
142 // install RMT channel driver
143 rmt_config_t config = RMT_DEFAULT_CONFIG_TX(led_config->strip_gpio_num, dev_config->rmt_channel);
144 // set the minimal clock division because the LED strip needs a high clock resolution
145 config.clk_div = 2;
146
147 uint8_t mem_block_num = 2;
148 // override the default value if the user specify the mem block size
149 if (dev_config->mem_block_symbols) {
151 }
152 config.mem_block_num = mem_block_num;
153
154 ESP_GOTO_ON_ERROR(rmt_config(&config), err, TAG, "RMT config failed");
155 ESP_GOTO_ON_ERROR(rmt_driver_install(config.channel, 0, 0), err, TAG, "RMT install failed");
156
157 uint32_t counter_clk_hz = 0;
158 rmt_get_counter_clock((rmt_channel_t)dev_config->rmt_channel, &counter_clk_hz);
159 // ns -> ticks
160 float ratio = (float)counter_clk_hz / 1e9;
161 if (led_config->led_model == LED_MODEL_WS2812) {
162 led_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS);
163 led_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS);
164 led_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS);
165 led_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS);
166 } else if (led_config->led_model == LED_MODEL_SK6812) {
167 led_t0h_ticks = (uint32_t)(ratio * SK6812_T0H_NS);
168 led_t0l_ticks = (uint32_t)(ratio * SK6812_T0L_NS);
169 led_t1h_ticks = (uint32_t)(ratio * SK6812_T1H_NS);
170 led_t1l_ticks = (uint32_t)(ratio * SK6812_T1L_NS);
171 } else {
172 assert(false);
173 }
174
175 // adapter to translates the LES strip date frame into RMT symbols
176 rmt_translator_init((rmt_channel_t)dev_config->rmt_channel, ws2812_rmt_adapter);
177
178 rmt_strip->bytes_per_pixel = bytes_per_pixel;
179 rmt_strip->rmt_channel = (rmt_channel_t)dev_config->rmt_channel;
180 rmt_strip->strip_len = led_config->max_leds;
183 rmt_strip->base.clear = led_strip_rmt_clear;
184 rmt_strip->base.del = led_strip_rmt_del;
185
186 *ret_strip = &rmt_strip->base;
187 return ESP_OK;
188
189err:
190 if (rmt_strip) {
191 free(rmt_strip);
192 }
193 return ret;
194}
#define ESP_GOTO_ON_ERROR(x, goto_tag, log_tag, format,...)
int esp_err_t
Definition esp_err.h:21
#define ESP_OK
Definition esp_err.h:23
static esp_err_t led_strip_rmt_refresh(led_strip_t *strip)
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)
static esp_err_t led_strip_rmt_clear(led_strip_t *strip)
#define LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS
static esp_err_t led_strip_rmt_del(led_strip_t *strip)
static uint32_t led_t1l_ticks
#define WS2812_T1H_NS
static void ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num)
#define WS2812_T1L_NS
static uint32_t led_t0h_ticks
#define SK6812_T1H_NS
static uint32_t led_t0l_ticks
#define SK6812_T1L_NS
#define WS2812_T0H_NS
#define WS2812_T0L_NS
#define SK6812_T0L_NS
#define SK6812_T0H_NS
static uint32_t led_t1h_ticks
@ LED_MODEL_WS2812
@ LED_MODEL_SK6812
@ LED_PIXEL_FORMAT_GRB
@ LED_PIXEL_FORMAT_INVALID
@ LED_PIXEL_FORMAT_GRBW
static const char * TAG
Definition main/main.c:31
led_pixel_format_t led_pixel_format
struct led_strip_rmt_config_t::@177205126266303010206200207206146127175132325264 flags
esp_err_t(* refresh)(led_strip_t *strip)
Refresh memory colors to LEDs.
esp_err_t(* set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue)
Set RGB for a specific pixel.
esp_err_t(* del)(led_strip_t *strip)
Free LED strip resources.
esp_err_t(* clear)(led_strip_t *strip)
Clear LED strip (turn off all LEDs).

References led_strip_rmt_obj::base, led_strip_rmt_obj::bytes_per_pixel, led_strip_t::clear, led_strip_rmt_config_t::clk_src, led_strip_t::del, ESP_GOTO_ON_ERROR, ESP_OK, led_strip_config_t::flags, led_strip_rmt_config_t::flags, led_strip_config_t::invert_out, led_strip_config_t::led_model, LED_MODEL_SK6812, LED_MODEL_WS2812, led_strip_config_t::led_pixel_format, LED_PIXEL_FORMAT_GRB, LED_PIXEL_FORMAT_GRBW, LED_PIXEL_FORMAT_INVALID, led_strip_rmt_clear(), LED_STRIP_RMT_DEFAULT_MEM_BLOCK_SYMBOLS, LED_STRIP_RMT_DEFAULT_RESOLUTION, LED_STRIP_RMT_DEFAULT_TRANS_QUEUE_SIZE, led_strip_rmt_del(), led_strip_rmt_refresh(), led_strip_rmt_set_pixel(), led_strip_rmt_set_pixel_rgbw(), led_t0h_ticks, led_t0l_ticks, led_t1h_ticks, led_t1l_ticks, led_strip_config_t::max_leds, led_strip_rmt_config_t::mem_block_symbols, led_strip_t::refresh, led_strip_rmt_config_t::resolution_hz, led_strip_rmt_obj::rmt_chan, led_strip_rmt_obj::rmt_channel, rmt_new_led_strip_encoder(), led_strip_t::set_pixel, led_strip_t::set_pixel_rgbw, SK6812_T0H_NS, SK6812_T0L_NS, SK6812_T1H_NS, SK6812_T1L_NS, led_strip_rmt_obj::strip_encoder, led_strip_config_t::strip_gpio_num, led_strip_rmt_obj::strip_len, TAG, led_strip_rmt_config_t::with_dma, ws2812_rmt_adapter(), WS2812_T0H_NS, WS2812_T0L_NS, WS2812_T1H_NS, and WS2812_T1L_NS.

Here is the call graph for this function:

◆ led_strip_rmt_clear()

esp_err_t led_strip_rmt_clear ( led_strip_t * strip)
static

Definition at line 105 of file led_strip_rmt_dev_idf4.c.

106{
107 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
108 // Write zero to turn off all LEDs
109 memset(rmt_strip->buffer, 0, rmt_strip->strip_len * rmt_strip->bytes_per_pixel);
110 return led_strip_rmt_refresh(strip);
111}
static esp_err_t led_strip_rmt_refresh(led_strip_t *strip)

References led_strip_rmt_obj::buffer, led_strip_rmt_obj::bytes_per_pixel, led_strip_rmt_refresh(), and led_strip_rmt_obj::strip_len.

Here is the call graph for this function:

◆ led_strip_rmt_del()

esp_err_t led_strip_rmt_del ( led_strip_t * strip)
static

Definition at line 113 of file led_strip_rmt_dev_idf4.c.

114{
115 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
116 ESP_RETURN_ON_ERROR(rmt_driver_uninstall(rmt_strip->rmt_channel), TAG, "uninstall RMT driver failed");
117 free(rmt_strip);
118 return ESP_OK;
119}
#define ESP_RETURN_ON_ERROR(x, log_tag, format,...)

References ESP_OK, ESP_RETURN_ON_ERROR, led_strip_rmt_obj::rmt_channel, and TAG.

◆ led_strip_rmt_refresh()

esp_err_t led_strip_rmt_refresh ( led_strip_t * strip)
static

Definition at line 96 of file led_strip_rmt_dev_idf4.c.

97{
98 led_strip_rmt_obj *rmt_strip = __containerof(strip, led_strip_rmt_obj, base);
99 ESP_RETURN_ON_ERROR(rmt_write_sample(rmt_strip->rmt_channel, rmt_strip->buffer, rmt_strip->strip_len * rmt_strip->bytes_per_pixel, true), TAG,
100 "transmit RMT samples failed");
101 vTaskDelay(pdMS_TO_TICKS(LED_STRIP_RESET_MS));
102 return ESP_OK;
103}
#define LED_STRIP_RESET_MS

References led_strip_rmt_obj::buffer, led_strip_rmt_obj::bytes_per_pixel, ESP_OK, ESP_RETURN_ON_ERROR, LED_STRIP_RESET_MS, led_strip_rmt_obj::rmt_channel, led_strip_rmt_obj::strip_len, and TAG.

Referenced by led_strip_rmt_clear().

Here is the caller graph for this function:

◆ led_strip_rmt_set_pixel()

esp_err_t led_strip_rmt_set_pixel ( led_strip_t * strip,
uint32_t index,
uint32_t red,
uint32_t green,
uint32_t blue )
static

Definition at line 81 of file led_strip_rmt_dev_idf4.c.

82{
83 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 the maximum number of leds");
85 uint32_t start = index * rmt_strip->bytes_per_pixel;
86 // In thr order of GRB
87 rmt_strip->buffer[start + 0] = green & 0xFF;
88 rmt_strip->buffer[start + 1] = red & 0xFF;
89 rmt_strip->buffer[start + 2] = blue & 0xFF;
90 if (rmt_strip->bytes_per_pixel > 3) {
91 rmt_strip->buffer[start + 3] = 0;
92 }
93 return ESP_OK;
94}

References led_strip_rmt_obj::buffer, led_strip_rmt_obj::bytes_per_pixel, ESP_OK, and TAG.

◆ ws2812_rmt_adapter()

void ws2812_rmt_adapter ( const void * src,
rmt_item32_t * dest,
size_t src_size,
size_t wanted_num,
size_t * translated_size,
size_t * item_num )
static

Definition at line 49 of file led_strip_rmt_dev_idf4.c.

51{
52 if (src == NULL || dest == NULL) {
53 *translated_size = 0;
54 *item_num = 0;
55 return;
56 }
57 const rmt_item32_t bit0 = {{{ led_t0h_ticks, 1, led_t0l_ticks, 0 }}}; //Logical 0
58 const rmt_item32_t bit1 = {{{ led_t1h_ticks, 1, led_t1l_ticks, 0 }}}; //Logical 1
59 size_t size = 0;
60 size_t num = 0;
61 uint8_t *psrc = (uint8_t *)src;
62 rmt_item32_t *pdest = dest;
63 while (size < src_size && num < wanted_num) {
64 for (int i = 0; i < 8; i++) {
65 // MSB first
66 if (*psrc & (1 << (7 - i))) {
67 pdest->val = bit1.val;
68 } else {
69 pdest->val = bit0.val;
70 }
71 num++;
72 pdest++;
73 }
74 size++;
75 psrc++;
76 }
77 *translated_size = size;
78 *item_num = num;
79}

References led_t0h_ticks, led_t0l_ticks, led_t1h_ticks, and led_t1l_ticks.

Referenced by led_strip_new_rmt_device().

Here is the caller graph for this function:

Variable Documentation

◆ led_t0h_ticks

uint32_t led_t0h_ticks = 0
static

Definition at line 36 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device(), and ws2812_rmt_adapter().

◆ led_t0l_ticks

uint32_t led_t0l_ticks = 0
static

Definition at line 38 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device(), and ws2812_rmt_adapter().

◆ led_t1h_ticks

uint32_t led_t1h_ticks = 0
static

Definition at line 37 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device(), and ws2812_rmt_adapter().

◆ led_t1l_ticks

uint32_t led_t1l_ticks = 0
static

Definition at line 39 of file led_strip_rmt_dev_idf4.c.

Referenced by led_strip_new_rmt_device(), and ws2812_rmt_adapter().

◆ TAG

const char* TAG = "led_strip_rmt"
static

Definition at line 15 of file led_strip_rmt_dev_idf4.c.