diff --git a/docs/_static/usb_device/ext_phy_schematic_stusb03e.png b/docs/_static/usb_device/ext_phy_schematic_stusb03e.png new file mode 100644 index 0000000000..9f43400832 Binary files /dev/null and b/docs/_static/usb_device/ext_phy_schematic_stusb03e.png differ diff --git a/docs/_static/usb_host/ext_phy_schematic_stusb03e.png b/docs/_static/usb_host/ext_phy_schematic_stusb03e.png new file mode 100644 index 0000000000..edba55a129 Binary files /dev/null and b/docs/_static/usb_host/ext_phy_schematic_stusb03e.png differ diff --git a/docs/en/api-reference/peripherals/usb_device.rst b/docs/en/api-reference/peripherals/usb_device.rst index f4f567aa48..dfcd07af7b 100644 --- a/docs/en/api-reference/peripherals/usb_device.rst +++ b/docs/en/api-reference/peripherals/usb_device.rst @@ -57,6 +57,84 @@ Hardware Connection Self-powered devices must also connect VBUS through a voltage divider or comparator. For more details, please refer to :ref:`self-powered-device`. +.. only:: esp32s3 + + External PHY Configuration + -------------------------- + + The {IDF_TARGET_NAME} contains two USB controllers - the USB-OTG and USB-Serial-JTAG. However, both controllers share a **single PHY**, which means only one can operate at a time. To use USB Device functionality while the USB-Serial-JTAG is active (e.g., for debugging or flashing), an **external PHY** is required, since the PHY is used by USB-Serial-JTAG. + + .. note:: + An external PHY is not the only way to enable debugging alongside USB Host or Device functionality. It is also possible to switch the debugging interface from USB-Serial-JTAG to plain JTAG by burning the appropriate eFuses. For details, refer to the *JTAG Debugging* section in the ESP-IDF Programming Guide for your target. + + {IDF_TARGET_NAME} supports connecting external PHY ICs. This becomes especially relevant when full-speed USB device functionality is needed while the USB-Serial-JTAG controller is also in use. Various external PHY ICs may require different hardware modifications. Please refer to each IC's datasheet for specifics. A general connection diagram can be found in the official ESP documentation: + + `ESP PHY Guide (External PHY Section) `__ + + **List of Tested External PHY ICs:** + + - **SP5301** — Directly supported by {IDF_TARGET_NAME}. See the guide above for schematic and routing information. + - **STUSB03E** — Requires signal routing using an analog switch. See example below. + + .. figure:: ../../../_static/usb_device/ext_phy_schematic_stusb03e.png + :align: center + :alt: External PHY with Analog Switch Schematic (Device mode) + + Example connection using STUSB03E and analog switch (Device mode) + + .. note:: + This schematic is a minimal example intended only to demonstrate the external PHY connection. It omits other essential components and signals (e.g., VCC, GND, RESET) required for a complete, functional {IDF_TARGET_NAME} design. + The schematic includes both a +5V rail (usually from USB VBUS) and a VCC rail. VCC should match the chip supply voltage (usually 3.3V). Ensure that the external PHY and the chip are powered from the same voltage domain. If designing a self-powered USB device, connect VBUSDET signal from the external PHY to {IDF_TARGET_NAME} for mandatory VBUS monitoring. + + Hardware configuration is handled via GPIO mapping to the PHY's pins. Any unused pins (e.g., :cpp:member:`usb_phy_ext_io_conf_t::suspend_n_io_num`, :cpp:member:`usb_phy_ext_io_conf_t::fs_edge_sel_io_num`) **must be set to -1**. + + .. note:: + The :cpp:member:`usb_phy_ext_io_conf_t::suspend_n_io_num` pin is **currently not supported** and does not need to be connected. + The :cpp:member:`usb_phy_ext_io_conf_t::fs_edge_sel_io_num` pin is optional and only required if switching between low-speed and full-speed modes is needed. + + Starting from version 2.0, the ESP TinyUSB Device Stack supports external PHY usage. To use an external PHY in device mode: + + 1. Configure the GPIO mapping and PHY using :cpp:type:`usb_phy_config_t` + 2. Create the PHY using :cpp:func:`usb_new_phy()` + 3. Use :cpp:func:`TINYUSB_DEFAULT_CONFIG()` to initialize :cpp:type:`tinyusb_config_t` + 4. Set the `phy.skip_setup` field of :cpp:type:`tinyusb_config_t` to ``true`` to bypass PHY reinitialization and use the externally configured PHY. + + **Example Code:** + + .. code-block:: c + + // GPIO configuration for external PHY + const usb_phy_ext_io_conf_t ext_io_conf = { + .vp_io_num = 8, + .vm_io_num = 5, + .rcv_io_num = 11, + .oen_io_num = 17, + .vpo_io_num = 4, + .vmo_io_num = 46, + .suspend_n_io_num = -1, + .fs_edge_sel_io_num = -1, + }; + + // Configuration and initialization of external PHY for OTG controller (Device mode) + const usb_phy_config_t phy_config = { + .controller = USB_PHY_CTRL_OTG, + .target = USB_PHY_TARGET_EXT, + .otg_mode = USB_OTG_MODE_DEVICE, + .otg_speed = USB_PHY_SPEED_FULL, + .ext_io_conf = &ext_io_conf + }; + + usb_phy_handle_t phy_hdl; + ESP_ERROR_CHECK(usb_new_phy(&phy_config, &phy_hdl)); + + // Initialize TinyUSB with default configuration (event handler can be set if needed) + tinyusb_config_t config = TINYUSB_DEFAULT_CONFIG(); + config.phy.skip_setup = true; + + tinyusb_driver_install(&config); + + This setup ensures that the USB Device stack uses the **external PHY** instead of attempting to configure the internal one. + Device Stack Structure ---------------------- @@ -145,7 +223,7 @@ To install the Device Stack, please call :cpp:func:`tinyusb_driver_install`. The const tinyusb_config_t partial_init = { .device_descriptor = NULL, // Use the default device descriptor specified in Menuconfig .string_descriptor = NULL, // Use the default string descriptors specified in Menuconfig - .external_phy = false, // Use internal USB PHY + .external_phy = false, // Use internal PHY #if (TUD_OPT_HIGH_SPEED) .fs_configuration_descriptor = NULL, // Use the default full-speed configuration descriptor according to settings in Menuconfig .hs_configuration_descriptor = NULL, // Use the default high-speed configuration descriptor according to settings in Menuconfig diff --git a/docs/en/api-reference/peripherals/usb_host.rst b/docs/en/api-reference/peripherals/usb_host.rst index a389cb604d..8a207a3f4d 100644 --- a/docs/en/api-reference/peripherals/usb_host.rst +++ b/docs/en/api-reference/peripherals/usb_host.rst @@ -407,6 +407,77 @@ UVC .. ---------------------------------------------- USB Host Menuconfig -------------------------------------------------- +.. only:: esp32s3 + + External PHY Configuration + -------------------------- + + The {IDF_TARGET_NAME} contains two USB controllers - the USB-OTG and USB-Serial-JTAG. However, both controllers share a **single PHY**, which means only one can operate at a time. To use USB Host functionality while the USB-Serial-JTAG is active (e.g., for debugging or flashing), an **external PHY** is required, since the PHY is used by USB-Serial-JTAG. + + .. note:: + An external PHY is not the only way to enable debugging alongside USB Host or Device functionality. It is also possible to switch the debugging interface from USB-Serial-JTAG to plain JTAG by burning the appropriate eFuses. For details, refer to the *JTAG Debugging* section in the ESP-IDF Programming Guide for your target. + + {IDF_TARGET_NAME} supports connecting external PHY ICs. This allows independent operation of both USB-OTG and USB-Serial-JTAG controllers. Various external PHY ICs may require different hardware configurations. Please refer to the respective IC datasheets for details. A general connection diagram is available in the official ESP documentation: + + `ESP PHY Guide (External PHY Section) `__ + + **List of Tested External PHY ICs:** + + - **SP5301** — Directly supported by {IDF_TARGET_NAME}. See the guide above for schematic and routing details. + - **STUSB03E** — Requires signal routing using an analog switch. See example below. + + .. figure:: ../../../_static/usb_host/ext_phy_schematic_stusb03e.png + :align: center + :alt: External PHY with Analog Switch Schematic (Host mode) + + Example connection using STUSB03E and analog switch (Host mode) + + .. note:: + This schematic is a minimal example intended only to demonstrate the external PHY connection. It omits other essential components and signals (e.g., VCC, GND, RESET) required for a complete, functional {IDF_TARGET_NAME} design. + The schematic includes both a +5 V rail (used to power USB devices) and a VCC rail (typically 3.3 V). VCC should match the chip supply voltage. Ensure that +5 V for the USB bus is appropriately sourced and protected (e.g., with a power switch and current limiting). Always comply with USB host power requirements, particularly when supporting USB bus-powered devices. + + Hardware configuration is handled via GPIO mapping to the PHY's pins. Any unused pins (e.g., :cpp:member:`usb_phy_ext_io_conf_t::suspend_n_io_num`) **must be set to -1**. + + .. note:: + The :cpp:member:`usb_phy_ext_io_conf_t::suspend_n_io_num` pin is **currently not supported** and does not need to be connected. + + **Example Code:** + + .. code-block:: c + + // GPIO configuration for external PHY + const usb_phy_ext_io_conf_t ext_io_conf = { + .vp_io_num = 8, + .vm_io_num = 5, + .rcv_io_num = 11, + .oen_io_num = 17, + .vpo_io_num = 4, + .vmo_io_num = 46, + .fs_edge_sel_io_num = 38, + .suspend_n_io_num = -1, + }; + + // Configuration and initialization of external PHY for OTG controller (Host mode) + const usb_phy_config_t phy_config = { + .controller = USB_PHY_CTRL_OTG, + .target = USB_PHY_TARGET_EXT, + .otg_mode = USB_OTG_MODE_HOST, + .otg_speed = USB_PHY_SPEED_FULL, + .ext_io_conf = &ext_io_conf + }; + + usb_phy_handle_t phy_hdl; + ESP_ERROR_CHECK(usb_new_phy(&phy_config, &phy_hdl)); + + // Configure USB Host to use the externally initialized PHY + usb_host_config_t host_config = { + .skip_phy_setup = true, + // Add other host configuration fields as needed + }; + ESP_ERROR_CHECK(usb_host_install(&host_config)); + + This setup ensures that the USB Host stack uses the **external PHY** and bypasses PHY setup. + Host Stack Configuration ------------------------