Skip to content

Arduino 3.0.x doesn't work with RMT Legacy Driver #9866

Closed
@Xylopyrographer

Description

@Xylopyrographer

Board

ESP32S3 Dev Module

Device Description

ESP32S3 Dev Module with an on-board WS2812 RGB LED on GPIO48.

Hardware Configuration

No

Version

v3.0.1

IDE Name

Arduino IDE 2.3.2

Operating System

Debian 12

Flash frequency

Flash Mode: "QIO 80MHZ"

PSRAM enabled

yes

Upload speed

921600

Description

When using the legacy RMT driver as per:
https://docs.espressif.com/projects/esp-idf/en/v5.1.4/esp32/migration-guides/release-5.x/5.0/peripherals.html#rmt-driver
and when USB CDC On Boot is set to "Disabled" the sketch below runs.

If however USB CDC On Boot is set to "Enabled" the sketch crashes into a boot loop. Crash log is below.

The LiteLED library uses only ESP-IDF calls.

To test, must use the LiteLED v3 development branch at: https://github.com/Xylopyrographer/LiteLED/tree/v1.3

Sketch

// arduino-esp32 core v3.0.1 RMT legacy driver bug
// must use LiteLED v1.3.0-dev at https://github.com/Xylopyrographer/LiteLED/tree/v1.3

#include <LiteLED.h>

#define LED_GPIO        48  // change this number to be the GPIO pin connected to DIN of the matrix panel
#define LED_TYPE        LED_STRIP_WS2812
#define LED_TYPE_IS_RGBW    0   // if the LED matrix uses RGBW type LED's, change the 0 to 1

static const uint8_t currBright = 20;    // change this to set the brightness level of the matrix
static const crgb_t BLINK_COL = 0x00002f;

LiteLED myDisplay( LED_TYPE, LED_TYPE_IS_RGBW );    // create the LiteLED object

void setup() {
    delay( 2000 );
    printf( "printf: Sketch in setup()" );
    Serial.begin( 115200 );
    delay( 2000 );
    Serial.println( "Sketch in setup()" );

    myDisplay.begin( LED_GPIO, 1, 0 );        // initialze the myDisplay object.
    myDisplay.brightness( currBright );
    myDisplay.setPixel( 0, BLINK_COL, 1 );
}

void loop() {
  // blink a pixel   
  myDisplay.brightness( 0, 1 );
  delay( 1000 );

  myDisplay.brightness( currBright, 1 );
  delay( 1000 );
}

Debug Message

With USB CDC On Boot: "Enabled":

Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40377d1d
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
E (91) rmt(legacy): CONFLICT! driver_ng is not allowed to be used with the legacy driver

abort() was called at PC 0x4200951f on core 0

Backtrace: 0x4037770a:0x3fceb200 0x4037c4bd:0x3fceb220 0x40381f11:0x3fceb240 0x4200951f:0x3fceb2c0 0x4200d166:0x3fceb2e0 0x40377a0f:0x3fceb310 0x403cd852:0x3fceb340 0x403cdafe:0x3fceb380 0x403c98d5:0x3fceb4b0 0x40045c01:0x3fceb570 0x40043ab6:0x3fceb6f0 0x40034c45:0x3fceb710

ESP Exception Decoder
Sketch: S3_RMT_Bug FQBN: esp32:esp32:esp32s3

Backtrace: 0x4037770a:0x3fceb200 0x4037c4bd:0x3fceb220 0x40381f11:0x3fceb240 0x4200951f:0x3fceb2c0 0x4200d166:0x3fceb2e0 0x40377a0f:0x3fceb310 0x403cd852:0x3fceb340 0x403cdafe:0x3fceb380 0x403c98d5:0x3fceb4b0 0x40045c01:0x3fceb570 0x40043ab6:0x3fceb6f0 0x40034c45:0x3fceb710

Decoding stack results
0x4037770a: panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:466
0x4037c4bd: 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
0x40381f11: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/abort.c:38
0x4200951f: check_rmt_legacy_driver_conflict at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/driver/deprecated/rmt_legacy.c:1380
0x4200d166: start_cpu0_default at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/startup.c:205
0x40377a0f: call_start_cpu0 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/xtensa/include/xt_utils.h:40

Other Steps to Reproduce

Crash occurs whenever USB CDC On Boot is enabled, regardless of other USB settings and whether PSRAM is enabled or not.

Serial monitor output with Core Debug Level: "Debug" and USB DFU On Boot: "Disabled":

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
[   310][I][esp32-hal-psram.c:90] psramInit(): PSRAM enabled
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32-S3
  Package           : 0
  Revision          : 1
  Cores             : 2
  Frequency         : 240 MHz
  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        :   405836 B ( 396.3 KB)
  Free Bytes        :   378016 B ( 369.2 KB)
  Allocated Bytes   :    23044 B (  22.5 KB)
  Minimum Free Bytes:   372968 B ( 364.2 KB)
  Largest Free Block:   335860 B ( 328.0 KB)
