Posted on 1 Comment

USB Settings for Logging with the ESP32-S3 in PlatformIO

The ESP32-S3 is endowed with two noteworthy USB features that its predecessor, the original ESP32, lacked: USB OTG and USB CDC/JTAG. This blog post delves into the platformio.ini settings that govern the USB behavior of the ESP32-S3, with a particular focus on logging in CDC/JTAG mode.

Let’s quickly look at the two different USB related features.

USB OTG Mode

The OTG (On-The-Go) mode of the ESP32-S3 allows it to function as both a host and a peripheral device in USB communications. This means that it has the capability to initiate connections with other USB devices (acting as a host) and also to be recognized as a USB device by another host system (acting as a peripheral).

When the ESP32-S3 is operating in host mode, you can connect various USB peripherals, such as cameras, keyboards, or memory sticks, directly to its USB port. This interaction is similar to how you would connect these devices to a computer. As a host, the ESP32-S3 has the ability to control and communicate with the connected USB devices.

On the other hand, when the ESP32-S3 is set to device mode, it can emulate different types of USB devices, like a memory stick or a mouse. This allows it to be recognized and utilized by a host system, just as if it were a standalone USB device. For instance, when connected to a computer, the ESP32-S3 in device mode can simulate mouse movements or input keystrokes.

The OTG mode grants the ESP32-S3 a versatile USB functionality, enabling it to adapt to different scenarios where it may need to act as a host or a peripheral device in USB communications. This flexibility is valuable in applications where USB connections are integral to the device’s functionality, allowing it to interact seamlessly with other USB-enabled hardware.

CDC/JTAG Mode

The CDC/JTAG mode of the ESP32-S3 refers to a specific USB operating mode that leverages the USB CDC (Communication Device Class) and JTAG (Joint Test Action Group) functionalities.

  1. CDC (Communication Device Class): In this context, CDC mode allows the ESP32-S3 to emulate a serial communication device over USB. Essentially, it transforms the ESP32-S3 into a virtual COM port on a computer. This virtual COM port can be used for serial communication, similar to how you would connect an external device like an Arduino to a computer for programming or data exchange.
  2. JTAG (Joint Test Action Group): JTAG is a standardized interface used for debugging and programming integrated circuits, including microcontrollers like the ESP32-S3. When the ESP32-S3 is in JTAG mode, it allows for direct communication with debugging tools and programming hardware via USB. This is especially useful during development and debugging phases, enabling tasks such as flashing firmware and performing advanced debugging operations.

In practical terms, when the ESP32-S3 is set to CDC/JTAG mode, it activates the USB-To-Serial module within the chip. This module performs functions similar to what an external UART (Universal Asynchronous Receiver-Transmitter) chip would do in other configurations. The USB connection is established through specific pins on the ESP32-S3 (D+ and D-, connected to GPIO19 and GPIO20 respectively).

By utilizing CDC/JTAG mode, developers can benefit from a streamlined and cost-effective approach to USB communications. It reduces the need for additional components on custom boards, ultimately saving space and reducing production costs.

Overall, CDC/JTAG mode plays a crucial role in the development and debugging process of applications running on the ESP32-S3, providing a direct USB interface for communication and programming tasks.

Logging in CDC Mode

Now let’s look at the scenario where you have a ESP32-S3 based device. We will program this device in CDC/ JTAG mode. And we want to receive the log statements over this connection and display them in the platformio logging console. Let’s assume the following program:

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println("Serial.println");
  log_e("log_e");
  delay(1000);
}

In the loop function we added two methods for logging. Serial.println and the log_e macro. Without additional settings we receive no logging output in the Serial console of Visual Studio Code:

By default our little program logs to the built-in UART and not to the CDC interface. Let’s change that by adding this line to the platformio.ini configuration:

build_flags = -DARDUINO_USB_CDC_ON_BOOT=1

By setting the ARDUINO_USB_CDC_ON_BOOT to 1 we enable the CDC interface already at boot. The result is:

Looks good, right? But wait, the log_e macro is not creating output. As described in our earlier blog post about logging we need to increase the log level:

build_flags = -DARDUINO_USB_CDC_ON_BOOT=1
              -DCORE_DEBUG_LEVEL=1

Now we get:

Here we go! Raising the log level to 1 included error (log_e) log statements. You could further increase the log level to also display warning, info, debug or verbose messages.

  • ESPGateway with antennas, bridging Espressif ESP-Now to WiFi

    ESPGateway – ESP32 WiFi/ BLE Gateway

    Sale! Original price was: $44.90.Current price is: $39.90.
    Read more
  • ThingPulse Color Kit Grand with sample application: weather station

    ESP32 WiFi Color Display Kit Grande

    Sale! Original price was: $44.50.Current price is: $36.90.
    Add to cart

Logging in OTG Mode

Let’s now have a look at OTG mode and enable it by adding another line to platformio.ini:

build_flags = -DARDUINO_USB_CDC_ON_BOOT=1
              -DCORE_DEBUG_LEVEL=1
              -DARDUINO_USB_MODE=0

The setting ARDUINO_USB_MODE=0 disables CDC mode and turns on OTG. In order to flash the firmware I had to set the device manually into boot mode by pressing the BOOT and the RESET button. After flashing the device stayed in download mode so I had to press the RESET button once more. Now a new serial device showed up:

Again, the output from the log_e macro is missing! We will fix this by enabling debug output on the Serial object with Serial.setDebugOutput(true). The complete sample looks now like:

#include <Arduino.h>

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
}

void loop() {
  Serial.println("Serial.println");
  log_e("log_e");
  delay(1000);
}

And the output now includes the macro:

Summary

In this blog post we looked at the options for logging with an ESP32-S3 on the platformio environment in CDC/ JTAG and OTG mode. Our Swiss countryman Andreas Spiess (“the guy with the Swiss accent”) recently published an excellent video about logging. It explains the differences of USB OTC/ CDC/ JTAG and how they are available on ESP32-S2, S3 and C3 family modules.

1 thought on “USB Settings for Logging with the ESP32-S3 in PlatformIO

  1. Hi, thank you for your article. I think there is a contradiction on this information I found on https://docs.espressif.com/projects/arduino-esp32/en/latest/troubleshooting.html#serial-not-printing

    “to find Espressif products with the appropriate USB connections for your needs. If you use the UART connector, you should disable USB-CDC on boot under the Tools menu (-D ARDUINO_USB_CDC_ON_BOOT=0). If you use the USB connector, you should have that enabled (-D ARDUINO_USB_CDC_ON_BOOT=1) and set USB Mode to “Hardware CDC and JTAG” (-D ARDUINO_USB_MODE=0). ”

    You are saying the opposite:

    “The setting ARDUINO_USB_MODE=0 disables CDC mode and turns on OTG”

    I’m confused. Could you explain the meaning of the different flags (I’m using PlatformIO) and it’s corresponding USB modes in detail? Thanks in advance.

Leave a Reply

Your email address will not be published. Required fields are marked *