Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bricks/_common/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ PBIO_SRC_C = $(addprefix lib/pbio/,\
drv/uart/uart_stm32f0.c \
drv/uart/uart_stm32f4_ll_irq.c \
drv/uart/uart_stm32l4_ll_dma.c \
drv/usb/usb_common_desc.c \
drv/usb/usb_ev3.c \
drv/usb/usb_nxt.c \
drv/usb/usb_stm32.c \
Expand Down
12 changes: 8 additions & 4 deletions lib/lego/lego/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

/** Official LEGO USB Vendor ID. */
#define LEGO_USB_VID 0x0694
/** Official LEGO USB Product ID for MINDSTORMS NXT. */
#define LEGO_USB_PID_NXT 0x0002
/** Official LEGO USB Product ID for MINDSTORMS EV3. */
#define LEGO_USB_PID_EV3 0x0005
/** Official LEGO USB Product ID for MINDSTORMS EV3. */
Expand All @@ -28,12 +30,14 @@
#define LEGO_USB_PID_ROBOT_INVENTOR_DFU 0x0011

/** Official LEGO USB Manufacturer String. */
#define LEGO_USB_MFG_STR "LEGO System A/S"
#define LEGO_USB_MFG_STR u"LEGO System A/S"
/** NXT does not officially come with a product string */
#define LEGO_USB_PROD_STR_NXT u"NXT"
/** Official LEGO USB Product String for MINDSTORMS EV3. */
#define LEGO_USB_PROD_STR_EV3 "LEGO MINDSTORMS EV3"
#define LEGO_USB_PROD_STR_EV3 u"LEGO MINDSTORMS EV3"
/** Official LEGO USB Product String for SPIKE Prime and MINDSTORMS Robot Inventor. */
#define LEGO_USB_PROD_STR_TECHNIC_LARGE_HUB "LEGO Technic Large Hub"
#define LEGO_USB_PROD_STR_TECHNIC_LARGE_HUB u"LEGO Technic Large Hub"
/** Official LEGO USB Product String for SPIKE Essential. */
#define LEGO_USB_PROD_STR_TECHNIC_SMALL_HUB "LEGO Technic Small Hub"
#define LEGO_USB_PROD_STR_TECHNIC_SMALL_HUB u"LEGO Technic Small Hub"

#endif // _LEGO_USB_H_
254 changes: 36 additions & 218 deletions lib/pbio/drv/usb/stm32_usbd/usbd_desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@
#include "usbd_conf.h"
#include "usbd_pybricks.h"

#include "../usb_ch9.h"
#include "../usb_common_desc.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USBD_LANGID_STRING 0x409
#define USBD_CONFIGURATION_FS_STRING "Pybricks Config"
#define USBD_INTERFACE_FS_STRING "Pybricks Interface"

// STM32 MCU Device ID register addresses
// REVISIT: make pbdrv_xxx_get_serial_number() and use that instead
Expand All @@ -71,197 +72,37 @@

// descriptor sizes
#define USB_SIZ_STRING_SERIAL 26
#define USB_SIZ_BOS_DESC (5 + 28 + 24)

/* USB Standard Device Descriptor */
__ALIGN_BEGIN static
static
#if !defined(PBDRV_CONFIG_USB_STM32F4_HUB_VARIANT_ADDR)
const
#endif
uint8_t USBD_DeviceDesc[] __ALIGN_END = {
0x12, /* bLength */
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
0x10, 0x02, /* bcdUSB = 2.1.0 (for BOS support) */
PBIO_PYBRICKS_USB_DEVICE_CLASS, /* bDeviceClass */
PBIO_PYBRICKS_USB_DEVICE_SUBCLASS, /* bDeviceSubClass */
PBIO_PYBRICKS_USB_DEVICE_PROTOCOL, /* bDeviceProtocol */
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
LOBYTE(PBDRV_CONFIG_USB_VID), /* idVendor */
HIBYTE(PBDRV_CONFIG_USB_VID), /* idVendor */
LOBYTE(PBDRV_CONFIG_USB_PID), /* idProduct */
HIBYTE(PBDRV_CONFIG_USB_PID), /* idProduct */
0x00, 0x02, /* bcdDevice rel. 2.0.0 */
USBD_IDX_MFC_STR, /* Index of manufacturer string */
USBD_IDX_PRODUCT_STR, /* Index of product string */
USBD_IDX_SERIAL_STR, /* Index of serial number string */
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
pbdrv_usb_dev_desc_union_t USBD_DeviceDesc = {
.s = {
.bLength = sizeof(pbdrv_usb_dev_desc_t),
.bDescriptorType = DESC_TYPE_DEVICE,
.bcdUSB = 0x0210, /* 2.1.0 (for BOS support) */
.bDeviceClass = PBIO_PYBRICKS_USB_DEVICE_CLASS,
.bDeviceSubClass = PBIO_PYBRICKS_USB_DEVICE_SUBCLASS,
.bDeviceProtocol = PBIO_PYBRICKS_USB_DEVICE_PROTOCOL,
.bMaxPacketSize0 = USB_MAX_EP0_SIZE,
.idVendor = PBDRV_CONFIG_USB_VID,
.idProduct = PBDRV_CONFIG_USB_PID,
.bcdDevice = 0x0200, /* rel. 2.0.0 */
.iManufacturer = USBD_IDX_MFC_STR,
.iProduct = USBD_IDX_PRODUCT_STR,
.iSerialNumber = USBD_IDX_SERIAL_STR,
.bNumConfigurations = USBD_MAX_NUM_CONFIGURATION,
}
}; /* USB_DeviceDescriptor */
_Static_assert(USB_LEN_DEV_DESC == sizeof(USBD_DeviceDesc));

/** BOS descriptor. */
__ALIGN_BEGIN static const uint8_t USBD_BOSDesc[] __ALIGN_END =
{
5, /* bLength */
USB_DESC_TYPE_BOS, /* bDescriptorType = BOS */
LOBYTE(USB_SIZ_BOS_DESC), /* wTotalLength */
HIBYTE(USB_SIZ_BOS_DESC), /* wTotalLength */
2, /* bNumDeviceCaps */

// IMPORTANT: The WebUSB descriptor must be first to make Chromium happy.

24, /* bLength */
USB_DEVICE_CAPABITY_TYPE, /* bDescriptorType = Device Capability */
USB_DEV_CAP_TYPE_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */

/*
* PlatformCapabilityUUID
* WebUSB Platform Capability descriptor
* 3408B638-09A9-47A0-8BFD-A0768815B665
* RFC 4122 explains the correct byte ordering
*/
0x38, 0xB6, 0x08, 0x34, /* 32-bit value */
0xA9, 0x09, /* 16-bit value */
0xA0, 0x47, /* 16-bit value */
0x8B, 0xFD,
0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,

LOBYTE(0x0100), /* bcdVersion */
HIBYTE(0x0100), /* bcdVersion */
USBD_VENDOR_CODE_WEBUSB, /* bVendorCode */
USBD_WEBUSB_LANDING_PAGE_IDX, /* iLandingPage */

// IMPORTANT: The MS OS 2.0 descriptor must be last to make Chromium happy.

28, /* bLength */
USB_DEVICE_CAPABITY_TYPE, /* bDescriptorType = Device Capability */
USB_DEV_CAP_TYPE_PLATFORM, /* bDevCapabilityType */
0x00, /* bReserved */

/*
* PlatformCapabilityUUID
* Microsoft OS 2.0 descriptor platform capability ID
* D8DD60DF-4589-4CC7-9CD2-659D9E648A9F
* RFC 4122 explains the correct byte ordering
*/
0xDF, 0x60, 0xDD, 0xD8, /* 32-bit value */
0x89, 0x45, /* 16-bit value */
0xC7, 0x4C, /* 16-bit value */
0x9C, 0xD2,
0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F,

0x00, 0x00, 0x03, 0x06, /* dwWindowsVersion = 0x06030000 for Windows 8.1 Build */
LOBYTE(USBD_SIZ_MS_OS_DSCRPTR_SET), /* wMSOSDescriptorSetTotalLength */
HIBYTE(USBD_SIZ_MS_OS_DSCRPTR_SET), /* wMSOSDescriptorSetTotalLength */
USBD_VENDOR_CODE_MS, /* bMS_VendorCode */
0x00, /* bAltEnumCode = Does not support alternate enumeration */
};
_Static_assert(USB_SIZ_BOS_DESC == sizeof(USBD_BOSDesc));

__ALIGN_BEGIN const uint8_t USBD_OSDescSet[] __ALIGN_END =
{
0x0A, 0x00, /* wLength = 10 */
0x00, 0x00, /* wDescriptorType = MS_OS_20_SET_HEADER_DESCRIPTOR */
0x00, 0x00, 0x03, 0x06, /* dwWindowsVersion = 0x06030000 for Windows 8.1 Build */
LOBYTE(USBD_SIZ_MS_OS_DSCRPTR_SET), /* wTotalLength */
HIBYTE(USBD_SIZ_MS_OS_DSCRPTR_SET), /* wTotalLength (cont.) */

0x14, 0x00, /* wLength = 20 */
0x03, 0x00, /* wDescriptorType = MS_OS_20_FEATURE_COMPATBLE_ID */
'W', 'I', 'N', 'U', 'S', 'B', /* CompatibleID */
0x00, 0x00, /* CompatibleID (cont.) */
0x00, 0x00, 0x00, 0x00, /* SubCompatibleID */
0x00, 0x00, 0x00, 0x00, /* SubCompatibleID (cont.) */

0x84, 0x00, /* wLength = 132 */
0x04, 0x00, /* wDescriptorType = MS_OS_20_FEATURE_REG_PROPERTY */
0x07, 0x00, /* wStringType = REG_MULTI_SZ */
/* wPropertyNameLength = 42 */
0x2A, 0x00,
/* PropertyName = DeviceInterfaceGUIDs */
'D', '\0',
'e', '\0',
'v', '\0',
'i', '\0',
'c', '\0',
'e', '\0',
'I', '\0',
'n', '\0',
't', '\0',
'e', '\0',
'r', '\0',
'f', '\0',
'a', '\0',
'c', '\0',
'e', '\0',
'G', '\0',
'U', '\0',
'I', '\0',
'D', '\0',
's', '\0',
'\0', '\0',

/* wPropertyDataLength = 80 */
0x50, 0x00,
/* PropertyData = {A5C44A4C-53D4-4389-9821-AE95051908A1} */
'{', '\0',
'A', '\0',
'5', '\0',
'C', '\0',
'4', '\0',
'4', '\0',
'A', '\0',
'4', '\0',
'C', '\0',
'-', '\0',
'5', '\0',
'3', '\0',
'D', '\0',
'4', '\0',
'-', '\0',
'4', '\0',
'3', '\0',
'8', '\0',
'9', '\0',
'-', '\0',
'9', '\0',
'8', '\0',
'2', '\0',
'1', '\0',
'-', '\0',
'A', '\0',
'E', '\0',
'9', '\0',
'5', '\0',
'0', '\0',
'5', '\0',
'1', '\0',
'9', '\0',
'0', '\0',
'8', '\0',
'A', '\0',
'1', '\0',
'}', '\0',
'\0', '\0',
'\0', '\0'
};
_Static_assert(USBD_SIZ_MS_OS_DSCRPTR_SET == sizeof(USBD_OSDescSet));

/* USB Standard Device Descriptor */
__ALIGN_BEGIN static const uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
USB_LEN_LANGID_STR_DESC,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING),
};