------------------------------------------
SPIRAM Memory Info:
------------------------------------------
  Total Size        :  2097152 B (2048.0 KB)
  Free Bytes        :  2095104 B (2046.0 KB)
  Allocated Bytes   :        0 B (   0.0 KB)
  Minimum Free Bytes:  2095104 B (2046.0 KB)
  Largest Free Block:  2064372 B (2016.0 KB)
  Bus Mode          : QSPI
------------------------------------------
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:  1920.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x001F0000, size:  1920.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x003D0000, size:   128.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Jun 14 2024 17:26:18
  Compile Host OS   : linux
  ESP-IDF Version   : v5.1.4-51-g442a798083-dirty
  Arduino Version   : 3.0.1
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32S3_DEV
  Arduino Variant   : esp32s3
  Arduino FQBN      : esp32:esp32:esp32s3:UploadSpeed=921600,USBMode=hwcdc,CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,CPUFreq=240,FlashMode=qio,FlashSize=8M,PartitionScheme=min_spiffs,DebugLevel=debug,PSRAM=enabled,LoopCore=1,EventsCore=1,EraseFlash=none,JTAGAdapter=default,ZigbeeMode=default
============ Before Setup End ============
Sketch in setup()
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   405836 B ( 396.3 KB)
  Free Bytes        :   375564 B ( 366.8 KB)
  Allocated Bytes   :    25096 B (  24.5 KB)
  Minimum Free Bytes:   370516 B ( 361.8 KB)
  Largest Free Block:   335860 B ( 328.0 KB)
------------------------------------------
SPIRAM Memory Info:
------------------------------------------
  Total Size        :  2097152 B (2048.0 KB)
  Free Bytes        :  2094844 B (2045.7 KB)
  Allocated Bytes   :      244 B (   0.2 KB)
  Minimum Free Bytes:  2094844 B (2045.7 KB)
  Largest Free Block:  2064372 B (2016.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------  
    43 : UART_TX[0]
    44 : UART_RX[0]
============ After Setup End =============

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Activity

me-no-dev

me-no-dev commented on Jun 15, 2024

@me-no-dev
Member
Xylopyrographer

Xylopyrographer commented on Jun 15, 2024

@Xylopyrographer
ContributorAuthor

Short answer is yes, using neopixelWrite() works with USB CDC On Boot either Enabled or Disabled.

Real question is why does Enabling USB CDC On Boot crash the legacy RMT driver at runtime while Disabling USB CDC On Boot does not?

me-no-dev

me-no-dev commented on Jun 15, 2024

@me-no-dev
Member

Agree on the real question. @SuGlider will have a look

SuGlider

SuGlider commented on Jun 20, 2024

@SuGlider
Collaborator

@Xylopyrographer - I see that your project does #include "driver/rmt.h", which is the legacy driver of IDF 5.1
https://github.com/espressif/esp-idf/blob/release/v5.1/components/driver/deprecated/driver/rmt.h
It is deprecated, as said in the folder name.

Arduino Core 3.0.x (IDF 5.1) uses new drivers from driver/rmt_tx.h and driver/rmt_rx.h instead.

I think that there is a mix of many thing here that have a conflict, exactly as reported in the issue:
E (91) rmt(legacy): CONFLICT! driver_ng is not allowed to be used with the legacy driver
That sounds like the application is trying to use both, legacy and the new one at the same time... which seems to be forbiden.

Regarding CDC On Boot, I only can guess that it may lead to initialize the new Arduino RMT driver, somehow.
I could not find any call to rmtInit() or neopixelWrite() that would cause the issue...

Xylopyrographer

Xylopyrographer commented on Jun 20, 2024

@Xylopyrographer
ContributorAuthor

@SuGlider, thanks for the reply.

Couple of points: The RMT driver, though legacy, is included in ESP-IDF v5.x and as well in arduino-esp32 core 3.0.x. Given that any RMT code moving from IDF 4.x to 5.x has to be rewritten from the ground up to use the new API's, inclusion of the legacy driver in the IDF 5.x and core 3.0.x releases is the wise and correct thing to do.

So the issue is, the example above (which uses only the legacy ESP-IDF driver) runs 100% on targets where USB-CDC On Boot is Disabled (or where USB CDC is not available on the target SOC) but fails as noted when USB-CDC On Boot is Enabled.

As the S3 has a complete and separate USB OTG peripheral (in addition to the USB Serial/JTAG peripheral), why would Enabling USB CDC on Boot do anything with the RMT peripheral?

Were you able find from where driver_ng is invoked?

me-no-dev

me-no-dev commented on Jun 20, 2024

@me-no-dev
Member

@Xylopyrographer both drivers should never be used/compiled together. We have moved to the new driver and so should you :) Maybe start using the Arduino layer for it from now on?

