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.