Seeed Studio ESP32-3C debugging requires esp-prog?

Looking for an expert to clarify something - the documentation states

Seeed Studio XIAO ESP32C3 does not have on-board debug probe and IS NOT READY for debugging. You will need to use/buy one of external probe listed below.

However the chip has on-chip JTAG and the serial pins are directly connected to the USB port. Is this a chip issue or a board issue or a PlatformIO support for this board issue?

thanks

That’s weird because the TRM states on page 742:

30 USBSerial/JTAG Controller (USB_SERIAL_JTAG)

The ESP32-C3 contains an USB Serial/JTAG Controller. This unit can be used to program the SoC’s flash, read program output, as well as attach a debugger to the running program. All of these are possible for any computer with a USB host (’host’ in the rest of this text) without any active external components.

There is also a tutorial available:

There is probably a parlance breakdown somewhere. Everything except the very first mont’s of public pre-production (super hard to get as it was the first RISC-V part from Espressif, there was demand from low-level devs to bootstrap that world) run of the ESP32-C3 has working JTAG debugging to my knowledge.

It’s possible that Seeed blew the fuses JTAG_SEL_ENABLE and DIS_USB_JTAG that disallow development with JTAG on the development boards. That would be a choice. It would also be easy to identify.

The certainity (caps AND bold? Better pour myself a strong one!) of conviction in that first sentence is unwarranted. I mean, it would take a Special Kind Of Coworker to assert that ’ SS XAIO ESP32C3 doesn’t have on-board debug" … because the feature is technically on the ESP32C3 itself and not the board. (We’ve all worked with this guy. Nobody likes him.) You can apply that same logic and end up in similar-sounding places like “Board X has no timer” … because the timer is on the chip and not the board. With commonly shared concepts of English, that’s just, well, weird.

So before we try to split that further, remember that “extraordinary claims require extraordinary proof”. Beyond the already offered TRM (thank you, @sivar2311 ) we have the entire section of Espressif’s own doc on JTAG on ESP32-C3, including the sentences “The quickest and most convenient way to start with JTAG debugging is through a USB cable connected to the D+/D- USB pins of ESP32-C3. No need for an external JTAG adapter and extra wiring/cable to connect JTAG to ESP32-C3.” There is certainly no shortage of tutorials on the web of using JTAG on ESP32-C3 and witnesses that would testify to having used it. I would be one such. So we’ll just await that clarification for your assertion that it’s not there.

While we wait, I’m bored; it’s storytime!

The part of JTAG we don’t have to talk about is the protocol that drives the state machines of the endpoint for inspection of a processor that’s not really running and lets an external entity read and write arbitrary signals inside the part. Those books describing JTAG’s exist, and we’ve not collectively gotten around to burning them and denying their existence…but we still have a day left in the week, and little surprises us any longer.

The “hard” part of JTAG has been inside the interesting chips for years at this point. The part that we know as the business end of TDI, TDO, TCK, TMS, and SRT are just a couple of pins that let you build a bidirectional communication portal that’s pretty darn fast. The contents of a commodity JTAG probe, whether ESP-Prog or BlackMagic, PIne64 JTAG, or an ST-Link or whatever, are “just” a device that provides a way to wiggle those pins very quickly and connect them to some kind of computer. Years ago, this was hard and required complicated hardware, but given the number of single-chip, $10 devices I’m citing here, you may see decades of trends have taken us where they’ve taken everything else: lower cost and higher integration.

No longer does a JTAG probe (or, for that matter, a simple logic analyzer) inherently NEEED to be a $10,000 device. You can’t really wiggle the pins yourself to meet the timing and speed requirements from a general-purpose computer that you’re also trying to run a debugger on, so you put it on an inexpensive specialized device. You’re just not going to dig out that parallel port cable and bang on inb() and outb() quickly enough to keep that SCLK pin holding down the groove. You just need a device with enough autonomy that you don’t need to totally hold its hand for everything that provides a fast link to a real computer. In modern times, that means USB.

JTAG is not serial in the async sense; there are no start bits and stop bits). It’s not traditional SDLC/HDLC synchronous; it’s not a frame-oriented packet protocol. It’s not like it’s RS-485 or pretty much anything else from the serial port world. So we need a device with some smarts, a USB hose on one side, and a half dozen GPIO pins on the other. Oh, and some programming to handle the JTAG stuff.

