Skip to content

Commit 37302f2

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. Signed-off-by: Nate Karstens <[email protected]>
1 parent 9ff624c commit 37302f2

File tree

5 files changed

+786
-8
lines changed

5 files changed

+786
-8
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: 139 additions & 8 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,21 +62,23 @@
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 */
66-
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
68+
__ALIGN_BEGIN static uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
6769
0x12, /* bLength */
6870
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
69-
0x00, /* bcdUSB */
71+
0x01, /* bcdUSB */ /* changed to USB version 2.01
72+
in order to support BOS Desc */
7073
0x02,
7174
0x02, /* bDeviceClass */
7275
0x02, /* bDeviceSubClass */
7376
0x00, /* bDeviceProtocol */
7477
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
7578
LOBYTE(USBD_VID), /* idVendor */
7679
HIBYTE(USBD_VID), /* idVendor */
77-
LOBYTE(USBD_PID), /* idVendor */
78-
HIBYTE(USBD_PID), /* idVendor */
80+
LOBYTE(USBD_PID), /* idProduct */
81+
HIBYTE(USBD_PID), /* idProduct */
7982
0x00, /* bcdDevice rel. 2.00 */
8083
0x02,
8184
USBD_IDX_MFC_STR, /* Index of manufacturer string */
@@ -84,21 +87,140 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
8487
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
8588
}; /* USB_DeviceDescriptor */
8689

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

95-
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
218+
__ALIGN_BEGIN static uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
96219
USB_SIZ_STRING_SERIAL,
97220
USB_DESC_TYPE_STRING,
98221
};
99222

100-
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
101-
223+
__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
102224

103225
/**
104226
* @brief Convert Hex 32Bits value into char
@@ -236,6 +358,14 @@ static uint8_t *USBD_Pybricks_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, ui
236358
return USBD_StrDesc;
237359
}
238360

361+
static uint8_t *USBD_Pybricks_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
362+
/* Prevent unused argument(s) compilation warning */
363+
UNUSED(speed);
364+
365+
*length = sizeof(USBD_BOSDesc);
366+
return (uint8_t *)USBD_BOSDesc;
367+
}
368+
239369
USBD_DescriptorsTypeDef Pybricks_Desc = {
240370
.GetDeviceDescriptor = USBD_Pybricks_DeviceDescriptor,
241371
.GetLangIDStrDescriptor = USBD_Pybricks_LangIDStrDescriptor,
@@ -244,4 +374,5 @@ USBD_DescriptorsTypeDef Pybricks_Desc = {
244374
.GetSerialStrDescriptor = USBD_Pybricks_SerialStrDescriptor,
245375
.GetConfigurationStrDescriptor = USBD_Pybricks_ConfigStrDescriptor,
246376
.GetInterfaceStrDescriptor = USBD_Pybricks_InterfaceStrDescriptor,
377+
.GetBOSDescriptor = USBD_Pybricks_BOSDescriptor,
247378
};

0 commit comments

Comments
 (0)