ESP32S3 - Continuous RMT transmissions (IDFGH-11922) · Issue #13003 · espressif/esp-idf (original) (raw)

Answers checklist.

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.

esp32s3_rmt_bug

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