Skip to content

Commit d15f44a

Browse files
committed
fl16: Add MSOS descriptor to install winusb on picoboot interface
Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent c55fa52 commit d15f44a

File tree

4 files changed

+171
-21
lines changed

4 files changed

+171
-21
lines changed

keyboards/framework/config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,5 @@
144144

145145
// Add BOS descriptor to tell fwupd that we support rpi-pico protocol
146146
#define FWUPD_CAP
147+
#define PICOBOOT_CAP
148+
//#define MSOS2_CAP

tmk_core/protocol/chibios/usb_main.c

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ report_mouse_t mouse_report_sent = {0};
7878
#if defined(FWUPD_CAP)
7979
static uint8_t fwupd_descriptor_set[] __attribute__((aligned(4))) = {
8080
// Generated with `~/clone/fwupd/contrib/generate-ds20.py fwup.quirk`
81+
// 0x59 bytes
8182
0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x3d, 0x72, 0x70, 0x5f, 0x70, 0x69,
8283
0x63, 0x6f, 0x0a, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x3d, 0x69, 0x6e, 0x74,
8384
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x0a, 0x49, 0x63, 0x6f, 0x6e, 0x3d, 0x69,
@@ -87,7 +88,82 @@ static uint8_t fwupd_descriptor_set[] __attribute__((aligned(4))) = {
8788
0x56, 0x45, 0x4e, 0x5f, 0x32, 0x45, 0x38, 0x41, 0x26, 0x44, 0x45, 0x56,
8889
0x5f, 0x30, 0x30, 0x30, 0x33
8990
};
90-
#endif
91+
#endif // FWUPD_CAP
92+
93+
#if defined(PICOBOOT_CAP)
94+
static uint8_t picoboot_descriptor_set[] __attribute__((aligned(4))) = {
95+
// Mirror this to associate WinUSB with the picoboot interface
96+
// Otherwise Windows complains that no driver is loaded for that interface/device
97+
// https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_stdio_usb/reset_interface.c#L46
98+
// 0xA6/166 bytes
99+
//
100+
// Microsoft OS 2.0 Descriptor Set Header
101+
//
102+
0x0A, 0x00, // wLength - 10 bytes
103+
0x00, 0x00, // wDescriptorType - MSOS20_SET_HEADER_DESCRIPTOR
104+
0x00, 0x00, 0x03, 0x06, // dwWindowsVersion – 0x06030000 for Windows Blue
105+
0xA6, 0x00, // wTotalLength – 166 bytes
106+
107+
//
108+
// Microsoft OS 2.0 Function Subset Header
109+
//
110+
0x08, 0x00, // wLength - 8 bytes
111+
0x02, 0x00, // wDescriptorType - MS_OS_20_SUBSET_HEADER_FUNCTION
112+
RP2040_RESET_INTERFACE, // bFirstInterface
113+
0x00, // bReserved
114+
0x9C, 0x00, // wSubsetLength – 156 bytes
115+
116+
117+
//
118+
// Microsoft OS 2.0 Compatible ID Header
119+
//
120+
0x14, 0x00, // wLength - 20 bytes
121+
0x03, 0x00, // wDescriptorType - MS_OS_20_FEATURE_COMPATBLE_ID
122+
'W', 'I', 'N', 'U', // CompatibleID
123+
'S', 'B', 0x00, 0x00, //
124+
0x00, 0x00, 0x00, 0x00, // SubCompatibleID
125+
0x00, 0x00, 0x00, 0x00, //
126+
127+
//
128+
// Microsoft OS 2.0 Registry Value Feature Descriptor
129+
//
130+
0x80, 0x00, // wLength - 128 bytes
131+
0x04, 0x00, // wDescriptorType – 4 MS_OS_20_FEATURE_REG_PROPERTY
132+
0x01, 0x00, // wPropertyDataType - 1 for A NULL-terminated Unicode String (REG_SZ)
133+
0x28, 0x00, // wPropertyNameLength – 40 bytes
134+
'D', 0x00, 'e', 0x00, // Property Name - "DeviceInterfaceGUID"
135+
'v', 0x00, 'i', 0x00,
136+
'c', 0x00, 'e', 0x00,
137+
'I', 0x00, 'n', 0x00,
138+
't', 0x00, 'e', 0x00,
139+
'r', 0x00, 'f', 0x00,
140+
'a', 0x00, 'c', 0x00,
141+
'e', 0x00, 'G', 0x00,
142+
'U', 0x00, 'I', 0x00,
143+
'D', 0x00, 0x00, 0x00,
144+
0x4E, 0x00, // wPropertyDataLength – 78 bytes
145+
'{', 0x00, 'b', 0x00, // PropertyData - "{bc7398c1-73cd-4cb7-98b8-913a8fca7bf6}"
146+
'c', 0x00, '7', 0x00,
147+
'3', 0x00, '9', 0x00,
148+
'8', 0x00, 'c', 0x00,
149+
'1', 0x00, '-', 0x00,
150+
'7', 0x00, '3', 0x00,
151+
'c', 0x00, 'd', 0x00,
152+
'-', 0x00, '4', 0x00,
153+
'c', 0x00, 'b', 0x00,
154+
'7', 0x00, '-', 0x00,
155+
'9', 0x00, '8', 0x00,
156+
'b', 0x00, '8', 0x00,
157+
'-', 0x00, '9', 0x00,
158+
'1', 0x00, '3', 0x00,
159+
'a', 0x00, '8', 0x00,
160+
'f', 0x00, 'c', 0x00,
161+
'a', 0x00, '7', 0x00,
162+
'b', 0x00, 'f', 0x00,
163+
'6', 0x00, '}', 0x00,
164+
0x00, 0x00
165+
};
166+
#endif // PICOBOOT_CAP
91167

92168
#if defined(MSOS2_CAP)
93169
static uint8_t msos_descriptor_set[] __attribute__((aligned(4))) = {
@@ -826,6 +902,33 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
826902
}
827903
#endif
828904

905+
#if defined(PICOBOOT_CAP)
906+
// if (usbp->setup[0] == 0xC0) {
907+
// dprintf("zoid. Vendor request\n");
908+
// dprintf("zoid:\n bmRequestType: %d\n bRequest: %d\n wValue: %d %d\n wIndex: %d %d\n wLength: %d %d\n",
909+
// usbp->setup[0], usbp->setup[1], usbp->setup[2], usbp->setup[3], usbp->setup[4], usbp->setup[5], usbp->setup[6], usbp->setup[7]);
910+
// }
911+
/* Handle Vendor Specific Request */
912+
if (
913+
//usbp->setup[0] == (USB_RTYPE_TYPE_VENDOR | USB_RTYPE_DIR_HOST2DEV | USB_RTYPE_RECIPIENT_DEVICE)
914+
usbp->setup[0] == 0xC0
915+
// Microsoft vendor code = 0x01
916+
// FWUPD vendor code = 0x2a
917+
// wRequest
918+
&& usbp->setup[1] == 0x01
919+
// wValue
920+
&& usbp->setup[2] == 0x00 && usbp->setup[3] == 0x00
921+
// wIndex: MS_OS_20_DESCRIPTOR_INDEX
922+
&& usbp->setup[4] == 0x07 && usbp->setup[5] == 0x00
923+
// wLength: 0x00A6
924+
&& usbp->setup[6] == 0xA6 && usbp->setup[7] == 0x00
925+
) {
926+
//dprint("zoid: Detected MS OS 2.0 descriptor request\n");
927+
usbSetupTransfer(usbp, &picoboot_descriptor_set[0], 0xA6, NULL);
928+
return TRUE;
929+
}
930+
#endif
931+
829932
#if defined(MSOS2_CAP)
830933
/* Handle Vendor Specific Request */
831934
//if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_VENDOR) && ((usbp->setup[0] & USB_RTYPE_RECIPIENT_MASK) == USB_RTYPE_RECIPIENT_DEVICE)) {

tmk_core/protocol/usb_descriptor.c

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,25 @@ const USB_Descriptor_Bos_t PROGMEM BosDescriptor = {
493493
},
494494
// 3 Bytes (=> 5 Bytes)
495495
// Value must be header + each cap
496-
#if defined(MSOS2_CAP) || defined(FWUPD_CAP)
496+
#if defined(MSOS2_CAP) && defined(FWUPD_CAP) && defined(PICOBOOT_CAP)
497+
.TotalLength = 0x0060,
498+
.NumDeviceCaps = 0x04,
499+
#elif defined(FWUPD_CAP) && defined(PICOBOOT_CAP)
500+
.TotalLength = 0x0044,
501+
.NumDeviceCaps = 0x03,
502+
#elif defined(MSOS2_CAP) && defined(FWUPD_CAP)
503+
.TotalLength = 0x0044,
504+
.NumDeviceCaps = 0x03,
505+
#elif defined(MSOS2_CAP) && defined(PICOBOOT_CAP)
506+
.TotalLength = 0x0044,
507+
.NumDeviceCaps = 0x03,
508+
#elif defined(MSOS2_CAP)
509+
.TotalLength = 0x0028,
510+
.NumDeviceCaps = 0x02,
511+
#elif defined(FWUPD_CAP)
512+
.TotalLength = 0x0028,
513+
.NumDeviceCaps = 0x02,
514+
#elif defined(PICOBOOT_CAP)
497515
.TotalLength = 0x0028,
498516
.NumDeviceCaps = 0x02,
499517
#else
@@ -535,13 +553,40 @@ const USB_Descriptor_Bos_t PROGMEM BosDescriptor = {
535553
// 0x00020002
536554
.WindowsVersion = {0x02, 0x00, 0x02, 0x00},
537555
// Length of the data returned by control request
538-
.TotalLength = 0x0059,
556+
.TotalLength = 0x59,
539557
.VendorCode = 0x2a,
540558
.AltEnumCode = 0,
541559
}},
542560
},
543561
#endif // FWUPD_CAP
544562

