Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value of RMT mem_block_symbols for proper DMA operation has changed between v5.1.1 and current master (IDFGH-11426) #12564

Closed
3 tasks done
tonystuart opened this issue Nov 11, 2023 · 0 comments
Assignees
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@tonystuart
Copy link
Contributor

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.

v5.3-dev-280-gedc3b268a9

Espressif SoC revision.

ESP32-S3

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.

Custom Board

Power Supply used.

USB

What is the expected behavior?

I expected code that drives an LED strip and works with DMA on ESP-IDF v5.1.1 to work on the latest master.

What is the actual behavior?

Instead it illuminates random LEDs with random colors.

Steps to reproduce.

I encountered the problem with my existing code when I switched to the latest version of ESP-IDF master. It works in v5.1.1.

To better understand the problem, I created a simplified version of the ESP-IDF led_strip example and added .with_dma = true to the RMT TX channel configuration.

This simplified version illustrates the problem:

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/rmt_tx.h"
#include "led_strip_encoder.h"

#define RMT_LED_STRIP_RESOLUTION_HZ 10000000
#define RMT_LED_STRIP_GPIO_NUM      1

#define EXAMPLE_LED_NUMBERS         18
#define EXAMPLE_CHASE_SPEED_MS      250

static const char *TAG = "example";

static uint8_t led_strip_pixels[EXAMPLE_LED_NUMBERS * 3];

void app_main(void)
{
    rmt_channel_handle_t led_chan = NULL;
    rmt_tx_channel_config_t tx_chan_config = {
        .clk_src = RMT_CLK_SRC_DEFAULT,
        .gpio_num = RMT_LED_STRIP_GPIO_NUM,
        .mem_block_symbols = 64,
        .resolution_hz = RMT_LED_STRIP_RESOLUTION_HZ,
        .trans_queue_depth = 4,
        .flags.with_dma = true,
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_chan_config, &led_chan));

    rmt_encoder_handle_t led_encoder = NULL;
    led_strip_encoder_config_t encoder_config = {
        .resolution = RMT_LED_STRIP_RESOLUTION_HZ,
    };
    ESP_ERROR_CHECK(rmt_new_led_strip_encoder(&encoder_config, &led_encoder));

    ESP_ERROR_CHECK(rmt_enable(led_chan));

    rmt_transmit_config_t tx_config = {
        .loop_count = 0,
    };
    int active = 0;
    while (1) {
        ESP_LOGI(TAG, "active=%d", active);
        memset(led_strip_pixels, 0, sizeof(led_strip_pixels));
        led_strip_pixels[(active * 3) + 0] = 0x80;
        led_strip_pixels[(active * 3) + 1] = 0x00;
        led_strip_pixels[(active * 3) + 2] = 0x00;
        ESP_ERROR_CHECK(rmt_transmit(led_chan, led_encoder, led_strip_pixels, sizeof(led_strip_pixels), &tx_config));
        ESP_ERROR_CHECK(rmt_tx_wait_all_done(led_chan, portMAX_DELAY));
        vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
        if (++active == EXAMPLE_LED_NUMBERS) {
            active = 0;
        }
    }
}

Debug Logs.

No response

More Information.

The documentation for the RMT peripheral currently includes this description for mem_block_symbols:

If the DMA is enabled via rmt_tx_channel_config_t::with_dma, then this field controls the size of the internal DMA buffer. To achieve a better throughput and smaller CPU overhead, you can set a larger value, e.g., 1024.

This implies to me that it should work with a lower value (even if it's not desirable due to efficiency concerns).

I found that I could resolve the problem by changing the rmt_tx_channel_config_t::mem_block_symbols from 64 to 1024.

Is this change in behavior between v5.1.1 and the current master intentional, or a regression?

If intentional, I would recommend updating the documentation (and example) to better establish the importance of the role that mem_block_symbols plays in proper with_dma operation, including information on how to select a reasonable value.

@tonystuart tonystuart added the Type: Bug bugs in IDF label Nov 11, 2023
@espressif-bot espressif-bot added the Status: Opened Issue is new label Nov 11, 2023
@github-actions github-actions bot changed the title Value of RMT mem_block_symbols for proper DMA operation has changed between v5.1.1 and current master Value of RMT mem_block_symbols for proper DMA operation has changed between v5.1.1 and current master (IDFGH-11426) Nov 11, 2023
@espressif-bot espressif-bot added Status: In Progress Work is in progress Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Opened Issue is new Status: In Progress Work is in progress labels Nov 14, 2023
espressif-bot pushed a commit that referenced this issue Dec 1, 2023
movsb pushed a commit to movsb/esp-idf that referenced this issue Dec 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

3 participants