Adafruit Feather-S2 using ESP-IDF USB Issue

Hi,

I’m having issues getting USB and serial to work correctly on an Adafruit Feather-S2 using PlatformIO and ESP-IDF framework. With Arduino IDE, and with the Arduino framework on PlatformIO, I can upload a sketch and monitor serial output without issue. However with ESP-IDF on PlatformIO the serial port /dev/ttyACM0 disappears after uploading.

To upload the first time, I have to hold boot + reset after which the serial port appears and I can upload. The programmer complains that it cannot autoreset because I manually put it in boot mode which is fair enough. However, when I restart the chip the serial port never reappears and to re-upload I have to hold the buttons again. Is there something I need to add to platformio.ini to enable USB serial to work properly?

The sketch is just the hello world ESP-IDF example. I’m running PIO core 6.1.4, Espressif 32 5.1.1, VSCodium 1.70.2 on Manjaro Linux.

Any suggestions welcome!

I have tried setting Component config → ESP32S2-specific → Keep USB peripheral enabled at start up via pio -t menuconfig to no avail.

dmesg does not show anything, nor does lsusb.

It seems like the ESP32S2 is not enabling the USB CDC ADM device at all unless I force it by pushing Boot and Reset buttons.

Can anyone help?

Solved it.

Using pio -t menuconfig you need to set Component config → ESP System Settings → Channel for console output to USB CDC.

Is there any way this can be set as a default option for this board in PlatformIO so new users don’t fall into the same trap?

1 Like

Thank you so much for the info !!! I felt into the trap, but hopefully I read your post !

But Sadly, as I’m using a multicore ESP32-S3, I get the following error :
"… error: static assertion failed: “usb_osglue_*_int is not multicore capable …”

Hopefully, this issue is supposed to soon be fixed : esp32s3 IDF-2048 multicore usb_osglue review (IDFGH-7291) · Issue #8879 · espressif/esp-idf · GitHub

Short update: For multicore, today unfortunately still does not work in esp-idf 5.0.3. Hopefully, they integrated the fix it in the latest esp-idf 5.1.1. However that is not yet incorporated into platformio. Because of that I am really considering to drop platformio for the esp-idf extension in VSCode for quicker access to releases.

Tested, it is fixed in esp-idf 5.1.1. So, we just need to wait for the integration of 5.1.1 into pio.

Hi,
I still can’t getting it running, any help very much appreciated! I am using a comparable board though:

[env:lolin_s2_mini]
platform = espressif32
board = lolin_s2_mini
framework = arduino, espidf

I tried pio -t menuconfig but USB CDC was already set.

I tried to add -DARDUINO_USB_MODE=0 and -DARDUINO_USB_CDC_ON_BOOT=1 without any luck.

This is the error:

/home/jeroen/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.cpp: In function 'void serialEventRun()':
/home/jeroen/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.cpp:51:23: error: 'Serial' was not declared in this scope
     if(serialEvent && Serial.available()) serialEvent();

In the Arduino IDE Serial output is working, although I have to reset the board first.

I doubt that you can create an “Arduino as ESP-IDF Component” project with the ArduinoIDE.

In order to be able to compare something, the same conditions must first be met. Therefore, please change the setting for the framework: framework = arduino and see if the error still occurs.

Please name the Arduino versions that you use in the ArduinoIDE and in PlatformIO.

Thank you for your reply! No I can not create the espidf with the ArduinoIDE. I use ArduinoIDE 2.3.2 on Ubuntu with the latest release of the core. PlatformIO I installed this week, so latest version.

With framework = arduino everything works as expected.

I investigated further, I think the problem arises in HardwareSerial.h.In the manifest file lolin_s2_mini.json it sets #defines like this:

    "core": "esp32",
    "extra_flags": [
      "-DARDUINO_LOLIN_S2_MINI",
      "-DBOARD_HAS_PSRAM",
      "-DARDUINO_USB_CDC_ON_BOOT=1",
      "-DARDUINO_USB_MODE=0"
    ],