__ALIGN_BEGIN static uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};

__ALIGN_BEGIN static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;


/**
* @brief Convert Hex 32Bits value into char
Expand Down Expand Up @@ -316,8 +157,8 @@ static uint8_t *USBD_Pybricks_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t
/* Prevent unused argument(s) compilation warning */
UNUSED(speed);

*length = sizeof(USBD_DeviceDesc);
return (uint8_t *)USBD_DeviceDesc;
*length = sizeof(USBD_DeviceDesc.s);
return (uint8_t *)&USBD_DeviceDesc;
}

/**
Expand All @@ -330,8 +171,8 @@ static uint8_t *USBD_Pybricks_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint1
/* Prevent unused argument(s) compilation warning */
UNUSED(speed);

*length = sizeof(USBD_LangIDDesc);
return (uint8_t *)USBD_LangIDDesc;
*length = sizeof(pbdrv_usb_str_desc_langid.s);
return (uint8_t *)&pbdrv_usb_str_desc_langid;
}

/**
Expand All @@ -341,8 +182,11 @@ static uint8_t *USBD_Pybricks_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint1
* @retval Pointer to descriptor buffer
*/
static uint8_t *USBD_Pybricks_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString((uint8_t *)PBDRV_CONFIG_USB_PROD_STR, USBD_StrDesc, length);
return USBD_StrDesc;
/* Prevent unused argument(s) compilation warning */
UNUSED(speed);

