esp32s3/c3 hardware JTAG control to external pins
Description
Allows routing of ESP32C3 and ESP32S3 internal hardware usb-jtag
to external gpio pins making ESP32S3/C3 cheap and fast JTAG for
programming other devices.
Once enabled this ESP32 hardware services JTAG by itself
so no other software interrupts or any server running
is needed.
Code Size
12 lines of code to enable, 6 lines to disable here is arduino example
#if CONFIG_IDF_TARGET_ESP32S3
#define OMATRIX_TCK 85
#define OMATRIX_TMS 86
#define OMATRIX_TDI 87
#define OMATRIX_SRST 251
#define IMATRIX_TDO 251
#endif
#if CONFIG_IDF_TARGET_ESP32C3
#define OMATRIX_TCK 36
#define OMATRIX_TMS 37
#define OMATRIX_TDI 38
#define OMATRIX_SRST 127
#define IMATRIX_TDO 39
#endif
void route_usb_jtag_to_gpio()
{
digitalWrite(LED_BUILTIN, LED_ON);
pinMode(PIN_TCK, OUTPUT);
pinMode(PIN_TMS, OUTPUT);
pinMode(PIN_TDI, OUTPUT);
pinMode(PIN_TDO, INPUT);
pinMode(PIN_SRST, OUTPUT);
WRITE_PERI_REG(USB_SERIAL_JTAG_CONF0_REG,
READ_PERI_REG(USB_SERIAL_JTAG_CONF0_REG)
| USB_SERIAL_JTAG_USB_JTAG_BRIDGE_EN);
// esp_rom_gpio_connect_out_signal(GPIO, IOMATRIX, false, false);
esp_rom_gpio_connect_out_signal(PIN_TCK, OMATRIX_TCK, false, false);
esp_rom_gpio_connect_out_signal(PIN_TMS, OMATRIX_TMS, false, false);
esp_rom_gpio_connect_out_signal(PIN_TDI, OMATRIX_TDI, false, false);
esp_rom_gpio_connect_out_signal(PIN_SRST, OMATRIX_SRST, false, false);
esp_rom_gpio_connect_in_signal (PIN_TDO, IMATRIX_TDO, false);
}
void unroute_usb_jtag_to_gpio()
{
WRITE_PERI_REG(USB_SERIAL_JTAG_CONF0_REG,
READ_PERI_REG(USB_SERIAL_JTAG_CONF0_REG)
& ~USB_SERIAL_JTAG_USB_JTAG_BRIDGE_EN);
pinMode(PIN_TCK, INPUT);
pinMode(PIN_TMS, INPUT);
pinMode(PIN_TDI, INPUT);
pinMode(PIN_TDO, INPUT);
pinMode(PIN_SRST, INPUT);
digitalWrite(LED_BUILTIN, LED_OFF);
}
Implementation
I hope the MicroPython maintainers or community will implement this feature
Code of Conduct
Yes, I agree
Disabling USB_SERIAL_JTAG on esp32c3 to free up the pins.
Port, board and/or hardware
esp32c3
MicroPython version
MicroPython v1.25.0-preview.114.gbdda91fe7.dirty on 2024-12-14; ESP32C3 module with ESP32C3
Reproduction
import espnow
from machine import Pin
from time import sleep
relay = Pin(19, Pin.OUT)
while True:
relay.on()
sleep(1)
relay.off()
sleep(1)
Expected behaviour
Relay to Turn on and off.
Observed behaviour
Traceback (most recent call last):
File "<stdin>", line 13, in <module>
ValueError: invalid pin
Additional Information
previous branch sdkconfig.c3usb
CONFIG_ESP32C3_REV_MIN_3=y
CONFIG_ESP32C3_BROWNOUT_DET=y
CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_7=
CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_4=y
CONFIG_ESP32C3_BROWNOUT_DET_LVL=4
CONFIG_ESP_CONSOLE_UART_DEFAULT=
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
master branch sdkconfig.c3usb
CONFIG_ESP32C3_REV_MIN_3=y
# Workaround for https://github.com/espressif/esp-idf/issues/14456
CONFIG_ESP_SYSTEM_HW_STACK_GUARD=n
Usually I can block CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y and pin 18 and 19 work but not in this case?
Code of Conduct
Yes, I agree