If you look at the schematic of ESP-PROG, you’ll recognize FT2232HL as a later variant of the serial port that grew from the FTD USB/serial bridges of the 90’s. This is a pumped-up version of the chip sometimes known as “FTDI Friend”—it easily lets you have some serial pins (which we don’t need) and some control signals, which, in a post line-driver/receiver world, sound like plain old GPIO signals. The FTDI merely needs to know to drop RTS when input buffers get too full, for example. It can’t rely on the computer to wiggle that pin. Heck, it’s too busy to drain the RX queue; it sure can’t get a USB transaction scheduled and to us in time. How do you abstract away coding bit-wiggling in silicon?

Let’s do it with a dumb little microcontroller. It turns out that for years, FTDI had been progressively adding intelligence to that dumb little serial chip, making their “Multi-Protocol Synchronous Serial Engine” progressively smarter and adding more pins (maybe you want to build a parallel printer port with those GPIO pins; you need a little bit of logic to independently control embedded signals at high speeds). FTDI grew their own little processor that they tried to fiercely guard (perhaps too fiercely) and they hid all the opcode/looping “programmer-y” stuff inside their MPSE library. Over time, we saw chip revisions and models get progressively smarter and sprouted the ability to bang i2c, spi, and other protocols using this MPSE model. Many people just wanted to drive an asynch serial port and had no idea these parts were programmable on their own and had crude opcodes that conditionally banged GPIOs to clock edge. It was key that the FT family became a bridge from USB to wiggling arbitrary physical pins. Similar chips are now made by Microchip, WCH, and Silicon Labs.

