There's a good old (>3yrs) project called ESP-USB-Bridge. It turns any ESP32-S2 or ESP32-S3 into a fully functional debug probe tool, with JTAG or SWD, UART pass through, and UF2 flashing too.
I'd been meaning to give it a try for ages, and this week I finally had the excuse to debug an uncooperative chip!
Mainly my reasoning for wanting these is that each PicoProbe costs ~$12, and JLink even more, and I ideally want one debug probe per board in my Hardware Testing farm (bunch of boards in boxes, controlled via SBCs with USB PPPS hubs).
Yes, you can use a Pico (~$6) as a pico probe, but that doesn't cover non SWD targets. Ideally I want to spend <$3 per target to add debugging, and cheap ESP32-S3 nano boards ($2 clones with bad aerial) seem ideal for that.
The firmware I work on (Adafruit WipperSnapper) supports over 40boards, and 100 components/peripherals, so there's quite the combination to debug / support (too expensive for official probes). I also aspire to support as many CircuitPython boards as possible, and at 500 boards that's a tall order!
What, a universal probe for $2? Almost, but not quite...
Yes it supports JTAG and SWD transports, no not interchangeably on demand (yet).
You must pick SWD or JTAG, and reflash the firmware to switch between. UART / Serial remains unaffected.
The pins remain the same, and it seems like you don't need to unplug them, except nReset (remove for SWD).
See the Docs here: https://documentation.espressif.com/esp-usb-bridge/master/README.md
Last gotcha, is that you'll probably want the openocd-esp32 forked copy (releases include windows binaries), which maintains parity with the SWD upstream code along with espressif specific patches.
Follow the recommended commands in the readme linked above, but mainly it's the same as usual.
Speaking of Pins...which ones did I use:
There's a handy Diagram on the back of the SWD/JTAG breakout, seen also on the Product page, and it lists each pin name for JTAG or SWD. It also works as a convenient presoldered breakout for jumper cables!
When planning my pin use, I got Google Gemini to suggest an appropriate pinout (for a Super-Mini S3 board):
| Target Interface | Bridge (S3 Super Mini) Pin | Notes |
| Target TX | IO 4 (Bridge RX) |
|
| Target RX | IO 5 (Bridge TX) |
|
| Target TMS | IO 6 |
|
| Target TCK | IO 7 |
|
| Target TDI | IO 8 |
|
| Target TDO | IO 15 |
|
| Target EN (Reset) | IO 1 |
Automatically toggled by bridge DTR/RTS |
| Target IO0 (Boot) | IO 2 |
Automatically toggled by bridge DTR/RTS |
And it worked with another S3 board as expected (an official Espressif ESP32-S3-DevkitC-1-N8):
Cloning, reconfiguring pin selection, building and flashing:
Grab your copy of the software from github:
git clone https://github.com/espressif/esp-usb-bridge
Make sure you have the esp-idf installed and loaded (use installer or via git):
(drop/swap the .ps1 extension if not on windows powershell)
git clone https://github.com/espressif/esp-idf
cd esp-idf
git checkout origin/release/v5.3
git submodule update --init --recursive --depth=0
./install.ps1
./export.ps1
cd ..
Now update esp-usb-bridge submodules, set target (s2 or s3), then run menuconfig and select pins for JTAG or SWD:
cd esp-usb-bridge
git submodule update --init --recursive --depth=0
idf.py set-target esp32s3
idf.py menuconfig
Go to Bridge config and alter anything desired (nothing), then go back to main menu, then Component Config, then Debug Probe Config, and then select the interface type (SWD or JTAG) and update the Pin numbers.
Save before exiting.
Finally build and flash the software:idf.py build flash
Success?
Yes in theory!
I got bored of setting up and tweaking the openocd and platformio config for SAMD debugging (the Adafruit Metro M4 AirLift being debugged by an ESP32-S3 Devkit board), as VsCode takes an age to reload metadata after each save of platformio.ini, so left Opus model via Claude Code running on it along with other things, and it happily beavered away until resolved:
Microcontroller Board as the Debug Tool
Any of these boards are suitable, as are ANY manufacturers ESP32-S2 or ESP32-S3 based boards:
Improvements (hopefully an incoming PR or two in the future)
- It would be lovely if the nRESET line was supported in SWD mode, or at least left in a compatible state.
- Having to swap firmware for SWD or JTAG is silly, and two OTA partitions instead would be clever.
You set the led/neopixel to one colour on boot and wait for one or two button presses, picking SWD or JTAG accordingly, or maybe smarter yet is one press just swaps. Colour of LED indicates SWD or JTAG.
Either way, the boot app (factory) checks the buttons and lights the LEDs, then sets the OTA partition active for JTAG or SWD (or via a flag in NVM) and reboots / loads chosen app partition. Upon loading OTA0 or OTA1 switch to factory app as default partition (or just rely on NVM next boot if not OTA) and then run SWD/JTAG app mode.
- DebugMCP allows your agentic harness to interact with debugging tools and was a VsCode extension, but just recently became a CLI tool too / independent of vscode. It probably needs a bit of configuration to select the correct debug target+protocol / add an adapter, but looks pretty solid:
https://github.com/microsoft/DebugMCP (Multiple session id / support is an open recent issue)
- Wireless debugging would be cool...
This page (Using an ESP32-S3 / S2 as a JTAG / SWD / CMSIS-DAP debug probe tool to debug anything (like a SAMD51 M4 Metro, Pico, or ESP)) was last updated on September 18, 2026.
Text editor powered by tinymce.