Hi,
I'm designing a board that has USB, and I'd like to still be able to debug it. Accordingly, I've built a small test PCB that breaks out both the int and ext pins to a USB-C connector.
1. At boot, I get SERIAL_JTAG on INT USB
2. If I try the tinyusb console program, I get WARP on INT USB
3. If I call `usb_phy_ll_int_jtag_enable(&USB_SERIAL_JTAG);` then I get SERIAL_TAG back on INT USB even without deinitializing tinyusb
4. I get no useful output on EXT USB regardless of what I try.
When I say "no useful output" I mean I can see my host PC attempting to enumerate, but it gives up. I see traffic flowing -- both DP and DM -- but the ESP32-S3 does not do anything with the signals. The waveforms are well-shaped and do not appear to be suffering from any sort of contention. They are 3.3V, as is expected.
I would expect that I would see the MTDO/JTAG/GPIO40/OEN go high and some interesting data to appear on MTCK/JTAG/GPIO39/VPO and GPIO38/VMO, but those pins are absolutely still. It's as if they're not muxed for USB PHY support.
My PCB has D+ go to MTMS, and D- go to MTDI. Then pins MTCK and GPIO38 go through a small buffer (SN74AUP1G125DCKR) that outputs on negative edge.
Since I don't see GPIO38, MTCK, or MTDO toggling I can only assume that the block isn't receiving the signals.
Are there any examples of how to get the SERIAL_JTAG block working? Are there steps I need to take beyond simply calling `usb_phy_ll_ext_jtag_enable(&USB_SERIAL_JTAG)`? Do I need to adjust pin mux somewhere?
ESP32-S3 USB Serial JTAG on External PHY?
Re: ESP32-S3 USB Serial JTAG on External PHY?
One thing I've noticed is that `gpio_sig_map.h` has mappings for the following:
However those signals are undocumented in the reference manual and are listed as `-`.
I've tried setting `.external_phy = true,` in the tusb configuration in the hopes that it would support an external PHY, but I still see absolutely no movement on the OEN or VPO/VMO signals where I'd expect to see OEN driven several cycles after the end of a USB frame.
Code: Select all
#define USB_EXTPHY_VP_IDX 55
#define USB_EXTPHY_OEN_IDX 55
#define USB_EXTPHY_VM_IDX 56
#define USB_EXTPHY_SPEED_IDX 56
#define USB_EXTPHY_RCV_IDX 57
#define USB_EXTPHY_VPO_IDX 57
I've tried setting `.external_phy = true,` in the tusb configuration in the hopes that it would support an external PHY, but I still see absolutely no movement on the OEN or VPO/VMO signals where I'd expect to see OEN driven several cycles after the end of a USB frame.
Re: ESP32-S3 USB Serial JTAG on External PHY?
One slightly concerning thing I'm starting to realize now that I have this board fabricated and I'm finding it doesn't work -- the `RCV` pin appears to be undocumented.
The reference manual on page 756 shows five pins are required: VP, VM, OEN, VPO, and VMO, but I see references in the code to a signal labeled "RCV". Furthermore, it appears to be on pin 21.
The reference manual on page 756 shows five pins are required: VP, VM, OEN, VPO, and VMO, but I see references in the code to a signal labeled "RCV". Furthermore, it appears to be on pin 21.
Re: ESP32-S3 USB Serial JTAG on External PHY?
After shorting VP to GPIO21 I'm starting to get somewhere. So it definitely seems like it's missing something in the documentation. I'm going to rework a second board and see if I can get something updated.
Is the RCV signal documented anywhere, or will it be?
Is the RCV signal documented anywhere, or will it be?
Re: ESP32-S3 USB Serial JTAG on External PHY?
After further investigation, I've managed to come up with the following function -- posted here in the hopes that it will help someone else:
If you call it, the USB Serial JTAG device will appear on the second PHY. It will also drive D+ LOW, overriding the pullup that may or may not be permanently installed and causing re-enumeration.
Note that `esptool.py` doesn't yet like this solution, mostly because resetting the device doesn't reset the port so the host just sees a series of NAKs from the device. I'll have to investigate efuses now to see how to work around that.
I'm concerned about needing to include `esp_private/usb_phy.h` but I can't see any other way to call `usb_new_phy()`.
Code: Select all
#include "esp_private/usb_phy.h"
#include "hal/usb_phy_ll.h"
#include "soc/usb_pins.h"
#include "driver/gpio.h"
#include "esp_check.h"
static esp_err_t configure_usb_jtag(void)
{
static usb_phy_handle_t usb_jtag_phy_hdl;
// Drive 0 out D+ in order to override the 1.5k pullup
// and force a reset, since we're changing which PHY
// is driving the bus and the host may not realize that
// the part needs re-enumeration.
{
// zero-initialize the config structure.
const gpio_config_t io_conf = {
.intr_type = GPIO_INTR_DISABLE,
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = ((1ULL << USBPHY_OEN_NUM) | (1ULL << USBPHY_VPO_NUM)),
.pull_down_en = 0,
.pull_up_en = 0,
};
// configure GPIO with the given settings
gpio_config(&io_conf);
// Drive the VPO line low, which will coutneract the 1.5k pullup
// (which we cannot otherwise disable).
gpio_set_level(USBPHY_VPO_NUM, 0);
// Enable the buffers to drive the value out to override the 1.5k pullup
gpio_set_level(USBPHY_OEN_NUM, 0);
// USB resets require 5ms minimum
vTaskDelay(pdMS_TO_TICKS(10));
// External PHY IOs config
const usb_phy_ext_io_conf_t ext_io_conf = {
.vp_io_num = USBPHY_VP_NUM,
.vm_io_num = USBPHY_VM_NUM,
.rcv_io_num = USBPHY_RCV_NUM,
.oen_io_num = USBPHY_OEN_NUM,
.vpo_io_num = USBPHY_VPO_NUM,
.vmo_io_num = USBPHY_VMO_NUM,
};
const usb_phy_config_t usb_jtag_phy_conf = {
.controller = USB_PHY_CTRL_SERIAL_JTAG,
.otg_mode = USB_PHY_MODE_DEFAULT,
.otg_speed = USB_PHY_SPEED_UNDEFINED,
.target = USB_PHY_TARGET_EXT,
.ext_io_conf = &ext_io_conf,
};
ESP_RETURN_ON_ERROR(usb_new_phy(&usb_jtag_phy_conf, &usb_jtag_phy_hdl), "usbphy-jtag", "Install USB JTAG PHY failed");
}
usb_phy_ll_ext_jtag_enable(&USB_SERIAL_JTAG);
return ESP_OK;
}
Note that `esptool.py` doesn't yet like this solution, mostly because resetting the device doesn't reset the port so the host just sees a series of NAKs from the device. I'll have to investigate efuses now to see how to work around that.
I'm concerned about needing to include `esp_private/usb_phy.h` but I can't see any other way to call `usb_new_phy()`.
Re: ESP32-S3 USB Serial JTAG on External PHY?
Thanks for sharing the solution, I had no Idea this was possible.
Although I suppose the easier would be to disable USB-Serail-JTAG peripheral alltogether and use JTAG pins directly with external USB-JTAG adapter (like ESP-PROG for example), just like you would with ESP32's with no USB peripheral. The app itself would work with USB-OTG peripheral only. At least I suppose this should work?
Although I suppose the easier would be to disable USB-Serail-JTAG peripheral alltogether and use JTAG pins directly with external USB-JTAG adapter (like ESP-PROG for example), just like you would with ESP32's with no USB peripheral. The app itself would work with USB-OTG peripheral only. At least I suppose this should work?
Who is online
Users browsing this forum: No registered users and 40 guests