From f1c57b8b2a417dc2adf1478cb7f4688ff9957e42 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Mon, 21 Sep 2026 10:13:42 -0500 Subject: [PATCH] fix(examples): route the console to UART0 in every usb_device example bldc_haptics, can_bridge, coredump, mcp266 webapp and telemetry examples left the console on USB-Serial-JTAG (the CAN bridge and MCP266 ones selected it explicitly), which shares the S3 / P4 native USB PHY with USB-OTG: TinyUSB takes that port, so the examples did not enumerate with a stock sdkconfig. Use UART0 as the primary console with USB-Serial-JTAG secondary, like the ota / switch_pro / msc / xinput examples, and fix the READMEs that claimed the console stays on USB-Serial-JTAG. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DFjjnq3XCTRAXENSxsCxJU --- .../bldc_haptics/example/sdkconfig.defaults | 11 +++++++++++ components/canopen/can_bridge_example/README.md | 7 ++++--- .../canopen/can_bridge_example/sdkconfig.defaults | 15 ++++++++++----- components/coredump/example/sdkconfig.defaults | 11 +++++++++++ components/mcp266/webapp_example/README.md | 7 ++++--- .../mcp266/webapp_example/sdkconfig.defaults | 15 ++++++++++----- components/telemetry/example/README.md | 8 +++++--- components/telemetry/example/sdkconfig.defaults | 11 +++++++++++ 8 files changed, 66 insertions(+), 19 deletions(-) diff --git a/components/bldc_haptics/example/sdkconfig.defaults b/components/bldc_haptics/example/sdkconfig.defaults index 47992b1ffe..c80cd334e6 100644 --- a/components/bldc_haptics/example/sdkconfig.defaults +++ b/components/bldc_haptics/example/sdkconfig.defaults @@ -24,6 +24,17 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +# Console on UART0. On the ESP32-S3 (and -P4) USB-Serial-JTAG shares the native +# USB port's PHY with USB-OTG, which TinyUSB takes over for espp::UsbDevice's +# interfaces: a primary console on USB-Serial-JTAG contends with them for that one +# port and the device is unusable over USB. UART0 is an independent peripheral, so +# the console always has a place to go (connect a USB-UART adapter to UART0 for +# `idf.py monitor`). +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# USB-Serial-JTAG stays the SECONDARY console so early-boot / bootloader logs are +# still visible on the native USB port before the app brings up TinyUSB. +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y + # Enable the TinyUSB vendor-specific class (THE key enablement for the vendor / # WebUSB control interface). esp_tinyusb gates CFG_TUD_VENDOR behind # CONFIG_TINYUSB_VENDOR_COUNT; setting it > 0 compiles in the vendor class diff --git a/components/canopen/can_bridge_example/README.md b/components/canopen/can_bridge_example/README.md index 13d496c94c..f8b18a89c6 100644 --- a/components/canopen/can_bridge_example/README.md +++ b/components/canopen/can_bridge_example/README.md @@ -15,8 +15,9 @@ espp `stream_frame` framing and an `espp::Dispatcher` (this example uses console looks for 5 until told otherwise). The same framed protocol is exposed on both the USB **vendor** interface (WebUSB) and a **CDC** interface (Web Serial), so the web app can use -either transport. The system console/logs stay on the separate built-in -USB-Serial-JTAG. +either transport. The system console/logs go to **UART0** (set in +`sdkconfig.defaults`): on the S3 / P4, USB-Serial-JTAG shares the native USB +port's PHY with USB-OTG, which TinyUSB takes over. ## Wiring @@ -75,7 +76,7 @@ The bus starts **stopped**: the host sets baudrate/mode with `SET_CONFIG`, then ``` idf.py set-target esp32s3 -idf.py build flash monitor +idf.py build flash monitor # console is on UART0 (USB-UART adapter) ``` Then open the CAN console web app and Connect (WebUSB or Web Serial). diff --git a/components/canopen/can_bridge_example/sdkconfig.defaults b/components/canopen/can_bridge_example/sdkconfig.defaults index fc50e6354e..22ec9822ed 100644 --- a/components/canopen/can_bridge_example/sdkconfig.defaults +++ b/components/canopen/can_bridge_example/sdkconfig.defaults @@ -7,11 +7,16 @@ CONFIG_IDF_TARGET="esp32s3" CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 -# Keep the system console/logs on the built-in USB-Serial-JTAG peripheral so it -# stays separate from the native USB-OTG (vendor / CDC) interfaces created by -# espp::UsbDevice for the framed CAN protocol. (On an S3 devkit these are two -# distinct USB connectors.) -CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +# Console on UART0. On the ESP32-S3 (and -P4) USB-Serial-JTAG shares the native +# USB port's PHY with USB-OTG, which TinyUSB takes over for espp::UsbDevice's +# interfaces: a primary console on USB-Serial-JTAG contends with them for that one +# port and the device is unusable over USB. UART0 is an independent peripheral, so +# the console always has a place to go (connect a USB-UART adapter to UART0 for +# `idf.py monitor`). +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# USB-Serial-JTAG stays the SECONDARY console so early-boot / bootloader logs are +# still visible on the native USB port before the app brings up TinyUSB. +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y # Enable the TinyUSB vendor + CDC class drivers. The vendor interface carries # the framed protocol for WebUSB; the CDC interface carries the SAME framed diff --git a/components/coredump/example/sdkconfig.defaults b/components/coredump/example/sdkconfig.defaults index 8ffcb111ba..ff9327f4e5 100644 --- a/components/coredump/example/sdkconfig.defaults +++ b/components/coredump/example/sdkconfig.defaults @@ -7,6 +7,17 @@ CONFIG_IDF_TARGET="esp32s3" CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +# Console on UART0. On the ESP32-S3 (and -P4) USB-Serial-JTAG shares the native +# USB port's PHY with USB-OTG, which TinyUSB takes over for espp::UsbDevice's +# interfaces: a primary console on USB-Serial-JTAG contends with them for that one +# port and the device is unusable over USB. UART0 is an independent peripheral, so +# the console always has a place to go (connect a USB-UART adapter to UART0 for +# `idf.py monitor`). +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# USB-Serial-JTAG stays the SECONDARY console so early-boot / bootloader logs are +# still visible on the native USB port before the app brings up TinyUSB. +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y + # Enable the TinyUSB vendor-specific class (THE key enablement for the vendor / # WebUSB interface). esp_tinyusb gates CFG_TUD_VENDOR behind # CONFIG_TINYUSB_VENDOR_COUNT; setting it > 0 compiles in the vendor class diff --git a/components/mcp266/webapp_example/README.md b/components/mcp266/webapp_example/README.md index ddb2bb00bc..6425397bc1 100644 --- a/components/mcp266/webapp_example/README.md +++ b/components/mcp266/webapp_example/README.md @@ -16,8 +16,9 @@ and runs CANopen in the browser), this example runs the `espp::Mcp266` driver **on the device** and exposes a small high-level protocol (see `main/mcp266_protocol.hpp`, dispatcher **module id 6**), so the web app needs no CANopen/DS402 knowledge. Both the vendor (WebUSB) and CDC (Web Serial) interfaces -carry the same protocol; the system console/logs stay on the built-in -USB-Serial-JTAG. +carry the same protocol; the system console/logs go to **UART0** (set in +`sdkconfig.defaults`): on the S3 / P4, USB-Serial-JTAG shares the native USB +port's PHY with USB-OTG, which TinyUSB takes over. ## Wiring & configuration @@ -63,7 +64,7 @@ high-nibble 6; replies/events use high-nibble E (reply flag set). ``` idf.py set-target esp32s3 -idf.py build flash monitor +idf.py build flash monitor # console is on UART0 (USB-UART adapter) ``` Then open the MCP266 console web app and Connect (WebUSB or Web Serial). Click diff --git a/components/mcp266/webapp_example/sdkconfig.defaults b/components/mcp266/webapp_example/sdkconfig.defaults index 49e3129bc1..77a50d4bd6 100644 --- a/components/mcp266/webapp_example/sdkconfig.defaults +++ b/components/mcp266/webapp_example/sdkconfig.defaults @@ -7,11 +7,16 @@ CONFIG_IDF_TARGET="esp32s3" CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096 CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 -# Keep the system console/logs on the built-in USB-Serial-JTAG peripheral so it -# stays separate from the native USB-OTG (vendor / CDC) interfaces created by -# espp::UsbDevice for the framed MCP266 protocol. (On an S3 devkit these are two -# distinct USB connectors.) -CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +# Console on UART0. On the ESP32-S3 (and -P4) USB-Serial-JTAG shares the native +# USB port's PHY with USB-OTG, which TinyUSB takes over for espp::UsbDevice's +# interfaces: a primary console on USB-Serial-JTAG contends with them for that one +# port and the device is unusable over USB. UART0 is an independent peripheral, so +# the console always has a place to go (connect a USB-UART adapter to UART0 for +# `idf.py monitor`). +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# USB-Serial-JTAG stays the SECONDARY console so early-boot / bootloader logs are +# still visible on the native USB port before the app brings up TinyUSB. +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y # Enable the TinyUSB vendor + CDC class drivers. The vendor interface carries # the framed protocol for WebUSB; the CDC interface carries the SAME framed diff --git a/components/telemetry/example/README.md b/components/telemetry/example/README.md index eb4feaae66..ad77352253 100644 --- a/components/telemetry/example/README.md +++ b/components/telemetry/example/README.md @@ -31,12 +31,14 @@ in channel order and call `telemetry.emit(...)`. ## Build & run ```sh -idf.py -p /dev/ttyACM0 flash monitor # target esp32s3 (set in sdkconfig.defaults) +idf.py -p /dev/ttyACM0 flash # target esp32s3 (set in sdkconfig.defaults) +idf.py -p /dev/ttyUSB0 monitor # console is on UART0 (USB-UART adapter) ``` Then open the Serial Plotter web app, click **Connect (USB)**, and pick the -"espp Serial Plotter" device. The system console/logs go to the separate -built-in USB-Serial-JTAG. +"espp Serial Plotter" device. The system console/logs go to **UART0**: on the +S3 / P4, USB-Serial-JTAG shares the native USB port's PHY with USB-OTG, which +TinyUSB takes over. ## Notes diff --git a/components/telemetry/example/sdkconfig.defaults b/components/telemetry/example/sdkconfig.defaults index 314a2e5151..591c9efe04 100644 --- a/components/telemetry/example/sdkconfig.defaults +++ b/components/telemetry/example/sdkconfig.defaults @@ -6,6 +6,17 @@ CONFIG_IDF_TARGET="esp32s3" # Common ESP-related CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 +# Console on UART0. On the ESP32-S3 (and -P4) USB-Serial-JTAG shares the native +# USB port's PHY with USB-OTG, which TinyUSB takes over for espp::UsbDevice's +# interfaces: a primary console on USB-Serial-JTAG contends with them for that one +# port and the device is unusable over USB. UART0 is an independent peripheral, so +# the console always has a place to go (connect a USB-UART adapter to UART0 for +# `idf.py monitor`). +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# USB-Serial-JTAG stays the SECONDARY console so early-boot / bootloader logs are +# still visible on the native USB port before the app brings up TinyUSB. +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y + # Enable the TinyUSB vendor-specific class (THE key enablement for the vendor / # WebUSB interface). esp_tinyusb gates CFG_TUD_VENDOR behind # CONFIG_TINYUSB_VENDOR_COUNT; setting it > 0 compiles in the vendor class