diff --git a/components/openthread/CMakeLists.txt b/components/openthread/CMakeLists.txt index 49f91d3be7..dc3938e76f 100644 --- a/components/openthread/CMakeLists.txt +++ b/components/openthread/CMakeLists.txt @@ -171,7 +171,7 @@ if(CONFIG_OPENTHREAD_ENABLED) if(CONFIG_OPENTHREAD_NCP_VENDOR_HOOK) list(APPEND src_dirs "src/ncp") - if(CONFIG_OPENTHREAD_RCP_UART) + if(CONFIG_OPENTHREAD_RCP_UART OR CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) list(APPEND exclude_srcs "src/ncp/esp_openthread_ncp_spi.cpp") elseif(CONFIG_OPENTHREAD_RCP_SPI) diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index e87e108048..6b82fe4bf8 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -189,6 +189,12 @@ menu "OpenThread" select GPIO_CTRL_FUNC_IN_IRAM help Select this to enable SPI connection to host. + + config OPENTHREAD_RCP_USB_SERIAL_JTAG + depends on ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG && !OPENTHREAD_CONSOLE_TYPE_USB_SERIAL_JTAG + bool "USB RCP" + help + Select this to enable connection to host over USB JTAG serial. endchoice config OPENTHREAD_NCP_VENDOR_HOOK diff --git a/components/openthread/include/esp_openthread_types.h b/components/openthread/include/esp_openthread_types.h index 364d596100..c5f4f4cba6 100644 --- a/components/openthread/include/esp_openthread_types.h +++ b/components/openthread/include/esp_openthread_types.h @@ -150,6 +150,7 @@ typedef enum { HOST_CONNECTION_MODE_CLI_USB, /*!< CLI USB connection to the host */ HOST_CONNECTION_MODE_RCP_UART, /*!< RCP UART connection to the host */ HOST_CONNECTION_MODE_RCP_SPI, /*!< RCP SPI connection to the host */ + HOST_CONNECTION_MODE_RCP_USB, /*!< RCP USB Serial JTAG connection to the host */ HOST_CONNECTION_MODE_MAX, /*!< Using for parameter check */ } esp_openthread_host_connection_mode_t; diff --git a/components/openthread/private_include/esp_openthread_uart.h b/components/openthread/private_include/esp_openthread_uart.h index 50b5f44706..8a01690646 100644 --- a/components/openthread/private_include/esp_openthread_uart.h +++ b/components/openthread/private_include/esp_openthread_uart.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,6 +64,18 @@ esp_err_t esp_openthread_host_cli_usb_init(const esp_openthread_platform_config_ */ esp_err_t esp_openthread_host_rcp_uart_init(const esp_openthread_platform_config_t *config); +/** + * @brief Initializes the RCP USB for OpenThread host connection. + * + * @param[in] config The platform configuration. + * + * @return + * - ESP_OK on success + * - ESP_ERROR on failure + * + */ +esp_err_t esp_openthread_host_rcp_usb_init(const esp_openthread_platform_config_t *config); + /** * @brief Deintializes the uart for OpenThread host connection. * diff --git a/components/openthread/private_include/openthread-core-esp32x-radio-config.h b/components/openthread/private_include/openthread-core-esp32x-radio-config.h index 009635bac7..8be7e0de72 100644 --- a/components/openthread/private_include/openthread-core-esp32x-radio-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-radio-config.h @@ -91,7 +91,7 @@ #ifdef OPENTHREAD_CONFIG_NCP_HDLC_ENABLE #error `OPENTHREAD_CONFIG_NCP_HDLC_ENABLE` is redefined. #endif -#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE CONFIG_OPENTHREAD_RCP_UART +#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE (CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) /** * @def OPENTHREAD_LIB_SPINEL_RX_FRAME_BUFFER_SIZE diff --git a/components/openthread/src/esp_openthread_platform.cpp b/components/openthread/src/esp_openthread_platform.cpp index 51bfd77904..f16891d69c 100644 --- a/components/openthread/src/esp_openthread_platform.cpp +++ b/components/openthread/src/esp_openthread_platform.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -106,6 +106,12 @@ static esp_err_t esp_openthread_host_interface_init(const esp_openthread_platfor "esp_openthread_host_rcp_uart_init failed"); break; #endif +#if CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG + case HOST_CONNECTION_MODE_RCP_USB: + ESP_RETURN_ON_ERROR(esp_openthread_host_rcp_usb_init(config), OT_PLAT_LOG_TAG, + "esp_openthread_host_rcp_usb_init failed"); + break; +#endif #if CONFIG_OPENTHREAD_CONSOLE_TYPE_UART case HOST_CONNECTION_MODE_CLI_UART: ESP_RETURN_ON_ERROR(esp_openthread_host_cli_uart_init(config), OT_PLAT_LOG_TAG, diff --git a/components/openthread/src/ncp/esp_openthread_ncp.cpp b/components/openthread/src/ncp/esp_openthread_ncp.cpp index c9ddd03e3e..94c31113de 100644 --- a/components/openthread/src/ncp/esp_openthread_ncp.cpp +++ b/components/openthread/src/ncp/esp_openthread_ncp.cpp @@ -13,11 +13,11 @@ #include "esp_coex_i154.h" #endif -#if CONFIG_OPENTHREAD_RCP_UART +#if (CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) #include "utils/uart.h" #endif -#if CONFIG_OPENTHREAD_RCP_UART +#if (CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG) extern "C" { static int NcpSend(const uint8_t *aBuf, uint16_t aBufLength) { diff --git a/components/openthread/src/port/esp_openthread_uart.c b/components/openthread/src/port/esp_openthread_uart.c index 4d2f031359..6893d0400e 100644 --- a/components/openthread/src/port/esp_openthread_uart.c +++ b/components/openthread/src/port/esp_openthread_uart.c @@ -31,7 +31,7 @@ static int s_uart_fd; static uint8_t s_uart_buffer[ESP_OPENTHREAD_UART_BUFFER_SIZE]; static const char *uart_workflow = "uart"; -#if (CONFIG_OPENTHREAD_CLI || (CONFIG_OPENTHREAD_RADIO && CONFIG_OPENTHREAD_RCP_UART)) +#if (CONFIG_OPENTHREAD_CLI || (CONFIG_OPENTHREAD_RADIO && (CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG))) otError otPlatUartEnable(void) { return OT_ERROR_NONE; @@ -116,6 +116,7 @@ esp_err_t esp_openthread_host_cli_uart_init(const esp_openthread_platform_config } #endif +#if CONFIG_OPENTHREAD_RCP_UART esp_err_t esp_openthread_host_rcp_uart_init(const esp_openthread_platform_config_t *config) { esp_err_t ret = ESP_OK; @@ -135,6 +136,28 @@ esp_err_t esp_openthread_host_rcp_uart_init(const esp_openthread_platform_config return ret; } +#endif + +#if CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG +esp_err_t esp_openthread_host_rcp_usb_init(const esp_openthread_platform_config_t *config) +{ + esp_err_t ret = ESP_OK; + + usb_serial_jtag_vfs_set_rx_line_endings(ESP_LINE_ENDINGS_LF); + usb_serial_jtag_vfs_set_tx_line_endings(ESP_LINE_ENDINGS_LF); + + ESP_ERROR_CHECK(usb_serial_jtag_driver_install((usb_serial_jtag_driver_config_t *)&config->host_config.host_usb_config)); + ESP_ERROR_CHECK(usb_serial_jtag_vfs_register()); + usb_serial_jtag_vfs_use_driver(); + + s_uart_fd = open("/dev/usbserjtag", O_RDWR | O_NONBLOCK); + ESP_RETURN_ON_FALSE(s_uart_fd >= 0, ESP_FAIL, OT_PLAT_LOG_TAG, "open usbserjtag failed"); + ret = esp_openthread_platform_workflow_register(&esp_openthread_uart_update, &esp_openthread_uart_process, + uart_workflow); + + return ret; +} +#endif void esp_openthread_uart_deinit() { @@ -159,7 +182,7 @@ esp_err_t esp_openthread_uart_process(otInstance *instance, const esp_openthread int rval = read(s_uart_fd, s_uart_buffer, sizeof(s_uart_buffer)); if (rval > 0) { -#if (CONFIG_OPENTHREAD_CLI || (CONFIG_OPENTHREAD_RADIO && CONFIG_OPENTHREAD_RCP_UART)) +#if (CONFIG_OPENTHREAD_CLI || (CONFIG_OPENTHREAD_RADIO && (CONFIG_OPENTHREAD_RCP_UART || CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG))) otPlatUartReceived(s_uart_buffer, (uint16_t)rval); #endif } else if (rval < 0) { diff --git a/examples/openthread/ot_rcp/main/esp_ot_config.h b/examples/openthread/ot_rcp/main/esp_ot_config.h index 71c74dfcb3..d7a1150329 100644 --- a/examples/openthread/ot_rcp/main/esp_ot_config.h +++ b/examples/openthread/ot_rcp/main/esp_ot_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 * @@ -52,7 +52,7 @@ .tx_pin = OPENTHREAD_RCP_UART_TX_PIN, \ }, \ } -#else // CONFIG_OPENTHREAD_RCP_SPI +#elif CONFIG_OPENTHREAD_RCP_SPI // CONFIG_OPENTHREAD_RCP_SPI #define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ { \ .host_connection_mode = HOST_CONNECTION_MODE_RCP_SPI, \ @@ -75,6 +75,12 @@ .intr_pin = 9, \ }, \ } +#else // CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_RCP_USB, \ + .host_usb_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(), \ + } #endif #define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ diff --git a/examples/openthread/ot_rcp/sdkconfig.ci.rcp_usb b/examples/openthread/ot_rcp/sdkconfig.ci.rcp_usb new file mode 100644 index 0000000000..7735b15871 --- /dev/null +++ b/examples/openthread/ot_rcp/sdkconfig.ci.rcp_usb @@ -0,0 +1 @@ +CONFIG_OPENTHREAD_RCP_USB_SERIAL_JTAG=y