That causes Serial not to be #define’d.

At the beginning of HardwareSerial.h the file USBCDC.h is included. This does define Serial if CONFIG_TINYUSB_CDC_ENABLED is defined. So I tried to use menuconfig to enable TinyUSB. This fails because an include file is not found.

Next I added:

lib_deps = 
  adafruit/Adafruit TinyUSB Library@^3.1.3
lib_ignore = USBHost

This fails as follows:

In file included from .pio/libdeps/lolin_s2_mini/Adafruit TinyUSB Library/src/tusb_option.h:240,
                 from .pio/libdeps/lolin_s2_mini/Adafruit TinyUSB Library/src/Adafruit_TinyUSB.h:33,
                 from src/main.cpp:3:
.pio/libdeps/lolin_s2_mini/Adafruit TinyUSB Library/src/tusb_config.h:47:14: fatal error: ../../arduino_tinyusb/include/tusb_config.h: No such file or directory
     #include "../../arduino_tinyusb/include/tusb_config.h"
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

When I look at the file tusb_config.h, at the location where the include fails, it reads:

#elif defined(ARDUINO_ARCH_ESP32)
  // Note: when compiling core Arduino IDEs will include tusb_config.h in the BSP
  // sdk/include/arduino_tinyusb/include. While compiling .c file in this library this
  // file will be used instead. For consistency: include the one in BSP here as well
  #include "sdkconfig.h"
  #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
    #include "../../arduino_tinyusb/include/tusb_config.h"
  #else
    #include "arduino/ports/esp32/tusb_config_esp32.h"
  #endif

What I undestand is that the library refers to a file present in the Arduino ESP32 core, by “going to directories up”, this line from the above snippet: #include "../../arduino_tinyusb/include/tusb_config.h". However, in PlatformIO espidf this file is at a different location.

Now I am sort of stuck. My preliminary conclusions so far are:

  1. The lolin_s2_mini board uses a different kind of serial monitor, no UART but a USB connection
  2. In the ESP32 Arduino core support for this kind of connection is compiled correctly
  3. In the PlatformIO espidf several #defines seem to be needed to set, but it is not clear for me which ones
  4. My best guess is that TinyUSB is needed for this board but either an include path is incorrect in that library for PlatformIO or I do not know how to import the library correctly

Any suggestion is welcome!

Do you want to create an ESP-IDF project or an Arduino Project?

Because the Serial object is irrelevant to ESP-IDF projects !?

I prefer to create an Arduino Project. Most of my software is written for the Arduino environment. Now I need an adaptation in the pre-compiled libraries (I need to increase the default pthread stack size). That is why I am trying to do this using PlatformIO. I like it, and the ability to compile the core yourself is very useful! I also use the ESP-S2 mini a lot. So either changing the board or from Arduino to espidf is an option, but both not very attractive.

My guess is that more people encounter this problem, with the S2 and the S3 boards. I also think that the solution is not very complicated, I think it is as little as setting the correct include path and one or more #defines. I only do not know how to do it myself :confused:

Still when using the S2 I need the monitor, so that leads to the same problem I guess?

As the board manifest set the ARDUINO_USB_USB_CDC to 1 try the following in you platformio.ini:

build_unflags = 
  -DARDUINO_USB_CDC_ON_BOOT
build_flags = 
  -DARDUINO_USB_CDC_ON_BOOT=0

Unfortunately that leads to the original error:

In file included from /home/jeroen/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-tinyusb.c:36:
/home/jeroen/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-tinyusb.h:24:10: fatal error: tusb.h: No such file or directory

**************************************************************
* Looking for tusb.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:tusb.h"
* Web  > https://registry.platformio.org/search?q=header:tusb.h
*
**************************************************************

 #include "tusb.h"
          ^~~~~~~~
compilation terminated.

Please show the complete platformio.ini.
Wich version of the espressif32 platform do you use?
What other modifications have you made?

