Skip to content

Commit b714409

Browse files
committed
feat: support ws2812 simple encode
1 parent 81aa67d commit b714409

7 files changed

Lines changed: 132 additions & 4 deletions

File tree

build_config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ projects:
9999
idf_version: release-v5.4
100100
target: esp32s3
101101

102+
- path: examples/peripherals/rmt/rmt_simple_tx
103+
idf_version: release-v5.4
104+
target: esp32s3
105+
106+
- path: examples/peripherals/rmt/ws2812_simple_encoder
107+
idf_version: release-v5.4
108+
target: esp32s3
109+
102110
- path: examples/peripherals/spi/spi_basic
103111
idf_version: release-v5.4
104112
target: esp32s3

examples/peripherals/rmt/rmt_simple_tx/main/main.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ void app_main(void)
1919

2020
rmt_encoder_handle_t bytes_encoder = NULL;
2121

22-
// 对bit 0和1 进行编码
22+
// Encode bit 0 and 1
2323
rmt_bytes_encoder_config_t bytes_enc_config = {
2424
.bit0 = {
2525
.level0 = 1,
2626
.duration0 = 1, // 1us
2727
.level1 = 0,
2828
.duration1 = 1, // 1us
29-
}, // 对于 0 而言,先高电平持续1us,在低电平持续1us
29+
}, // For bit 0: first high level for 1us, then low level for 1us
3030
.bit1 = {
3131
.level0 = 1,
3232
.duration0 = 9, // 9us
3333
.level1 = 0,
3434
.duration1 = 3, // 3us
35-
}, // 对于 1 而言,先高电平持续 9us,在低电平持续3us
35+
}, // For bit 1: first high level for 9us, then low level for 3us
3636
};
3737

3838
rmt_new_bytes_encoder(&bytes_enc_config, &bytes_encoder);
@@ -45,7 +45,7 @@ void app_main(void)
4545
while (1) {
4646
rmt_transmit(tx_channel, bytes_encoder, (uint8_t[]) {
4747
0x05
48-
}, 1, &transmit_config); // 对于0x05,其实是8bit的数据,对应 0000 0101
48+
}, 1, &transmit_config); // For 0x05, it's actually 8-bit data, corresponding to 0000 0101
4949
vTaskDelay(500 / portTICK_PERIOD_MS);
5050
}
5151
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_IDF_TARGET="esp32s3"
2+
CONFIG_IDF_TARGET_ESP32S3=y
3+
4+
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# For more information about build system see
2+
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
3+
# The following five lines of boilerplate have to be in your project's
4+
# CMakeLists in this exact order for cmake to work correctly
5+
cmake_minimum_required(VERSION 3.16)
6+
7+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
8+
project(ws2812_simple_encoder)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
idf_component_register(SRCS "main.c"
2+
INCLUDE_DIRS ".")
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include "freertos/FreeRTOS.h"
4+
#include "freertos/task.h"
5+
#include "driver/rmt_tx.h"
6+
#include "esp_log.h"
7+
8+
static const char *TAG = "WS2812";
9+
10+
static const rmt_symbol_word_t ws2812_zero = {
11+
.level0 = 1,
12+
.duration0 = 4, /*!< 0.4us */
13+
.level1 = 0,
14+
.duration1 = 9, /*!< 0.9us */
15+
};
16+
17+
static const rmt_symbol_word_t ws2812_one = {
18+
.level0 = 1,
19+
.duration0 = 9, /*!< 0.9us */
20+
.level1 = 0,
21+
.duration1 = 3, /*!< 0.4us */
22+
};
23+
24+
static const rmt_symbol_word_t ws2812_reset = {
25+
.level0 = 0,
26+
.duration0 = 250, /*!< 25us */
27+
.level1 = 0,
28+
.duration1 = 250, /*!< 25us */
29+
};
30+
31+
static size_t encoder_callback(const void *data, size_t data_size,
32+
size_t symbols_written, size_t symbols_free,
33+
rmt_symbol_word_t *symbols, bool *done, void *arg)
34+
{
35+
if (symbols_free < 8) {
36+
return 0; /*!< Need at least 8 symbols to form one byte */
37+
}
38+
printf("symbols_written:%d,data_size:%d\n", symbols_written, data_size);
39+
40+
size_t data_pos = symbols_written / 8; /*!< Calculate current byte position, assuming input is {0xFF, 0x00, 0x00}, data_size is 3, each byte written increments symbols_written by 8 */
41+
uint8_t *data_bytes = (uint8_t *)data;
42+
43+
if (data_pos < data_size) {
44+
size_t symbol_pos = 0;
45+
for (int bitmask = 0x80; bitmask != 0; bitmask >>= 1) {
46+
if (data_bytes[data_pos] & bitmask) {
47+
symbols[symbol_pos++] = ws2812_one;
48+
} else {
49+
symbols[symbol_pos++] = ws2812_zero;
50+
}
51+
}
52+
53+
return symbol_pos;
54+
} else {
55+
symbols[0] = ws2812_reset;
56+
*done = 1;
57+
return 1;
58+
}
59+
}
60+
61+
void app_main(void)
62+
{
63+
rmt_channel_handle_t led_chan = NULL;
64+
rmt_tx_channel_config_t tx_chan_config = {
65+
.mem_block_symbols = 64,
66+
.clk_src = RMT_CLK_SRC_DEFAULT,
67+
.resolution_hz = 10 * 1000 * 1000, // 10MHz, 1 tick = 0.1us
68+
.trans_queue_depth = 4,
69+
.gpio_num = GPIO_NUM_38,
70+
.intr_priority = 3
71+
};
72+
73+
ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan));
74+
75+
ESP_LOGI(TAG, "Create simple callback-based encoder");
76+
rmt_encoder_handle_t simple_encoder = NULL;
77+
const rmt_simple_encoder_config_t simple_encoder_cfg = {
78+
.callback = encoder_callback
79+
// Note we don't set min_chunk_size here as the default of 64 is good enough.
80+
};
81+
ESP_ERROR_CHECK(rmt_new_simple_encoder(&simple_encoder_cfg, &simple_encoder));
82+
83+
ESP_LOGI(TAG, "Enable RMT TX channel");
84+
ESP_ERROR_CHECK(rmt_enable(led_chan));
85+
86+
ESP_LOGI(TAG, "Start LED rainbow chase");
87+
rmt_transmit_config_t tx_config = {
88+
.loop_count = 0, // no transfer loop
89+
};
90+
91+
// WS2812 encoding is GRB
92+
uint8_t red[3] = {0x00, 0xFF, 0x00}; /*!< R */
93+
rmt_transmit(led_chan, simple_encoder, red, sizeof(red), &tx_config);
94+
vTaskDelay(1000 / portTICK_PERIOD_MS);
95+
96+
uint8_t green[3] = {0xFF, 0x00, 0x00}; /*!< G */
97+
rmt_transmit(led_chan, simple_encoder, green, sizeof(green), &tx_config);
98+
vTaskDelay(1000 / portTICK_PERIOD_MS);
99+
100+
uint8_t blue[3] = {0x00, 0x00, 0xFF}; /*!< B */
101+
rmt_transmit(led_chan, simple_encoder, blue, sizeof(blue), &tx_config);
102+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_IDF_TARGET="esp32s3"
2+
CONFIG_IDF_TARGET_ESP32S3=y
3+
4+
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y

0 commit comments

Comments
 (0)