{"id":7405,"date":"2021-07-16T17:17:20","date_gmt":"2021-07-17T00:17:20","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=7405"},"modified":"2025-09-09T19:27:40","modified_gmt":"2025-09-10T02:27:40","slug":"debugging-the-esp32-c3-device-with-jtag","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/esp32\/esp32-c3\/","title":{"rendered":"Debugging the ESP32-C3 Device with JTAG"},"content":{"rendered":"<p>This tutorial shows to to create a basic project for the RISC-V-based ESP32-C3 device and how to debug it with JTAG. We will show all the necessary wiring on the <a href=\"https:\/\/docs.espressif.com\/projects\/esp-idf\/en\/latest\/esp32c3\/hw-reference\/esp32c3\/user-guide-devkitm-1.html\">ESP32-C3-DevKitM<\/a> board, as well as the steps required to configure the software.<\/p>\n<p>The ESP32-C3 chip includes its own on-chip USB-to-JTAG engine, so it can be debugged by connecting a secondary USB cable to the special debug USB pins (Option A). Alternatively, it can also be debugged using an external JTAG probe (Option B), however it requires additional setup described <a href=\"https:\/\/github.com\/espressif\/openocd-esp32\/issues\/165#issuecomment-878397446\">here<\/a>.<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/jtag.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7407\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/jtag.png\" alt=\"\" width=\"1909\" height=\"547\" \/><\/a>In order to debug ESP32-C3 using the built-in JTAG engine, you need to use a secondary USB cable and connect it to the following pins on the board:<\/p>\n<table style=\"border-collapse: collapse; width: 100%; height: 120px;\" border=\"1\">\n<tbody>\n<tr style=\"height: 24px;\">\n<td style=\"width: 25%; height: 24px;\">USB Signal<\/td>\n<td style=\"width: 25%; height: 24px;\">Typical wire color<\/td>\n<td style=\"width: 25%; height: 24px;\">ESP32-C3 Signal Name<\/td>\n<td style=\"width: 25%; height: 24px;\">ESP32-C3-DevKitM Pin<\/td>\n<\/tr>\n<tr style=\"height: 24px;\">\n<td style=\"width: 25%; height: 24px;\">D-<\/td>\n<td style=\"width: 25%; height: 24px;\">White<\/td>\n<td style=\"width: 25%; height: 24px;\">GPIO18<\/td>\n<td style=\"width: 25%; height: 24px;\">J3.13<\/td>\n<\/tr>\n<tr style=\"height: 24px;\">\n<td style=\"width: 25%; height: 24px;\">D+<\/td>\n<td style=\"width: 25%; height: 24px;\">Green<\/td>\n<td style=\"width: 25%; height: 24px;\">GPIO19<\/td>\n<td style=\"width: 25%; height: 24px;\">J3.14<\/td>\n<\/tr>\n<tr style=\"height: 24px;\">\n<td style=\"width: 25%; height: 24px;\">V_BUS<\/td>\n<td style=\"width: 25%; height: 24px;\">Red<\/td>\n<td style=\"width: 25%; height: 24px;\">5V<\/td>\n<td style=\"width: 25%; height: 24px;\">J1.13 or J1.14<\/td>\n<\/tr>\n<tr style=\"height: 24px;\">\n<td style=\"width: 25%; height: 24px;\">GND<\/td>\n<td style=\"width: 25%; height: 24px;\">Black<\/td>\n<td style=\"width: 25%; height: 24px;\">GND<\/td>\n<td style=\"width: 25%; height: 24px;\">J1.15<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/usb1-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7418\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/usb1-1.jpg\" alt=\"\" width=\"1055\" height=\"993\" \/><\/a>The fully assembled setup will look like this:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/usb2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7409\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/usb2.jpg\" alt=\"\" width=\"2053\" height=\"1032\" \/><\/a>Note that since the secondary USB connection also supplies power to the board, you do not need to connect another cable to the primary USB connector.<\/p>\n<p>If you wanted to use an external USB-to-JTAG probe, you would need to connect the following signals according to the Espressif documentation:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 25%;\">JTAG signal<\/td>\n<td style=\"width: 25%;\">JTAG20 pin<\/td>\n<td style=\"width: 25%;\">ESP32-C3 signal<\/td>\n<td style=\"width: 25%;\">ESP32-C3-DevKitM Pin<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 25%;\">TMS<\/td>\n<td style=\"width: 25%;\">7<\/td>\n<td style=\"width: 25%;\">IO4<\/td>\n<td style=\"width: 25%;\">J3.11<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 25%;\">TDI<\/td>\n<td style=\"width: 25%;\">5<\/td>\n<td style=\"width: 25%;\">IO5<\/td>\n<td style=\"width: 25%;\">J3.10<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 25%;\">TCK<\/td>\n<td style=\"width: 25%;\">9<\/td>\n<td style=\"width: 25%;\">IO6<\/td>\n<td style=\"width: 25%;\">J3.9<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 25%;\">TDO<\/td>\n<td style=\"width: 25%;\">13<\/td>\n<td style=\"width: 25%;\">IO7<\/td>\n<td style=\"width: 25%;\">J3.8<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 25%;\">GND<\/td>\n<td style=\"width: 25%;\">4<\/td>\n<td style=\"width: 25%;\">GND<\/td>\n<td style=\"width: 25%;\">J3.1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>You would also need to do additional setup as shown in <a href=\"https:\/\/github.com\/espressif\/openocd-esp32\/issues\/165#issuecomment-878397446\">this thread<\/a>. For easier setup, we advise using the built-in JTAG controller instead.<\/strong><\/p>\n<p>Once you got all the wiring set up, follow the steps below to create a basic project and debug it:<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB ESP32 Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7411\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/01-newprj.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Pick a name and location for your project: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/02-name.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7412\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/02-name.png\" alt=\"\" width=\"1024\" height=\"680\" \/><\/a><\/li>\n<li>Proceed with the default CMake build system: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/03-cmake.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7413\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/03-cmake.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Make sure you are using VisualGDB 5.6+, the <strong>esp32-gcc8.4.0-r3<\/strong> toolchain or later and the ESP-IDF 4.3 or later. Then, select the ESP32C3 chip in the wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/04-c3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7414\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/04-c3.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><strong>Update:<\/strong> For better compatibility with the latest ESP32 tools, we recommend selecting the <a href=\"https:\/\/visualgdb.com\/documentation\/espidf\/consolidated\/\">consolidated toolchain<\/a> instead.<\/li>\n<li>Proceed with cloning the basic &#8220;blink&#8221; example: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/05-blink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7415\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/05-blink.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Connect the secondary USB cable as shown in the beginning of this tutorial. VisualGDB will automatically detect the <strong>ESP32C3 built-in JTAG <\/strong>interface and will select it on the Debug method page. Press &#8220;Test&#8221; to verify the connection: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/06-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7416\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/06-debug.png\" alt=\"\" width=\"856\" height=\"693\" \/><\/a><\/li>\n<li>Use the &#8220;test&#8221; button to verify the connection. Note that VisualGDB may report that most device registers are set to 0. This is expected for ESP32-C3 devices and does not indicate an error:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/test.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7419\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/test.png\" alt=\"\" width=\"1149\" height=\"593\" \/><\/a><\/li>\n<li>Finally, press &#8220;Finish&#8221; to create the project. Now you will be able to build and debug it as usual:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/07-built.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7417\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2021\/07\/07-built.png\" alt=\"\" width=\"1155\" height=\"794\" \/><\/a><\/li>\n<li>Note that the default <strong>blink<\/strong> example does not blink the on-board LED. Instead, it configures IO5 (that would be normally used as a TDI signal for external JTAG debugging) as an output and slowly toggles it. In order to debug the code with an external JTAG debugger, this would need to be disabled (e.g. by changing the BLINK_GPIO) in addition to following the steps described <a href=\"https:\/\/github.com\/espressif\/openocd-esp32\/issues\/165#issuecomment-878397446\">here<\/a>.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows to to create a basic project for the RISC-V-based ESP32-C3 device and how to debug it with<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[142],"tags":[138,234],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7405"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=7405"}],"version-history":[{"count":6,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7405\/revisions"}],"predecessor-version":[{"id":9034,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/7405\/revisions\/9034"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=7405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=7405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=7405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}