Skip to content

Commit e7883fe

Browse files
committed
Add new Pybricks device class
Adds a new Pybricks device class and provides the correct descriptors so that Windows will use the WinUSB driver.
1 parent 2c5d111 commit e7883fe

File tree

6 files changed

+990
-2
lines changed

6 files changed

+990
-2
lines changed

bricks/_common/arm_none_eabi.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ endif
373373
SRC_STM32_USB_DEV += $(addprefix lib/pbio/drv/usb/stm32_usbd/,\
374374
usbd_conf.c \
375375
usbd_desc.c \
376+
usbd_pybricks.c \
376377
)
377378

378379
NXOS_SRC_C = $(addprefix lib/pbio/platform/nxt/nxos/,\

lib/pbio/drv/usb/stm32_usbd/usbd_conf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
#define USBD_MAX_NUM_CONFIGURATION 1
1111
#define USBD_MAX_STR_DESC_SIZ 0x100
1212
#define USBD_SELF_POWERED 1
13+
#define USBD_CLASS_BOS_ENABLED 1
1314

1415
#endif /* _USBD_CONF_H_ */

lib/pbio/drv/usb/stm32_usbd/usbd_desc.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
/* Includes ------------------------------------------------------------------*/
4646
#include "usbd_core.h"
4747
#include "usbd_conf.h"
48+
#include "usbd_pybricks.h"
4849

4950
/* Private typedef -----------------------------------------------------------*/
5051
/* Private define ------------------------------------------------------------*/
@@ -61,12 +62,18 @@
6162
#define DEVICE_ID3 (0x1FFF7A18)
6263

6364
#define USB_SIZ_STRING_SERIAL 0x1A
65+
#define USB_SIZ_BOS_DESC 33
6466

6567
/* USB Standard Device Descriptor */
6668
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
6769
0x12, /* bLength */
6870
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
71+
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
72+
0x01, /* bcdUSB */ /* changed to USB version 2.01
73+
in order to support BOS Desc */
74+
#else
6975
0x00, /* bcdUSB */
76+
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
7077
0x02,
7178
0x02, /* bDeviceClass */
7279
0x02, /* bDeviceSubClass */
@@ -84,6 +91,136 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
8491
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
8592
}; /* USB_DeviceDescriptor */
8693