Xylopyrographer

Xylopyrographer commented on Jun 20, 2024

@Xylopyrographer
ContributorAuthor

@me-no-dev Agree that at some point, moving to the new world order is the thing to to.

In the mean time, the legacy driver is included in core 3.0.x and does work, except when USB-CDC On Boot is Enabled.

The sample sketch uses calls only to the legacy ESP-IDF v4.4.x driver.

Neither the new ESP-IDF v5.x.y RMT drivers nor the new arduino-esp32 core 3.0.x RMT drivers are included or called.

The issue is, why would enabling USB-CDC On Boot cause an RMT conflict?

SuGlider

SuGlider commented on Jun 23, 2024

@SuGlider
Collaborator

The issue is, why would enabling USB-CDC On Boot cause an RMT conflict?

I'll investigate this odd relation.

SuGlider

SuGlider commented on Jun 23, 2024

@SuGlider
Collaborator

This is the IDF place where it causes the error (rmt_legacy.c):

/**
 * @brief This function will be called during start up, to check that this legacy RMT driver is not running along with the new driver
 */
__attribute__((constructor))
static void check_rmt_legacy_driver_conflict(void)
{
    // This function was declared as weak here. The new RMT driver has one implementation.
    // So if the new RMT driver is not linked in, then `rmt_acquire_group_handle()` should be NULL at runtime.
    extern __attribute__((weak)) void *rmt_acquire_group_handle(int group_id);
    if ((void *)rmt_acquire_group_handle != NULL) {
        ESP_EARLY_LOGE(TAG, "CONFLICT! driver_ng is not allowed to be used with the legacy driver");
        abort();
    }
    ESP_EARLY_LOGW(TAG, "legacy driver is deprecated, please migrate to `driver/rmt_tx.h` and/or `driver/rmt_rx.h`");
}
SuGlider

SuGlider commented on Jun 24, 2024

@SuGlider
Collaborator

I have tested the LiteLED sketch and it fails only when USB CDC On Boot is enabled.
It doesn't matter if the CDC Driver is the OTG TinyUSB or Hardware CDC and JTAG.

Based on the IDF code, it looks like a linking issue...

For example, this code with USB CDC On Boot disabled, also causes the issue:
It just adds a simple digitalWrite() to the code...

static const uint8_t currBright = 20;    // change this to set the brightness level of the matrix
static const crgb_t BLINK_COL = 0x00002f;

LiteLED myDisplay( LED_TYPE, LED_TYPE_IS_RGBW );    // create the LiteLED object

void setup() {
    pinMode(2, OUTPUT);
    digitalWrite(2, HIGH);
    delay( 2000 );
    printf( "printf: Sketch in setup()" );
    Serial.begin( 115200 );
    delay( 2000 );
    Serial.println( "Sketch in setup()" );

    myDisplay.begin( LED_GPIO, 1, 0 );        // initialze the myDisplay object.
    myDisplay.brightness( currBright );
    myDisplay.setPixel( 0, BLINK_COL, 1 );
}

void loop() {
  // blink a pixel   
  myDisplay.brightness( 0, 1 );
  delay( 1000 );

  myDisplay.brightness( currBright, 1 );
  delay( 1000 );
}
SuGlider

SuGlider commented on Jun 24, 2024

@SuGlider
Collaborator

just the pinMode(2) causes the issue also...

SuGlider

SuGlider commented on Jun 24, 2024

@SuGlider
Collaborator

The reason for that is because in esp32-hal-gpio.c there is a possible call to neopixelWrite(RGB_BUILTIN, comm_val, comm_val, comm_val);, which in turn llinks RMT HAL into the final firmware.

The code that has it in HAL GPIO is:

extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
#ifdef RGB_BUILTIN
  if (pin == RGB_BUILTIN) {
    //use RMT to set all channels on/off
    RGB_BUILTIN_storage = val;
    const uint8_t comm_val = val != 0 ? RGB_BRIGHTNESS : 0;
    neopixelWrite(RGB_BUILTIN, comm_val, comm_val, comm_val);
    return;
  }
#endif
  if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) {
    gpio_set_level((gpio_num_t)pin, val);
  } else {
    log_e("IO %i is not set as GPIO.", pin);
  }
}
SuGlider

SuGlider commented on Jun 24, 2024

@SuGlider
Collaborator

@Xylopyrographer - If the board used has no RGB_BUILTIN definition in its variants/BOARD_NAME/pins_arduino.h file, the LiteLED sketch works fine.

24 remaining items

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

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Arduino 3.0.x doesn't work with RMT Legacy Driver · Issue #9866 · espressif/arduino-esp32