10#include <esp_clk_tree.h>
14static const char *
const TAG =
"esp32_rmt_led_strip";
16static const size_t RMT_SYMBOLS_PER_BYTE = 8;
24 esp_clk_tree_src_get_freq_hz((soc_module_clk_t) RMT_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq);
28#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
29static size_t IRAM_ATTR HOT encoder_callback(
const void *data,
size_t size,
size_t symbols_written,
size_t symbols_free,
30 rmt_symbol_word_t *symbols,
bool *done,
void *arg) {
31 auto *params =
static_cast<LedParams *
>(arg);
32 const auto *bytes =
static_cast<const uint8_t *
>(data);
33 size_t index = symbols_written / RMT_SYMBOLS_PER_BYTE;
37 if (symbols_free < RMT_SYMBOLS_PER_BYTE) {
40 for (
size_t i = 0; i < RMT_SYMBOLS_PER_BYTE; i++) {
41 if (bytes[index] & (1 << (7 - i))) {
42 symbols[i] = params->bit1;
44 symbols[i] = params->bit0;
47#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 1)
48 if ((index + 1) >=
size && params->reset.duration0 == 0 && params->reset.duration1 == 0) {
52 return RMT_SYMBOLS_PER_BYTE;
56 if (symbols_free < 1) {
59 symbols[0] = params->reset;
70 if (this->
buf_ ==
nullptr) {
71 ESP_LOGE(TAG,
"Cannot allocate LED buffer!");
75 memset(this->
buf_, 0, buffer_size);
79 ESP_LOGE(TAG,
"Cannot allocate effect data!");
84#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
94 rmt_tx_channel_config_t channel;
95 memset(&channel, 0,
sizeof(channel));
96 channel.clk_src = RMT_CLK_SRC_DEFAULT;
97 channel.resolution_hz = rmt_resolution_hz();
98 channel.gpio_num = gpio_num_t(this->
pin_);
100 channel.trans_queue_depth = 1;
102 channel.flags.with_dma = this->
use_dma_;
103 channel.intr_priority = 0;
104 if (rmt_new_tx_channel(&channel, &this->
channel_) != ESP_OK) {
105 ESP_LOGE(TAG,
"Channel creation failed");
110#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
111 rmt_simple_encoder_config_t encoder;
112 memset(&encoder, 0,
sizeof(encoder));
113 encoder.callback = encoder_callback;
115 encoder.min_chunk_size = RMT_SYMBOLS_PER_BYTE;
116 if (rmt_new_simple_encoder(&encoder, &this->
encoder_) != ESP_OK) {
117 ESP_LOGE(TAG,
"Encoder creation failed");
122 rmt_copy_encoder_config_t encoder;
123 memset(&encoder, 0,
sizeof(encoder));
124 if (rmt_new_copy_encoder(&encoder, &this->
encoder_) != ESP_OK) {
125 ESP_LOGE(TAG,
"Encoder creation failed");
131 if (rmt_enable(this->
channel_) != ESP_OK) {
132 ESP_LOGE(TAG,
"Enabling channel failed");
140 float ratio = (float) rmt_resolution_hz() / 1e09f;
171 ESP_LOGVV(TAG,
"Writing RGB values to bus");
173 esp_err_t error = rmt_tx_wait_all_done(this->
channel_, 1000);
174 if (error != ESP_OK) {
175 ESP_LOGE(TAG,
"RMT TX timeout");
181#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
188 uint8_t *psrc = this->
buf_;
189 rmt_symbol_word_t *pdest = this->
rmt_buf_;
190 while (size < buffer_size) {
192 for (
int i = 0; i < 8; i++) {
201 if (this->
params_.
reset.duration0 > 0 || this->params_.reset.duration1 > 0) {
208 rmt_transmit_config_t config;
209 memset(&config, 0,
sizeof(config));
210#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
215 if (error != ESP_OK) {
216 ESP_LOGE(TAG,
"RMT TX error");
226 return {led + colors.
r,
229 colors.
has_white() ? led + colors.
w :
nullptr,
236 "ESP32 RMT LED Strip:\n"
239 ESP_LOGCONFIG(TAG,
" RMT Symbols: %" PRIu32, this->
rmt_symbols_);
240 char channel_colors[5];
242 " Channel colors: %s\n"
243 " Max refresh rate: %" PRIu32
"\n"
244 " Number of LEDs: %u",
void mark_failed()
Mark this component as failed.
void status_set_warning()
void status_clear_warning()
An STL allocator that uses SPI or internal RAM.
float get_setup_priority() const override
size_t get_buffer_size_() const
rmt_encoder_handle_t encoder_
void write_state(light::LightState *state) override
light::ESPColorView get_view_internal(int32_t index) const override
int32_t size() const override
rmt_channel_handle_t channel_
void set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high, uint32_t bit1_low, uint32_t reset_time_high, uint32_t reset_time_low)
light::ChannelColors channel_colors_
void dump_config() override
optional< uint32_t > max_refresh_rate_
ESPColorCorrection correction_
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
constexpr float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
uint32_t IRAM_ATTR HOT micros()
Which byte of an addressable LED's data carries each colour.
const char * to_string(char *buf) const
Write the order back out as text, e.g.
uint8_t bytes_per_led() const