From cd4dd816246c75562e924aa383e3988ceff83743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Fri, 6 Jan 2023 14:35:28 +0100 Subject: [PATCH] add UDB DFU runtime --- usb/esp_tinyusb/CMakeLists.txt | 2 + usb/esp_tinyusb/include/tinyusb_types.h | 2 +- usb/esp_tinyusb/include/tusb_config.h | 1 + usb/esp_tinyusb/include/tusb_dfu_rt.h | 37 +++++++++++++++ usb/esp_tinyusb/tusb_dfu_rt.c | 61 +++++++++++++++++++++++++ usb/esp_tinyusb/usb_descriptors.c | 10 +++- 6 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 usb/esp_tinyusb/include/tusb_dfu_rt.h create mode 100644 usb/esp_tinyusb/tusb_dfu_rt.c diff --git a/usb/esp_tinyusb/CMakeLists.txt b/usb/esp_tinyusb/CMakeLists.txt index aa7b54e..df20958 100644 --- a/usb/esp_tinyusb/CMakeLists.txt +++ b/usb/esp_tinyusb/CMakeLists.txt @@ -16,6 +16,7 @@ set(priv_requires usb vfs esp_ringbuf + app_update ) if(NOT CONFIG_TINYUSB_NO_DEFAULT_TASK) @@ -28,6 +29,7 @@ if(CONFIG_TINYUSB_CDC_ENABLED) "tusb_cdc_acm.c" "tusb_console.c" "vfs_tinyusb.c" + "tusb_dfu_rt.c" ) endif() # CONFIG_TINYUSB_CDC_ENABLED diff --git a/usb/esp_tinyusb/include/tinyusb_types.h b/usb/esp_tinyusb/include/tinyusb_types.h index 7180231..2d6da7d 100644 --- a/usb/esp_tinyusb/include/tinyusb_types.h +++ b/usb/esp_tinyusb/include/tinyusb_types.h @@ -11,7 +11,7 @@ extern "C" { #endif #define USB_ESPRESSIF_VID 0x303A -#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 8 // (4 + TINYUSB_STR_DESC_LEN) +#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 9 // (4 + TINYUSB_STR_DESC_LEN) typedef enum { TINYUSB_USBDEV_0, diff --git a/usb/esp_tinyusb/include/tusb_config.h b/usb/esp_tinyusb/include/tusb_config.h index c519cb8..8bff752 100644 --- a/usb/esp_tinyusb/include/tusb_config.h +++ b/usb/esp_tinyusb/include/tusb_config.h @@ -104,6 +104,7 @@ extern "C" { #define CFG_TUD_HID CONFIG_TINYUSB_HID_COUNT #define CFG_TUD_MIDI CONFIG_TINYUSB_MIDI_COUNT #define CFG_TUD_CUSTOM_CLASS CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED +#define CFG_TUD_DFU_RUNTIME 1 #ifdef __cplusplus } diff --git a/usb/esp_tinyusb/include/tusb_dfu_rt.h b/usb/esp_tinyusb/include/tusb_dfu_rt.h new file mode 100644 index 0000000..b34ccf6 --- /dev/null +++ b/usb/esp_tinyusb/include/tusb_dfu_rt.h @@ -0,0 +1,37 @@ +// Copyright 2022 King Kévin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "tusb.h" +#include "tinyusb.h" + +/* Public functions */ +/** + * @brief Initialize DFU runtime. + * + * @return esp_err_t + */ +esp_err_t tusb_dfu_rf_init(void); + +/** Public functions*/ + +#ifdef __cplusplus +} +#endif diff --git a/usb/esp_tinyusb/tusb_dfu_rt.c b/usb/esp_tinyusb/tusb_dfu_rt.c new file mode 100644 index 0000000..b4d18eb --- /dev/null +++ b/usb/esp_tinyusb/tusb_dfu_rt.c @@ -0,0 +1,61 @@ +// Copyright 2022 King Kévin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include "esp_check.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_partition.h" +#include "esp_ota_ops.h" +#include "tusb.h" +#include "tusb_dfu_rt.h" +#include "sdkconfig.h" + +static const char *TAG = "tusb_dfu_rt"; + +esp_err_t tusb_dfu_rf_init(void) +{ + // verify if factory partition exists + const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); + if (!factory) { + return ESP_ERR_NOT_FOUND; + } + // verify if ota data partition exists + const esp_partition_t *otadata = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL); + if (!otadata) { + return ESP_ERR_NOT_FOUND; + } + return ESP_OK; +} + +/* TinyUSB callbacks */ + +// Invoked on DFU_DETACH request to reboot to the bootloader +// WARNING: function linked until public function (e.g. tusb_dfu_rf_init) is called +void tud_dfu_runtime_reboot_to_dfu_cb(void) +{ + ESP_LOGI(TAG, "reboot"); + // switch to dfu factory + const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); + if (!factory) { + ESP_LOGE(TAG, "factory partition not found"); + return; + } + esp_err_t rc = esp_ota_set_boot_partition(factory); + if (ESP_OK != rc) { + ESP_LOGE(TAG, "can't set boot to factory"); + return; + } + esp_restart(); +} diff --git a/usb/esp_tinyusb/usb_descriptors.c b/usb/esp_tinyusb/usb_descriptors.c index eb69192..3e1c485 100644 --- a/usb/esp_tinyusb/usb_descriptors.c +++ b/usb/esp_tinyusb/usb_descriptors.c @@ -6,6 +6,7 @@ #include "usb_descriptors.h" #include "sdkconfig.h" +#include "class/dfu/dfu_rt_device.h" /* * A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. @@ -116,7 +117,7 @@ tusb_desc_strarray_device_t descriptor_str_kconfig = { #else "", #endif - + "DFU (runtime mode)" // 6: DFU RT }; //------------- Configuration Descriptor -------------// @@ -135,13 +136,15 @@ enum { ITF_NUM_MSC, #endif + ITF_NUM_DFU_RT, ITF_NUM_TOTAL }; enum { TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN + CFG_TUD_CDC * TUD_CDC_DESC_LEN + - CFG_TUD_MSC * TUD_MSC_DESC_LEN + CFG_TUD_MSC * TUD_MSC_DESC_LEN + + CFG_TUD_DFU_RUNTIME * TUD_DFU_RT_DESC_LEN }; //------------- USB Endpoint numbers -------------// @@ -181,6 +184,9 @@ uint8_t const descriptor_cfg_kconfig[] = { // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 #endif + + // Interface number, string index, attributes, detach timeout, transfer size */ + TUD_DFU_RT_DESCRIPTOR(ITF_NUM_DFU_RT, 6, 0x0f, 1000, 512), // allow detach, manifest, upload, download; set transfer size to high speed 512 }; /* End of Kconfig driven Descriptor */