12 namespace esp32_rmt_led_strip {
14 static const char *
const TAG =
"esp32_rmt_led_strip";
16 #ifdef USE_ESP32_VARIANT_ESP32H2 17 static const uint32_t RMT_CLK_FREQ = 32000000;
18 static const uint8_t RMT_CLK_DIV = 1;
20 static const uint32_t RMT_CLK_FREQ = 80000000;
21 static const uint8_t RMT_CLK_DIV = 2;
25 ESP_LOGCONFIG(TAG,
"Setting up ESP32 LED Strip...");
31 if (this->
buf_ ==
nullptr) {
32 ESP_LOGE(TAG,
"Cannot allocate LED buffer!");
36 memset(this->
buf_, 0, buffer_size);
40 ESP_LOGE(TAG,
"Cannot allocate effect data!");
45 #if ESP_IDF_VERSION_MAJOR >= 5 51 rmt_tx_channel_config_t channel;
52 memset(&channel, 0,
sizeof(channel));
53 channel.clk_src = RMT_CLK_SRC_DEFAULT;
54 channel.resolution_hz = RMT_CLK_FREQ / RMT_CLK_DIV;
55 channel.gpio_num = gpio_num_t(this->
pin_);
57 channel.trans_queue_depth = 1;
58 channel.flags.io_loop_back = 0;
59 channel.flags.io_od_mode = 0;
60 channel.flags.invert_out = 0;
61 channel.flags.with_dma = 0;
62 channel.intr_priority = 0;
63 if (rmt_new_tx_channel(&channel, &this->
channel_) != ESP_OK) {
64 ESP_LOGE(TAG,
"Channel creation failed");
69 rmt_copy_encoder_config_t encoder;
70 memset(&encoder, 0,
sizeof(encoder));
71 if (rmt_new_copy_encoder(&encoder, &this->
encoder_) != ESP_OK) {
72 ESP_LOGE(TAG,
"Encoder creation failed");
77 if (rmt_enable(this->
channel_) != ESP_OK) {
78 ESP_LOGE(TAG,
"Enabling channel failed");
89 memset(&config, 0,
sizeof(config));
91 config.rmt_mode = RMT_MODE_TX;
92 config.gpio_num = gpio_num_t(this->
pin_);
93 config.mem_block_num = 1;
94 config.clk_div = RMT_CLK_DIV;
95 config.tx_config.loop_en =
false;
96 config.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
97 config.tx_config.carrier_en =
false;
98 config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
99 config.tx_config.idle_output_en =
true;
101 if (rmt_config(&config) != ESP_OK) {
102 ESP_LOGE(TAG,
"Cannot initialize RMT!");
106 if (rmt_driver_install(config.channel, 0, 0) != ESP_OK) {
107 ESP_LOGE(TAG,
"Cannot install RMT driver!");
115 uint32_t bit1_low, uint32_t reset_time_high, uint32_t reset_time_low) {
116 float ratio = (float) RMT_CLK_FREQ / RMT_CLK_DIV / 1e09f;
119 this->
bit0_.duration0 = (uint32_t) (ratio * bit0_high);
120 this->
bit0_.level0 = 1;
121 this->
bit0_.duration1 = (uint32_t) (ratio * bit0_low);
122 this->
bit0_.level1 = 0;
124 this->
bit1_.duration0 = (uint32_t) (ratio * bit1_high);
125 this->
bit1_.level0 = 1;
126 this->
bit1_.duration1 = (uint32_t) (ratio * bit1_low);
127 this->
bit1_.level1 = 0;
129 this->
reset_.duration0 = (uint32_t) (ratio * reset_time_high);
131 this->
reset_.duration1 = (uint32_t) (ratio * reset_time_low);
146 ESP_LOGVV(TAG,
"Writing RGB values to bus...");
148 #if ESP_IDF_VERSION_MAJOR >= 5 149 esp_err_t error = rmt_tx_wait_all_done(this->
channel_, 1000);
151 esp_err_t error = rmt_wait_tx_done(this->
channel_, pdMS_TO_TICKS(1000));
153 if (error != ESP_OK) {
154 ESP_LOGE(TAG,
"RMT TX timeout");
164 uint8_t *psrc = this->
buf_;
165 #if ESP_IDF_VERSION_MAJOR >= 5 166 rmt_symbol_word_t *pdest = this->
rmt_buf_;
168 rmt_item32_t *pdest = this->
rmt_buf_;
170 while (size < buffer_size) {
172 for (
int i = 0; i < 8; i++) {
173 pdest->val = b & (1 << (7 - i)) ? this->
bit1_.val : this->
bit0_.val;
181 if (this->
reset_.duration0 > 0 || this->reset_.duration1 > 0) {
182 pdest->val = this->
reset_.val;
187 #if ESP_IDF_VERSION_MAJOR >= 5 188 rmt_transmit_config_t config;
189 memset(&config, 0,
sizeof(config));
190 config.loop_count = 0;
191 config.flags.eot_level = 0;
196 if (error != ESP_OK) {
197 ESP_LOGE(TAG,
"RMT TX error");
205 int32_t r = 0, g = 0, b = 0;
239 uint8_t white = this->
is_wrgb_ ? 0 : 3;
241 return {this->
buf_ + (index * multiplier) + r + this->
is_wrgb_,
243 this->
buf_ + (index * multiplier) + b + this->is_wrgb_,
244 this->
is_rgbw_ || this->is_wrgb_ ? this->
buf_ + (index * multiplier) + white :
nullptr,
250 ESP_LOGCONFIG(TAG,
"ESP32 RMT LED Strip:");
251 ESP_LOGCONFIG(TAG,
" Pin: %u", this->
pin_);
252 #if ESP_IDF_VERSION_MAJOR >= 5 253 ESP_LOGCONFIG(TAG,
" RMT Symbols: %" PRIu32, this->
rmt_symbols_);
255 ESP_LOGCONFIG(TAG,
" Channel: %u", this->
channel_);
257 const char *rgb_order;
278 rgb_order =
"UNKNOWN";
281 ESP_LOGCONFIG(TAG,
" RGB Order: %s", rgb_order);
283 ESP_LOGCONFIG(TAG,
" Number of LEDs: %u", this->
num_leds_);
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
rmt_encoder_handle_t encoder_
light::ESPColorView get_view_internal(int32_t index) const override
void status_set_warning(const char *message="unspecified")
uint32_t IRAM_ATTR HOT micros()
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)
float get_setup_priority() const override
void status_clear_warning()
void write_state(light::LightState *state) override
rmt_channel_handle_t channel_
void dump_config() override
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
ESPColorCorrection correction_
virtual void mark_failed()
Mark this component as failed.
rmt_symbol_word_t * rmt_buf_
Implementation of SPI Controller mode.
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
int32_t size() const override
size_t get_buffer_size_() const
optional< uint32_t > max_refresh_rate_