*length = sizeof(pbdrv_usb_str_desc_prod.s);
return (uint8_t *)&pbdrv_usb_str_desc_prod;
}

/**
Expand All @@ -355,8 +199,8 @@ static uint8_t *USBD_Pybricks_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
/* Prevent unused argument(s) compilation warning */
UNUSED(speed);

USBD_GetString((uint8_t *)PBDRV_CONFIG_USB_MFG_STR, USBD_StrDesc, length);
return USBD_StrDesc;
*length = sizeof(pbdrv_usb_str_desc_mfg.s);
return (uint8_t *)&pbdrv_usb_str_desc_mfg;
}

/**
Expand All @@ -377,34 +221,12 @@ static uint8_t *USBD_Pybricks_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint1
return (uint8_t *)USBD_StringSerial;
}

/**
* @brief Returns the configuration string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
static uint8_t *USBD_Pybricks_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}

/**
* @brief Returns the interface string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
static uint8_t *USBD_Pybricks_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}

static uint8_t *USBD_Pybricks_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
/* Prevent unused argument(s) compilation warning */
UNUSED(speed);

*length = USB_SIZ_BOS_DESC;
return (uint8_t *)USBD_BOSDesc;
*length = sizeof(pbdrv_usb_bos_desc_set.s);
return (uint8_t *)&pbdrv_usb_bos_desc_set;
}

