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 example is broken on ESP32-S3 (IDFGH-14386) #15170

Closed
3 tasks done
zackees opened this issue Jan 8, 2025 · 2 comments
Closed
3 tasks done

led_strip example is broken on ESP32-S3 (IDFGH-14386) #15170

zackees opened this issue Jan 8, 2025 · 2 comments
Assignees
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@zackees
Copy link

zackees commented Jan 8, 2025

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.

Led strip 3.0.0

Espressif SoC revision.

ESP32-S3

Operating System used.

Windows

How did you build your project?

Other (please specify in More Information)

If you are using Windows, please specify command line type.

CMD

Development Kit.

Xaio Esp32S3

Power Supply used.

USB

What is the expected behavior?

I expect the demo to work with 4 or more strips.

What is the actual behavior?

It only works with two strips. Third strip causes a runtime crash.

Steps to reproduce.

Keep in mind I'm using a lightly modified version of the led_strip component library to enable async drawing so that parallel rmt drivers can be used.

I may issue an additional PR to enable parallel async for rmt led_strip drawing. You can find my fork here:

https://github.com/zackees/esp-rmt-led-strip-component-idf-5-1-cpp

/*
 * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_check.h"

#ifndef LED_STRIP_GPIO_PIN
// GPIO assignment
#define LED_STRIP_GPIO_PIN  2
#endif

#ifndef LED_STRIP_LED_COUNT
// Numbers of the LED in the strip
#define LED_STRIP_LED_COUNT 24
#endif


// 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(int pin, uint32_t led_count, led_model_t led_model, bool is_rgbw)
{

    #if CONFIG_IDF_TARGET_ESP32S3
    ESP_LOGI(TAG, "ESP32-S3 detected, using 48 symbols per RMT block");
    size_t memory_block_symbols = 48;
    #else
    ESP_LOGI(TAG, "Using 64 symbols per RMT block");
    size_t memory_block_symbols = 64;
    #endif

    led_color_component_format_t color_component_format =
        is_rgbw ? LED_STRIP_COLOR_COMPONENT_FMT_RGBW : LED_STRIP_COLOR_COMPONENT_FMT_RGB;
    // LED strip general initialization, according to your led board design
    led_strip_config_t strip_config = {
        .strip_gpio_num = pin, // The GPIO that connected to the LED strip's data line
        .max_leds = led_count,      // The number of LEDs in the strip,
        .led_model = led_model,        // LED strip model
        .color_component_format = color_component_format, // 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 = 0,               // the memory size of each RMT channel, in words (4 bytes)
        .flags = {
            .with_dma = false, // 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;
}


class RmtStrip {
 public:
  RmtStrip(int pin, uint32_t led_count, led_model_t led_model, bool is_rgbw): mIsRgbw(is_rgbw) {
    led_strip_handle_t led_strip = configure_led(pin, led_count, led_model, is_rgbw);
    mStrip = led_strip;
  }

  ~RmtStrip() {
    wait_done();
    led_strip_del(mStrip);
    mStrip = nullptr;
  }

  esp_err_t setPixel(uint32_t index, uint32_t red, uint32_t green, uint32_t blue) {
    ESP_RETURN_ON_FALSE(!mIsRgbw, ESP_ERR_INVALID_ARG, TAG, "cannot set RGB on RGBW strip");
    ESP_ERROR_CHECK(led_strip_set_pixel(mStrip, index, red, green, blue));
    return ESP_OK;
  }

  esp_err_t setPixelRGBW(uint32_t index, uint32_t red, uint32_t green, uint32_t blue, uint32_t white) {
    ESP_RETURN_ON_FALSE(mIsRgbw, ESP_ERR_INVALID_ARG, TAG, "cannot set RGBW on RGB strip");
    ESP_ERROR_CHECK(led_strip_set_pixel_rgbw(mStrip, index, red, green, blue, white));
    return ESP_OK;
  }

  void draw_sync() {
    draw_async();
    wait_done();
  }

  void draw_async() {
    if (mDrawIssued) {
        wait_done();
    }
    ESP_ERROR_CHECK(led_strip_refresh_async(mStrip));
    mDrawIssued = true;
  }

  void wait_done() {
    if (!mDrawIssued) {
        //ESP_LOGE(TAG, "No draw issued, skipping wait");
        return;
    }
    ESP_ERROR_CHECK(led_strip_refresh_wait_done(mStrip));
    mDrawIssued = false;
  }

  bool is_drawing() {
    return mDrawIssued;
  }

  void clear() {
    ESP_ERROR_CHECK(led_strip_clear(mStrip));
  }

  void fill_color(uint32_t red, uint32_t green, uint32_t blue) {
    for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
      setPixel(i, red, green, blue);
    }
  }

  private:
    led_strip_handle_t mStrip;
    bool mDrawIssued = false;
    bool mIsRgbw;
};

void app_main(void)
{
    // led_strip_handle_t led_strip = configure_led(6, LED_STRIP_LED_COUNT, LED_MODEL_WS2812);
    RmtStrip led_strip1(6, LED_STRIP_LED_COUNT, LED_MODEL_WS2812, false);
    RmtStrip led_strip2(7, LED_STRIP_LED_COUNT, LED_MODEL_WS2812, false);
    RmtStrip led_strip3(8, LED_STRIP_LED_COUNT, LED_MODEL_WS2812, false);
    RmtStrip led_strip4(9, LED_STRIP_LED_COUNT, LED_MODEL_WS2812, false);
    // RmtStrip* rmtstrips[] = {&led_strip1, &led_strip2, &led_strip3, &led_strip4};
    RmtStrip* rmtstrips[] = {&led_strip1, &led_strip2, &led_strip3, &led_strip4};
    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));
                // led_strip.setPixel(i, 5, 5, 5);
                for (auto strip : rmtstrips) {
                    strip->setPixel(i, 5, 5, 5);
                }
            }
            /* Refresh the strip to send data */
            // ESP_ERROR_CHECK(led_strip_refresh(led_strip));
            // led_strip.refresh();
            // led_strip.draw_async();
            for (auto strip : rmtstrips) {
                strip->draw_async();
            }
            ESP_LOGI(TAG, "LED ON!");
        } else {
            /* Set all LED off to clear all pixels */
            // ESP_ERROR_CHECK(led_strip_clear(led_strip));
            // led_strip.clear();
            // led_strip.fill_color(0, 0, 0);
            for (auto strip : rmtstrips) {
                strip->fill_color(0, 0, 0);
            }
            //led_strip.draw_async();
            for (auto strip : rmtstrips) {
                strip->draw_async();
            }
            ESP_LOGI(TAG, "LED OFF!");
        }

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

