🛠 Dompter le double USB : Serial/JTAG et OTG de front
Objetivos
Aprovechar la particularidad única del ESP32-S3: dos personalidades USB simultáneas. Por un lado, el dispositivo USB-Serial/JTAG (consola serie + depuración de hardware sin puente externo); por otro, el controlador USB-OTG (dispositivo HID/MSC/CDC o host). En las tarjetas que conectan ambos controladores a dos conectores distintos (algunas DevKitC-1, ESP32-S3-Box), se puede flashear y depurar por un puerto mientras se emula un teclado en el otro. Configurarás el modo Hardware CDC+JTAG, iniciarás una sesión de depuración y comprenderás el enrutamiento de los pines.
Material
- 1 tarjeta ESP32-S3 que exponga los dos puertos (o un adaptador UART en GPIO43/44 como respaldo)
- 2 cables USB
- IDE Arduino (core esp32 >= 2.0.14) o ESP-IDF v5.x con OpenOCD para JTAG
Código completo
// Mode "Hardware CDC and JTAG" : console + debug sur le port Serial/JTAG,
// le port OTG (GPIO19/20) reste libre pour un peripherique TinyUSB.
// Outils Arduino : USB CDC On Boot = Enabled,
// USB Mode = "Hardware CDC and JTAG"
#include "Arduino.h"
// Point d'arret logiciel : si un debogueur JTAG est attache, il s'y connecte ;
// sinon la boucle courte evite toute surprise côté watchdog.
volatile int drapeau_debug = 0;
void setup {
Serial.begin(115200); // passe par USB-Serial/JTAG (pas GPIO43/44)
Serial.println("Boot sur USB-Serial/JTAG");
}
void loop {
static uint32_t n = 0;
if (drapeau_debug) { // breakpoint logiciel : pause pour GDB
while (drapeau_debug) { asm volatile("nop"); delay(1); }
}
if (++n % 50 == 0) Serial.printf("tick %u, heap %u\n", n, ESP.getFreeHeap);
delay(20);
}
En el lado de ESP-IDF, la consola JTAG se activa mediante idf.py menuconfig → Component config → ESP System → «Channel for console output» → «USB Serial/JTAG», y la depuración mediante idf.py openocd seguido de idf.py gdb (o la configuración de lanzamiento de VS Code «OpenOCD GDB Server»).
Verificación esperada
Conectada al puerto Serial/JTAG, la tarjeta presenta un puerto serie sin ningún chip puente; la consola funciona a la velocidad del enlace USB. En modo de depuración (ESP-IDF), GDB se conecta mediante el mismo cable: puntos de interrupción, ejecución paso a paso y lectura de memoria sin JTAG externo. En una tarjeta con dos conectores, el segundo puerto sigue disponible para un dispositivo TinyUSB: los dos mundos coexisten realmente.
Errores frecuentes
- Confundir los dos controladores: «USB CDC On Boot» controla el Serial/JTAG de hardware (pines internos), mientras que TinyUSB requiere GPIO19/20; activar ambos al mismo tiempo en los mismos pines produce un puerto fantasma o inexistente.
- Pérdida de la consola al cambiar a TinyUSB: el puerto Serial/JTAG ya no se inicializa; vuelve a flashear manteniendo presionados BOOT + RESET (modo ROM) o conecta un adaptador serie en GPIO43 (RX) / GPIO44 (TX) / GND.
- Atención al reinicio: el dispositivo Serial/JTAG puede provocar un reinicio DTR/RTS al abrir el puerto; desactiva DTR/RTS en el terminal si el script se reinicia.
- Velocidad de la consola: con Serial/JTAG, el caudal real depende del host, no del baud configurado; no busques un «2000000» de UART.
- GDB que no se conecta: verifica que el cable esté conectado al conector correcto (el del Serial/JTAG, no el OTG) y que ningún programa configure GPIO19/20 como salida.
Otros tutoriales para esta placa
Ejemplos de código para esta placa
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht22.inoArduinooled-i2c.inoArduinoserveur-web.inoArduino