563+
#ifdef PICOBOOT_CAP
564+
.MsosCap = {
565+
// 2 Bytes (=> 7 Bytes)
566+
.Header = {
567+
.Size = sizeof(USB_Descriptor_Capability_Msos_t),
568+
.Type = 16,
569+
},
570+
// 5 Bytes (=> 12 Bytes / 0x0C Bytes)
571+
.DevCapabilityType = 5, // Platform
572+
.Reserved = 0,
573+
// Microsoft OS 2.0 {D8DD60DF-4589-4CC7-9CD2-659D9E648A9F}
574+
.PlatformCapabilityId = {
575+
0xDF, 0x60, 0xDD, 0xD8,
576+
0x89, 0x45, 0xC7, 0x4C,
577+
0x9C, 0xD2, 0x65, 0x9D,
578+
0x9E, 0x64, 0x8A, 0x9F
579+
},
580+
.Set = {{
581+
.WindowsVersion = {0x00, 0x00, 0x03, 0x06}, // Windows Blue
582+
// Length of the data returned by control request
583+
.TotalLength = 0xA6,
584+
.VendorCode = 0x01, // Microsoft
585+
.AltEnumCode = 0,
586+
}},
587+
},
588+
#endif // PICOBOOT_CAP
589+
545590
#ifdef MSOS2_CAP
546591
// 28 Bytes (0x1C)
547592
.MsosCap = {
@@ -768,19 +813,6 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
768813
.PollingIntervalMS = USB_POLLING_INTERVAL_MS
769814
},
770815
#endif
771-
.Rp2040_Reset_Interface = {
772-
.Header = {
773-
.Size = sizeof(USB_Descriptor_Interface_t),
774-
.Type = DTYPE_Interface
775-
},
776-
.InterfaceNumber = RP2040_RESET_INTERFACE,
777-
.AlternateSetting = 0x00,
778-
.TotalEndpoints = 0,
779-
.Class = 0xFF,
780-
.SubClass = 0x00, // RESET_INTERFACE_SUBCLASS
781-
.Protocol = 0x01, // RESET_INTERFACE_PROTOCOL
782-
.InterfaceStrIndex = NO_DESCRIPTOR
783-
},
784816

