Skip to content

RMT transmission with open drain adds pulse after transmission ends (IDFGH-7275) #8864

@floitsch

Description

@floitsch

Environment

  • Development Kit: ESP32-DevKitC
  • Kit version (for WroverKit/PicoKit/DevKitC): v4
  • IDF version (run git describe --tags to find it): v4.4.1 (but same code in master)
  • Build System: idf.py
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it): xtensa-esp32-elf-gcc (crosstool-NG esp-2021r2-patch3) 8.4.0
  • Operating System: Linux
  • Using an IDE?: No
  • Power Supply: USB

Problem Description

When the RMT module is set to output and the same pin is set to open drain, then rmt_write_items adds an
end-marker 0. However, when the idle-level is high, then this leads to the output being pulled down.

It is crucial that the pin is set to open drain and pulled high externally.

Expected Behavior

The rmt_write_items should not add additional signals.
Either the rmt_write_items should write an end marker that corresponds to the idle level, or the lower level shouldn't emit anything when seeing an end marker.

Actual Behavior

The pin is pulled low for a short period of time.
See the attached screenshot.

Steps to reproduce

  1. Pull pin 25 high with an external resistor (I used 15KOhm).
  2. Execute the given code.

Code to reproduce this issue

#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/rmt.h"

void app_main(void)
{
    gpio_num_t gpio_num = 25;
    rmt_config_t config_tx = RMT_DEFAULT_CONFIG_TX(gpio_num, 0);
    config_tx.tx_config.idle_level = 1;
    config_tx.tx_config.idle_output_en = true;

    ESP_ERROR_CHECK(rmt_config(&config_tx));
    ESP_ERROR_CHECK(rmt_driver_install(config_tx.channel, 0, 0));

    // Enable open drain
    GPIO.pin[gpio_num].pad_driver = 1;

    while (1) {
        rmt_item32_t pulse[] = {
            {{{ 50, 0, 50, 1 }}},
        };
        ESP_ERROR_CHECK(rmt_write_items(0, pulse, sizeof(pulse) / sizeof(pulse[0]), true));
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

rmt

Possible fix

The following patch potentially fixes the issue. If not, it might help to diagnose it.
It did remove the blip for me.

--- a/components/driver/rmt.c
+++ b/components/driver/rmt.c
@@ -1140,7 +1140,8 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, i
         p_rmt->tx_sub_len = item_sub_len;
     } else {
         rmt_fill_memory(channel, rmt_item, len_rem, 0);
-        rmt_item32_t stop_data = {0};
+        uint32_t idle_level = rmt_ll_tx_get_idle_level(rmt_contex.hal.regs, channel);
+        rmt_item32_t stop_data = {{{0, idle_level, 0, 0}}};
         rmt_ll_write_memory(rmt_contex.hal.mem, channel, &stop_data, 1, len_rem);
         p_rmt->tx_len_rem = 0;
     }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions