Improve performance on LED driver

This commit is contained in:
Daniel Öster 2024-06-30 17:48:28 +03:00
parent 2a388d2d48
commit cefb9807e6

View file

@ -87,25 +87,18 @@ static void IRAM_ATTR ws2812_rmt_adapter(const void* src, rmt_item32_t* dest, si
*item_num = num; *item_num = num;
} }
void espShow(uint8_t pin, uint8_t* pixels, uint32_t numBytes, boolean is800KHz) { static bool rmt_initialized = false;
// Reserve channel static bool rmt_adapter_initialized = false;
rmt_channel_t channel = ADAFRUIT_RMT_CHANNEL_MAX;
for (size_t i = 0; i < ADAFRUIT_RMT_CHANNEL_MAX; i++) {
if (!rmt_reserved_channels[i]) {
rmt_reserved_channels[i] = true;
channel = i;
break;
}
}
if (channel == ADAFRUIT_RMT_CHANNEL_MAX) {
// Ran out of channels!
return;
}
#if defined(HAS_ESP_IDF_4) void espShow(uint8_t pin, uint8_t* pixels, uint32_t numBytes, boolean is800KHz) {
if (rmt_initialized == false) {
// Reserve channel
rmt_channel_t channel = 0;
#if defined(HAS_ESP_IDF_4)
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin, channel); rmt_config_t config = RMT_DEFAULT_CONFIG_TX(pin, channel);
config.clk_div = 2; config.clk_div = 2;
#else #else
// Match default TX config from ESP-IDF version 3.4 // Match default TX config from ESP-IDF version 3.4
rmt_config_t config = {.rmt_mode = RMT_MODE_TX, rmt_config_t config = {.rmt_mode = RMT_MODE_TX,
.channel = channel, .channel = channel,
@ -121,16 +114,16 @@ void espShow(uint8_t pin, uint8_t* pixels, uint32_t numBytes, boolean is800KHz)
.loop_en = false, .loop_en = false,
.idle_output_en = true, .idle_output_en = true,
}}; }};
#endif #endif
rmt_config(&config); rmt_config(&config);
rmt_driver_install(config.channel, 0, 0); rmt_driver_install(config.channel, 0, 0);
// Convert NS timings to ticks // Convert NS timings to ticks
uint32_t counter_clk_hz = 0; uint32_t counter_clk_hz = 0;
#if defined(HAS_ESP_IDF_4) #if defined(HAS_ESP_IDF_4)
rmt_get_counter_clock(channel, &counter_clk_hz); rmt_get_counter_clock(channel, &counter_clk_hz);
#else #else
// this emulates the rmt_get_counter_clock() function from ESP-IDF 3.4 // this emulates the rmt_get_counter_clock() function from ESP-IDF 3.4
if (RMT_LL_HW_BASE->conf_ch[config.channel].conf1.ref_always_on == RMT_BASECLK_REF) { if (RMT_LL_HW_BASE->conf_ch[config.channel].conf1.ref_always_on == RMT_BASECLK_REF) {
uint32_t div_cnt = RMT_LL_HW_BASE->conf_ch[config.channel].conf0.div_cnt; uint32_t div_cnt = RMT_LL_HW_BASE->conf_ch[config.channel].conf0.div_cnt;
@ -141,7 +134,7 @@ void espShow(uint8_t pin, uint8_t* pixels, uint32_t numBytes, boolean is800KHz)
uint32_t div = div_cnt == 0 ? 256 : div_cnt; uint32_t div = div_cnt == 0 ? 256 : div_cnt;
counter_clk_hz = APB_CLK_FREQ / (div); counter_clk_hz = APB_CLK_FREQ / (div);
} }
#endif #endif
// NS to tick converter // NS to tick converter
float ratio = (float)counter_clk_hz / 1e9; float ratio = (float)counter_clk_hz / 1e9;
@ -159,17 +152,19 @@ void espShow(uint8_t pin, uint8_t* pixels, uint32_t numBytes, boolean is800KHz)
} }
// Initialize automatic timing translator // Initialize automatic timing translator
rmt_translator_init(config.channel, ws2812_rmt_adapter); rmt_translator_init(0, ws2812_rmt_adapter);
rmt_initialized = true;
}
// Write and wait to finish // Write and wait to finish
rmt_write_sample(config.channel, pixels, (size_t)numBytes, true); rmt_write_sample(0, pixels, (size_t)numBytes, false);
rmt_wait_tx_done(config.channel, pdMS_TO_TICKS(100)); // rmt_wait_tx_done(config.channel, pdMS_TO_TICKS(100));
// Free channel again // Free channel again
rmt_driver_uninstall(config.channel); // rmt_driver_uninstall(config.channel);
rmt_reserved_channels[channel] = false; // rmt_reserved_channels[channel] = false;
gpio_set_direction(pin, GPIO_MODE_OUTPUT); // gpio_set_direction(pin, GPIO_MODE_OUTPUT);
} }
#endif #endif