This is a [USB DFU](https://www.usb.org/document-library/device-firmware-upgrade-11-new-version-31-aug-2004) (DFU mode) implementation for [ESP32-S2](https://www.espressif.com/en/products/socs/esp32-s2) based on [tinyUSB](https://docs.tinyusb.org/en/latest/index.html).
It allows flashing the firmware using [dfu-util](http://dfu-util.sourceforge.net/).
To compile the firmware, you need the [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html#installation).
Here I compile it for the [WEMOS S2 mini](https://www.wemos.cc/en/latest/s2/s2_mini.html) board (other board definitions are available in `hw/bsp/esp32s2/boards/`).
The DFU firmware will in turn flash the downloaded image onto the [OTA0](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/ota.html) partition.
For that, a custom [partition table](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/partition-tables.html) is used.
When restating the ESP by pressing the reset button, the ESP bootloader will start the firmware which is in the factory partition, which should be the DFU firmware previously flashed.
The [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html) uses [tinyUSB](https://github.com/espressif/tinyusb), but only offers [few profiles](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_device.html) (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
-------
[TinyUSB](https://github.com/hathach/tinyusb) is a generic USB stack for micro-controllers.
It [supports](https://docs.tinyusb.org/en/latest/reference/supported.html) ESP32-S2.
DFU is [implemented](https://github.com/hathach/tinyusb/tree/master/src/class/dfu) and there is an [example](https://github.com/hathach/tinyusb/tree/master/examples/device/dfu).
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.
bootloader
----------
The ESP-IDF allows you to have a [custom](https://github.com/espressif/esp-idf/tree/master/examples/custom_bootloader) [bootloader](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/bootloader.html) (2nd stage), but I was not able to add freeRTOS to it, required by the tinyUSB implementation.
factory
-------
This USB DFU implementation is flashed as a factory application image.
It will then flash the main firmware image into the [OTA0 partition](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/ota.html).
Thus it requires a custom [partition table](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-guides/partition-tables.html), 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.
alternatives
============
TinyUF2
-------
[TinyUF2](https://github.com/adafruit/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.