Skip to content

Commit

Permalink
Merge pull request #248 from lucianomartin/feature/bos_desc
Browse files Browse the repository at this point in the history
Add support for MSOS2.0 descriptor to have WinUSB driver automatically assigned to DFU at the time of enumeration
  • Loading branch information
xluciano authored Sep 27, 2024
2 parents 196eda3 + 5bc0b33 commit 5e1834d
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 13 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
RTOS Framework change log
=========================

3.3.0
-----

* ADDED: Support for MSOS2.0 descriptor to automatically assign the WinUSB drivers to the DFU interface
during enumeration on Windows. This enhancement is included in the USB descriptors of the USB tests.
* ADDED: Support for multiread and multiwrite functions to the I2C master drivers.

3.2.0
-----

Expand Down
2 changes: 1 addition & 1 deletion settings.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
project: fwk_rtos
title: XCORE RTOS Framework
version: 3.0.5
version: 3.3.0

documentation:
exclude_patterns_path: doc/exclude_patterns.inc
Expand Down
5 changes: 0 additions & 5 deletions test/rtos_drivers/usb/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ Example for Debian:
$ apt-get install dfu-util
On Windows platforms, prior to running the test, the user must manually update
the driver for the enumerated DFU interface using a driver utility such as
`Zadig <https://zadig.akeo.ie/>`_ to use one of the available ``libusb``
compatible drivers.

**************
Building Tests
**************
Expand Down
8 changes: 4 additions & 4 deletions test/rtos_drivers/usb/serial_send_receive.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ def transfer_data(input_file, output_file, write_port, read_port, max_read_size)
out_file.write(read_port.read(len(tx_data)))

def main(if0, if1, of0, of1):

test_ports = find_ports_by_vid_pid(required_ports, N_PORTS_ERROR_MSG)
port0 = None
port1 = None

try:
d0 = test_ports[0].device
d1 = test_ports[1].device

print(f'Opening port 0 ({d0}).')
port0 = serial.Serial(d0)

print(f'Opening port 1 ({d1}).')
port1 = serial.Serial(d1)

Expand All @@ -71,7 +71,7 @@ def main(if0, if1, of0, of1):
except Exception as e:
print(e)
sys.exit(1)

finally:
if port0 is not None:
print('Closing port 0.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

#define XMOS_VID 0x20B1
#define TEST_PID 0x4000
#define USB_BCD 0x0200
#define NUM_CONFIGURATIONS 0x01

//--------------------------------------------------------------------+
Expand All @@ -40,7 +39,7 @@
tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
.bcdUSB = 0x0201, // For BOS descriptor! https://microchip.my.site.com/s/article/Does-a-USB2-1-Specification-Exist

// Use Interface Association Descriptor (IAD) for CDC
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
Expand Down Expand Up @@ -68,6 +67,48 @@ uint8_t const* tud_descriptor_device_cb(void)
return (uint8_t const *) &desc_device;
}

// MSOS 2.0 descriptor copied from the examples in https://github.com/xmos/xcore_iot/blob/develop/test/usb/tinyusb_demos/webusb_serial/src/usb_descriptors.c#L152
// and https://github.com/pololu/libusbp/blob/master/test/firmware/wixel/main.c#L460
#define MS_OS_20_DESC_LEN 0xB2
#define REQUEST_GET_MS_DESCRIPTOR 0x20
// Microsoft OS 2.0 Descriptors, Table 8
#define MS_OS_20_DESCRIPTOR_INDEX 7
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
uint8_t const desc_bos[] =
{
// total length, number of device caps
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1),
// Microsoft OS 2.0 descriptor
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, REQUEST_GET_MS_DESCRIPTOR)
};
uint8_t const desc_ms_os_20[] =
{
// Set header: length, type, windows version, total length
U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN),
// Configuration subset header: length, type, configuration index, reserved, configuration total length
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A),
// Function Subset header: length, type, first interface, reserved, subset length
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_DFU_MODE, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible
// MS OS 2.0 Registry property descriptor: length, type
U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY),
U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00,
U16_TO_U8S_LE(0x0050), // wPropertyDataLength
//bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
'{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00,
'0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00,
'8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00,
'8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t const * tud_descriptor_bos_cb(void)
{
return desc_bos;
}

//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -121,7 +162,7 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
.bcdUSB = 0x0201, // For BOS descriptor! https://microchip.my.site.com/s/article/Does-a-USB2-1-Specification-Exist

.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
Expand Down Expand Up @@ -223,3 +264,22 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index,

return _desc_str;
}

bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request)
{
switch (request->bRequest)
{
case REQUEST_GET_MS_DESCRIPTOR:
if ( request->wIndex == MS_OS_20_DESCRIPTOR_INDEX )
{
if (stage != CONTROL_STAGE_SETUP) return true; // nothing to with DATA & ACK stage
// Send Microsoft OS 2.0 compatible descriptor
return tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_ms_os_20, MS_OS_20_DESC_LEN);
}else
{
return false;
}
default:
return false;
}
}

0 comments on commit 5e1834d

Please sign in to comment.