I have not much experience with Arduino as ESP-IDF component. But it seems that ARDUINO_USB_CDC_ON_BOOT behaves differently to pure Arduino projects and cause some trouble.

Yes ARDUINO_USB_CDC_ON_BOOT behaves differently on ArduinoIDE and PlatformIO. And it shouldn’t!! That is why I think small changes are needed in the configuration (that I unfortunately can not figure out myself).

This is the full platform.ini, I kept the commented out tests I did, maybe it helps:

[env:lolin_s2_mini]
platform = espressif32
board = lolin_s2_mini
framework = arduino, espidf
lib_deps = 
  adafruit/Adafruit TinyUSB Library@^3.1.3
lib_ignore = USBHost

build_unflags = 
  -DARDUINO_USB_CDC_ON_BOOT
;  -DARDUINO_USB_MODE

build_flags =
   -DARDUINO_USB_MODE=0
;   -DARDUINO_USB_MODE=1
;   -DARDUINO_USB_CDC_ON_BOOT=1
   -DARDUINO_USB_CDC_ON_BOOT=0
   -DCONFIG_TINYUSB_CDC_ENABLED=1
   -DCONFIG_TINYUSB_ENABLED=1
;   -DUSE_TINYUSB
;   -I "${PROJECT_CORE_DIR}/packages/framework-arduino-samd-seeed/libraries/Adafruit_TinyUSB_Arduino/src/arduino"

;   -DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC

;    -DUSB_VID = 0x303a
;    -DUSB_PID= 0x80C2
;    -DUSB_MANUFACTURER ="WEMOS.CC"
;    -DUSB_PRODUCT = "LOLIN-S2-MINI"
;    -DUSB_SERIAL = "0"
;    -DUSB_FW_MSC_VENDOR_ID = "ESP32-S2"
;    -DUSB_FW_MSC_PRODUCT_ID = "Firmware MSC"
;    -DUSB_FW_MSC_PRODUCT_REVISION = "1.23"
;    -DUSB_FW_MSC_VOLUME_NAME = "S2-Firmware"
;    -DUSB_FW_MSC_SERIAL_NUMBER = 0x00000000


;monitor_port = /dev/ttyACM0
monitor_speed = 115200
;monitor_rts = 1
;monitor_dtr = 1

These are the versions:

Processing lolin_s2_mini (platform: espressif32; board: lolin_s2_mini; framework: arduino, espidf)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/lolin_s2_mini.html
PLATFORM: Espressif 32 (6.9.0) > WEMOS LOLIN S2 Mini
HARDWARE: ESP32S2 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: 
 - framework-arduinoespressif32 @ 3.20017.241212+sha.dcc1105b 
 - framework-espidf @ 3.40407.240606 (4.4.7) 
 - tool-cmake @ 3.16.4 
 - tool-esptoolpy @ 1.40501.0 (4.5.1) 
 - tool-ninja @ 1.7.1 
 - toolchain-esp32ulp @ 1.23800.240113 (2.38.0) 
 - toolchain-riscv32-esp @ 8.4.0+2021r2-patch5 
 - toolchain-xtensa-esp32s2 @ 8.4.0+2021r2-patch5
Warning! Arduino framework as an ESP-IDF component doesn't handle the `variant` field! The default `esp32` variant will be used.

Maybe @maxgerhardt has an idea and can help when he is online.

@sivar2311 Thank you very much for your help so far!
@maxgerhardt Would you be so kind of having a look at this issue?

Does anyone else have the serial monitor working on an ESP32-S2 arduino framework with espidf as a component?

The Tiny USB library seems unneeded. I used the menuconfig tool to set Channel for console output (USB CDC), I set the build flag -DARDUINO_USB_CDC_ON_BOOT=1. Now sometimes I can print to the serial monitor using printf(), so without Serial… If I rebuild and restart the monitor is does not work anymore.

I keep on trying but actually I have no idea what I am looking for. So, any help is very much appreciated!