diff --git a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c index eb38a267e6..a730a636c0 100644 --- a/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c +++ b/components/esp_driver_usb_serial_jtag/src/usb_serial_jtag_connection_monitor.c @@ -52,7 +52,7 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void) #if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION esp_pm_lock_release(s_usb_serial_jtag_pm_lock); #endif -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL +#if USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL rtc_clk_bbpll_remove_consumer(); #endif s_usb_serial_jtag_conn_status = false; @@ -62,7 +62,7 @@ static void IRAM_ATTR usb_serial_jtag_sof_tick_hook(void) #if CONFIG_USJ_NO_AUTO_LS_ON_CONNECTION esp_pm_lock_acquire(s_usb_serial_jtag_pm_lock); #endif -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL +#if USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL rtc_clk_bbpll_add_consumer(); #endif s_usb_serial_jtag_conn_status = true; @@ -79,8 +79,8 @@ ESP_SYSTEM_INIT_FN(usb_serial_jtag_conn_status_init, SECONDARY, BIT(0), 230) // We always assume it is connected at first, so acquires the lock to avoid auto light sleep esp_pm_lock_acquire(s_usb_serial_jtag_pm_lock); #endif -#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7496 SOC_USB_SERIAL_JTAG_PHY_ON_BBPLL -// TODO: esp32p4 USJ rely on SPLL, if it will also be disabled during sleep, we need to call spll_add_consumer? +#if USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL +// TODO: esp32p4 USJ rely on SPLL, if it will also be disabled during sleep, we need to call spll_add_consumer? IDF-9947 rtc_clk_bbpll_add_consumer(); #endif s_usb_serial_jtag_conn_status = true; diff --git a/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml b/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml index 5605004cfc..18ab2db959 100644 --- a/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml +++ b/components/esp_driver_usb_serial_jtag/test_apps/.build-test-rules.yml @@ -3,6 +3,10 @@ components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag: disable: - if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET in ["esp32p4"] + temporary: true + reason: No runners. depends_components: - vfs - esp_driver_gpio diff --git a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md index f1988f4a40..ad95e41133 100644 --- a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md +++ b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py b/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py index 730a390a47..06432a8158 100644 --- a/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py +++ b/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py @@ -20,7 +20,6 @@ JTAG_SERIAL_MARKS = [ pytest.mark.esp32c3, pytest.mark.esp32c6, pytest.mark.esp32h2, - pytest.mark.esp32p4, ] diff --git a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h index 1183029621..f57b378e7f 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -16,6 +16,7 @@ /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h index 56b44d0a1a..d9aa7e58fa 100644 --- a/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c6/include/hal/usb_serial_jtag_ll.h @@ -16,6 +16,7 @@ /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h index bacbf3d3fb..289f0adf18 100644 --- a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h @@ -16,6 +16,7 @@ /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h index 029e363526..f6b13b9a79 100644 --- a/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32p4/include/hal/usb_serial_jtag_ll.h @@ -14,17 +14,188 @@ #include "soc/usb_serial_jtag_struct.h" #include "hal/usb_serial_jtag_types.h" -// This header is temporarily disabled until USJ is supported on the P4 (IDF-7496) #if SOC_USB_SERIAL_JTAG_SUPPORTED /* ----------------------------- Macros & Types ----------------------------- */ #define USB_SERIAL_JTAG_LL_SELECT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask + +// Define USB_SERIAL_JTAG interrupts +// Note the hardware has more interrupts, but they're only useful for debugging +// the hardware. +typedef enum { + USB_SERIAL_JTAG_INTR_SOF = (1 << 1), + USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT = (1 << 2), + USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY = (1 << 3), + USB_SERIAL_JTAG_INTR_TOKEN_REC_IN_EP1 = (1 << 8), + USB_SERIAL_JTAG_INTR_BUS_RESET = (1 << 9), + USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), +} usb_serial_jtag_ll_intr_t; + #ifdef __cplusplus extern "C" { #endif +/* ----------------------------- USJ Peripheral ----------------------------- */ + +/** + * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts need to be enabled. + * + * @return None + */ +static inline void usb_serial_jtag_ll_ena_intr_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_ena.val |= mask; +} + +/** + * @brief Disable the USB_SERIAL_JTAG interrupt based on the given mask. + * + * @param mask The bitmap of the interrupts need to be disabled. + * + * @return None + */ +static inline void usb_serial_jtag_ll_disable_intr_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_ena.val &= (~mask); +} + +/** + * @brief Get the USB_SERIAL_JTAG interrupt status. + * + * @return The USB_SERIAL_JTAG interrupt status. + */ +static inline uint32_t usb_serial_jtag_ll_get_intsts_mask(void) +{ + return USB_SERIAL_JTAG.int_st.val; +} + +/** + * @brief Get the USB_SERIAL_JTAG raw interrupt status. + * + * @return The USB_SERIAL_JTAG raw interrupt status. + */ +static inline __attribute__((always_inline)) uint32_t usb_serial_jtag_ll_get_intraw_mask(void) +{ + return USB_SERIAL_JTAG.int_raw.val; +} + +/** + * @brief Clear the USB_SERIAL_JTAG interrupt status based on the given mask. + * + * @param mask The bitmap of the interrupts need to be cleared. + * + * @return None + */ +static inline __attribute__((always_inline)) void usb_serial_jtag_ll_clr_intsts_mask(uint32_t mask) +{ + USB_SERIAL_JTAG.int_clr.val = mask; +} + +/** + * @brief Get status of enabled interrupt. + * + * @return interrupt enable value + */ +static inline uint32_t usb_serial_jtag_ll_get_intr_ena_status(void) +{ + return USB_SERIAL_JTAG.int_ena.val; +} + +/** + * @brief Read the bytes from the USB_SERIAL_JTAG rxfifo. + * + * @param buf The data buffer. + * @param rd_len The data length needs to be read. + * + * @return amount of bytes read + */ +static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) +{ + int i; + for (i = 0; i < (int)rd_len; i++) { + if (!USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail) break; + buf[i] = USB_SERIAL_JTAG.ep1.rdwr_byte; + } + return i; +} + +/** + * @brief Write byte to the USB_SERIAL_JTAG txfifo. Only writes bytes as long / if there + * is room in the buffer. + * + * @param buf The data buffer. + * @param wr_len The data length needs to be written. + * + * @return Amount of bytes actually written. May be less than wr_len. + */ +static inline int usb_serial_jtag_ll_write_txfifo(const uint8_t *buf, uint32_t wr_len) +{ + int i; + for (i = 0; i < (int)wr_len; i++) { + if (!USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free) break; + USB_SERIAL_JTAG.ep1.rdwr_byte = buf[i]; + } + return i; +} + +/** + * @brief Returns 1 if the USB_SERIAL_JTAG rxfifo has data available. + * + * @return 0 if no data available, 1 if data available + */ +static inline int usb_serial_jtag_ll_rxfifo_data_available(void) +{ + return USB_SERIAL_JTAG.ep1_conf.serial_out_ep_data_avail; +} + +/** + * @brief Returns 1 if the USB_SERIAL_JTAG txfifo has room. + * + * @return 0 if no data available, 1 if data available + */ +static inline int usb_serial_jtag_ll_txfifo_writable(void) +{ + return USB_SERIAL_JTAG.ep1_conf.serial_in_ep_data_free; +} + +/** + * @brief Flushes the TX buffer, that is, make it available for the + * host to pick up. + * + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically, + * if this function is called directly after, this effectively turns into a + * no-op. Because a 64-byte packet will be interpreted as a not-complete USB + * transaction, you need to transfer either more data or a zero-length packet + * for the data to actually end up at the program listening to the CDC-ACM + * serial port. To send a zero-length packet, call + * usb_serial_jtag_ll_txfifo_flush() again when + * usb_serial_jtag_ll_txfifo_writable() returns true. + * + * @return na + */ +static inline void usb_serial_jtag_ll_txfifo_flush(void) +{ + USB_SERIAL_JTAG.ep1_conf.wr_done=1; +} + +/** + * @brief Enable USJ JTAG bridge + * + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} + /* ---------------------------- USB PHY Control ---------------------------- */ /** diff --git a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h index a3b8c90733..8a1addeb11 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -18,6 +18,7 @@ #define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask #define USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY +#define USB_SERIAL_JTAG_LL_PHY_DEPENDS_ON_BBPLL (1) // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 268919ce91..7fc01d249a 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -83,6 +83,10 @@ config SOC_WIRELESS_HOST_SUPPORTED bool default y +config SOC_USB_SERIAL_JTAG_SUPPORTED + bool + default y + config SOC_TEMP_SENSOR_SUPPORTED bool default y diff --git a/components/soc/esp32p4/include/soc/interrupts.h b/components/soc/esp32p4/include/soc/interrupts.h index 76d65315f2..78bde5055e 100644 --- a/components/soc/esp32p4/include/soc/interrupts.h +++ b/components/soc/esp32p4/include/soc/interrupts.h @@ -38,7 +38,7 @@ typedef enum { ETS_LP_SYSREG_INTR_SOURCE, ETS_LP_HUK_INTR_SOURCE, ETS_SYS_ICM_INTR_SOURCE, - ETS_USB_DEVICE_INTR_SOURCE, + ETS_USB_SERIAL_JTAG_INTR_SOURCE, ETS_SDIO_HOST_INTR_SOURCE, ETS_DW_GDMA_INTR_SOURCE, ETS_SPI2_INTR_SOURCE, diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index d87955757e..9c54eaaec5 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -39,8 +39,7 @@ #define SOC_EMAC_SUPPORTED 1 #define SOC_USB_OTG_SUPPORTED 1 #define SOC_WIRELESS_HOST_SUPPORTED 1 -// disable usb serial jtag for esp32p4, current image does not support -// #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 //TODO: IDF-7496 +#define SOC_USB_SERIAL_JTAG_SUPPORTED 1 #define SOC_TEMP_SENSOR_SUPPORTED 1 #define SOC_SUPPORTS_SECURE_DL_MODE 1 #define SOC_ULP_SUPPORTED 1 diff --git a/components/soc/esp32p4/interrupts.c b/components/soc/esp32p4/interrupts.c index 8ade2b23ec..818367e955 100644 --- a/components/soc/esp32p4/interrupts.c +++ b/components/soc/esp32p4/interrupts.c @@ -29,7 +29,7 @@ const char *const esp_isr_names[] = { [ETS_LP_SYSREG_INTR_SOURCE] = "LP_SYSREG", [ETS_LP_HUK_INTR_SOURCE] = "LP_HUK", [ETS_SYS_ICM_INTR_SOURCE] = "SYS_ICM", - [ETS_USB_DEVICE_INTR_SOURCE] = "USB_DEVICE", + [ETS_USB_SERIAL_JTAG_INTR_SOURCE] = "USB_SERIAL_JTAG", [ETS_SDIO_HOST_INTR_SOURCE] = "SDIO_HOST", [ETS_DW_GDMA_INTR_SOURCE] = "DW_GDMA", [ETS_SPI2_INTR_SOURCE] = "SPI2", diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index a78e2aa313..733b44b998 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -7,7 +7,6 @@ api-guides/RF_calibration.rst api-guides/deep-sleep-stub.rst api-guides/coexist.rst api-guides/flash_psram_config.rst -api-guides/usb-serial-jtag-console.rst api-guides/wifi.rst api-guides/usb-otg-console.rst api-guides/esp-wifi-mesh.rst diff --git a/docs/en/api-guides/usb-serial-jtag-console.rst b/docs/en/api-guides/usb-serial-jtag-console.rst index 23d57436a3..4bde079df7 100644 --- a/docs/en/api-guides/usb-serial-jtag-console.rst +++ b/docs/en/api-guides/usb-serial-jtag-console.rst @@ -19,8 +19,8 @@ Generally, ESP chips implement a serial port using UART and can be connected to Hardware Requirements ===================== -{IDF_TARGET_USB_DP_GPIO:default="Not Updated!",esp32c3="19",esp32s3="20", esp32c6="13", esp32h2="27"} -{IDF_TARGET_USB_DM_GPIO:default="Not Updated!",esp32c3="18",esp32s3="19", esp32c6="12", esp32h2="26"} +{IDF_TARGET_USB_DP_GPIO:default="Not Updated!",esp32c3="19",esp32s3="20", esp32c6="13", esp32h2="27", esp32p4="25/27"} +{IDF_TARGET_USB_DM_GPIO:default="Not Updated!",esp32c3="18",esp32s3="19", esp32c6="12", esp32h2="26", esp32p4="24/26"} Connect {IDF_TARGET_NAME} to the USB port as follows: diff --git a/docs/en/get-started/establish-serial-connection.rst b/docs/en/get-started/establish-serial-connection.rst index 78a3bc576a..98cbf6f4d7 100644 --- a/docs/en/get-started/establish-serial-connection.rst +++ b/docs/en/get-started/establish-serial-connection.rst @@ -146,15 +146,15 @@ Sometimes the USB-to-UART bridge is external. This is often used in small develo The USB on the {IDF_TARGET_NAME} uses the **{IDF_TARGET_USB_PIN_DP}** for **D+** and **{IDF_TARGET_USB_PIN_DM}** for **D-**. - .. only:: SOC_USB_SERIAL_JTAG_SUPPORTED and not esp32s3 and not esp32p4 + .. only:: SOC_USB_SERIAL_JTAG_SUPPORTED - .. note:: The {IDF_TARGET_NAME} supports only *USB CDC and JTAG*. + .. only:: not SOC_USB_OTG_SUPPORTED + + .. note:: The {IDF_TARGET_NAME} supports only *USB CDC and JTAG*. If you are flashing for the first time, you need to get the {IDF_TARGET_NAME} into the download mode manually. To do so, press and hold the ``BOOT`` button and then press the ``RESET`` button once. After that release the ``BOOT`` button. - .. only:: esp32s3 - - If you are flashing for the first time, you need to get the {IDF_TARGET_NAME} into the download mode manually. To do so, press and hold the ``BOOT`` button and then press the ``RESET`` button once. After that release the ``BOOT`` button. + For any usage for usb serial jtag, please refer to :doc:`USB_SERIAL_JTAG_CONSOLE <../api-guides/usb-serial-jtag-console>` for more information. .. only:: esp32s2 diff --git a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md index 1b053da468..ce33f425ea 100644 --- a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md +++ b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | # USB SERIAL JTAG Echo Example