diff --git a/rx_esp32/CMakeLists.txt b/rx_esp32/CMakeLists.txt index b35ba0d..ac19fa6 100644 --- a/rx_esp32/CMakeLists.txt +++ b/rx_esp32/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16.0) -set(COMPONENT_DIRS $ENV{IDF_PATH}/components ./lib ./src) +set(COMPONENT_DIRS $ENV{IDF_PATH}/components $ENV{IDF_PATH}/../idf-extra-components/led_strip ./lib ./src) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(rx_esp32) diff --git a/rx_esp32/dependencies.lock b/rx_esp32/dependencies.lock new file mode 100644 index 0000000..80bd792 --- /dev/null +++ b/rx_esp32/dependencies.lock @@ -0,0 +1,9 @@ +dependencies: + idf: + component_hash: null + source: + type: idf + version: 5.2.2 +manifest_hash: 25da577a782e8f239c184378e32f45cca356a1cf3257d50b4f7446629da3faa1 +target: esp32c6 +version: 1.0.0 diff --git a/rx_esp32/src/CMakeLists.txt b/rx_esp32/src/CMakeLists.txt index 39b41cf..2bf1fa4 100644 --- a/rx_esp32/src/CMakeLists.txt +++ b/rx_esp32/src/CMakeLists.txt @@ -10,7 +10,7 @@ idf_component_register( ./led.c ./commands.c INCLUDE_DIRS "./" - PRIV_REQUIRES - cli + PRIV_REQUIRES + cli led_strip spi_flash driver nvs_flash esp_wifi ) diff --git a/rx_esp32/src/led.c b/rx_esp32/src/led.c index e0f94c6..c20fde2 100644 --- a/rx_esp32/src/led.c +++ b/rx_esp32/src/led.c @@ -1,146 +1,47 @@ #include "led.h" -#include - #include -#include "driver/rmt_tx.h" -#include "driver/rmt_types.h" -#include "driver/rmt_encoder.h" -#include "driver/gpio.h" +#include "led_strip.h" -typedef struct { - rmt_encoder_t base; - rmt_encoder_t *bytes_encoder; - rmt_encoder_t *copy_encoder; - int state; - rmt_symbol_word_t reset_code; -} rmt_led_strip_encoder_t; +#define BUILDIN_LED_GPIO 8 -rmt_channel_handle_t led_rmt_channel; -rmt_led_strip_encoder_t led_enc; - -static size_t rmt_encode_led_strip(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state) -{ - rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); - rmt_encode_state_t session_state = 0; - rmt_encode_state_t state = 0; - size_t encoded_symbols = 0; - switch (led_encoder->state) { - case 0: // send RGB data - encoded_symbols += led_encoder->bytes_encoder->encode(led_encoder->bytes_encoder, channel, primary_data, data_size, &session_state); - if (session_state & RMT_ENCODING_COMPLETE) { - led_encoder->state = 1; // switch to next state when current encoding session finished - } - if (session_state & RMT_ENCODING_MEM_FULL) { - state |= RMT_ENCODING_MEM_FULL; - goto out; // yield if there's no free space for encoding artifacts - } - // fall-through - case 1: // send reset code - encoded_symbols += led_encoder->copy_encoder->encode(led_encoder->copy_encoder, channel, &led_encoder->reset_code, - sizeof(led_encoder->reset_code), &session_state); - if (session_state & RMT_ENCODING_COMPLETE) { - led_encoder->state = 0; // back to the initial encoding session - state |= RMT_ENCODING_COMPLETE; - } - if (session_state & RMT_ENCODING_MEM_FULL) { - state |= RMT_ENCODING_MEM_FULL; - goto out; // yield if there's no free space for encoding artifacts - } - } -out: - *ret_state = state; - return encoded_symbols; -} - -static esp_err_t rmt_del_led_strip_encoder(rmt_encoder_t *encoder) -{ - rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); - rmt_del_encoder(led_encoder->bytes_encoder); - rmt_del_encoder(led_encoder->copy_encoder); - free(led_encoder); - return ESP_OK; -} - -static esp_err_t rmt_led_strip_encoder_reset(rmt_encoder_t *encoder) -{ - rmt_led_strip_encoder_t *led_encoder = __containerof(encoder, rmt_led_strip_encoder_t, base); - rmt_encoder_reset(led_encoder->bytes_encoder); - rmt_encoder_reset(led_encoder->copy_encoder); - led_encoder->state = 0; - return ESP_OK; -} - -void led_init_encoder() -{ - led_enc.base.encode = rmt_encode_led_strip; - led_enc.base.del = rmt_del_led_strip_encoder; - led_enc.base.reset = rmt_led_strip_encoder_reset; - - rmt_bytes_encoder_config_t bytes_encoder_config; - // different led strip might have its own timing requirements, following parameter is for WS2812 - bytes_encoder_config = (rmt_bytes_encoder_config_t) { - .bit0 = { - .level0 = 1, - .duration0 = 0.3, // T0H=0.3us - .level1 = 0, - .duration1 = 0.9, // T0L=0.9us - }, - .bit1 = { - .level0 = 1, - .duration0 = 0.9, // T1H=0.9us - .level1 = 0, - .duration1 = 0.3, // T1L=0.3us - }, - .flags.msb_first = 1 // WS2812 transfer bit order: G7...G0R7...R0B7...B0 - }; - - rmt_new_bytes_encoder(&bytes_encoder_config, &led_enc.bytes_encoder); - rmt_copy_encoder_config_t copy_encoder_config = {}; - rmt_new_copy_encoder(©_encoder_config, &led_enc.copy_encoder); - - uint32_t reset_ticks = 10 /*MHz*/ * 280 / 2; // reset code duration defaults to 280us to accomodate WS2812B-V5 - led_enc.reset_code = (rmt_symbol_word_t) { - .level0 = 0, - .duration0 = reset_ticks, - .level1 = 0, - .duration1 = reset_ticks, - }; -} +led_strip_handle_t led_strip; void led_init(void) { - /* LED strip initialization with the GPIO and pixels number */ - rmt_tx_channel_config_t rmt_chan_config = { - .clk_src = RMT_CLK_SRC_DEFAULT, - .gpio_num = 8, - .mem_block_symbols = 48, - .resolution_hz = 10 * 1000 * 1000, // 10 MHz - .trans_queue_depth = 4, - .flags.with_dma = false, - .flags.invert_out = false, + // LED strip general initialization, according to your led board design + led_strip_config_t strip_config = { + .strip_gpio_num = BUILDIN_LED_GPIO, // The GPIO that connected to the LED strip's data line + .max_leds = 1, // The number of LEDs in the strip, + .led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip + .led_model = LED_MODEL_WS2812, // LED strip model + .flags.invert_out = false, // whether to invert the output signal }; - rmt_new_tx_channel(&rmt_chan_config, &led_rmt_channel); - led_init_encoder(); + + // LED strip backend configuration: RMT + led_strip_rmt_config_t rmt_config = { +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) + .rmt_channel = 0, +#else + .clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption + .resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency + .flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3 +#endif + }; + + // LED Strip object handle + led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip); led_setRGB(0, 0, 0); } void led_deinit(void) { - rmt_del_channel(led_rmt_channel); - rmt_del_encoder(&led_enc.base); + led_strip_del(led_strip); } void led_setRGB(uint8_t r, uint8_t g, uint8_t b) { - rmt_transmit_config_t tx_conf = { - .loop_count = 0, - }; - uint8_t pixel[] = {g, r, b}; - - rmt_enable(led_rmt_channel); - rmt_transmit(led_rmt_channel, &(led_enc.base), pixel, 3, &tx_conf); - rmt_tx_wait_all_done(led_rmt_channel, -1); - rmt_disable(led_rmt_channel); + led_strip_set_pixel(led_strip, 0, r, g, b); + led_strip_refresh(led_strip); }