Inside Espressif, they were already adding a USB host controller block to their embedded cores that started shipping in 2020. Notably, these are WAY more powerful parts than the USB/serial bridges. A few stages were necessary:

  • Espressif presumably already know what the expected “call and response” traffic on those JTAG pins to the chip looks like. It may not be the same as what’s on ESP32-Legacy, but someone there understands this.

  • They knew enough about USB to implement devices (like the built-in serial module on the S3 packages that didn’t quite stick the landing on C3, though you can see some evidence of it in C3) to know how to implement what looks like an FTDI-Friend to the host computer and either emulate enough of the MPSEE core (later versions of the MPSEE access library are called “D2XX”) that OpenOCD’s programming of those cores to “speak JTAG

  • They have the source to OpenOCD-like tools that run on any OS and conveniently open the host’s abstraction of a serial port (it’s actually a USB endpoint. The “only” have to either emulate the big engine well enough to accept what’s being sent and expected by OpenOCD or they can just replace the bottom edge of OpenOCD and read and write “serial” traffic that corresponds to the needed code that sets their own interface that would sit below the TMS/TDI/DTO later, but since they have to have their own handler for that for hardware JTAG debugging boards, replacing that would be a false savings in gates and simplicity.

That’s it. At this point, Espresif was on the fast path to completely connect the TMI/TMO/TMS data from the chip’s internals, up through the physical interface, over the bytestream, and into the virtualized USB transport.

I don’t know if Espressif actually was the first to deliver JTAG debugging like this, but I still don’t know of any other chip vendors delivering this feature inside their chips.

The engineering costs should have been minimal to espressif. Nothing was needed at the host OS driver level for Mac, Windows, or Linux drivers as as the existing FTDI drivers already know how to direct a dev node to opcodes and traffict for the bit-blasters. Either nothing or not very much is needed at the bottom of OpenOCD, depending on whether they emulate the MPSE totally (it’s possible they licensed it - IP law in Shenzhen is beyond the scope of even this epic explanation). Sure, they did have some work inside the chip itself, but that’s literally what they do. Comparing it to the work needed for the S3’s (and H4 and C6 and P4 and…) own serial endpoint that’s used for Serial0 on /dev/usbmodemFOO, I’d expect the projects to be of comparable size and in similar orbits.

Developers can now use one single wire to provide power, serial console (whoops, not on C3…), JTAG, and other needed USB endpoints. To this developer, it’s an important feature on the chips. NOT carryiung around extra boards, DuPont wires, and nursing fragile cabling is a big deal for some of us.

Disclaimer: I have no inside information on the forehead-smacking and apple-falling-on-my-head motivations that resulted in this. I was in professionally adjacent worlds to much of this over decdes starting in the 90’s. There’s enough observable behaviour of all this (usb protocol analyzer traces, debugging in OpenOCD, comparisons of traces beyond this virualized case of smuggling MPSEto real hardware, system call tracers, and more, to be pretty sure that this is how JTAG debugging does, in fact, work on ESP32-C3 and later chips from Espressif.

Development with JTAG in Espressif’s newer parts is here, it’s available, and it’s awesome. Board developers can continue to plumb out the legacy five or six JTAG pins or they can leave them not connected on the chip. An irreversible fuse can completely disable JTAG for production cases where you don’t want random people breaking in and dumping flash images and such.

TL;DR: “Does too!”

P.S. It’s late as I wrote this. I’ll come back and shorten it tomorrow.

I don’t understand why Seeed would blow the JTAG fuse, it makes no sense.

Here is the error message when I try to upload and run the debugger. NOTE I am using default esp-tool for upload, not debugger. My first thing to confirm is that platformIO integrated debugging should work without esp-prog (ie, everything I see says on-chip JTAG should work…). Or maybe I’m missing something - but the debug build and download work fine…

Reading symbols from /home/tony/ESPprojects/ESP32c-Switch/.pio/build/seeed_xiao_esp32c3/firmware.elf…
PlatformIO Unified Debugger → Redirecting...
PlatformIO: debug_tool = cmsis-dap
PlatformIO: Initializing remote target…
Open On-Chip Debugger v0.11.0-esp32-20220706 (2022-07-06-15:48)
Licensed under GNU GPL v2
For bug reports, read
OpenOCD: Bug Reporting
adapter speed: 5000 kHz

Info : tcl server disabled
Info : telnet server disabled
Error: unable to find a matching CMSIS-DAP device

Error: Unsupported xlen: -1
Error: Unknown target arch!
.pioinit:11: Error in sourced command file:
Remote communication error. Target disconnected.: Connection reset by peer.

Thanks for finding this! I’m going to try to set the platformio settings per the example - I assumed that the board type setting would make these automatic but who knows? I’ll come back with what I find.

Debugging the ESP-C3 via USB works perfectly.
It takes about 30 seconds for the debugging process to start.

Here is a short recording of my debugging session (recorded a few minutes ago):

main.cpp

#include <Arduino.h>

int i=0;

void setup() {
    Serial.begin(115200);
    Serial.println("Hello World");
}

void loop() {
    Serial.println(i++);
    delay(1000);
}

platformio.ini

[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = arduino
monitor_speed = 115200
build_flags = 
  -DARDUINO_USB_CDC_ON_BOOT=1
  -DARDUINO_USB_MODE=1
debug_tool = esp-builtin
debug_init_break = break setup

Note:

Used platform: pioarduino (Arduino 3.0.7 @ esp-idf 5.1.4)
but platform = espressif32 @ 6.9.0 also works fine

Used board: ESP32-C3 SuperMini

Progress but still errors. I explicitly added these items to the platformio.ini file per the tutorial.

debug_tool = esp-builtin
debug_init_break = break setup
debug_server =
$PLATFORMIO_CORE_DIR/packages/tool-openocd-esp32/bin/openocd
-f
$PLATFORMIO_CORE_DIR/packages/tool-openocd-esp32/share/openocd/scripts/board/esp32c3-builtin.cfg

The good news is that it’s connecting.
First time - got an error about protection - per tutorial I hit the reset button and restarted the debugging. Now I always get these errors. What are the USB build flags you are using? I’ll add those and see if it makes a difference.

They won’t make any difference for debugging.

This is just to route the output of Serial.println to the USB Serial (HWCDC).
Without them there won’t be any output on my serial interface because I use the esp32-c3-devkitm-1 in my platformio.ini.

Why do you use this? Do you really need it?
Please show the complete content of your platformio.ini.
Use preformatted-text when posting logs or code.

Which errors exactly?
I can’t see the messages on yous screen

LOL. Nope you can’t, the paste didn’t paste. Changing the build flags forced a complete rebuild so I can start from scratch. I’ll try to paste properly, thank you for your help.

First off - the platform server list in platformio.ini is directly in the tutorial you sent me so I just cloned it. It seems to me that by specifying the board type explicitly I should not need any of these things, but here we are :-).

Here is the error output (hope I paste this correctly)… From the first run. After this per the tutorial I press reset on the board and try to reattach. Similar result.

Reading symbols from /home/tony/ESPprojects/ESP32c-Switch/.pio/build/seeed_xiao_esp32c3/firmware.elf...
PlatformIO Unified Debugger -> https://bit.ly/pio-debug
PlatformIO: debug_tool = esp-builtin
PlatformIO: Initializing remote target...
Open On-Chip Debugger  v0.11.0-esp32-20220706 (2022-07-06-15:48)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001
Info : esp_usb_jtag: capabilities descriptor set to 0x2000
Warn : Transport "jtag" was already selected
adapter speed: 5000 kHz

Info : tcl server disabled
Info : telnet server disabled
Info : esp_usb_jtag: serial (64:E8:33:86:10:88)
Info : esp_usb_jtag: Device found. Base speed 40000KHz, div range 1 to 255
Info : clock speed 5000 kHz
Error: libusb_bulk_write error: LIBUSB_ERROR_IO
Info : JTAG tap: esp32c3.cpu tap/device found: 0x00005c25 (mfg: 0x612 (Espressif Systems), part: 0x0005, ver: 0x0)
Error: libusb_bulk_write error: LIBUSB_ERROR_IO
Error: missing data from bitq interface
Error: failed jtag scan: -104
Error: Unsupported DTM version: 8
Warn : target esp32c3 examination failed
Info : starting gdb server for esp32c3 on pipe
Info : accepting 'gdb' connection from pipe
Error: Target not examined yet
Error executing event gdb-attach on target esp32c3:

Warn : No symbols for FreeRTOS!
Error: Target not halted
Error: auto_probe failed
Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
Error: attempted 'gdb' connection rejected
Ignoring packet error, continuing...
warning: unrecognized item "timeout" in "qSupported" response

Here is my platformio.ini incl my build flags for wifi (which is blowing up inside WiFi.begin with an unhandled exception, which is what started this mess…)

[env:seeed_xiao_esp32c3]
platform = espressif32
board = seeed_xiao_esp32c3
framework = arduino
monitor_speed = 115200
upload_speed = 115200
build_type = debug
debug_tool = esp-builtin
debug_init_break = break setup
debug_server = 
   $PLATFORMIO_CORE_DIR/packages/tool-openocd-esp32/bin/openocd
   -f
   $PLATFORMIO_CORE_DIR/packages/tool-openocd-esp32/share/openocd/scripts/board/esp32c3-builtin.cfg
build_flags =
        '-DWIFI="WIFI"'
        '-DMYSSID="theCollective"'
        '-DMYPASSWD="xxxxxxxxx"'
        -DARDUINO_USB_CDC_ON_BOOT=1
        -DARDUINO_USB_MODE=1

Please try this platformio.ini

[env:seeed_xiao_esp32c3]
platform = espressif32 @6.9.0
board = seeed_xiao_esp32c3
framework = arduino
monitor_speed = 115200
debug_tool = esp-builtin
debug_init_break = break setup
build_flags =
  '-DWIFI="WIFI"'
  '-DMYSSID="theCollective"'
  '-DMYPASSWD="xxxxxxxxx"'

It still failed. So I got another board - and it’s entering debug. Bizarre. There must be some sort of defect on that chip - but the program is running with my print statements, it just wouldnt go into debug.

Can you tell me what the “@6.9.0” version of the framework is or point me to some references now that I’m about to start debugging the original wifi problem I hit…

Thanks for the help!!!

tony

please see

Oh - the platformIO document that says this board only will work with an external JTAG - not sure who owns that. I think I found an errata somewhere that implied the first spin of the chip had a JTAG problem - maybe(?) , and maybe one of my boards has one of those??? IDK but just my luck :slight_smile:

Interesting… the 2nd board is now in the same state as the first board. I started a debug session stepping over “serial.begin” and I got an error “duplicate breakpoint” and when I forced break it seems to be in an endless loop - tried to restart the debug session and now this board is dumping the same errors as the first one - the error dump looks the same. Very strange. Any ideas appreciated as I start banging away on this…

Unfortunately this does not contain a link to the document you mention and
Do you mean this one?
https://docs.platformio.org/en/latest/boards/espressif32/seeed_xiao_esp32c3.html

You will always find an ‘edit on GitHub button’ at the top right of the documents where you can improve and correct documents.

Please provide more precise information.
Do you mean this one ?

.pioinit:11: Error in sourced command file:
Remote communication error. Target disconnected.: Connection reset by peer