USB DFU (DFU mode) implementation for ESP32-S2 based on tinyUSB
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
King Kévin 78a85cdb5b dfu: use task to handle download 2 months ago
.github add 3 months ago
docs add get-deps target 3 months ago
examples dfu: use task to handle download 2 months ago
hw support UART write on ESP32-S2-based boards 2 months ago
lib Remove lib/Pico-PIO-USB, which has moved to hw/mcu/raspberry_pi/Pico-PIO-USB. 4 months ago
src Merge pull request #1514 from maddyaby/audiod_typo 3 months ago
test Add test CI. 1 year ago
tools add 3 months ago
.gitattributes Add gitattributes 3 years ago
.gitignore Unify skip and only logic for build scripts 9 months ago
.gitmodules add upstream Pico-PIO-USB 5 months ago
.readthedocs.yaml rename to .readthedocs.yaml 1 year ago
CODE_OF_CONDUCT.rst code_of_conduct: refactor file from markdown to restructuredtext 1 year ago
CONTRIBUTORS.rst increase version, update doc for release 7 months ago
LICENSE migrate license from BSD 3 clause to MIT 4 years ago doc: provide compile and flash instructions 2 months ago
README.rst update readme 4 months ago
pkg.yml Change mynewt package type to sdk 2 years ago
repository.yml Add missing releases to Mynewt repository.yml 7 months ago
version.yml add repo & version yml 4 years ago

This is a USB DFU (DFU mode) implementation for ESP32-S2 based on tinyUSB. It allows flashing the firmware using dfu-util.



To compile the firmware, you need the ESP-IDF. Here I compile it for the WEMOS S2 mini board (other board definitions are available in hw/bsp/esp32s2/boards/).

cd examples/device/dfu_freertos/
make BOARD=wemos_s2_mini all

This is equivalent to: -B_build/wemos_s2_mini -DFAMILY=esp32s2 -DBOARD=wemos_s2_mini  -DIDF_TARGET=esp32s2 build


To flash the compiled fimware: -B_build/wemos_s2_mini -DFAMILY=esp32s2 -DBOARD=wemos_s2_mini  -DIDF_TARGET=esp32s2 -p /dev/ttyACM0 flash

or to use esptool directly over the ROM USB DFU bootloader, without ESP-IDF: -p /dev/ttyACM0 --before no_reset --after no_reset --chip esp32s2  write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x1000 _build/wemos_s2_mini/bootloader/bootloader.bin 0x8000 _build/wemos_s2_mini/partition_table/partition-table.bin 0xd000 _build/wemos_s2_mini/ota_data_initial.bin 0x10000 _build/wemos_s2_mini/dfu_freertos.bin

This will flash the DFU firmware to the factory partition. The DFU firmware will in turn flash the downladed image onto the OTA0 partition. For that a custom partition table is used.


To further configure the build: -B_build/wemos_s2_mini -DFAMILY=esp32s2 -DBOARD=wemos_s2_mini  -DIDF_TARGET=esp32s2 menuconfig


This firmware is just for the DFU mode. The main application needs to implement the runtime mode seperately.

To switch from runtime to DFU mode during detach, set the boot partition in otadata to factory, and restart the ESP.

design choice


The ESP-IDF uses tinyUSB, but only offers few profiles (e.g. CDC, MSC). They are defined in 'esp-idf/components/tinyusb/additions', and re-use the tinyUSB device implementations. But there is no DFU implementation (runtime or DFU mode).


TinyUSB is a generic USB stack for micro-controllers. It supports ESP32-S2. DFU is implemented and there is an example. This example can't be used for ESP32-S2 though. I've added freeRTOS to it so it can be used on the ESP32-S2.


The ESP-IDF allows you to have a custom bootloader (2nd stage), but I was not able to add freeRTOS to it, required by the tinyUSB implementation.


This USB DFU implementation is flashed as a factory application image. It will then flash the main firmware image into the OTA0 partition. Thus it requires a custom partition table, with a "small" factory partition, just one OTA application partition, and one OTA data partition. The factory partition should be 200 KB. This is super large for just a "bootloader" to flash firmware images, but since ESP32 often use large external flash memory, this is not too much of an issue. Feel free to reuse the 'partitions.csv' file as example.



The ESP-S2 comes with a ROM bootloader that already allows you to flash over USB using the serial CDC ACM profile. But this method does not let you restart into the main firmware. The ROM bootloader USB stack even offers DFU capability, and you can flash using dfu-util. But this one also does not let you restart into the main firmware.

To flash using USB serial (can't restart the device): -p /dev/ttyACM0 flash
WARNING: ESP32-S2 chip was placed into download mode using GPIO0. can not exit the download mode over USB. To run the app, reset the chip manually.
To suppress this note, set --after option to 'no_reset'.

And to flash using DFU:

# generate the DFU binary (not the same as the usual flash binary) dfu
dfu-util --device 303a:0002 --download build/dfu.bin
# or dfu-flash

Note: after detaching, the bootloader claims for be in runtime mode, but this is still the bootloader, and not the flashed firmware.


TinyUF2 is a UF2 bootloader by Adafruit. It is based on TinyUSB, and supports ESP32-S2. It uses the DFU name (Device Firmware Upgrade), but it's not the DFU specified by USB. Instead it provides a MSC interface where you can copy the firmware binary file to.