From 87b0c4c40d5e398a4073e4441241f19b6dd22649 Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Thu, 28 May 2026 11:34:36 +0800 Subject: [PATCH 1/8] feat(sleep/usb): support usb as wakeup source from light sleep --- components/esp_hw_support/include/esp_sleep.h | 17 +++++++++++++ components/esp_hw_support/sleep_modes.c | 25 +++++++++++++++++++ .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32p4/include/soc/soc_caps.h | 1 + .../esp32s31/include/soc/Kconfig.soc_caps.in | 4 +++ .../soc/esp32s31/include/soc/soc_caps.h | 1 + 6 files changed, 52 insertions(+) diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 8d0941435d7..7145e5b1906 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -137,6 +137,7 @@ typedef enum { ESP_SLEEP_WAKEUP_BT, //!< Wakeup caused by BT (light sleep only) ESP_SLEEP_WAKEUP_VAD, //!< Wakeup caused by VAD ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT, //!< Wakeup caused by VDD_BAT under voltage. + ESP_SLEEP_WAKEUP_USB, //!< Wakeup caused by USB (light sleep only) } esp_sleep_source_t; /** @@ -565,6 +566,22 @@ esp_err_t esp_sleep_enable_bt_wakeup(void); */ esp_err_t esp_sleep_disable_bt_wakeup(void); +/** + * @brief Enable wakeup by USB + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_SUPPORTED if wakeup from USB is not supported + */ +esp_err_t esp_sleep_enable_usb_wakeup(void); + +/** + * @brief Disable wakeup by USB + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_SUPPORTED if wakeup from USB is not supported + */ +esp_err_t esp_sleep_disable_usb_wakeup(void); + /** * @brief Enable wakeup by WiFi MAC * @return diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index ae71740a8af..d13f76abe0b 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2456,6 +2456,26 @@ esp_err_t esp_sleep_disable_bt_wakeup(void) #endif } +esp_err_t esp_sleep_enable_usb_wakeup(void) +{ +#if SOC_PM_SUPPORT_USB_WAKEUP + s_config.wakeup_triggers |= RTC_USB_TRIG_EN; + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} + +esp_err_t esp_sleep_disable_usb_wakeup(void) +{ +#if SOC_PM_SUPPORT_USB_WAKEUP + s_config.wakeup_triggers &= (~RTC_USB_TRIG_EN); + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} + esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) { if (esp_rom_get_reset_reason(0) != RESET_REASON_CORE_DEEP_SLEEP && !s_light_sleep_wakeup) { @@ -2640,6 +2660,11 @@ uint32_t esp_sleep_get_wakeup_causes(void) if (wakeup_cause_raw & RTC_VBAT_UNDER_VOLT_TRIG_EN) { wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT); } +#endif +#if SOC_PM_SUPPORT_USB_WAKEUP + if (wakeup_cause_raw & RTC_USB_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_USB); + } #endif if (wakeup_cause == 0) { wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_UNDEFINED); diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index a49d6378765..f3e84e9d262 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1163,6 +1163,10 @@ config SOC_USB_UTMI_PHY_NUM int default 1 +config SOC_PM_SUPPORT_USB_WAKEUP + int + default 1 + config SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH int default 16 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 5eade623e78..2ca760497f5 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -429,6 +429,7 @@ // USB PHY Caps #define SOC_USB_UTMI_PHY_NUM (1U) +#define SOC_PM_SUPPORT_USB_WAKEUP (1U) /*-------------------------- PARLIO CAPS --------------------------------------*/ #define SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH 16 /*!< Number of data lines of the TX unit */ diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 4aed35e6376..631cc9f1d93 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -387,6 +387,10 @@ config SOC_USB_UTMI_PHY_NUM int default 1 +config SOC_PM_SUPPORT_USB_WAKEUP + int + default 1 + config SOC_PHY_SUPPORTED bool default y diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index eb9ae8eaa7f..346eaf61d94 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -128,6 +128,7 @@ #define SOC_USB_OTG_PERIPH_NUM (1U) #define SOC_USB_FSLS_PHY_NUM (0U) #define SOC_USB_UTMI_PHY_NUM (1U) +#define SOC_PM_SUPPORT_USB_WAKEUP (1U) #define SOC_PHY_SUPPORTED 1 #define SOC_WIFI_SUPPORTED 1 From c8dcd0d2aa75385134290ef841131d49aa11c48a Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Thu, 28 May 2026 11:37:13 +0800 Subject: [PATCH 2/8] feat(esp_hal_usb): add usb suspend wakeup status in ll layer --- .../esp32p4/include/hal/usb_utmi_ll.h | 18 ++++++++++++++++++ .../esp32s31/include/hal/usb_utmi_ll.h | 19 +++++++++++++++++++ .../esp_hal_usb/include/hal/usb_utmi_hal.h | 12 ++++++++++++ components/esp_hal_usb/usb_utmi_hal.c | 10 ++++++++++ 4 files changed, 59 insertions(+) diff --git a/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h b/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h index 1c2978f95b9..65e91cb9748 100644 --- a/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h +++ b/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h @@ -119,6 +119,24 @@ FORCE_INLINE_ATTR void usb_utmi_ll_enable_precise_detection(bool enable) HP_SYSTEM.sys_usbotg20_ctrl.sys_otg_suspendm = enable; } +/** + * @brief Set USB OTG2.0 suspend state for PMU USB wakeup logic + * + * @param[in] in_suspend True if USB OTG2.0 is suspended + */ +FORCE_INLINE_ATTR void usb_utmi_ll_set_suspend_state(bool in_suspend) +{ + LP_SYS.usb_ctrl.usbotg20_in_suspend = in_suspend; +} + +/** + * @brief Clear USB OTG2.0 wakeup status sent to PMU + */ +FORCE_INLINE_ATTR void usb_utmi_ll_clear_wakeup_status(void) +{ + LP_SYS.usb_ctrl.usbotg20_wakeup_clr = 1; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_usb/esp32s31/include/hal/usb_utmi_ll.h b/components/esp_hal_usb/esp32s31/include/hal/usb_utmi_ll.h index 3ad7538e0f4..e61801c2bf2 100644 --- a/components/esp_hal_usb/esp32s31/include/hal/usb_utmi_ll.h +++ b/components/esp_hal_usb/esp32s31/include/hal/usb_utmi_ll.h @@ -12,6 +12,7 @@ #include "soc/cnnt_sys_struct.h" #include "soc/hp_alive_sys_struct.h" #include "soc/hp_sys_clkrst_struct.h" +#include "soc/lp_system_struct.h" #include "soc/reg_base.h" #include "soc/usb_utmi_struct.h" @@ -146,6 +147,24 @@ FORCE_INLINE_ATTR void usb_utmi_ll_enable_precise_detection(bool enable) HP_ALIVE_SYS.usb_otghs_ctrl.reg_usb_otghs_phy_otg_suspendm = enable; } +/** + * @brief Set USB OTG2.0 suspend state for PMU USB wakeup logic + * + * @param[in] in_suspend True if USB OTG2.0 is suspended + */ +FORCE_INLINE_ATTR void usb_utmi_ll_set_suspend_state(bool in_suspend) +{ + LP_SYS.usb_ctrl.usbotghs_in_suspend = in_suspend; +} + +/** + * @brief Clear USB OTG2.0 wakeup status sent to PMU + */ +FORCE_INLINE_ATTR void usb_utmi_ll_clear_wakeup_status(void) +{ + LP_SYS.usb_ctrl.usbotghs_wakeup_clr = 1; +} + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_usb/include/hal/usb_utmi_hal.h b/components/esp_hal_usb/include/hal/usb_utmi_hal.h index ad7ba50f6c2..1466c57b516 100644 --- a/components/esp_hal_usb/include/hal/usb_utmi_hal.h +++ b/components/esp_hal_usb/include/hal/usb_utmi_hal.h @@ -67,6 +67,18 @@ void _usb_utmi_hal_disable(void); */ void usb_utmi_hal_enable_data_pulldowns(bool enable); +/** + * @brief Set USB OTG2.0 suspend state for PMU USB wakeup logic + * + * @param[in] in_suspend True if USB OTG2.0 is suspended + */ +void usb_utmi_hal_set_suspend_state(bool in_suspend); + +/** + * @brief Clear USB OTG2.0 wakeup status sent to PMU + */ +void usb_utmi_hal_clear_wakeup_status(void); + #endif // (SOC_USB_UTMI_PHY_NUM > 0) #ifdef __cplusplus diff --git a/components/esp_hal_usb/usb_utmi_hal.c b/components/esp_hal_usb/usb_utmi_hal.c index 137f493d99d..76ba413852c 100644 --- a/components/esp_hal_usb/usb_utmi_hal.c +++ b/components/esp_hal_usb/usb_utmi_hal.c @@ -28,6 +28,16 @@ void usb_utmi_hal_enable_data_pulldowns(bool enable) usb_utmi_ll_enable_data_pulldowns(enable); } +void usb_utmi_hal_set_suspend_state(bool in_suspend) +{ + usb_utmi_ll_set_suspend_state(in_suspend); +} + +void usb_utmi_hal_clear_wakeup_status(void) +{ + usb_utmi_ll_clear_wakeup_status(); +} + void _usb_utmi_hal_disable(void) { _usb_utmi_ll_enable_bus_clock(false); From 1c9c394197f2596ab428464621b8ff42c9e9d737 Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Thu, 28 May 2026 11:39:19 +0800 Subject: [PATCH 3/8] feat(usb): add usb wakeup from light sleep example --- examples/peripherals/.build-test-rules.yml | 4 + .../device/tud_cdc_acm_wakeup/CMakeLists.txt | 8 + .../usb/device/tud_cdc_acm_wakeup/README.md | 83 +++++++++ .../tud_cdc_acm_wakeup/main/CMakeLists.txt | 3 + .../tud_cdc_acm_wakeup/main/idf_component.yml | 4 + .../main/tud_cdc_acm_wakeup_main.c | 167 ++++++++++++++++++ .../tud_cdc_acm_wakeup/sdkconfig.defaults | 40 +++++ 7 files changed, 309 insertions(+) create mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt create mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md create mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt create mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/idf_component.yml create mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c create mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 1700a3324af..ab438750322 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -817,6 +817,10 @@ examples/peripherals/usb/device/cherryusb_serial_device: temporary: true reason: CherryUSB does not support esp32h4 or esp32s31 +examples/peripherals/usb/device/tud_cdc_acm_wakeup: + disable: + - if: IDF_TARGET not in ["esp32p4", "esp32s31"] + examples/peripherals/usb/device/tusb_ncm: disable: - if: SOC_USB_OTG_SUPPORTED != 1 or SOC_WIFI_SUPPORTED != 1 diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt new file mode 100644 index 00000000000..c16aac83db3 --- /dev/null +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.22) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +idf_build_set_property(MINIMAL_BUILD ON) +project(tud_cdc_acm_wakeup) diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md new file mode 100644 index 00000000000..8e021256d46 --- /dev/null +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md @@ -0,0 +1,83 @@ +| Supported Targets | ESP32-P4 | ESP32-S31 | +| ----------------- | -------- | --------- | + +# TinyUSB CDC ACM Wakeup Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example shows how to set up an ESP chip as a USB CDC ACM device that enters light sleep when the USB bus is suspended and wakes up from USB activity. + +As a USB stack, a TinyUSB component is used. + +## How to use example + +The example implements a USB CDC ACM echo device. When the host suspends the USB bus, the `tud_suspend_cb` callback configures the USB peripheral suspend state and enters light sleep. USB bus activity from the host wakes the chip and the CDC ACM echo device continues running. + +### Hardware Required + +Any ESP board that supports USB wakeup from light sleep. + +#### Pin Assignment + +_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below. + +See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments). + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +```bash +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +After the flashing you should see this output: + +``` +I (285) tud_cdc_acm_wakeup: USB initialization +I (455) TinyUSB: TinyUSB Driver installed +I (465) tud_cdc_acm_wakeup: USB initialization DONE +``` + +Connect to the serial port (e.g. on Linux, it should be `/dev/ttyACM0`) by any terminal application (e.g. `picocom /dev/ttyACM0`). +Now you can send data strings to the device, the device will echo back the same data string. + +When the USB host suspends and resumes the bus, the monitor output should include: + +``` +I (122142) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (122272) tud_cdc_acm_wakeup: Data from channel 0: +I (122272) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (122402) tud_cdc_acm_wakeup: Data from channel 0: +I (122402) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (122622) tud_cdc_acm_wakeup: Data from channel 0: +I (122622) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (127432) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (132402) tud_cdc_acm_wakeup: USB suspended, entering light sleep +I (132422) tud_cdc_acm_wakeup: Woke up from: USB +I (132422) tud_cdc_acm_wakeup: USB resumed +I (145762) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145812) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145812) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145822) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145822) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145832) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (148762) tud_cdc_acm_wakeup: Data from channel 0: +I (148762) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (148902) tud_cdc_acm_wakeup: Data from channel 0: +I (148902) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (149032) tud_cdc_acm_wakeup: Data from channel 0: +I (149032) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (149252) tud_cdc_acm_wakeup: Data from channel 0: +I (149252) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (151382) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (155312) tud_cdc_acm_wakeup: USB suspended, entering light sleep +``` diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt new file mode 100644 index 00000000000..10b20b81a8c --- /dev/null +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "tud_cdc_acm_wakeup_main.c" + INCLUDE_DIRS . + PRIV_REQUIRES esp_hal_usb) diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/idf_component.yml b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/idf_component.yml new file mode 100644 index 00000000000..e1a93a262ee --- /dev/null +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/idf_component.yml @@ -0,0 +1,4 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_tinyusb: + version: "^2.0.1~1" diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c new file mode 100644 index 00000000000..59c8496d07a --- /dev/null +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c @@ -0,0 +1,167 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "esp_log.h" +#include "esp_rom_serial_output.h" +#include "esp_sleep.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "hal/usb_utmi_hal.h" +#include "sdkconfig.h" +#include "soc/soc_caps.h" +#include "tinyusb.h" +#include "tinyusb_cdc_acm.h" +#include "tinyusb_default_config.h" + +#if !SOC_PM_SUPPORT_USB_WAKEUP || !SOC_PM_SUPPORT_CNNT_PD +#error This example requires a target with SOC_PM_SUPPORT_USB_WAKEUP. +#endif + +static const char *TAG = "tud_cdc_acm_wakeup"; +static uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; + +/** + * @brief Application Queue + */ +static QueueHandle_t app_queue; +typedef struct { + uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; // Data buffer + size_t buf_len; // Number of bytes received + uint8_t itf; // Index of CDC device interface +} app_message_t; + +/** + * @brief CDC device RX callback + * + * CDC device signals, that new data were received + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ +void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + (void) event; + + size_t rx_size = 0; + + esp_err_t ret = tinyusb_cdcacm_read(itf, rx_buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + app_message_t tx_msg = { + .buf_len = rx_size, + .itf = itf, + }; + + memcpy(tx_msg.buf, rx_buf, rx_size); + xQueueSend(app_queue, &tx_msg, 0); + } else { + ESP_LOGE(TAG, "Read Error"); + } +} + +/** + * @brief CDC device line change callback + * + * CDC device signals, that the DTR, RTS states changed + * + * @param[in] itf CDC device index + * @param[in] event CDC event type + */ +void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event) +{ + int dtr = event->line_state_changed_data.dtr; + int rts = event->line_state_changed_data.rts; + ESP_LOGI(TAG, "Line state changed on channel %d: DTR:%d, RTS:%d", itf, dtr, rts); +} + +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + + ESP_LOGI(TAG, "USB suspended, entering light sleep"); + usb_utmi_hal_set_suspend_state(true); + + esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); + + esp_err_t err = esp_light_sleep_start(); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Light sleep rejected: %s", esp_err_to_name(err)); + } else { + uint32_t causes = esp_sleep_get_wakeup_causes(); + if (causes & BIT(ESP_SLEEP_WAKEUP_UNDEFINED)) { + ESP_LOGI(TAG, "Woke up from: unknown"); + printf("%lx\n", causes); + return; + } + if (causes & BIT(ESP_SLEEP_WAKEUP_USB)) { + ESP_LOGI(TAG, "Woke up from: USB"); + } + } + usb_utmi_hal_set_suspend_state(false); + usb_utmi_hal_clear_wakeup_status(); +} + +void tud_resume_cb(void) +{ + ESP_LOGI(TAG, "USB resumed"); +} + +void tud_reset_cb(void) +{ + ESP_LOGI(TAG, "USB reset"); +} + +void app_main(void) +{ + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); + app_message_t msg; + + ESP_ERROR_CHECK(esp_sleep_cpu_retention_init()); + ESP_ERROR_CHECK(esp_sleep_enable_usb_wakeup()); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_CNNT, ESP_PD_OPTION_ON)); + + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = TINYUSB_DEFAULT_CONFIG(); + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .cdc_port = TINYUSB_CDC_ACM_0, + .callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tinyusb_cdcacm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &tinyusb_cdc_line_state_changed_callback)); + + ESP_LOGI(TAG, "USB initialization DONE"); + while (1) { + if (xQueueReceive(app_queue, &msg, portMAX_DELAY)) { + if (msg.buf_len) { + /* Print received data */ + ESP_LOGI(TAG, "Data from channel %d:", msg.itf); + ESP_LOG_BUFFER_HEXDUMP(TAG, msg.buf, msg.buf_len, ESP_LOG_INFO); + + /* Write back */ + tinyusb_cdcacm_write_queue(msg.itf, msg.buf, msg.buf_len); + esp_err_t err = tinyusb_cdcacm_write_flush(msg.itf, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "CDC ACM write flush error: %s", esp_err_to_name(err)); + } + } + } + } +} diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults new file mode 100644 index 00000000000..d541888bd98 --- /dev/null +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults @@ -0,0 +1,40 @@ +# This file was generated using idf.py save-defconfig or menuconfig [D] key. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 6.2.0 Project Minimal Configuration +# +# default: +CONFIG_IDF_TARGET="esp32p4" + +# +# Component config +# + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32P4_REV_MIN_300=y +# end of Chip revision +# end of Hardware Settings + +# +# Power Management +# +CONFIG_PM_ENABLE=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y +# end of Power Management + +# +# TinyUSB Stack +# +CONFIG_TINYUSB_DEBUG_LEVEL=1 + +# +# Communication Device Class (CDC) +# +CONFIG_TINYUSB_CDC_ENABLED=y +# end of Communication Device Class (CDC) +# end of TinyUSB Stack +# end of Component config From 348c4a4f1956a5534a77487eb1295712bf93182b Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Thu, 28 May 2026 12:29:35 +0800 Subject: [PATCH 4/8] feat(docs): update docs for usb wakeup from light sleep example --- docs/en/api-reference/system/sleep_modes.rst | 1 + docs/zh_CN/api-reference/system/sleep_modes.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index 65b57286c60..2710c68e781 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -701,6 +701,7 @@ Application Examples :esp32c3: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, supported by ESP32-C3. :esp32h2: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer and EXT1, supported by ESP32-H2. - :example:`system/light_sleep` demonstrates the usage of Light-sleep wakeup triggered by various sources, such as the timer, GPIOs, supported by {IDF_TARGET_NAME}. + :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tud_cdc_acm_wakeup` demonstrates the usage of USB 2.0 wakeup from Light-sleep. :SOC_TOUCH_SENSOR_SUPPORTED and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP: - :example:`peripherals/touch_sensor/touch_sens_sleep` demonstrates the usage of Light-sleep and Deep-sleep wakeup triggered by the touch sensor. :SOC_VBAT_SUPPORTED: - :example:`lowpower/vbat` demonstrates the use of backup battery power (VBAT) during Deep-sleep, allowing the RTC timer to keep running after the main power is removed. diff --git a/docs/zh_CN/api-reference/system/sleep_modes.rst b/docs/zh_CN/api-reference/system/sleep_modes.rst index d0d06ec4c62..ffcf613e90d 100644 --- a/docs/zh_CN/api-reference/system/sleep_modes.rst +++ b/docs/zh_CN/api-reference/system/sleep_modes.rst @@ -701,6 +701,7 @@ UART 输出处理 :esp32c3: - :example:`system/deep_sleep` 演示如何通过 ESP32-C3 的唤醒源,如 RTC 定时器、GPIO 等,触发 Deep-sleep 唤醒。 :esp32h2: - :example:`system/deep_sleep` 演示如何通过 ESP32-H2 的唤醒源,如 RTC 定时器、EXT1 等,触发 Deep-sleep 唤醒。 - :example:`system/light_sleep` 演示如何使用 {IDF_TARGET_NAME} 的唤醒源,如定时器,GPIO 等,触发 Light-sleep 唤醒。 + :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tud_cdc_acm_wakeup` 演示如何使用 USB 2.0 将芯片从 Light-sleep 唤醒。 :SOC_TOUCH_SENSOR_SUPPORTED and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP: - :example:`peripherals/touch_sensor/touch_sens_sleep` 演示如何使用触摸传感器唤醒 Light-sleep 或 Deep-sleep。 :SOC_VBAT_SUPPORTED: - :example:`lowpower/vbat` 演示如何在 Deep-sleep 期间使用备用电池电源(VBAT),使 RTC 定时器在主电源断开后继续运行。 From d65b467108be638d0d4fe812d9695fcda33d970f Mon Sep 17 00:00:00 2001 From: Jiang Guang Ming Date: Mon, 8 Jun 2026 15:26:45 +0800 Subject: [PATCH 5/8] fix(usb): address usb wakeup review comments --- .../esp32p4/include/hal/usb_utmi_ll.h | 4 +--- .../esp_hw_support/include/esp_private/usb_phy.h | 15 ++++++++++++++- components/esp_hw_support/include/esp_sleep.h | 7 +++---- components/esp_hw_support/usb_phy/usb_phy.c | 16 ++++++++++++++++ .../usb/device/tud_cdc_acm_wakeup/README.md | 5 ++++- .../main/tud_cdc_acm_wakeup_main.c | 15 ++++++--------- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h b/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h index 65e91cb9748..fd34ade1cdb 100644 --- a/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h +++ b/components/esp_hal_usb/esp32p4/include/hal/usb_utmi_ll.h @@ -11,11 +11,9 @@ #include "soc/lp_clkrst_struct.h" #include "soc/hp_sys_clkrst_struct.h" #include "soc/hp_system_struct.h" +#include "soc/lp_system_struct.h" #include "soc/usb_utmi_struct.h" #include "hal/config.h" -#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 -#include "soc/lp_system_struct.h" -#endif #ifdef __cplusplus extern "C" { diff --git a/components/esp_hw_support/include/esp_private/usb_phy.h b/components/esp_hw_support/include/esp_private/usb_phy.h index 7553b879bad..05dcddd7a84 100644 --- a/components/esp_hw_support/include/esp_private/usb_phy.h +++ b/components/esp_hw_support/include/esp_private/usb_phy.h @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include #include #include "esp_err.h" #include "soc/soc_caps.h" @@ -164,6 +165,18 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r */ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode); +/** + * @brief Set the USB OTG suspend state for USB wakeup logic + * + * @param in_suspend True if the USB OTG bus is suspended + */ +void usb_phy_set_otg_suspend_state(bool in_suspend); + +/** + * @brief Clear USB OTG wakeup status from the USB wakeup logic + */ +void usb_phy_clear_otg_wakeup_status(void); + /** * @brief Delete a USB PHY * diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 7145e5b1906..723774eeb88 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -137,7 +137,7 @@ typedef enum { ESP_SLEEP_WAKEUP_BT, //!< Wakeup caused by BT (light sleep only) ESP_SLEEP_WAKEUP_VAD, //!< Wakeup caused by VAD ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT, //!< Wakeup caused by VDD_BAT under voltage. - ESP_SLEEP_WAKEUP_USB, //!< Wakeup caused by USB (light sleep only) + ESP_SLEEP_WAKEUP_USB, //!< Wakeup caused by USB HS (light sleep only) } esp_sleep_source_t; /** @@ -150,7 +150,6 @@ typedef enum { /* Leave this type define for compatibility */ typedef esp_sleep_source_t esp_sleep_wakeup_cause_t; - enum { ESP_ERR_SLEEP_REJECT = ESP_ERR_INVALID_STATE, ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION = ESP_ERR_INVALID_ARG, @@ -567,7 +566,7 @@ esp_err_t esp_sleep_enable_bt_wakeup(void); esp_err_t esp_sleep_disable_bt_wakeup(void); /** - * @brief Enable wakeup by USB + * @brief Enable wakeup by High-Speed USB-OTG * @return * - ESP_OK on success * - ESP_ERR_NOT_SUPPORTED if wakeup from USB is not supported @@ -575,7 +574,7 @@ esp_err_t esp_sleep_disable_bt_wakeup(void); esp_err_t esp_sleep_enable_usb_wakeup(void); /** - * @brief Disable wakeup by USB + * @brief Disable wakeup by High-Speed USB-OTG * @return * - ESP_OK on success * - ESP_ERR_NOT_SUPPORTED if wakeup from USB is not supported diff --git a/components/esp_hw_support/usb_phy/usb_phy.c b/components/esp_hw_support/usb_phy/usb_phy.c index c7e40a6805e..57fc7fca215 100644 --- a/components/esp_hw_support/usb_phy/usb_phy.c +++ b/components/esp_hw_support/usb_phy/usb_phy.c @@ -180,6 +180,22 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode) return ESP_OK; } +void usb_phy_set_otg_suspend_state(bool in_suspend) +{ +#if SOC_USB_UTMI_PHY_NUM + usb_utmi_hal_set_suspend_state(in_suspend); +#else + (void)in_suspend; +#endif +} + +void usb_phy_clear_otg_wakeup_status(void) +{ +#if SOC_USB_UTMI_PHY_NUM + usb_utmi_hal_clear_wakeup_status(); +#endif +} + static esp_err_t usb_phy_install(void) { PHY_ENTER_CRITICAL(); diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md index 8e021256d46..b12c127747f 100644 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md @@ -6,6 +6,7 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) This example shows how to set up an ESP chip as a USB CDC ACM device that enters light sleep when the USB bus is suspended and wakes up from USB activity. +The wakeup source is available only on USB-OTG capable targets with High-Speed USB support. It is not supported by USB Serial/JTAG-only peripherals. As a USB stack, a TinyUSB component is used. @@ -15,7 +16,7 @@ The example implements a USB CDC ACM echo device. When the host suspends the USB ### Hardware Required -Any ESP board that supports USB wakeup from light sleep. +Any ESP board that supports High-Speed USB-OTG wakeup from light sleep. #### Pin Assignment @@ -50,6 +51,8 @@ I (465) tud_cdc_acm_wakeup: USB initialization DONE Connect to the serial port (e.g. on Linux, it should be `/dev/ttyACM0`) by any terminal application (e.g. `picocom /dev/ttyACM0`). Now you can send data strings to the device, the device will echo back the same data string. +To trigger USB suspend from the host, disable or suspend the CDC ACM device on the host side. On Windows, open Device Manager, find the COM port for the device, and disable it. On Linux, you can unbind the CDC ACM driver for the device or put the USB device into autosuspend. On macOS, disconnecting the terminal application and letting the host suspend the interface can also trigger suspend depending on the host power policy. + When the USB host suspends and resumes the bus, the monitor output should include: ``` diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c index 59c8496d07a..639a7fb124c 100644 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c +++ b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c @@ -10,10 +10,10 @@ #include "esp_log.h" #include "esp_rom_serial_output.h" #include "esp_sleep.h" +#include "esp_private/usb_phy.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" -#include "hal/usb_utmi_hal.h" #include "sdkconfig.h" #include "soc/soc_caps.h" #include "tinyusb.h" @@ -85,7 +85,7 @@ void tud_suspend_cb(bool remote_wakeup_en) (void) remote_wakeup_en; ESP_LOGI(TAG, "USB suspended, entering light sleep"); - usb_utmi_hal_set_suspend_state(true); + usb_phy_set_otg_suspend_state(true); esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM); @@ -95,16 +95,13 @@ void tud_suspend_cb(bool remote_wakeup_en) } else { uint32_t causes = esp_sleep_get_wakeup_causes(); if (causes & BIT(ESP_SLEEP_WAKEUP_UNDEFINED)) { - ESP_LOGI(TAG, "Woke up from: unknown"); - printf("%lx\n", causes); - return; - } - if (causes & BIT(ESP_SLEEP_WAKEUP_USB)) { + ESP_LOGW(TAG, "Woke up from an unknown source: 0x%lx", causes); + } else if (causes & BIT(ESP_SLEEP_WAKEUP_USB)) { ESP_LOGI(TAG, "Woke up from: USB"); } } - usb_utmi_hal_set_suspend_state(false); - usb_utmi_hal_clear_wakeup_status(); + usb_phy_set_otg_suspend_state(false); + usb_phy_clear_otg_wakeup_status(); } void tud_resume_cb(void) From ec27869a8986b51b76109ba77e1081e92f15c95e Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Wed, 10 Jun 2026 10:29:01 +0800 Subject: [PATCH 6/8] fix(usb): use capability macros for wakeup example rule Co-authored-by: Cursor --- examples/peripherals/.build-test-rules.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index ab438750322..7a9f544320c 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -819,7 +819,7 @@ examples/peripherals/usb/device/cherryusb_serial_device: examples/peripherals/usb/device/tud_cdc_acm_wakeup: disable: - - if: IDF_TARGET not in ["esp32p4", "esp32s31"] + - if: SOC_USB_OTG_SUPPORTED != 1 or SOC_PM_SUPPORT_USB_WAKEUP != 1 examples/peripherals/usb/device/tusb_ncm: disable: From 0f4bf3e0974e55dbb5ac4c27cc124543f20ac137 Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Wed, 10 Jun 2026 10:45:57 +0800 Subject: [PATCH 7/8] fix(sleep): disable usb wakeup through generic API Co-authored-by: Cursor --- components/esp_hw_support/sleep_modes.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index d13f76abe0b..acc10a45878 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1830,6 +1830,10 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) #if SOC_VBAT_SUPPORTED } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT, RTC_VBAT_UNDER_VOLT_TRIG_EN)) { s_config.wakeup_triggers &= ~RTC_VBAT_UNDER_VOLT_TRIG_EN; +#endif +#if SOC_PM_SUPPORT_USB_WAKEUP + } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_USB, RTC_USB_TRIG_EN)) { + s_config.wakeup_triggers &= ~RTC_USB_TRIG_EN; #endif } else { ESP_EARLY_LOGE(TAG, "Incorrect wakeup source (%d) to disable.", (int) source); From 6020aec17762f68cf96bbb7e859440ba11e01b0e Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Wed, 10 Jun 2026 18:53:23 +0800 Subject: [PATCH 8/8] fix(usb): address wakeup example review comments Co-authored-by: Cursor --- .../include/esp_private/usb_phy.h | 4 ++ docs/en/api-reference/system/sleep_modes.rst | 2 +- .../api-reference/system/sleep_modes.rst | 2 +- examples/peripherals/.build-test-rules.yml | 2 +- .../tud_cdc_acm_wakeup/sdkconfig.defaults | 40 ------------- .../CMakeLists.txt | 2 +- .../README.md | 58 +++++++++---------- .../main/CMakeLists.txt | 2 +- .../main/idf_component.yml | 0 .../main/tusb_cdc_acm_wakeup_main.c} | 2 +- .../tusb_cdc_acm_wakeup/sdkconfig.defaults | 6 ++ 11 files changed, 45 insertions(+), 75 deletions(-) delete mode 100644 examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults rename examples/peripherals/usb/device/{tud_cdc_acm_wakeup => tusb_cdc_acm_wakeup}/CMakeLists.txt (92%) rename examples/peripherals/usb/device/{tud_cdc_acm_wakeup => tusb_cdc_acm_wakeup}/README.md (53%) rename examples/peripherals/usb/device/{tud_cdc_acm_wakeup => tusb_cdc_acm_wakeup}/main/CMakeLists.txt (60%) rename examples/peripherals/usb/device/{tud_cdc_acm_wakeup => tusb_cdc_acm_wakeup}/main/idf_component.yml (100%) rename examples/peripherals/usb/device/{tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c => tusb_cdc_acm_wakeup/main/tusb_cdc_acm_wakeup_main.c} (99%) create mode 100644 examples/peripherals/usb/device/tusb_cdc_acm_wakeup/sdkconfig.defaults diff --git a/components/esp_hw_support/include/esp_private/usb_phy.h b/components/esp_hw_support/include/esp_private/usb_phy.h index 05dcddd7a84..176bc22e2b7 100644 --- a/components/esp_hw_support/include/esp_private/usb_phy.h +++ b/components/esp_hw_support/include/esp_private/usb_phy.h @@ -168,12 +168,16 @@ esp_err_t usb_phy_otg_set_mode(usb_phy_handle_t handle, usb_otg_mode_t mode); /** * @brief Set the USB OTG suspend state for USB wakeup logic * + * @note Only applies to the UTMI (HS) PHY. + * * @param in_suspend True if the USB OTG bus is suspended */ void usb_phy_set_otg_suspend_state(bool in_suspend); /** * @brief Clear USB OTG wakeup status from the USB wakeup logic + * + * @note Only applies to the UTMI (HS) PHY. */ void usb_phy_clear_otg_wakeup_status(void); diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index 2710c68e781..948df371484 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -701,7 +701,7 @@ Application Examples :esp32c3: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, supported by ESP32-C3. :esp32h2: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer and EXT1, supported by ESP32-H2. - :example:`system/light_sleep` demonstrates the usage of Light-sleep wakeup triggered by various sources, such as the timer, GPIOs, supported by {IDF_TARGET_NAME}. - :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tud_cdc_acm_wakeup` demonstrates the usage of USB 2.0 wakeup from Light-sleep. + :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tusb_cdc_acm_wakeup` demonstrates the usage of USB 2.0 wakeup from Light-sleep. :SOC_TOUCH_SENSOR_SUPPORTED and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP: - :example:`peripherals/touch_sensor/touch_sens_sleep` demonstrates the usage of Light-sleep and Deep-sleep wakeup triggered by the touch sensor. :SOC_VBAT_SUPPORTED: - :example:`lowpower/vbat` demonstrates the use of backup battery power (VBAT) during Deep-sleep, allowing the RTC timer to keep running after the main power is removed. diff --git a/docs/zh_CN/api-reference/system/sleep_modes.rst b/docs/zh_CN/api-reference/system/sleep_modes.rst index ffcf613e90d..6c2466b3873 100644 --- a/docs/zh_CN/api-reference/system/sleep_modes.rst +++ b/docs/zh_CN/api-reference/system/sleep_modes.rst @@ -701,7 +701,7 @@ UART 输出处理 :esp32c3: - :example:`system/deep_sleep` 演示如何通过 ESP32-C3 的唤醒源,如 RTC 定时器、GPIO 等,触发 Deep-sleep 唤醒。 :esp32h2: - :example:`system/deep_sleep` 演示如何通过 ESP32-H2 的唤醒源,如 RTC 定时器、EXT1 等,触发 Deep-sleep 唤醒。 - :example:`system/light_sleep` 演示如何使用 {IDF_TARGET_NAME} 的唤醒源,如定时器,GPIO 等,触发 Light-sleep 唤醒。 - :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tud_cdc_acm_wakeup` 演示如何使用 USB 2.0 将芯片从 Light-sleep 唤醒。 + :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tusb_cdc_acm_wakeup` 演示如何使用 USB 2.0 将芯片从 Light-sleep 唤醒。 :SOC_TOUCH_SENSOR_SUPPORTED and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP: - :example:`peripherals/touch_sensor/touch_sens_sleep` 演示如何使用触摸传感器唤醒 Light-sleep 或 Deep-sleep。 :SOC_VBAT_SUPPORTED: - :example:`lowpower/vbat` 演示如何在 Deep-sleep 期间使用备用电池电源(VBAT),使 RTC 定时器在主电源断开后继续运行。 diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 7a9f544320c..dc496cdd30b 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -817,7 +817,7 @@ examples/peripherals/usb/device/cherryusb_serial_device: temporary: true reason: CherryUSB does not support esp32h4 or esp32s31 -examples/peripherals/usb/device/tud_cdc_acm_wakeup: +examples/peripherals/usb/device/tusb_cdc_acm_wakeup: disable: - if: SOC_USB_OTG_SUPPORTED != 1 or SOC_PM_SUPPORT_USB_WAKEUP != 1 diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults b/examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults deleted file mode 100644 index d541888bd98..00000000000 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/sdkconfig.defaults +++ /dev/null @@ -1,40 +0,0 @@ -# This file was generated using idf.py save-defconfig or menuconfig [D] key. It can be edited manually. -# Espressif IoT Development Framework (ESP-IDF) 6.2.0 Project Minimal Configuration -# -# default: -CONFIG_IDF_TARGET="esp32p4" - -# -# Component config -# - -# -# Hardware Settings -# - -# -# Chip revision -# -CONFIG_ESP32P4_REV_MIN_300=y -# end of Chip revision -# end of Hardware Settings - -# -# Power Management -# -CONFIG_PM_ENABLE=y -CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y -# end of Power Management - -# -# TinyUSB Stack -# -CONFIG_TINYUSB_DEBUG_LEVEL=1 - -# -# Communication Device Class (CDC) -# -CONFIG_TINYUSB_CDC_ENABLED=y -# end of Communication Device Class (CDC) -# end of TinyUSB Stack -# end of Component config diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/CMakeLists.txt similarity index 92% rename from examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt rename to examples/peripherals/usb/device/tusb_cdc_acm_wakeup/CMakeLists.txt index c16aac83db3..a310f9ffd0c 100644 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/CMakeLists.txt +++ b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/CMakeLists.txt @@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.22) include($ENV{IDF_PATH}/tools/cmake/project.cmake) # "Trim" the build. Include the minimal set of components, main, and anything it depends on. idf_build_set_property(MINIMAL_BUILD ON) -project(tud_cdc_acm_wakeup) +project(tusb_cdc_acm_wakeup) diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/README.md similarity index 53% rename from examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md rename to examples/peripherals/usb/device/tusb_cdc_acm_wakeup/README.md index b12c127747f..89f34e47d21 100644 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/README.md +++ b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/README.md @@ -43,9 +43,9 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui After the flashing you should see this output: ``` -I (285) tud_cdc_acm_wakeup: USB initialization +I (285) tusb_cdc_acm_wakeup: USB initialization I (455) TinyUSB: TinyUSB Driver installed -I (465) tud_cdc_acm_wakeup: USB initialization DONE +I (465) tusb_cdc_acm_wakeup: USB initialization DONE ``` Connect to the serial port (e.g. on Linux, it should be `/dev/ttyACM0`) by any terminal application (e.g. `picocom /dev/ttyACM0`). @@ -56,31 +56,31 @@ To trigger USB suspend from the host, disable or suspend the CDC ACM device on t When the USB host suspends and resumes the bus, the monitor output should include: ``` -I (122142) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (122272) tud_cdc_acm_wakeup: Data from channel 0: -I (122272) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (122402) tud_cdc_acm_wakeup: Data from channel 0: -I (122402) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (122622) tud_cdc_acm_wakeup: Data from channel 0: -I (122622) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (127432) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (132402) tud_cdc_acm_wakeup: USB suspended, entering light sleep -I (132422) tud_cdc_acm_wakeup: Woke up from: USB -I (132422) tud_cdc_acm_wakeup: USB resumed -I (145762) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (145812) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (145812) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (145822) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (145822) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (145832) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (148762) tud_cdc_acm_wakeup: Data from channel 0: -I (148762) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (148902) tud_cdc_acm_wakeup: Data from channel 0: -I (148902) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (149032) tud_cdc_acm_wakeup: Data from channel 0: -I (149032) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (149252) tud_cdc_acm_wakeup: Data from channel 0: -I (149252) tud_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| -I (151382) tud_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 -I (155312) tud_cdc_acm_wakeup: USB suspended, entering light sleep +I (122142) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (122272) tusb_cdc_acm_wakeup: Data from channel 0: +I (122272) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (122402) tusb_cdc_acm_wakeup: Data from channel 0: +I (122402) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (122622) tusb_cdc_acm_wakeup: Data from channel 0: +I (122622) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (127432) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (132402) tusb_cdc_acm_wakeup: USB suspended, entering light sleep +I (132422) tusb_cdc_acm_wakeup: Woke up from: USB +I (132422) tusb_cdc_acm_wakeup: USB resumed +I (145762) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145812) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145812) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145822) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145822) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (145832) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (148762) tusb_cdc_acm_wakeup: Data from channel 0: +I (148762) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (148902) tusb_cdc_acm_wakeup: Data from channel 0: +I (148902) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (149032) tusb_cdc_acm_wakeup: Data from channel 0: +I (149032) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (149252) tusb_cdc_acm_wakeup: Data from channel 0: +I (149252) tusb_cdc_acm_wakeup: 0x4ff3afa4 48 65 6c 6c 6f |Hello| +I (151382) tusb_cdc_acm_wakeup: Line state changed on channel 0: DTR:0, RTS:0 +I (155312) tusb_cdc_acm_wakeup: USB suspended, entering light sleep ``` diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/CMakeLists.txt similarity index 60% rename from examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt rename to examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/CMakeLists.txt index 10b20b81a8c..f2c0b4447b0 100644 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/CMakeLists.txt +++ b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "tud_cdc_acm_wakeup_main.c" +idf_component_register(SRCS "tusb_cdc_acm_wakeup_main.c" INCLUDE_DIRS . PRIV_REQUIRES esp_hal_usb) diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/idf_component.yml b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/idf_component.yml similarity index 100% rename from examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/idf_component.yml rename to examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/idf_component.yml diff --git a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/tusb_cdc_acm_wakeup_main.c similarity index 99% rename from examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c rename to examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/tusb_cdc_acm_wakeup_main.c index 639a7fb124c..519404a30b8 100644 --- a/examples/peripherals/usb/device/tud_cdc_acm_wakeup/main/tud_cdc_acm_wakeup_main.c +++ b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/main/tusb_cdc_acm_wakeup_main.c @@ -24,7 +24,7 @@ #error This example requires a target with SOC_PM_SUPPORT_USB_WAKEUP. #endif -static const char *TAG = "tud_cdc_acm_wakeup"; +static const char *TAG = "tusb_cdc_acm_wakeup"; static uint8_t rx_buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1]; /** diff --git a/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/sdkconfig.defaults b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/sdkconfig.defaults new file mode 100644 index 00000000000..2b132661a29 --- /dev/null +++ b/examples/peripherals/usb/device/tusb_cdc_acm_wakeup/sdkconfig.defaults @@ -0,0 +1,6 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_PM_ENABLE=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y +CONFIG_TINYUSB_CDC_ENABLED=y