🛠 Dompter le double USB : Serial/JTAG et OTG de front
Objectifs
Exploiter la particularité unique de l'ESP32-S3 : deux personnalités USB simultanées. D'un côté le périphérique USB-Serial/JTAG (console série + débogage matériel sans pont externe), de l'autre le contrôleur USB-OTG (device HID/MSC/CDC ou hôte). Sur les cartes qui câblent les deux contrôleurs sur deux connecteurs distincts (certaines DevKitC-1, ESP32-S3-Box), on peut ainsi flasher et debugger par un port tout en émulant un clavier sur l'autre. Vous configurerez le mode Hardware CDC+JTAG, lancerez une session de debug et comprendrez le routage des broches.
Matériel
- 1 carte ESP32-S3 exposant les deux ports (ou un adaptateur UART sur GPIO43/44 en secours)
- 2 câbles USB
- IDE Arduino (core esp32 >= 2.0.14) ou ESP-IDF v5.x avec OpenOCD pour le JTAG
Code complet
// 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'arrêt 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);
}
Côté ESP-IDF, la console JTAG s'active par idf.py menuconfig → Component config → ESP System → « Channel for console output » → « USB Serial/JTAG », et le debug par idf.py openocd puis idf.py gdb (ou la configuration launch VS Code « OpenOCD GDB Server »).
Vérification attendue
Branché sur le port Serial/JTAG, la carte présente un port série sans aucune puce pont ; la console fonctionne à la vitesse du lien USB. En mode debug (ESP-IDF), GDB s'attache par le même câble : breakpoints, pas-à-pas et lecture mémoire sans JTAG externe. Sur une carte à deux connecteurs, le second port reste disponible pour un device TinyUSB : les deux mondes coexistent réellement.
Erreurs fréquentes
- Confondre les deux contrôleurs : « USB CDC On Boot » pilote le Serial/JTAG matériel (broches internes), alors que TinyUSB réclame GPIO19/20 ; mettre les deux en même temps sur les mêmes broches produit un port fantôme ou inexistant.
- Console perdue après passage en TinyUSB : le port Serial/JTAG n'est plus initialisé ; reflasher en maintenant BOOT + RESET (mode ROM) ou brancher un adaptateur série sur GPIO43 (RX) / GPIO44 (TX) / GND.
- Attention au reset : le périphérique Serial/JTAG peut déclencher un reset DTR/RTS à l'ouverture du port ; désactiver DTR/RTS dans le terminal si le script se fait reset.
- Vitesse de console : avec Serial/JTAG, le débit réel dépend du hôte, pas du baud configuré ; ne pas chercher un « 2000000 » d'UART.
- GDB qui ne s'attache pas : vérifier que le câble est branché sur le bon connecteur (celui du Serial/JTAG, pas l'OTG) et qu'aucun programme ne configure GPIO19/20 en sortie.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht22.inoArduinooled-i2c.inoArduinoserveur-web.inoArduino