ESP32S3 - Continuous RMT transmissions (IDFGH-11922) · Issue #13003 · espressif/esp-idf (original) (raw)
Answers checklist.
- I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- I have searched the issue tracker for a similar issue and not found a similar issue.
IDF version.
ESP-IDF v5.3-dev-1353-gb3f7e2c8a4
Espressif SoC revision.
ESP32-S3 (QFN56) (revision v0.1)
Operating System used.
Linux
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
None
Development Kit.
ESP32-S3-DevKitC-1
Power Supply used.
USB
What is the expected behavior?
I've always been under the impression that the RMT peripheral should be able to do continuous transmissions when the transmission queue is specified to be greater 1. However this does not seem to be the case. The current driver does introduce a significant delay between two consecutive transmissions.
What is the actual behavior?
Take a look at the following scope image. It shows a simple bytes encoder transmitting a 1 bit as a 50us high/50 us low pulse. Inside a transmission frame those timings are kept perfect, but between two transmissions they are clearly not although the very first bit is a 1 again.
Steps to reproduce.
Here is a reproducible example of my issue. It uses GPIO11 to output a signal with RMT and GPIO10 to get some reference toggle between two transmissions. The whole example is also available here: https://github.com/higaski/esp32s3_rmt_bug
#include <driver/gpio.h> #include <driver/rmt_tx.h> #include <esp_task.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include #include "sdkconfig.h"
rmt_channel_handle_t channel{}; rmt_encoder_handle_t encoder{};
// Toggle GPIO10 after each RMT transmission bool gpio10_state{}; bool IRAM_ATTR rmt_callback(rmt_channel_handle_t, rmt_tx_done_event_data_t const*, void*) { gpio_set_level(GPIO_NUM_10, gpio10_state = !gpio10_state); return pdFALSE; }
void task_function(void*) { // Initialize RMT on GPIO11 static constexpr rmt_tx_channel_config_t chan_config{ .gpio_num = GPIO_NUM_11, .clk_src = RMT_CLK_SRC_DEFAULT, .resolution_hz = 1'000'000u, .mem_block_symbols = (SOC_RMT_CHANNELS_PER_GROUP * SOC_RMT_MEM_WORDS_PER_CHANNEL) / sizeof(rmt_symbol_word_t), // 8 channels sharing 384x32 bit RAM .trans_queue_depth = 2uz, .intr_priority = 3, .flags = { .invert_out = false, .with_dma = false, .io_loop_back = false, .io_od_mode = false, }}; ESP_ERROR_CHECK(rmt_new_tx_channel(&chan_config, &channel)); ESP_ERROR_CHECK(rmt_enable(channel));
// Some simple bytes encoder static constexpr rmt_bytes_encoder_config_t bytes_encoder_config{ .bit0 = { .duration0 = 100, .level0 = 1, .duration1 = 100, .level1 = 0, }, .bit1 = { .duration0 = 50, .level0 = 1, .duration1 = 50, .level1 = 0, }, }; ESP_ERROR_CHECK(rmt_new_bytes_encoder(&bytes_encoder_config, &encoder));
// Enable RMT callback rmt_tx_event_callbacks_t cbs{.on_trans_done = rmt_callback}; ESP_ERROR_CHECK(rmt_tx_register_event_callbacks(channel, &cbs, NULL));
// Some bytes to send std::array<uint8_t, 3uz> bytes_to_send{0xFFu, 0x00u, 0xFFu};
for (;;) { static constexpr rmt_transmit_config_t config{}; ESP_ERROR_CHECK(rmt_transmit( channel, encoder, data(bytes_to_send), size(bytes_to_send), &config)); } }
extern "C" void app_main() { // Get some pin to toggle static constexpr gpio_config_t io_conf{.pin_bit_mask = 1ull << GPIO_NUM_10, .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE}; ESP_ERROR_CHECK(gpio_config(&io_conf));
xTaskCreatePinnedToCore( task_function, NULL, 4096uz, NULL, ESP_TASK_PRIO_MAX - 1u, NULL, 1);
for (;;) vTaskDelay(pdMS_TO_TICKS(5000u)); }
Debug Logs.
No response
More Information.
No response