stm32f405 msc enumerated

This commit is contained in:
hathach 2020-10-14 23:22:42 +07:00
parent 50b2235afd
commit fd45127847
17 changed files with 355 additions and 81 deletions

View file

@ -33,7 +33,7 @@ jobs:
submodules: 'true'
- name: Build
run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest idf.py build -DBOARD=${{ matrix.board }}
run: docker run --rm -v $PWD:/project -w /project/ports/esp32s2 espressif/idf:latest idf.py build -DBOARD=${{ matrix.board }}
- name: Rename release artifact
run: cp build/uf2-esp32s.bin uf2-${{ matrix.board }}-${{ github.event.release.tag_name }}.bin

7
.gitignore vendored
View file

@ -1,3 +1,6 @@
/build/
/_build/
/ports/*/build/
/sdkconfig
.settings/
*.o
*.d
*.P

View file

@ -20,6 +20,8 @@ if(NOT (DEFINED BOARD AND EXISTS "${CMAKE_SOURCE_DIR}/components/boards/${BOARD}
message(FATAL_ERROR "Invalid BOARD specified")
endif()
set(EXTRA_COMPONENT_DIRS "../../src")
set(SDKCONFIG_DEFAULTS sdkconfig.defaults components/boards/${BOARD}/sdkconfig)
set(SDKCONFIG build/sdkconfig)

View file

@ -1,5 +1,5 @@
idf_component_register(SRCS boards.c
idf_component_register(SRCS boards.c flash_hal.c
INCLUDE_DIRS "." "${BOARD}"
#PRIV_REQUIRES "driver"
REQUIRES led_strip lcd)
REQUIRES spi_flash led_strip lcd)

View file

@ -24,8 +24,6 @@
#include <string.h>
#include "boards.h"
#include "flash_hal.h"
#include "esp_log.h"
#include "esp_partition.h"

View file

@ -40,9 +40,35 @@ RM = rm
#-------------- Source files and compiler flags --------------
# Include all source C in board folder
SRC_C += hw/bsp/board.c
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/$(BOARD)/*.c))
# Bootloader src
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/src/*.c))
INC += $(TOP)/src
# Include all source C in board folder and Include path
#SRC_C += hw/bsp/board.c
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/ports/$(PORT)/boards/$(BOARD)/*.c))
INC += $(TOP)/ports/$(PORT)
INC += $(TOP)/ports/$(PORT)/boards/$(BOARD)
# TinyUSB Stack source
TINYUSB_LIB = lib/tinyusb/src
SRC_C += \
$(TINYUSB_LIB)/tusb.c \
$(TINYUSB_LIB)/common/tusb_fifo.c \
$(TINYUSB_LIB)/device/usbd.c \
$(TINYUSB_LIB)/device/usbd_control.c \
$(TINYUSB_LIB)/class/cdc/cdc_device.c \
$(TINYUSB_LIB)/class/dfu/dfu_rt_device.c \
$(TINYUSB_LIB)/class/hid/hid_device.c \
$(TINYUSB_LIB)/class/midi/midi_device.c \
$(TINYUSB_LIB)/class/msc/msc_device.c \
$(TINYUSB_LIB)/class/net/net_device.c \
$(TINYUSB_LIB)/class/usbtmc/usbtmc_device.c \
$(TINYUSB_LIB)/class/vendor/vendor_device.c \
$(TINYUSB_LIB)/portable/$(TINYUSB_DCD)
INC += $(TOP)/$(TINYUSB_LIB)
# Compiler Flags
CFLAGS += \

View file

@ -21,31 +21,7 @@ else
# GNU Make build system
# libc
LIBS += -lgcc -lm -lnosys
ifneq ($(BOARD), spresense)
LIBS += -lc
endif
# TinyUSB Stack source
SRC_C += \
src/tusb.c \
src/common/tusb_fifo.c \
src/device/usbd.c \
src/device/usbd_control.c \
src/class/audio/audio_device.c \
src/class/cdc/cdc_device.c \
src/class/dfu/dfu_rt_device.c \
src/class/hid/hid_device.c \
src/class/midi/midi_device.c \
src/class/msc/msc_device.c \
src/class/net/net_device.c \
src/class/usbtmc/usbtmc_device.c \
src/class/vendor/vendor_device.c \
src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c
# TinyUSB stack include
INC += $(TOP)/src
LIBS += -lgcc -lm -lnosys -lc
CFLAGS += $(addprefix -I,$(INC))

View file

@ -3,12 +3,7 @@ PORT = stm
include ../../tools/top.mk
include ../make.mk
INC += \
src \
$(TOP)/hw \
# Example source
EXAMPLE_SOURCE += $(wildcard src/*.c)
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
# Port source
SRC_C += $(addprefix $(CURRENT_PATH)/, $(wildcard *.c))
include ../rules.mk

View file

@ -23,20 +23,177 @@
*/
#include "boards.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_conf.h"
#include "tusb.h"
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
// Blue LED is chosen because the other LEDs are connected to ST-LINK lines.
#define LED_PORT GPIOC
#define LED_PIN GPIO_PIN_1
#define LED_STATE_ON 1
// Pin D5
#define BUTTON_PORT GPIOC
#define BUTTON_PIN GPIO_PIN_7
#define BUTTON_STATE_ACTIVE 0
#define UARTx USART3
#define UART_GPIO_PORT GPIOB
#define UART_GPIO_AF GPIO_AF7_USART3
#define UART_TX_PIN GPIO_PIN_10
#define UART_RX_PIN GPIO_PIN_11
UART_HandleTypeDef UartHandle;
#define RGB_USB_UNMOUNTED 0xff, 0x00, 0x00 // Red
#define RGB_USB_MOUNTED 0x00, 0xff, 0x00 // Green
#define RGB_WRITING 0xcc, 0x66, 0x00
#define RGB_UNKNOWN 0x00, 0x00, 0x88 // for debug
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void OTG_FS_IRQHandler(void)
{
tud_int_handler(0);
}
// enable all LED, Button, Uart, USB clock
static void all_rcc_clk_enable(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE(); // USB D+, D-
__HAL_RCC_GPIOC_CLK_ENABLE(); // LED, Button
__HAL_RCC_GPIOB_CLK_ENABLE(); // Uart tx, rx
__HAL_RCC_USART3_CLK_ENABLE(); // Uart module
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 168000000
* HCLK(Hz) = 168000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 12000000
* PLL_M = HSE_VALUE/1000000
* PLL_N = 336
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
void board_init(void)
{
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
SystemClock_Config();
SystemCoreClockUpdate();
all_rcc_clk_enable();
GPIO_InitTypeDef GPIO_InitStruct;
// LED
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
board_led_state(0);
// Button
GPIO_InitStruct.Pin = BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
// Uart
GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = UART_GPIO_AF;
HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct);
// USB Pin Init
// PA9- VUSB, PA10- ID, PA11- DM, PA12- DP
/* Configure DM DP Pins */
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure VBUS Pin */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* This for ID line debug */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// Enable USB OTG clock
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
// Enable VBUS sense (B device) via pin PA9
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
}
void board_teardown(void)
@ -73,6 +230,8 @@ static void neopixel_set(uint8_t r, uint8_t g, uint8_t b)
void board_led_state(uint32_t state)
{
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
#ifdef PIN_NEOPIXEL
switch(state)
{
@ -103,6 +262,11 @@ void board_led_state(uint32_t state)
#endif
}
void SysTick_Handler (void)
{
}
// Required by __libc_init_array in startup code if we are compiling using
// -nostdlib/-nostartfiles.
void _init(void)

View file

@ -0,0 +1,76 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ha Thach for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef BOARD_H_
#define BOARD_H_
//--------------------------------------------------------------------+
// Button
//--------------------------------------------------------------------+
// Enter UF2 mode if GPIO is pressed while 2nd stage bootloader indicator
// is on e.g RGB = Purple. If it is GPIO0, user should not hold this while
// reset since that will instead run the 1st stage ROM bootloader
#define PIN_BUTTON_UF2 0
// GPIO that implement 1-bit memory with RC components which hold the
// pin value long enough for double reset detection.
// #define PIN_DOUBLE_RESET_RC
//--------------------------------------------------------------------+
// LED
//--------------------------------------------------------------------+
// GPIO connected to Neopixel data
// Note: On the production version Saola (v1.2) it is GPIO 18,
// however on earlier revision v1.1 it is GPIO 17
#define PIN_NEOPIXEL 18
// Brightness percentage from 1 to 255
#define NEOPIXEL_BRIGHTNESS 0x10
// Number of neopixels
#define NEOPIXEL_NUMBER 1
// LED for indicator and writing flash
// If not defined neopixel will be use for flash writing instead
#define PIN_LED 33
//--------------------------------------------------------------------+
// USB UF2
//--------------------------------------------------------------------+
#define USB_VID 0x239A
#define USB_PID 0x0059
#define USB_MANUFACTURER "Adafruit"
#define USB_PRODUCT "Feather STM32F405 Express"
#define UF2_PRODUCT_NAME USB_MANUFACTURER " " USB_PRODUCT
#define UF2_BOARD_ID "STM32F405-Feather-revB"
#define UF2_VOLUME_LABEL "FTHR405BOOT"
#define UF2_INDEX_URL "https://www.adafruit.com/product/4382"
#endif

View file

@ -12,11 +12,12 @@ CFLAGS += \
# suppress warning caused by vendor mcu driver
CFLAGS += -Wno-error=cast-align
ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver
ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F4xx
ST_HAL_DRIVER = lib/st/stm32f4xx_hal_driver
ST_CMSIS = lib/st/cmsis_device_f4
CMSIS_5 = lib/CMSIS_5
# All source paths should be relative to the top level.
LD_FILE = hw/bsp/$(BOARD)/STM32F405RGTx_FLASH.ld
LD_FILE = ports/$(PORT)/boards/$(BOARD)/STM32F405RGTx_FLASH.ld
SRC_C += \
$(ST_CMSIS)/Source/Templates/system_stm32f4xx.c \
@ -30,24 +31,15 @@ SRC_S += \
$(ST_CMSIS)/Source/Templates/gcc/startup_stm32f405xx.s
INC += \
$(TOP)/hw/mcu/st/st_driver/CMSIS/Include \
$(TOP)/$(CMSIS_5)/CMSIS/Core/Include \
$(TOP)/$(ST_CMSIS)/Include \
$(TOP)/$(ST_HAL_DRIVER)/Inc \
$(TOP)/hw/bsp/$(BOARD)
$(TOP)/$(ST_HAL_DRIVER)/Inc
# For TinyUSB port source
VENDOR = st
CHIP_FAMILY = synopsys
# For freeRTOS port source
FREERTOS_PORT = ARM_CM4F
TINYUSB_DCD = st/synopsys/dcd_synopsys.c
# For flash-jlink target
JLINK_DEVICE = stm32f405rg
# Path to STM32 Cube Programmer CLI, should be added into system path
STM32Prog = STM32_Programmer_CLI
# flash target ROM bootloader
flash: $(BUILD)/$(BOARD)-firmware.bin
dfu-util -R -a 0 --dfuse-address 0x08000000 -D $<

View file

@ -35,11 +35,14 @@ void flash_hal_init(void)
uint32_t flash_hal_size(void)
{
return 0;
return 256;
}
void flash_hal_read(uint32_t addr, void* buffer, uint32_t len)
{
(void) addr;
(void) buffer;
(void) len;
}
void flash_hal_flush(void)
@ -48,5 +51,8 @@ void flash_hal_flush(void)
void flash_hal_write (uint32_t dst, void const *src, uint32_t len)
{
(void) dst;
(void) src;
(void) len;
}

View file

@ -1,3 +1,3 @@
idf_component_register(SRCS flash_hal.c ghostfat.c images.c main.c msc.c screen.c usb_descriptors.c
idf_component_register(SRCS ghostfat.c images.c main.c msc.c screen.c usb_descriptors.c
INCLUDE_DIRS "."
REQUIRES app_update boards led_strip spi_flash tinyusb lcd)

View file

@ -28,11 +28,15 @@
#include <stdio.h>
#include <assert.h>
#include "esp_log.h"
#include "uf2.h"
#include "compile_date.h"
#include "flash_hal.h"
#include "uf2.h"
#include "tusb.h"
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2
#include "esp_log.h"
#endif
//--------------------------------------------------------------------+
//
@ -364,6 +368,7 @@ void uf2_read_block (uint32_t block_no, uint8_t *data)
*/
int uf2_write_block (uint32_t block_no, uint8_t *data, WriteState *state)
{
(void) block_no;
UF2_Block *bl = (void*) data;
if ( !is_uf2_block(bl) ) return -1;

View file

@ -28,6 +28,12 @@
#include <stdbool.h>
#include <string.h>
#include "flash_hal.h"
#include "uf2.h"
#include "boards.h"
#include "tusb.h"
#if CFG_TUSB_OS == OPT_OS_FREERTOS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
@ -35,16 +41,6 @@
#include "freertos/semphr.h"
#include "esp_log.h"
#include "boards.h"
#include "flash_hal.h"
#include "tusb.h"
#include "uf2.h"
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
static const char *TAG = "uf2";
// static task for usbd
// Increase stack size when debug log is enabled
@ -66,10 +62,15 @@ void usb_device_task(void* param)
}
}
void app_main(void)
{
ESP_LOGI(TAG, "Hello");
#endif
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
int main(void)
{
board_init();
tusb_init();
@ -77,15 +78,30 @@ void app_main(void)
uf2_init();
board_led_state(STATE_BOOTLOADER_STARTED);
// Create a task for tinyusb device stack
(void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-2, usb_device_stack, &usb_device_taskdef);
#if USE_SCREEN
screen_init();
screen_draw_drag();
#endif
#if CFG_TUSB_OS == OPT_OS_NONE
while(1)
{
tud_task();
}
#endif
}
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2
// TODO move to ports/esp32s2
void app_main(void)
{
main();
// Create a task for tinyusb device stack
(void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-2, usb_device_stack, &usb_device_taskdef);
}
#endif
//--------------------------------------------------------------------+
// Device callbacks
//--------------------------------------------------------------------+
@ -140,4 +156,6 @@ void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uin
// This example doesn't use multiple report and report ID
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
}

View file

@ -25,8 +25,10 @@
#include "tusb.h"
#include "uf2.h"
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2
#include "esp_partition.h"
#include "esp_ota_ops.h"
#endif
/*------------------------------------------------------------------*/
/* MACRO TYPEDEF CONSTANT ENUM
@ -134,6 +136,7 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
{
(void) lun;
(void) offset;
uint32_t count = 0;
while ( count < bufsize )
@ -153,6 +156,7 @@ int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
void tud_msc_write10_complete_cb(uint8_t lun)
{
(void) lun;
static bool first_write = true;
// abort the DFU, uf2 block failed integrity check
@ -173,11 +177,14 @@ void tud_msc_write10_complete_cb(uint8_t lun)
// All block of uf2 file is complete --> complete DFU process
if (_wr_state.numWritten >= _wr_state.numBlocks)
{
// Set partition OTA0 as bootable
esp_ota_set_boot_partition(esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL));
board_led_state(STATE_WRITING_FINISHED);
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2
// Set partition OTA0 as bootable
esp_ota_set_boot_partition(esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL));
esp_restart();
#endif
}
}
}

View file

@ -172,11 +172,17 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{
if ( (index == STRID_SERIAL) && (desc_str_serial[0] == 0) )
{
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2
// use factory default MAC as serial ID
uint8_t mac[6];
esp_efuse_mac_get_default(mac);
esp_efuse_mac_get_default(mac);
sprintf(desc_str_serial, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#else
desc_str_serial[0] = 'T';
desc_str_serial[1] = 'U';
#endif
}
// Convert ASCII string into UTF-16