94+
/** BOS descriptor. */
95+
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
96+
#if defined ( __ICCARM__ ) /* IAR Compiler */
97+
#pragma data_alignment=4
98+
#endif /* defined ( __ICCARM__ ) */
99+
__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
100+
{
101+
5, /* bLength */
102+
USB_DESC_TYPE_BOS, /* bDescriptorType = BOS */
103+
LOBYTE(USB_SIZ_BOS_DESC), /* wTotalLength */
104+
HIBYTE(USB_SIZ_BOS_DESC), /* wTotalLength */
105+
0x01, /* bNumDeviceCaps = 1 */
106+
107+
28, /* bLength */
108+
USB_DEVICE_CAPABITY_TYPE, /* bDescriptorType = Device Capability */
109+
0x05, /* bDevCapabilityType = Platform */
110+
0x00, /* bReserved */
111+
112+
/*
113+
* PlatformCapabilityUUID
114+
* Microsoft OS 2.0 descriptor platform capability ID
115+
* D8DD60DF-4589-4CC7-9CD2-659D9E648A9F
116+
* RFC 4122 explains the correct byte ordering
117+
*/
118+
0xDF, 0x60, 0xDD, 0xD8, /* 32-bit value */
119+
0x89, 0x45, /* 16-bit value */
120+
0xC7, 0x4C, /* 16-bit value */
121+
0x9C, 0xD2,
122+
0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,
123+
124+
0x00, 0x00, 0x03, 0x06, /* dwWindowsVersion = 0x06030000 for Windows 8.1 Build */
125+
LOBYTE(USB_SIZ_MS_OS_DSCRPTR_SET), /* wMSOSDescriptorSetTotalLength */
126+
HIBYTE(USB_SIZ_MS_OS_DSCRPTR_SET), /* wMSOSDescriptorSetTotalLength */
127+
USB_MS_VENDOR_CODE, /* bMS_VendorCode */
128+
0x00 /* bAltEnumCode = Does not support alternate enumeration */
129+
};
130+
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
131+
132+
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
133+
#if defined ( __ICCARM__ ) /* IAR Compiler */
134+
#pragma data_alignment=4
135+
#endif /* defined ( __ICCARM__ ) */
136+
__ALIGN_BEGIN uint8_t USBD_OSDescSet[USB_SIZ_MS_OS_DSCRPTR_SET] __ALIGN_END =
137+
{
138+
0x0A, 0x00, /* wLength = 10 */
139+
0x00, 0x00, /* wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR */
140+
0x00, 0x00, 0x03, 0x06, /* dwWindowsVersion = 0x06030000 for Windows 8.1 Build */
141+
LOBYTE(USB_SIZ_MS_OS_DSCRPTR_SET), /* wTotalLength */
142+
HIBYTE(USB_SIZ_MS_OS_DSCRPTR_SET), /* wTotalLength (cont.) */
143+
144+
0x14, 0x00, /* wLength = 20 */
145+
0x03, 0x00, /* wDescriptorType = MS_OS_20_FEATURE_COMPATBLE_ID */
146+
'W', 'I', 'N', 'U', 'S', 'B', /* CompatibleID */
147+
0x00, 0x00, /* CompatibleID (cont.) */
148+
0x00, 0x00, 0x00, 0x00, /* SubCompatibleID */
149+
0x00, 0x00, 0x00, 0x00, /* SubCompatibleID (cont.) */
150+
151+
0x82, 0x00, /* wLength = 130 */
152+
0x04, 0x00, /* wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY */
153+
0x07, 0x00, /* wStringType = REG_MULTI_SZ */
154+
/* wPropertyNameLength = 42 */
155+
0x2A, 0x00,
156+
/* PropertyName = DeviceInterfaceGUIDs */
157+
'D', '\0',
158+
'e', '\0',
159+
'v', '\0',
160+
'i', '\0',
161+
'c', '\0',
162+
'e', '\0',
163+
'I', '\0',
164+
'n', '\0',
165+
't', '\0',
166+
'e', '\0',
167+
'r', '\0',
168+
'f', '\0',
169+
'a', '\0',
170+
'c', '\0',
171+
'e', '\0',
172+
'G', '\0',
173+
'U', '\0',
174+
'I', '\0',
175+
'D', '\0',
176+
's', '\0',
177+
'\0', '\0',
178+
179+
/* wPropertyDataLength = 78 */
180+
0x4E, 0x00,
181+
/* PropertyData = {A5C44A4C-53D4-4389-9821-AE95051908A1} */
182+
'{', '\0',
183+
'A', '\0',
184+
'5', '\0',
185+
'C', '\0',
186+
'4', '\0',
187+
'4', '\0',
188+
'A', '\0',
189+
'4', '\0',
190+
'C', '\0',
191+
'-', '\0',
192+
'5', '\0',
193+
'3', '\0',
194+
'D', '\0',
195+
'4', '\0',
196+
'-', '\0',
197+
'4', '\0',
198+
'3', '\0',
199+
'8', '\0',
200+
'9', '\0',
201+
'-', '\0',
202+
'9', '\0',
203+
'8', '\0',
204+
'2', '\0',
205+
'1', '\0',
206+
'-', '\0',
207+
'A', '\0',
208+
'E', '\0',
209+
'9', '\0',
210+
'5', '\0',
211+
'0', '\0',
212+
'5', '\0',
213+
'1', '\0',
214+
'9', '\0',
215+
'0', '\0',
216+
'8', '\0',
217+
'A', '\0',
218+
'1', '\0',
219+
'}', '\0',
220+
'\0', '\0'
221+
};
222+
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
223+
87224
/* USB Standard Device Descriptor */
88225
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
89226
USB_LEN_LANGID_STR_DESC,
@@ -236,6 +373,16 @@ static uint8_t *USBD_Pybricks_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, ui
236373
return USBD_StrDesc;
237374
}
238375

376+
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
377+
static uint8_t *USBD_Pybricks_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
378+
/* Prevent unused argument(s) compilation warning */
379+
UNUSED(speed);
380+
381+
*length = sizeof(USBD_BOSDesc);
382+
return (uint8_t *)USBD_BOSDesc;
383+
}
384+
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
385+
239386
USBD_DescriptorsTypeDef Pybricks_Desc = {
240387
.GetDeviceDescriptor = USBD_Pybricks_DeviceDescriptor,
241388
.GetLangIDStrDescriptor = USBD_Pybricks_LangIDStrDescriptor,
@@ -244,4 +391,7 @@ USBD_DescriptorsTypeDef Pybricks_Desc = {
244391
.GetSerialStrDescriptor = USBD_Pybricks_SerialStrDescriptor,
245392
.GetConfigurationStrDescriptor = USBD_Pybricks_ConfigStrDescriptor,
246393
.GetInterfaceStrDescriptor = USBD_Pybricks_InterfaceStrDescriptor,
394+
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
395+
.GetBOSDescriptor = USBD_Pybricks_BOSDescriptor,
396+
#endif
247397
};

0 commit comments

Comments
 (0)