From a37b9efc902a5951b748dd5c7fc509b6ceeae425 Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Fri, 5 Jun 2026 15:59:04 +0800 Subject: [PATCH 1/3] feat: support esp32s31 dfu feature --- components/soc/esp32s31/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s31/include/soc/soc_caps.h | 1 + tools/cmake/dfu.cmake | 4 ++-- tools/cmakev2/dfu.cmake | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 023070cf68a..8f5a78dfdf7 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -107,6 +107,10 @@ config SOC_USB_OTG_SUPPORTED bool default y +config SOC_USB_DFU_SUPPORTED + bool + default y + config SOC_TEMP_SENSOR_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 f0549b97bc7..41fcf330ffc 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -49,6 +49,7 @@ #define SOC_PARLIO_LCD_SUPPORTED 1 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_USB_OTG_SUPPORTED 1 +#define SOC_USB_DFU_SUPPORTED 1 #define SOC_TEMP_SENSOR_SUPPORTED 1 #define SOC_USB_SERIAL_JTAG_SUPPORTED 1 // #define SOC_SUPPORTS_SECURE_DL_MODE 1 // TODO: [ESP32S31] IDF-14629 diff --git a/tools/cmake/dfu.cmake b/tools/cmake/dfu.cmake index 68dfa5f3210..fcafeb7930b 100644 --- a/tools/cmake/dfu.cmake +++ b/tools/cmake/dfu.cmake @@ -25,10 +25,10 @@ function(__add_dfu_targets) return() elseif("${target}" STREQUAL "esp32h4") return() - elseif("${target}" STREQUAL "esp32s31") - return() elseif("${target}" STREQUAL "esp32p4") set(dfu_pid "12") + elseif("${target}" STREQUAL "esp32s31") + set(dfu_pid "20") elseif("${target}" STREQUAL "linux") return() else() diff --git a/tools/cmakev2/dfu.cmake b/tools/cmakev2/dfu.cmake index c1dc96a1065..7b1d116b8b2 100644 --- a/tools/cmakev2/dfu.cmake +++ b/tools/cmakev2/dfu.cmake @@ -65,6 +65,8 @@ function(idf_create_dfu binary) set(dfu_pid "9") elseif("${target}" STREQUAL "esp32p4") set(dfu_pid "12") + elseif("${target}" STREQUAL "esp32s31") + set(dfu_pid "20") else() # DFU not supported on this target idf_msg("DFU not supported on ${target}, skipping DFU target creation") From 729241db7f8f48de663fcdf0de7be32c18fd787a Mon Sep 17 00:00:00 2001 From: JiangGuangMing Date: Fri, 5 Jun 2026 16:05:32 +0800 Subject: [PATCH 2/3] docs: update docs with esp32s31 dfu feature --- docs/en/api-guides/dfu.rst | 2 +- docs/zh_CN/api-guides/dfu.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/api-guides/dfu.rst b/docs/en/api-guides/dfu.rst index e599352c90a..d96c62819be 100644 --- a/docs/en/api-guides/dfu.rst +++ b/docs/en/api-guides/dfu.rst @@ -29,7 +29,7 @@ Device Firmware Upgrade (DFU) is a mechanism for upgrading the firmware of {IDF_ USB Connection -------------- -.. only:: esp32p4 +.. only:: esp32p4 or esp32s31 {IDF_TARGET_NAME} routes the USB D+ and D- signals to their dedicated pins. For USB device functionality, these pins must be connected to the USB bus (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug). diff --git a/docs/zh_CN/api-guides/dfu.rst b/docs/zh_CN/api-guides/dfu.rst index a45d5c093a9..09718e91b22 100644 --- a/docs/zh_CN/api-guides/dfu.rst +++ b/docs/zh_CN/api-guides/dfu.rst @@ -29,7 +29,7 @@ USB 连接 -------------- -.. only:: esp32p4 +.. only:: esp32p4 or esp32s31 {IDF_TARGET_NAME} 将 USB D+ 和 D- 信号连接到其专用引脚。为了实现 USB 设备功能,这些引脚必须连接到 USB 总线,如,通过 Micro-B 接口、USB-C 接口进行连接,或直接连接到标准 A 型插头。 From 5c3306ac04b850a923222ec1e9dcbb877097b8b7 Mon Sep 17 00:00:00 2001 From: Jiang Guang Ming Date: Tue, 9 Jun 2026 15:40:34 +0800 Subject: [PATCH 3/3] fix(dfu): retry dfu-util flash on macOS detach failure Co-authored-by: Cursor --- docs/en/api-guides/dfu.rst | 2 +- docs/zh_CN/api-guides/dfu.rst | 2 +- tools/cmake/run_dfu_util.cmake | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/en/api-guides/dfu.rst b/docs/en/api-guides/dfu.rst index d96c62819be..7023c0cd35b 100644 --- a/docs/en/api-guides/dfu.rst +++ b/docs/en/api-guides/dfu.rst @@ -161,7 +161,7 @@ Common Errors and Known Issues - The reason for ``No DFU capable USB device available`` could be that the USB driver was not properly installed on Windows (see :ref:`api_guide_dfu_flash_win`), udev rule was not setup on Linux (see :ref:`api_guide_dfu_flash_udev`) or the device is not in bootloader mode. -- Flashing with ``dfu-util`` on Windows fails on the first attempt with error ``Lost device after RESET?``. Please retry the flashing and it should succeed the next time. +- Flashing with ``dfu-util`` on Windows or macOS may fail on the first attempt with error ``Lost device after RESET?``. ``idf.py dfu-flash`` retries once automatically. If flashing still fails, run ``idf.py dfu-flash`` again manually. .. only:: SOC_SUPPORTS_SECURE_DL_MODE diff --git a/docs/zh_CN/api-guides/dfu.rst b/docs/zh_CN/api-guides/dfu.rst index 09718e91b22..cce679078c7 100644 --- a/docs/zh_CN/api-guides/dfu.rst +++ b/docs/zh_CN/api-guides/dfu.rst @@ -161,7 +161,7 @@ Zadig 工具可能会检测到 {IDF_TARGET_NAME} 的多个 USB 接口。请 ** - 出现 ``No DFU capable USB device available`` 错误的原因可能是在 Windows 上没有正确安装 USB 驱动程序(请参考 :ref:`api_guide_dfu_flash_win`),或是未在 Linux 上设置 Udev 规则(请参考 :ref:`api_guide_dfu_flash_udev`),或是设备未处于引导加载程序模式。 -- 在 Windows 上使用 ``dfu-util`` 第一次烧录失败,并出现 ``Lost device after RESET?`` 错误信息。出现此问题时,请重新烧录一次,再次烧录应该会成功。 +- 在 Windows 或 macOS 上使用 ``dfu-util`` 第一次烧录可能失败,并出现 ``Lost device after RESET?`` 错误信息。``idf.py dfu-flash`` 会自动重试一次。如果仍然失败,请手动再次运行 ``idf.py dfu-flash``。 .. only:: SOC_SUPPORTS_SECURE_DL_MODE diff --git a/tools/cmake/run_dfu_util.cmake b/tools/cmake/run_dfu_util.cmake index 49113030c4b..967ce182580 100644 --- a/tools/cmake/run_dfu_util.cmake +++ b/tools/cmake/run_dfu_util.cmake @@ -23,6 +23,13 @@ endif() message("Command list: ${CMD}") execute_process(COMMAND ${CMD} RESULT_VARIABLE result) +# dfu-util may fail on the first attempt while switching from runtime to DFU mode, +# e.g. with "Lost device after RESET?" on Windows/macOS. Retry once. +if(${result} AND NOT ${ESP_DFU_LIST}) + message(WARNING "${TOOL} failed, retrying once...") + execute_process(COMMAND ${CMD} RESULT_VARIABLE result) +endif() + if(${result}) message(FATAL_ERROR "${TOOL} failed") endif()