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

led_strip component does not work with DMA for ESP32-S3 using the Xiao variant - probably more (IEC-252) #466

Open
3 tasks done
zackees opened this issue Jan 9, 2025 · 8 comments

Comments

@zackees
Copy link
Contributor

zackees commented Jan 9, 2025

Answers checklist.

  • I have read the component documentation ESP-IDF Components and the issue is not addressed there.
  • I am using target and esp-idf version as defined in component's idf_component.yml
  • I have searched the issue tracker for a similar issue and not found any related issue.

Which component are you using? If you choose Other, provide details in More Information.

led_strip

ESP-IDF version.

5.3

Development Kit.

Xaio Esp32S3

Used Component version.

led_strip 3.0.0

More Information.

In the example code for the WS2812 led_strip, the with_dma is default off.

I went ahead and enabled it and noticed that enabling dma just immediately crashes the device.

FYI: I'm using this code for integration with the FastLED library. Right now we can't turn on any DMA on RMT so our user's WS2812 strips won't be robust against WIFI connections.

To reproduce this issue just git clone the led_strip repo: https://github.com/espressif/idf-extra-components/tree/4769e0adc3462c25caa6b62ac42f9b9aa726443f/led_strip/examples/led_strip_rmt_ws2812

And set the with_dma flag to true. Doesn't matter if there is 1 or 4 devices. As soon as any strip has dma on it error console will spew a failure that the RMT peripheral failed to initialize. See below.

Output:

============ After Setup End =============
E (3411) rmt: rmt_tx_register_to_group(152): no free tx channels
E (3411) rmt: rmt_new_tx_channel(288): register channel failed
E (3412) led_strip_rmt: led_strip_new_rmt_device(167): create RMT TX channel failed
ESP_ERROR_CHECK failed: esp_err_t 0x105 (ESP_ERR_NOT_FOUND) at 0x420023e6
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32-s3-devkitm-1]
platform = espressif32
board = esp32-s3-devkitm-1
framework = arduino
build_flags = -fopt-info-all=optimization_report.txt
@zackees zackees added the Type: Bug Bugs in components label Jan 9, 2025
@github-actions github-actions bot changed the title led_strip component does not work with DMA for ESP32-S3 using the Xiao variant - probably more led_strip component does not work with DMA for ESP32-S3 using the Xiao variant - probably more (IEC-252) Jan 9, 2025
@zackees
Copy link
Contributor Author

zackees commented Jan 9, 2025

Here's a repro case.

https://github.com/zackees/esp-rmt-led-strip-component-idf-5-1-cpp/tree/rmt-dma. Just compile + run it and look at the errors appearing in stdout.

Notice that my version of led_strip 3.0.0 modifies the source to enable async / parallel refresh for both RMT and SPI drivers. The changes are pretty minimal. The rmt DMA bug manifests with the stock library. But the SPI strip works fine. If this DMA issue get's fixed then I'll push a new update of the library to our large user base of developers who are using your chips for their installations/art / commercial ventures.

Here's the new release of our product to users.
https://www.reddit.com/r/FastLED/comments/1hxgtue/fastled_3910_release_new_super_stable_clockless/

@suda-morris
Copy link
Collaborator

@zackees I tested the example on my ESP32-S3 and set the with_dma flag to true. The example works as expected. Please note, only one RMT channel can use the DMA feature, and this is a hardware limitation. Thus, only one led_strip handle can utilize the DMA ability.

@zackees
Copy link
Contributor Author

zackees commented Jan 10, 2025

Weird, zero strips would work. I set the dma buffer at 1024.

Can you please share your code and board?

@suda-morris
Copy link
Collaborator

ESP32-S3 Devkit-C

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"
#include "esp_log.h"
#include "esp_err.h"

// GPIO assignment
#define LED_STRIP_GPIO_PIN  2
// Numbers of the LED in the strip
#define LED_STRIP_LED_COUNT 24
// 10MHz resolution, 1 tick = 0.1us (led strip needs a high resolution)
#define LED_STRIP_RMT_RES_HZ  (10 * 1000 * 1000)

static const char *TAG = "example";

led_strip_handle_t configure_led(void)
{
    // LED strip general initialization, according to your led board design
    led_strip_config_t strip_config = {
        .strip_gpio_num = LED_STRIP_GPIO_PIN, // The GPIO that connected to the LED strip's data line
        .max_leds = LED_STRIP_LED_COUNT,      // The number of LEDs in the strip,
        .led_model = LED_MODEL_WS2812,        // LED strip model
        .color_component_format = LED_STRIP_COLOR_COMPONENT_FMT_GRB, // The color order of the strip: GRB
        .flags = {
            .invert_out = false, // don't invert the output signal
        }
    };

    // LED strip backend configuration: RMT
    led_strip_rmt_config_t rmt_config = {
        .clk_src = RMT_CLK_SRC_DEFAULT,        // different clock source can lead to different power consumption
        .resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency
        .mem_block_symbols = 1024,               // DMA buffer size
        .flags = {
            .with_dma = true, // DMA feature is available on chips like ESP32-S3/P4
        }
    };

    // LED Strip object handle
    led_strip_handle_t led_strip;
    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
    ESP_LOGI(TAG, "Created LED strip object with RMT backend");
    return led_strip;
}

void app_main(void)
{
    led_strip_handle_t led_strip = configure_led();
    bool led_on_off = false;

    ESP_LOGI(TAG, "Start blinking LED strip");
    while (1) {
        if (led_on_off) {
            /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
            for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, i, 5, 5, 5));
            }
            /* Refresh the strip to send data */
            ESP_ERROR_CHECK(led_strip_refresh(led_strip));
            ESP_LOGI(TAG, "LED ON!");
        } else {
            /* Set all LED off to clear all pixels */
            ESP_ERROR_CHECK(led_strip_clear(led_strip));
            ESP_LOGI(TAG, "LED OFF!");
        }

        led_on_off = !led_on_off;
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

@zackees
Copy link
Contributor Author

zackees commented Jan 10, 2025

Thanks for this. I'm going to attempt to repro right now.

@zackees
Copy link
Contributor Author

zackees commented Jan 10, 2025

Confirmed, it works.

Okay, looks like I have some diffing and an investigation to do to see why it's not working correctly with the changes I made.

This demo here has a lot value, so I'm going to go ahead and add the example you did here to the espressif led_strip repo and send you a link to the PR.

@zackees
Copy link
Contributor Author

zackees commented Jan 10, 2025

Here you go.

#467

@suda-morris suda-morris removed the Type: Bug Bugs in components label Jan 13, 2025
@zackees
Copy link
Contributor Author

zackees commented Jan 14, 2025

ping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants