Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MSOS2.0 descriptor to have WinUSB driver automatically assigned to DFU at the time of enumeration #248

Merged
merged 7 commits into from
Sep 27, 2024
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
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;
}
}
Loading