USBD_DescriptorsTypeDef USBD_Pybricks_Desc = {
Expand All @@ -413,8 +235,6 @@ USBD_DescriptorsTypeDef USBD_Pybricks_Desc = {
.GetManufacturerStrDescriptor = USBD_Pybricks_ManufacturerStrDescriptor,
.GetProductStrDescriptor = USBD_Pybricks_ProductStrDescriptor,
.GetSerialStrDescriptor = USBD_Pybricks_SerialStrDescriptor,
.GetConfigurationStrDescriptor = USBD_Pybricks_ConfigStrDescriptor,
.GetInterfaceStrDescriptor = USBD_Pybricks_InterfaceStrDescriptor,
.GetBOSDescriptor = USBD_Pybricks_BOSDescriptor,
};

Expand All @@ -424,11 +244,9 @@ void USBD_Pybricks_Desc_Init(void) {
#ifdef PBDRV_CONFIG_USB_STM32F4_HUB_VARIANT_ADDR
#define VARIANT (*(uint32_t *)PBDRV_CONFIG_USB_STM32F4_HUB_VARIANT_ADDR)
if (VARIANT == 0) {
USBD_DeviceDesc[10] = LOBYTE(PBDRV_CONFIG_USB_PID_0);
USBD_DeviceDesc[11] = HIBYTE(PBDRV_CONFIG_USB_PID_0);
USBD_DeviceDesc.s.idProduct = PBDRV_CONFIG_USB_PID_0;
} else if (VARIANT == 1) {
USBD_DeviceDesc[10] = LOBYTE(PBDRV_CONFIG_USB_PID_1);
USBD_DeviceDesc[11] = HIBYTE(PBDRV_CONFIG_USB_PID_1);
USBD_DeviceDesc.s.idProduct = PBDRV_CONFIG_USB_PID_1;
}
#endif
}
Loading