Debug Logs.

Backtrace: 0x403775fe:0x3fcebc30 0x4037ab89:0x3fcebc50 0x4037fde1:0x3fcebc70 0x4037ab7f:0x3fcebcf0 0x42001d0e:0x3fcebd20 0x42001e5b:0x3fcebd70 0x42001fab:0x3fcebdc0 0x42002afc:0x3fcebde0 0x4037ce6a:0x3fcebe00
  #0  0x403775fe in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:466
  #1  0x4037ab89 in esp_system_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/port/esp_system_chip.c:84
  #2  0x4037fde1 in abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/abort.c:38
  #3  0x4037ab7f in _esp_error_check_failed at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/esp_err.c:50
  #4  0x42001d0e in configure_led(int, unsigned long, led_model_t, bool) at src/main_rmt.hpp:66 (discriminator 2)
  #5  0x42001e5b in RmtStrip::RmtStrip(int, unsigned long, led_model_t, bool) at src/main_rmt.hpp:75
      (inlined by) app_main() at src/main_rmt.hpp:144
  #6  0x42001fab in loop() at src/main.cpp:12
  #7  0x42002afc in loopTask(void*) at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:74   
  #8  0x4037ce6a in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162





ELF file SHA256: 11aa8dfa645cf11d

Rebooting...
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40379462
  #0  0x40379462 in esp_cpu_wait_for_intr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_hw_support/cpu.c:121

SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x109c
load:0x403c9700,len:0x4
load:0x403c9704,len:0xb50
load:0x403cc700,len:0x2fd0
entry 0x403c98ac
[    90][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x42004a38     
  #0  0x42004a38 in _uartDetachBus_RX at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:153

[   102][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x42004a04     
  #0  0x42004a04 in _uartDetachBus_TX at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:160

[   113][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x420049d0    
  #0  0x420049d0 in _uartDetachBus_CTS at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:167

[   124][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x4200499c    
  #0  0x4200499c in _uartDetachBus_RTS at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:174

[   135][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x42004a38     
  #0  0x42004a38 in _uartDetachBus_RX at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:153

[   147][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x42004a04     
  #0  0x42004a04 in _uartDetachBus_TX at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:160

[   158][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x420049d0    
  #0  0x420049d0 in _uartDetachBus_CTS at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:167

[   169][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x4200499c    
  #0  0x4200499c in _uartDetachBus_RTS at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:174

[   181][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x42004a38     
  #0  0x42004a38 in _uartDetachBus_RX at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:153

[   192][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x42004a04     
  #0  0x42004a04 in _uartDetachBus_TX at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:160

[   203][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x420049d0    
  #0  0x420049d0 in _uartDetachBus_CTS at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:167

[   215][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x4200499c
  #0  0x4200499c in _uartDetachBus_RTS at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:174

[   247][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 44 successfully set to type UART_RX (2) with bus 0x3fc91b00
  #0  0x3fc91b00 in ?? at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:82        

[   257][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 43 successfully set to type UART_TX (3) with bus 0x3fc91b00
  #0  0x3fc91b00 in ?? at C:/Users/niteris/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.c:82        

=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32-S3
  Package           : 0
  Revision          : 2
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000012
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : No
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   404700 B ( 395.2 KB)
  Free Bytes        :   376600 B ( 367.8 KB)
  Allocated Bytes   :    23260 B (  22.7 KB)
  Minimum Free Bytes:   371412 B ( 362.7 KB)
  Largest Free Block:   335860 B ( 328.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  8388608 B (8 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  3264.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00340000, size:  3264.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00670000, size:  1536.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x007F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Jan  8 2025 15:11:25
  ESP-IDF Version   : v5.1.4-586-gb6b4727c58-dirty
  Arduino Version   : 3.0.4
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : Espressif ESP32-S3-DevKitC-1-N8 (8 MB QD, No PSRAM)
  Arduino Variant   : esp32s3
  Core Debug Level  : 5
  Arduino Runs Core : 1
  Arduino Events on : 1
  Arduino USB Mode  : 1
  CDC On Boot       : 0
============ Before Setup End ============

More Information.

build type is platformio.

Here is the pull request to fix it.
espressif/idf-extra-components#465

@zackees zackees added the Type: Bug bugs in IDF label Jan 8, 2025
@github-actions github-actions bot changed the title led_strip example is broken on ESP32-S3 led_strip example is broken on ESP32-S3 (IDFGH-14386) Jan 8, 2025
@espressif-bot espressif-bot added the Status: Opened Issue is new label Jan 8, 2025
@suda-morris suda-morris removed the Type: Bug bugs in IDF label Jan 9, 2025
@suda-morris
Copy link
Collaborator

Yes, this is a hardware change in the RMT. On esp32 and esp32s2, the FIFO size for each channel is 64, but on other targets, the size is chrunked to 48. Thanks for your PR, we will take a look there. Using zero is a clever solution.

@suda-morris
Copy link
Collaborator

PR is merged. 🎉

@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: Opened Issue is new labels Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

3 participants