1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <limits.h> 8*91f16700Schasinglulu #include <string.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <common/debug.h> 11*91f16700Schasinglulu #include <drivers/st/bsec.h> 12*91f16700Schasinglulu #include <drivers/st/stm32mp1_usb.h> 13*91f16700Schasinglulu #include <drivers/usb_device.h> 14*91f16700Schasinglulu 15*91f16700Schasinglulu #include <platform_def.h> 16*91f16700Schasinglulu #include <stm32cubeprogrammer.h> 17*91f16700Schasinglulu #include <stm32mp_common.h> 18*91f16700Schasinglulu #include <usb_dfu.h> 19*91f16700Schasinglulu 20*91f16700Schasinglulu /* String size (1 byte) + type (1 byte) + 24 UTF16 characters: 2 bytes each */ 21*91f16700Schasinglulu #define SIZ_STRING_SERIAL U(24) 22*91f16700Schasinglulu #define USB_SIZ_STRING_SERIAL (1U + 1U + (SIZ_STRING_SERIAL * 2U)) 23*91f16700Schasinglulu #define USBD_MAX_STR_DESC_SIZ 0x100 24*91f16700Schasinglulu #define USBD_VID 0x0483 25*91f16700Schasinglulu #define USBD_PID 0xDF11 26*91f16700Schasinglulu #define USBD_LANGID_STRING 0x409 27*91f16700Schasinglulu #define USBD_MANUFACTURER_STRING "STMicroelectronics" 28*91f16700Schasinglulu #define USBD_CONFIGURATION_STRING "DFU Config" 29*91f16700Schasinglulu #define USBD_INTERFACE_STRING "DFU Interface" 30*91f16700Schasinglulu 31*91f16700Schasinglulu #if STM32MP13 32*91f16700Schasinglulu #define USB_DFU_ITF_NUM 2 33*91f16700Schasinglulu #endif 34*91f16700Schasinglulu #if STM32MP15 35*91f16700Schasinglulu #define USB_DFU_ITF_NUM 6 36*91f16700Schasinglulu #endif 37*91f16700Schasinglulu 38*91f16700Schasinglulu #define USB_DFU_CONFIG_DESC_SIZ USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM) 39*91f16700Schasinglulu 40*91f16700Schasinglulu /* DFU devices */ 41*91f16700Schasinglulu static struct usb_dfu_handle usb_dfu_handle; 42*91f16700Schasinglulu 43*91f16700Schasinglulu /* USB Standard Device Descriptor */ 44*91f16700Schasinglulu static const uint8_t usb_stm32mp1_desc[USB_LEN_DEV_DESC] = { 45*91f16700Schasinglulu USB_LEN_DEV_DESC, /* bLength */ 46*91f16700Schasinglulu USB_DESC_TYPE_DEVICE, /* bDescriptorType */ 47*91f16700Schasinglulu 0x00, /* bcdUSB */ 48*91f16700Schasinglulu 0x02, /* version */ 49*91f16700Schasinglulu 0x00, /* bDeviceClass */ 50*91f16700Schasinglulu 0x00, /* bDeviceSubClass */ 51*91f16700Schasinglulu 0x00, /* bDeviceProtocol */ 52*91f16700Schasinglulu USB_MAX_EP0_SIZE, /* bMaxPacketSize */ 53*91f16700Schasinglulu LOBYTE(USBD_VID), /* idVendor */ 54*91f16700Schasinglulu HIBYTE(USBD_VID), /* idVendor */ 55*91f16700Schasinglulu LOBYTE(USBD_PID), /* idVendor */ 56*91f16700Schasinglulu HIBYTE(USBD_PID), /* idVendor */ 57*91f16700Schasinglulu 0x00, /* bcdDevice rel. 2.00 */ 58*91f16700Schasinglulu 0x02, 59*91f16700Schasinglulu USBD_IDX_MFC_STR, /* Index of manufacturer string */ 60*91f16700Schasinglulu USBD_IDX_PRODUCT_STR, /* Index of product string */ 61*91f16700Schasinglulu USBD_IDX_SERIAL_STR, /* Index of serial number string */ 62*91f16700Schasinglulu USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ 63*91f16700Schasinglulu }; /* USB_DeviceDescriptor */ 64*91f16700Schasinglulu 65*91f16700Schasinglulu /* USB Standard String Descriptor */ 66*91f16700Schasinglulu static const uint8_t usb_stm32mp1_lang_id_desc[USB_LEN_LANGID_STR_DESC] = { 67*91f16700Schasinglulu USB_LEN_LANGID_STR_DESC, 68*91f16700Schasinglulu USB_DESC_TYPE_STRING, 69*91f16700Schasinglulu LOBYTE(USBD_LANGID_STRING), 70*91f16700Schasinglulu HIBYTE(USBD_LANGID_STRING), 71*91f16700Schasinglulu }; 72*91f16700Schasinglulu 73*91f16700Schasinglulu /* USB Standard Device Descriptor */ 74*91f16700Schasinglulu static const uint8_t 75*91f16700Schasinglulu usbd_stm32mp1_qualifier_desc[USB_LEN_DEV_QUALIFIER_DESC] = { 76*91f16700Schasinglulu USB_LEN_DEV_QUALIFIER_DESC, 77*91f16700Schasinglulu USB_DESC_TYPE_DEVICE_QUALIFIER, 78*91f16700Schasinglulu 0x00, 79*91f16700Schasinglulu 0x02, 80*91f16700Schasinglulu 0x00, 81*91f16700Schasinglulu 0x00, 82*91f16700Schasinglulu 0x00, 83*91f16700Schasinglulu 0x40, 84*91f16700Schasinglulu 0x01, 85*91f16700Schasinglulu 0x00, 86*91f16700Schasinglulu }; 87*91f16700Schasinglulu 88*91f16700Schasinglulu /* USB serial number: build dynamically */ 89*91f16700Schasinglulu static uint8_t usb_stm32mp1_serial[USB_SIZ_STRING_SERIAL + 1]; 90*91f16700Schasinglulu 91*91f16700Schasinglulu /* USB DFU device Configuration Descriptor */ 92*91f16700Schasinglulu static const uint8_t usb_stm32mp1_config_desc[USB_DFU_CONFIG_DESC_SIZ] = { 93*91f16700Schasinglulu 0x09, /* bLength: Configuration Descriptor size */ 94*91f16700Schasinglulu USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ 95*91f16700Schasinglulu USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 96*91f16700Schasinglulu 0x00, 97*91f16700Schasinglulu 0x01, /* bNumInterfaces: 1 interface */ 98*91f16700Schasinglulu 0x01, /* bConfigurationValue: Configuration value */ 99*91f16700Schasinglulu 0x02, /* iConfiguration: Index of string descriptor for configuration */ 100*91f16700Schasinglulu 0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */ 101*91f16700Schasinglulu 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ 102*91f16700Schasinglulu 103*91f16700Schasinglulu /* Descriptor of DFU interface 0 Alternate setting 0..N */ 104*91f16700Schasinglulu USBD_DFU_IF_DESC(0), 105*91f16700Schasinglulu USBD_DFU_IF_DESC(1), 106*91f16700Schasinglulu #if USB_DFU_ITF_NUM > 2 107*91f16700Schasinglulu USBD_DFU_IF_DESC(2), 108*91f16700Schasinglulu #endif 109*91f16700Schasinglulu #if USB_DFU_ITF_NUM > 3 110*91f16700Schasinglulu USBD_DFU_IF_DESC(3), 111*91f16700Schasinglulu #endif 112*91f16700Schasinglulu #if USB_DFU_ITF_NUM > 4 113*91f16700Schasinglulu USBD_DFU_IF_DESC(4), 114*91f16700Schasinglulu #endif 115*91f16700Schasinglulu #if USB_DFU_ITF_NUM > 5 116*91f16700Schasinglulu USBD_DFU_IF_DESC(5), 117*91f16700Schasinglulu #endif 118*91f16700Schasinglulu /* DFU Functional Descriptor */ 119*91f16700Schasinglulu 0x09, /* blength = 9 Bytes */ 120*91f16700Schasinglulu DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */ 121*91f16700Schasinglulu DFU_BM_ATTRIBUTE, /* bmAttribute for DFU */ 122*91f16700Schasinglulu 0xFF, /* DetachTimeOut = 255 ms */ 123*91f16700Schasinglulu 0x00, 124*91f16700Schasinglulu TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */ 125*91f16700Schasinglulu ((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion */ 126*91f16700Schasinglulu ((USB_DFU_VERSION >> 8) & 0xFF) 127*91f16700Schasinglulu }; 128*91f16700Schasinglulu 129*91f16700Schasinglulu /* The user strings: one by alternate as defined in USBD_DFU_IF_DESC */ 130*91f16700Schasinglulu #if STM32MP13 131*91f16700Schasinglulu const char *const if_desc_string[USB_DFU_ITF_NUM] = { 132*91f16700Schasinglulu "@SSBL /0x03/1*16Me", 133*91f16700Schasinglulu "@virtual /0xF1/1*512Ba" 134*91f16700Schasinglulu }; 135*91f16700Schasinglulu #endif 136*91f16700Schasinglulu #if STM32MP15 137*91f16700Schasinglulu const char *const if_desc_string[USB_DFU_ITF_NUM] = { 138*91f16700Schasinglulu "@Partition0 /0x00/1*256Ke", 139*91f16700Schasinglulu "@FSBL /0x01/1*1Me", 140*91f16700Schasinglulu "@Partition2 /0x02/1*1Me", 141*91f16700Schasinglulu "@Partition3 /0x03/1*16Me", 142*91f16700Schasinglulu "@Partition4 /0x04/1*16Me", 143*91f16700Schasinglulu "@virtual /0xF1/1*512Ba" 144*91f16700Schasinglulu }; 145*91f16700Schasinglulu #endif 146*91f16700Schasinglulu 147*91f16700Schasinglulu /* Buffer to build the unicode string provided to USB device stack */ 148*91f16700Schasinglulu static uint8_t usb_str_dec[USBD_MAX_STR_DESC_SIZ]; 149*91f16700Schasinglulu 150*91f16700Schasinglulu /* 151*91f16700Schasinglulu * Convert Ascii string into unicode one 152*91f16700Schasinglulu * desc : descriptor buffer 153*91f16700Schasinglulu * unicode : Formatted string buffer (unicode) 154*91f16700Schasinglulu * len : descriptor length 155*91f16700Schasinglulu */ 156*91f16700Schasinglulu static void stm32mp1_get_string(const char *desc, uint8_t *unicode, uint16_t *len) 157*91f16700Schasinglulu { 158*91f16700Schasinglulu uint8_t idx = 0U; 159*91f16700Schasinglulu 160*91f16700Schasinglulu if (desc == NULL) { 161*91f16700Schasinglulu return; 162*91f16700Schasinglulu } 163*91f16700Schasinglulu 164*91f16700Schasinglulu *len = strlen(desc) * 2U + 2U; 165*91f16700Schasinglulu unicode[idx++] = *len; 166*91f16700Schasinglulu unicode[idx++] = USB_DESC_TYPE_STRING; 167*91f16700Schasinglulu 168*91f16700Schasinglulu while (*desc != '\0') { 169*91f16700Schasinglulu unicode[idx++] = *desc++; 170*91f16700Schasinglulu unicode[idx++] = 0x00U; 171*91f16700Schasinglulu } 172*91f16700Schasinglulu } 173*91f16700Schasinglulu 174*91f16700Schasinglulu /* 175*91f16700Schasinglulu * Create the serial number string descriptor 176*91f16700Schasinglulu */ 177*91f16700Schasinglulu static void update_serial_num_string(void) 178*91f16700Schasinglulu { 179*91f16700Schasinglulu uint8_t i; 180*91f16700Schasinglulu char serial_string[SIZ_STRING_SERIAL + 2U]; 181*91f16700Schasinglulu /* serial number is set to 0 */ 182*91f16700Schasinglulu uint32_t deviceserial[UID_WORD_NB] = {0U, 0U, 0U}; 183*91f16700Schasinglulu uint32_t otp; 184*91f16700Schasinglulu uint32_t len; 185*91f16700Schasinglulu uint16_t length; 186*91f16700Schasinglulu 187*91f16700Schasinglulu if (stm32_get_otp_index(UID_OTP, &otp, &len) != 0) { 188*91f16700Schasinglulu ERROR("BSEC: Get UID_OTP number Error\n"); 189*91f16700Schasinglulu return; 190*91f16700Schasinglulu } 191*91f16700Schasinglulu 192*91f16700Schasinglulu if ((len / __WORD_BIT) != UID_WORD_NB) { 193*91f16700Schasinglulu ERROR("BSEC: Get UID_OTP length Error\n"); 194*91f16700Schasinglulu return; 195*91f16700Schasinglulu } 196*91f16700Schasinglulu 197*91f16700Schasinglulu for (i = 0; i < UID_WORD_NB; i++) { 198*91f16700Schasinglulu if (bsec_shadow_read_otp(&deviceserial[i], i + otp) != 199*91f16700Schasinglulu BSEC_OK) { 200*91f16700Schasinglulu ERROR("BSEC: UID%d Error\n", i); 201*91f16700Schasinglulu return; 202*91f16700Schasinglulu } 203*91f16700Schasinglulu } 204*91f16700Schasinglulu /* build serial number with OTP value as in ROM code */ 205*91f16700Schasinglulu snprintf(serial_string, sizeof(serial_string), "%08X%08X%08X", 206*91f16700Schasinglulu deviceserial[0], deviceserial[1], deviceserial[2]); 207*91f16700Schasinglulu 208*91f16700Schasinglulu length = USB_SIZ_STRING_SERIAL; 209*91f16700Schasinglulu stm32mp1_get_string(serial_string, usb_stm32mp1_serial, &length); 210*91f16700Schasinglulu } 211*91f16700Schasinglulu 212*91f16700Schasinglulu /* 213*91f16700Schasinglulu * Return Device Qualifier descriptor 214*91f16700Schasinglulu * length : pointer data length 215*91f16700Schasinglulu * return : pointer to descriptor buffer 216*91f16700Schasinglulu */ 217*91f16700Schasinglulu static uint8_t *stm32mp1_get_qualifier_desc(uint16_t *length) 218*91f16700Schasinglulu { 219*91f16700Schasinglulu *length = sizeof(usbd_stm32mp1_qualifier_desc); 220*91f16700Schasinglulu 221*91f16700Schasinglulu return (uint8_t *)usbd_stm32mp1_qualifier_desc; 222*91f16700Schasinglulu } 223*91f16700Schasinglulu 224*91f16700Schasinglulu /* 225*91f16700Schasinglulu * Return configuration descriptor 226*91f16700Schasinglulu * length : pointer data length 227*91f16700Schasinglulu * return : pointer to descriptor buffer 228*91f16700Schasinglulu */ 229*91f16700Schasinglulu static uint8_t *stm32mp1_get_config_desc(uint16_t *length) 230*91f16700Schasinglulu { 231*91f16700Schasinglulu *length = sizeof(usb_stm32mp1_config_desc); 232*91f16700Schasinglulu 233*91f16700Schasinglulu return (uint8_t *)usb_stm32mp1_config_desc; 234*91f16700Schasinglulu } 235*91f16700Schasinglulu 236*91f16700Schasinglulu /* 237*91f16700Schasinglulu * Returns the device descriptor. 238*91f16700Schasinglulu * length: Pointer to data length variable 239*91f16700Schasinglulu * return : Pointer to descriptor buffer 240*91f16700Schasinglulu */ 241*91f16700Schasinglulu static uint8_t *stm32mp1_device_desc(uint16_t *length) 242*91f16700Schasinglulu { 243*91f16700Schasinglulu *length = sizeof(usb_stm32mp1_desc); 244*91f16700Schasinglulu 245*91f16700Schasinglulu return (uint8_t *)usb_stm32mp1_desc; 246*91f16700Schasinglulu } 247*91f16700Schasinglulu 248*91f16700Schasinglulu /* 249*91f16700Schasinglulu * Returns the LangID string descriptor. 250*91f16700Schasinglulu * length: Pointer to data length variable 251*91f16700Schasinglulu * return : Pointer to descriptor buffer 252*91f16700Schasinglulu */ 253*91f16700Schasinglulu static uint8_t *stm32mp1_lang_id_desc(uint16_t *length) 254*91f16700Schasinglulu { 255*91f16700Schasinglulu *length = sizeof(usb_stm32mp1_lang_id_desc); 256*91f16700Schasinglulu 257*91f16700Schasinglulu return (uint8_t *)usb_stm32mp1_lang_id_desc; 258*91f16700Schasinglulu } 259*91f16700Schasinglulu 260*91f16700Schasinglulu /* 261*91f16700Schasinglulu * Returns the product string descriptor. 262*91f16700Schasinglulu * length: Pointer to data length variable 263*91f16700Schasinglulu * return : Pointer to descriptor buffer 264*91f16700Schasinglulu */ 265*91f16700Schasinglulu static uint8_t *stm32mp1_product_desc(uint16_t *length) 266*91f16700Schasinglulu { 267*91f16700Schasinglulu char name[STM32_SOC_NAME_SIZE]; 268*91f16700Schasinglulu char product[128]; 269*91f16700Schasinglulu uint32_t chip_id; 270*91f16700Schasinglulu uint32_t chip_version; 271*91f16700Schasinglulu 272*91f16700Schasinglulu stm32mp_get_soc_name(name); 273*91f16700Schasinglulu chip_id = stm32mp_get_chip_dev_id(); 274*91f16700Schasinglulu chip_version = stm32mp_get_chip_version(); 275*91f16700Schasinglulu 276*91f16700Schasinglulu snprintf(product, sizeof(product), 277*91f16700Schasinglulu "DFU @Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,", 278*91f16700Schasinglulu chip_id, chip_version, name); 279*91f16700Schasinglulu 280*91f16700Schasinglulu stm32mp1_get_string(product, usb_str_dec, length); 281*91f16700Schasinglulu 282*91f16700Schasinglulu return usb_str_dec; 283*91f16700Schasinglulu } 284*91f16700Schasinglulu 285*91f16700Schasinglulu /* 286*91f16700Schasinglulu * Returns the manufacturer string descriptor. 287*91f16700Schasinglulu * length: Pointer to data length variable 288*91f16700Schasinglulu * return : Pointer to descriptor buffer 289*91f16700Schasinglulu */ 290*91f16700Schasinglulu static uint8_t *stm32mp1_manufacturer_desc(uint16_t *length) 291*91f16700Schasinglulu { 292*91f16700Schasinglulu stm32mp1_get_string(USBD_MANUFACTURER_STRING, usb_str_dec, length); 293*91f16700Schasinglulu 294*91f16700Schasinglulu return usb_str_dec; 295*91f16700Schasinglulu } 296*91f16700Schasinglulu 297*91f16700Schasinglulu /* 298*91f16700Schasinglulu * Returns the serial number string descriptor. 299*91f16700Schasinglulu * length: Pointer to data length variable 300*91f16700Schasinglulu * return : Pointer to descriptor buffer 301*91f16700Schasinglulu */ 302*91f16700Schasinglulu static uint8_t *stm32mp1_serial_desc(uint16_t *length) 303*91f16700Schasinglulu { 304*91f16700Schasinglulu *length = USB_SIZ_STRING_SERIAL; 305*91f16700Schasinglulu 306*91f16700Schasinglulu return (uint8_t *)usb_stm32mp1_serial; 307*91f16700Schasinglulu } 308*91f16700Schasinglulu 309*91f16700Schasinglulu /* 310*91f16700Schasinglulu * Returns the configuration string descriptor. 311*91f16700Schasinglulu * length: Pointer to data length variable 312*91f16700Schasinglulu * return : Pointer to descriptor buffer 313*91f16700Schasinglulu */ 314*91f16700Schasinglulu static uint8_t *stm32mp1_config_desc(uint16_t *length) 315*91f16700Schasinglulu { 316*91f16700Schasinglulu stm32mp1_get_string(USBD_CONFIGURATION_STRING, usb_str_dec, length); 317*91f16700Schasinglulu 318*91f16700Schasinglulu return usb_str_dec; 319*91f16700Schasinglulu } 320*91f16700Schasinglulu 321*91f16700Schasinglulu /* 322*91f16700Schasinglulu * Returns the interface string descriptor. 323*91f16700Schasinglulu * length : Pointer to data length variable 324*91f16700Schasinglulu * return : Pointer to descriptor buffer 325*91f16700Schasinglulu */ 326*91f16700Schasinglulu static uint8_t *stm32mp1_interface_desc(uint16_t *length) 327*91f16700Schasinglulu { 328*91f16700Schasinglulu stm32mp1_get_string(USBD_INTERFACE_STRING, usb_str_dec, length); 329*91f16700Schasinglulu 330*91f16700Schasinglulu return usb_str_dec; 331*91f16700Schasinglulu } 332*91f16700Schasinglulu 333*91f16700Schasinglulu /* 334*91f16700Schasinglulu * Manages the transfer of memory interfaces string descriptors. 335*91f16700Schasinglulu * index: descriptor index 336*91f16700Schasinglulu * length : pointer data length 337*91f16700Schasinglulu * return : pointer to the descriptor table or NULL if the descriptor 338*91f16700Schasinglulu * is not supported. 339*91f16700Schasinglulu */ 340*91f16700Schasinglulu static uint8_t *stm32mp1_get_usr_desc(uint8_t index, uint16_t *length) 341*91f16700Schasinglulu { 342*91f16700Schasinglulu if (index >= ARRAY_SIZE(if_desc_string)) { 343*91f16700Schasinglulu return NULL; 344*91f16700Schasinglulu } 345*91f16700Schasinglulu 346*91f16700Schasinglulu stm32mp1_get_string(if_desc_string[index], usb_str_dec, length); 347*91f16700Schasinglulu 348*91f16700Schasinglulu return usb_str_dec; 349*91f16700Schasinglulu } 350*91f16700Schasinglulu 351*91f16700Schasinglulu static const struct usb_desc dfu_desc = { 352*91f16700Schasinglulu .get_device_desc = stm32mp1_device_desc, 353*91f16700Schasinglulu .get_lang_id_desc = stm32mp1_lang_id_desc, 354*91f16700Schasinglulu .get_manufacturer_desc = stm32mp1_manufacturer_desc, 355*91f16700Schasinglulu .get_product_desc = stm32mp1_product_desc, 356*91f16700Schasinglulu .get_configuration_desc = stm32mp1_config_desc, 357*91f16700Schasinglulu .get_serial_desc = stm32mp1_serial_desc, 358*91f16700Schasinglulu .get_interface_desc = stm32mp1_interface_desc, 359*91f16700Schasinglulu .get_usr_desc = stm32mp1_get_usr_desc, 360*91f16700Schasinglulu .get_config_desc = stm32mp1_get_config_desc, 361*91f16700Schasinglulu .get_device_qualifier_desc = stm32mp1_get_qualifier_desc, 362*91f16700Schasinglulu /* only HS is supported, as ROM code */ 363*91f16700Schasinglulu .get_other_speed_config_desc = NULL, 364*91f16700Schasinglulu }; 365*91f16700Schasinglulu 366*91f16700Schasinglulu static struct usb_handle usb_core_handle; 367*91f16700Schasinglulu static struct pcd_handle pcd_handle; 368*91f16700Schasinglulu 369*91f16700Schasinglulu struct usb_handle *usb_dfu_plat_init(void) 370*91f16700Schasinglulu { 371*91f16700Schasinglulu /* Prepare USB Driver */ 372*91f16700Schasinglulu pcd_handle.in_ep[0].maxpacket = USB_MAX_EP0_SIZE; 373*91f16700Schasinglulu pcd_handle.out_ep[0].maxpacket = USB_MAX_EP0_SIZE; 374*91f16700Schasinglulu stm32mp1_usb_init_driver(&usb_core_handle, &pcd_handle, 375*91f16700Schasinglulu (uint32_t *)USB_OTG_BASE); 376*91f16700Schasinglulu 377*91f16700Schasinglulu #if STM32MP15 378*91f16700Schasinglulu /* STM32MP15 = keep the configuration from ROM code */ 379*91f16700Schasinglulu usb_core_handle.ep0_state = USBD_EP0_DATA_IN; 380*91f16700Schasinglulu usb_core_handle.dev_state = USBD_STATE_CONFIGURED; 381*91f16700Schasinglulu #endif 382*91f16700Schasinglulu 383*91f16700Schasinglulu /* Update the serial number string descriptor from the unique ID */ 384*91f16700Schasinglulu update_serial_num_string(); 385*91f16700Schasinglulu 386*91f16700Schasinglulu /* Prepare USB DFU stack */ 387*91f16700Schasinglulu usb_dfu_register(&usb_core_handle, &usb_dfu_handle); 388*91f16700Schasinglulu 389*91f16700Schasinglulu /* Register DFU descriptor in USB stack */ 390*91f16700Schasinglulu register_platform(&usb_core_handle, &dfu_desc); 391*91f16700Schasinglulu 392*91f16700Schasinglulu return &usb_core_handle; 393*91f16700Schasinglulu } 394*91f16700Schasinglulu 395*91f16700Schasinglulu /* Link between USB alternate and STM32CubeProgramer phase */ 396*91f16700Schasinglulu uint8_t usb_dfu_get_phase(uint8_t alt) 397*91f16700Schasinglulu { 398*91f16700Schasinglulu uint8_t ret; 399*91f16700Schasinglulu 400*91f16700Schasinglulu switch (alt) { 401*91f16700Schasinglulu #if STM32MP13 402*91f16700Schasinglulu case 0: 403*91f16700Schasinglulu ret = PHASE_SSBL; 404*91f16700Schasinglulu break; 405*91f16700Schasinglulu case 1: 406*91f16700Schasinglulu ret = PHASE_CMD; 407*91f16700Schasinglulu break; 408*91f16700Schasinglulu #endif 409*91f16700Schasinglulu #if STM32MP15 410*91f16700Schasinglulu case 3: 411*91f16700Schasinglulu ret = PHASE_SSBL; 412*91f16700Schasinglulu break; 413*91f16700Schasinglulu case 5: 414*91f16700Schasinglulu ret = PHASE_CMD; 415*91f16700Schasinglulu break; 416*91f16700Schasinglulu #endif 417*91f16700Schasinglulu default: 418*91f16700Schasinglulu ret = PHASE_RESET; 419*91f16700Schasinglulu break; 420*91f16700Schasinglulu } 421*91f16700Schasinglulu 422*91f16700Schasinglulu return ret; 423*91f16700Schasinglulu } 424