Auto updated submodule references [07-02-2025]
[betaflight.git] / src / platform / APM32 / usb / msc / usbd_msc_descriptor.c
blob48059a76885a4e72566a6f4d0476c783be8e0435
1 /**
2 * @file usbd_descriptor.c
4 * @brief USB device descriptor configuration
6 * @attention
8 * Copyright (C) 2023 Geehy Semiconductor
10 * You may not use this file except in compliance with the
11 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
13 * The program is only for reference, which is distributed in the hope
14 * that it will be useful and instructional for customers to develop
15 * their software. Unless required by applicable law or agreed to in
16 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
17 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
19 * and limitations under the License.
22 /* Includes ***************************************************************/
23 #include "usbd_msc_descriptor.h"
25 /* Private includes *******************************************************/
26 #include "usbd_msc.h"
27 #include "platform.h"
29 #include <string.h>
31 /* Private macro **********************************************************/
32 #define USBD_GEEHY_VID 0x314B
33 #define USBD_FS_PID 0x5720
34 #define USBD_LANGID_STR 0x0409
35 #define USBD_MANUFACTURER_STR "Geehy"
36 #define USBD_PRODUCT_HS_STR "Betaflight FC Mass Storage (HS Mode)"
37 #define USBD_PRODUCT_FS_STR "Betaflight FC Mass Storage (FS Mode)"
38 #define USBD_CONFIGURATION_HS_STR "MSC Config"
39 #define USBD_CONFIGURATION_FS_STR "MSC Config"
40 #define USBD_INTERFACE_HS_STR "MSC Interface"
41 #define USBD_INTERFACE_FS_STR "MSC Interface"
43 /* Private function prototypes ********************************************/
44 static USBD_DESC_INFO_T USBD_MSC_DeviceDescHandler(uint8_t usbSpeed);
45 static USBD_DESC_INFO_T USBD_MSC_ConfigDescHandler(uint8_t usbSpeed);
46 static USBD_DESC_INFO_T USBD_MSC_ConfigStrDescHandler(uint8_t usbSpeed);
47 static USBD_DESC_INFO_T USBD_MSC_InterfaceStrDescHandler(uint8_t usbSpeed);
48 static USBD_DESC_INFO_T USBD_MSC_LangIdStrDescHandler(uint8_t usbSpeed);
49 static USBD_DESC_INFO_T USBD_MSC_ManufacturerStrDescHandler(uint8_t usbSpeed);
50 static USBD_DESC_INFO_T USBD_MSC_ProductStrDescHandler(uint8_t usbSpeed);
51 static USBD_DESC_INFO_T USBD_MSC_SerialStrDescHandler(uint8_t usbSpeed);
52 #if USBD_SUP_LPM
53 static USBD_DESC_INFO_T USBD_MSC_BosDescHandler(uint8_t usbSpeed);
54 #endif
55 static USBD_DESC_INFO_T USBD_OtherSpeedConfigDescHandler(uint8_t usbSpeed);
56 static USBD_DESC_INFO_T USBD_DevQualifierDescHandler(uint8_t usbSpeed);
58 static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len);
59 static void Get_SerialNum(void);
61 /* Private typedef ********************************************************/
63 /* USB device descripotr handler */
64 USBD_DESC_T USBD_DESC_MSC =
66 "MSC Descriptor",
67 USBD_MSC_DeviceDescHandler,
68 USBD_MSC_ConfigDescHandler,
69 USBD_MSC_ConfigStrDescHandler,
70 USBD_MSC_InterfaceStrDescHandler,
71 USBD_MSC_LangIdStrDescHandler,
72 USBD_MSC_ManufacturerStrDescHandler,
73 USBD_MSC_ProductStrDescHandler,
74 USBD_MSC_SerialStrDescHandler,
75 #if USBD_SUP_LPM
76 USBD_MSC_BosDescHandler,
77 #endif
78 NULL,
79 USBD_OtherSpeedConfigDescHandler,
80 USBD_DevQualifierDescHandler,
83 /* Private variables ******************************************************/
85 /**
86 * @brief Device descriptor
88 static uint8_t USBD_DeviceDesc[USBD_DEVICE_DESCRIPTOR_SIZE] =
90 /* bLength */
91 0x12,
92 /* bDescriptorType */
93 USBD_DESC_DEVICE,
94 /* bcdUSB */
95 #if USBD_SUP_LPM
96 0x01, /*<! For resume test of USBCV3.0. Only support LPM USB device */
97 #else
98 0x00,
99 #endif
100 0x02,
101 /* bDeviceClass */
102 0x00,
103 /* bDeviceSubClass */
104 0x00,
105 /* bDeviceProtocol */
106 0x00,
107 /* bMaxPacketSize */
108 USBD_EP0_PACKET_MAX_SIZE,
109 /* idVendor */
110 USBD_GEEHY_VID & 0xFF, USBD_GEEHY_VID >> 8,
111 /* idProduct */
112 USBD_FS_PID & 0xFF, USBD_FS_PID >> 8,
113 /* bcdDevice = 2.00 */
114 0x00, 0x02,
115 /* Index of string descriptor describing manufacturer */
116 USBD_DESC_STR_MFC,
117 /* Index of string descriptor describing product */
118 USBD_DESC_STR_PRODUCT,
119 /* Index of string descriptor describing the device serial number */
120 USBD_DESC_STR_SERIAL,
121 /* bNumConfigurations */
122 USBD_SUP_CONFIGURATION_MAX_NUM,
126 * @brief Configuration descriptor
128 static uint8_t USBD_ConfigDesc[USBD_CONFIG_DESCRIPTOR_SIZE] =
130 /* bLength */
131 0x09,
132 /* bDescriptorType */
133 USBD_DESC_CONFIGURATION,
134 /* wTotalLength */
135 USBD_CONFIG_DESCRIPTOR_SIZE & 0xFF,
136 USBD_CONFIG_DESCRIPTOR_SIZE >> 8,
138 /* bNumInterfaces */
139 0x01,
140 /* bConfigurationValue */
141 0x01,
142 /* iConfiguration */
143 0x01,
144 /* bmAttributes */
145 #if USBD_SUP_SELF_PWR
146 0xC0,
147 #else
148 0x80,
149 #endif
150 /* MaxPower */
151 0x32,
153 /* Mass Storage interface */
154 /* bLength */
155 0x09,
156 /* bDescriptorType */
157 USBD_DESC_INTERFACE,
158 /* bInterfaceNumber */
159 0x00,
160 /* bAlternateSetting */
161 0x00,
162 /* bNumEndpoints */
163 0x02,
164 /* bInterfaceClass */
165 USBD_MSC_ITF_CLASS_ID,
166 /* bInterfaceSubClass */
167 USBD_MSC_ITF_SUB_CLASS,
168 /* bInterfaceProtocol */
169 USBD_MSC_ITF_PROTOCOL,
170 /* iInterface */
171 0x05,
173 /* Mass Storage Endpoints */
174 /* bLength */
175 0x07,
176 /* bDescriptorType: Endpoint */
177 USBD_DESC_ENDPOINT,
178 /* bEndpointAddress */
179 USBD_MSC_IN_EP_ADDR,
180 /* bmAttributes */
181 0x02,
182 /* wMaxPacketSize: */
183 USBD_MSC_FS_MP_SIZE & 0xFF,
184 USBD_MSC_FS_MP_SIZE >> 8,
185 /* bInterval: */
186 0x00,
188 /* bLength */
189 0x07,
190 /* bDescriptorType: Endpoint */
191 USBD_DESC_ENDPOINT,
192 /* bEndpointAddress */
193 USBD_MSC_OUT_EP_ADDR,
194 /* bmAttributes */
195 0x02,
196 /* wMaxPacketSize: */
197 USBD_MSC_FS_MP_SIZE & 0xFF,
198 USBD_MSC_FS_MP_SIZE >> 8,
199 /* bInterval: */
200 0x00,
204 * @brief Other speed configuration descriptor
206 static uint8_t USBD_OtherSpeedCfgDesc[USBD_CONFIG_DESCRIPTOR_SIZE] =
208 /* bLength */
209 0x09,
210 /* bDescriptorType */
211 USBD_DESC_OTHER_SPEED,
212 /* wTotalLength */
213 USBD_CONFIG_DESCRIPTOR_SIZE & 0xFF,
214 USBD_CONFIG_DESCRIPTOR_SIZE >> 8,
216 /* bNumInterfaces */
217 0x01,
218 /* bConfigurationValue */
219 0x01,
220 /* iConfiguration */
221 0x01,
222 /* bmAttributes */
223 #if USBD_SUP_SELF_PWR
224 0xC0,
225 #else
226 0x80,
227 #endif
228 /* MaxPower */
229 0x32,
231 /* Mass Storage interface */
232 /* bLength */
233 0x09,
234 /* bDescriptorType */
235 USBD_DESC_INTERFACE,
236 /* bInterfaceNumber */
237 0x00,
238 /* bAlternateSetting */
239 0x00,
240 /* bNumEndpoints */
241 0x02,
242 /* bInterfaceClass */
243 USBD_MSC_ITF_CLASS_ID,
244 /* bInterfaceSubClass */
245 USBD_MSC_ITF_SUB_CLASS,
246 /* bInterfaceProtocol */
247 USBD_MSC_ITF_PROTOCOL,
248 /* iInterface */
249 0x05,
251 /* Mass Storage Endpoints */
252 /* bLength */
253 0x07,
254 /* bDescriptorType: Endpoint */
255 USBD_DESC_ENDPOINT,
256 /* bEndpointAddress */
257 USBD_MSC_IN_EP_ADDR,
258 /* bmAttributes */
259 0x02,
260 /* wMaxPacketSize: */
261 USBD_MSC_FS_MP_SIZE & 0xFF,
262 USBD_MSC_FS_MP_SIZE >> 8,
263 /* bInterval: */
264 0x00,
266 /* bLength */
267 0x07,
268 /* bDescriptorType: Endpoint */
269 USBD_DESC_ENDPOINT,
270 /* bEndpointAddress */
271 USBD_MSC_OUT_EP_ADDR,
272 /* bmAttributes */
273 0x02,
274 /* wMaxPacketSize: */
275 USBD_MSC_FS_MP_SIZE & 0xFF,
276 USBD_MSC_FS_MP_SIZE >> 8,
277 /* bInterval: */
278 0x00,
281 #if USBD_SUP_LPM
283 * @brief BOS descriptor
285 static uint8_t USBD_BosDesc[USBD_BOS_DESCRIPTOR_SIZE] =
287 /* bLength */
288 0x05,
289 /* bDescriptorType */
290 USBD_DESC_BOS,
291 /* wtotalLength */
292 0x0C, 0x00,
293 /* bNumDeviceCaps */
294 0x01,
296 /* Device Capability */
297 /* bLength */
298 0x07,
299 /* bDescriptorType */
300 USBD_DEVICE_CAPABILITY_TYPE,
301 /* bDevCapabilityType */
302 USBD_20_EXTENSION_TYPE,
303 /* bmAttributes */
304 0x02, 0x00, 0x00, 0x00,
306 #endif
309 * @brief Serial string descriptor
311 static uint8_t USBD_SerialStrDesc[USBD_SERIAL_STRING_SIZE] =
313 /* bLength */
314 USBD_SERIAL_STRING_SIZE,
315 /* bDescriptorType */
316 USBD_DESC_STRING,
320 * @brief Language ID string descriptor
322 static uint8_t USBD_LandIDStrDesc[USBD_LANGID_STRING_SIZE] =
324 /* bLength */
325 USBD_LANGID_STRING_SIZE,
326 /* bDescriptorType */
327 USBD_DESC_STRING,
328 USBD_LANGID_STR & 0xFF, USBD_LANGID_STR >> 8
332 * @brief Device qualifier descriptor
334 static uint8_t USBD_DevQualifierDesc[USBD_DEVICE_QUALIFIER_DESCRIPTOR_SIZE] =
336 /* bLength */
337 USBD_DEVICE_QUALIFIER_DESCRIPTOR_SIZE,
338 /* bDescriptorType */
339 USBD_DESC_DEVICE_QUALIFIER,
340 0x00,
341 0x02,
342 0x00,
343 0x00,
344 0x00,
345 USBD_MSC_FS_MP_SIZE, /* In FS device*/
346 0x01,
347 0x00,
350 /* Private functions ******************************************************/
353 * @brief USB device convert ascii string descriptor to unicode format
355 * @param desc : descriptor string
357 * @retval usb descriptor information
359 static USBD_DESC_INFO_T USBD_DESC_Ascii2Unicode(uint8_t* desc)
361 USBD_DESC_INFO_T descInfo;
362 uint8_t* buffer;
363 uint8_t str[USBD_SUP_STR_DESC_MAX_NUM];
365 uint8_t* unicode = str;
366 uint16_t length = 0;
367 __IO uint8_t index = 0;
369 if (desc == NULL)
371 descInfo.desc = NULL;
372 descInfo.size = 0;
374 else
376 buffer = desc;
377 length = (strlen((char*)buffer) * 2) + 2;
378 /* Get unicode descriptor */
379 unicode[index] = length;
381 index++;
382 unicode[index] = USBD_DESC_STRING;
383 index++;
385 while (*buffer != '\0')
387 unicode[index] = *buffer;
388 buffer++;
389 index++;
391 unicode[index] = 0x00;
392 index++;
396 descInfo.desc = unicode;
397 descInfo.size = length;
399 return descInfo;
403 * @brief USB device FS device descriptor
405 * @param usbSpeed : usb speed
407 * @retval usb descriptor information
409 static USBD_DESC_INFO_T USBD_MSC_DeviceDescHandler(uint8_t usbSpeed)
411 USBD_DESC_INFO_T descInfo;
413 UNUSED(usbSpeed);
415 descInfo.desc = USBD_DeviceDesc;
416 descInfo.size = sizeof(USBD_DeviceDesc);
418 return descInfo;
422 * @brief USB device FS configuration descriptor
424 * @param usbSpeed : usb speed
426 * @retval usb descriptor information
428 static USBD_DESC_INFO_T USBD_MSC_ConfigDescHandler(uint8_t usbSpeed)
430 USBD_DESC_INFO_T descInfo;
432 UNUSED(usbSpeed);
434 descInfo.desc = USBD_ConfigDesc;
435 descInfo.size = sizeof(USBD_ConfigDesc);
437 return descInfo;
440 #if USBD_SUP_LPM
442 * @brief USB device FS BOS descriptor
444 * @param usbSpeed : usb speed
446 * @retval usb descriptor information
448 static USBD_DESC_INFO_T USBD_MSC_BosDescHandler(uint8_t usbSpeed)
450 USBD_DESC_INFO_T descInfo;
452 UNUSED(usbSpeed);
454 descInfo.desc = USBD_BosDesc;
455 descInfo.size = sizeof(USBD_BosDesc);
457 return descInfo;
459 #endif
462 * @brief USB device FS configuration string descriptor
464 * @param usbSpeed : usb speed
466 * @retval usb descriptor information
468 static USBD_DESC_INFO_T USBD_MSC_ConfigStrDescHandler(uint8_t usbSpeed)
470 USBD_DESC_INFO_T descInfo;
472 UNUSED(usbSpeed);
474 if (usbSpeed == USBD_SPEED_HS)
476 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_CONFIGURATION_HS_STR);
478 else
480 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_CONFIGURATION_FS_STR);
483 return descInfo;
487 * @brief USB device FS interface string descriptor
489 * @param usbSpeed : usb speed
491 * @retval usb descriptor information
493 static USBD_DESC_INFO_T USBD_MSC_InterfaceStrDescHandler(uint8_t usbSpeed)
495 USBD_DESC_INFO_T descInfo;
497 if (usbSpeed == USBD_SPEED_HS)
499 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_INTERFACE_HS_STR);
501 else
503 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_INTERFACE_FS_STR);
506 return descInfo;
510 * @brief USB device FS LANG ID string descriptor
512 * @param usbSpeed : usb speed
514 * @retval usb descriptor information
516 static USBD_DESC_INFO_T USBD_MSC_LangIdStrDescHandler(uint8_t usbSpeed)
518 USBD_DESC_INFO_T descInfo;
520 UNUSED(usbSpeed);
522 descInfo.desc = USBD_LandIDStrDesc;
523 descInfo.size = sizeof(USBD_LandIDStrDesc);
525 return descInfo;
529 * @brief USB device FS manufacturer string descriptor
531 * @param usbSpeed : usb speed
533 * @retval usb descriptor information
535 static USBD_DESC_INFO_T USBD_MSC_ManufacturerStrDescHandler(uint8_t usbSpeed)
537 USBD_DESC_INFO_T descInfo;
539 UNUSED(usbSpeed);
541 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_MANUFACTURER_STR);
543 return descInfo;
547 * @brief USB device FS product string descriptor
549 * @param usbSpeed : usb speed
551 * @retval usb descriptor information
553 static USBD_DESC_INFO_T USBD_MSC_ProductStrDescHandler(uint8_t usbSpeed)
555 USBD_DESC_INFO_T descInfo;
557 if (usbSpeed == USBD_SPEED_HS)
559 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_PRODUCT_HS_STR);
561 else
563 descInfo = USBD_DESC_Ascii2Unicode((uint8_t*)USBD_PRODUCT_FS_STR);
566 return descInfo;
570 * @brief USB device FS serial string descriptor
572 * @param usbSpeed : usb speed
574 * @retval usb descriptor information
576 static USBD_DESC_INFO_T USBD_MSC_SerialStrDescHandler(uint8_t usbSpeed)
578 USBD_DESC_INFO_T descInfo;
580 UNUSED(usbSpeed);
582 /* Update the serial number string descriptor with the data from the unique ID*/
583 Get_SerialNum();
585 descInfo.desc = USBD_SerialStrDesc;
586 descInfo.size = sizeof(USBD_SerialStrDesc);
588 return descInfo;
592 * @brief USB device other speed configuration descriptor
594 * @param usbSpeed : usb speed
596 * @retval usb descriptor information
598 static USBD_DESC_INFO_T USBD_OtherSpeedConfigDescHandler(uint8_t usbSpeed)
600 USBD_DESC_INFO_T descInfo;
602 UNUSED(usbSpeed);
604 /* Use FS configuration */
605 descInfo.desc = USBD_OtherSpeedCfgDesc;
606 descInfo.size = sizeof(USBD_OtherSpeedCfgDesc);
608 return descInfo;
612 * @brief USB device device qualifier descriptor
614 * @param usbSpeed : usb speed
616 * @retval usb descriptor information
618 static USBD_DESC_INFO_T USBD_DevQualifierDescHandler(uint8_t usbSpeed)
620 USBD_DESC_INFO_T descInfo;
622 UNUSED(usbSpeed);
624 descInfo.desc = USBD_DevQualifierDesc;
625 descInfo.size = sizeof(USBD_DevQualifierDesc);
627 return descInfo;
631 * @brief Create the serial number string descriptor
632 * @param None
633 * @retval None
635 static void Get_SerialNum(void)
637 uint32_t deviceserial0, deviceserial1, deviceserial2;
639 deviceserial0 = U_ID_0;
640 deviceserial1 = U_ID_1;
641 deviceserial2 = U_ID_2;
643 deviceserial0 += deviceserial2;
645 if (deviceserial0 != 0)
647 IntToUnicode (deviceserial0, &USBD_SerialStrDesc[2] ,8);
648 IntToUnicode (deviceserial1, &USBD_SerialStrDesc[18] ,4);
653 * @brief Convert Hex 32Bits value into char
654 * @param value: value to convert
655 * @param pbuf: pointer to the buffer
656 * @param len: buffer length
657 * @retval None
659 static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len)
661 uint8_t idx = 0;
663 for ( idx = 0; idx < len; idx ++)
665 if ( ((value >> 28)) < 0xA )
667 pbuf[ 2* idx] = (value >> 28) + '0';
669 else
671 pbuf[2* idx] = (value >> 28) + 'A' - 10;
674 value = value << 4;
676 pbuf[ 2* idx + 1] = 0;