785817
#ifdef CONSOLE_ENABLE
786818
/*
@@ -1166,6 +1198,19 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
11661198
.PollingIntervalMS = USB_POLLING_INTERVAL_MS
11671199
},
11681200
#endif
1201+
.Rp2040_Reset_Interface = {
1202+
.Header = {
1203+
.Size = sizeof(USB_Descriptor_Interface_t),
1204+
.Type = DTYPE_Interface
1205+
},
1206+
.InterfaceNumber = RP2040_RESET_INTERFACE,
1207+
.AlternateSetting = 0x00,
1208+
.TotalEndpoints = 0,
1209+
.Class = 0xFF,
1210+
.SubClass = 0x00, // RESET_INTERFACE_SUBCLASS
1211+
.Protocol = 0x01, // RESET_INTERFACE_PROTOCOL
1212+
.InterfaceStrIndex = NO_DESCRIPTOR
1213+
},
11691214
};
11701215

11711216
/*

tmk_core/protocol/usb_descriptor.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ typedef struct {
9292
USB_Descriptor_Endpoint_t Shared_INEndpoint;
9393
#endif
9494

95-
USB_Descriptor_Interface_t Rp2040_Reset_Interface;
96-
9795
#ifdef CONSOLE_ENABLE
9896
// Console HID Interface
9997
USB_Descriptor_Interface_t Console_Interface;
@@ -147,6 +145,8 @@ typedef struct {
147145
USB_HID_Descriptor_HID_t Digitizer_HID;
148146
USB_Descriptor_Endpoint_t Digitizer_INEndpoint;
149147
#endif
148+
149+
USB_Descriptor_Interface_t Rp2040_Reset_Interface;
150150
} USB_Descriptor_Configuration_t;
151151

152152
/*
@@ -175,8 +175,6 @@ enum usb_interfaces {
175175
SHARED_INTERFACE,
176176
#endif
177177

178-
RP2040_RESET_INTERFACE,
179-
180178
#ifdef CONSOLE_ENABLE
181179
CONSOLE_INTERFACE,
182180
#endif
@@ -198,6 +196,8 @@ enum usb_interfaces {
198196
#if defined(DIGITIZER_ENABLE) && !defined(DIGITIZER_SHARED_EP)
199197
DIGITIZER_INTERFACE,
200198
#endif
199+
200+
RP2040_RESET_INTERFACE,
201201
TOTAL_INTERFACES
202202
};
203203

@@ -395,7 +395,7 @@ typedef struct
395395
#ifdef FWUPD_CAP
396396
USB_Descriptor_Capability_Msos_t FwupdCap;
397397
#endif
398-
#ifdef MSOS2_CAP
398+
#if defined(PICOBOOT_CAP) || defined(MSOS2_CAP)
399399
USB_Descriptor_Capability_Msos_t MsosCap;
400400
#endif
401401
} ATTR_PACKED USB_Descriptor_Bos_t;

0 commit comments

Comments
 (0)