Skip to content

Commit e144e6d

Browse files
Add USB BOS descriptor(Picotool), fix findIntfID (#3163)
Pull in latest SDK's new additional USB descriptor when in Picotool upload mode to hopefully make life easier for Windows users. Fix interface counting in USB::findInterfaceID()
1 parent a5b834b commit e144e6d

File tree

1 file changed

+83
-23
lines changed

1 file changed

+83
-23
lines changed

cores/rp2040/USB.cpp

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ void USBClass::removeEntry(Entry **head, unsigned int localid) {
147147
unsigned int USBClass::findID(Entry *head, unsigned int localid) {
148148
unsigned int x = 0;
149149
while (head && head->localid != localid) {
150+
x += head->interfaces;
150151
head = head->next;
151-
x++;
152152
}
153153
return x;
154154
}
@@ -225,10 +225,14 @@ const uint8_t *USBClass::tud_descriptor_device_cb() {
225225
usbd_desc_device = {
226226
.bLength = sizeof(tusb_desc_device_t),
227227
.bDescriptorType = TUSB_DESC_DEVICE,
228+
#ifdef ENABLE_PICOTOOL_USB
229+
.bcdUSB = 0x210,
230+
#else
228231
.bcdUSB = 0x0200,
229-
.bDeviceClass = 0,
230-
.bDeviceSubClass = 0,
231-
.bDeviceProtocol = 0,
232+
#endif
233+
.bDeviceClass = 0xef, //0,
234+
.bDeviceSubClass = 0x02, //0,
235+
.bDeviceProtocol = 0x01, //0,
232236
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
233237
.idVendor = _forceVID ? _forceVID : (uint16_t)USBD_VID,
234238
.idProduct = _forcePID ? _forcePID : (uint16_t)USBD_PID,
@@ -610,20 +614,82 @@ extern "C" void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t pr
610614

611615

612616
#ifdef ENABLE_PICOTOOL_USB
617+
// Support for Microsoft OS 2.0 descriptor
618+
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
619+
620+
#define MS_OS_20_DESC_LEN 166
621+
#define USBD_ITF_RPI_RESET 2
622+
623+
uint8_t const desc_bos[] = {
624+
// total length, number of device caps
625+
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1),
626+
627+
// Microsoft OS 2.0 descriptor
628+
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)
629+
};
630+
631+
TU_VERIFY_STATIC(sizeof(desc_bos) == BOS_TOTAL_LEN, "Incorrect size");
613632

614633
static uint32_t _itf_num = 0;
634+
uint8_t const * tud_descriptor_bos_cb(void) {
635+
return desc_bos;
636+
}
637+
638+
639+
bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) {
640+
static const uint8_t desc_ms_os_20[] = {
641+
// Set header: length, type, windows version, total length
642+
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),
643+
644+
// Function Subset header: length, type, first interface, reserved, subset length
645+
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), USB.findInterfaceID(_picotool_itf_num), 0, U16_TO_U8S_LE(0x009C),
646+
647+
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
648+
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
649+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible
650+
651+
// MS OS 2.0 Registry property descriptor: length, type
652+
U16_TO_U8S_LE(0x0080), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY),
653+
U16_TO_U8S_LE(0x0001), U16_TO_U8S_LE(0x0028), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUID" in UTF-16
654+
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
655+
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00,
656+
U16_TO_U8S_LE(0x004E), // wPropertyDataLength
657+
// Vendor-defined Property Data: {bc7398c1-73cd-4cb7-98b8-913a8fca7bf6}
658+
'{', 0, 'b', 0, 'c', 0, '7', 0, '3', 0, '9', 0,
659+
'8', 0, 'c', 0, '1', 0, '-', 0, '7', 0, '3', 0,
660+
'c', 0, 'd', 0, '-', 0, '4', 0, 'c', 0, 'b', 0,
661+
'7', 0, '-', 0, '9', 0, '8', 0, 'b', 0, '8', 0,
662+
'-', 0, '9', 0, '1', 0, '3', 0, 'a', 0, '8', 0,
663+
'f', 0, 'c', 0, 'a', 0, '7', 0, 'b', 0, 'f', 0,
664+
'6', 0, '}', 0, 0, 0
665+
};
615666

616-
static void resetd_init() {
667+
TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");
668+
// nothing to with DATA & ACK stage
669+
if (stage != CONTROL_STAGE_SETUP) {
670+
return true;
671+
}
672+
673+
if (request->bRequest == 1 && request->wIndex == 7) {
674+
// Get Microsoft OS 2.0 compatible descriptor
675+
return tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_ms_os_20, sizeof(desc_ms_os_20));
676+
} else {
677+
return false;
678+
}
679+
680+
// stall unknown request
681+
return false;
617682
}
618683

619-
static void resetd_reset(uint8_t rhport) {
620-
(void) rhport;
684+
685+
static void resetd_init(void) {
686+
}
687+
688+
static void resetd_reset(uint8_t __unused rhport) {
621689
_itf_num = 0;
622690
}
623691

624-
static uint16_t resetd_open(uint8_t rhport,
625-
tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
626-
(void) rhport;
692+
static uint16_t resetd_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) {
627693
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass &&
628694
RESET_INTERFACE_SUBCLASS == itf_desc->bInterfaceSubClass &&
629695
RESET_INTERFACE_PROTOCOL == itf_desc->bInterfaceProtocol, 0);
@@ -636,35 +702,28 @@ static uint16_t resetd_open(uint8_t rhport,
636702
}
637703

638704
// Support for parameterized reset via vendor interface control request
639-
static bool resetd_control_xfer_cb(uint8_t rhport, uint8_t stage,
640-
tusb_control_request_t const *request) {
641-
(void) rhport;
705+
static bool resetd_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_control_request_t const * request) {
642706
// nothing to do with DATA & ACK stage
643707
if (stage != CONTROL_STAGE_SETUP) {
644708
return true;
645709
}
646710

647711
if (request->wIndex == _itf_num) {
648712
if (request->bRequest == RESET_REQUEST_BOOTSEL) {
649-
reset_usb_boot(0, (request->wValue & 0x7f));
713+
int gpio = -1;
714+
bool active_low = false;
715+
rom_reset_usb_boot_extra(gpio, (request->wValue & 0x7f), active_low);
650716
// does not return, otherwise we'd return true
651717
}
652-
653718
if (request->bRequest == RESET_REQUEST_FLASH) {
654-
watchdog_reboot(0, 0, 100);
719+
watchdog_reboot(0, 0, 10);
655720
return true;
656721
}
657-
658722
}
659723
return false;
660724
}
661725

662-
static bool resetd_xfer_cb(uint8_t rhport, uint8_t ep_addr,
663-
xfer_result_t result, uint32_t xferred_bytes) {
664-
(void) rhport;
665-
(void) ep_addr;
666-
(void) result;
667-
(void) xferred_bytes;
726+
static bool resetd_xfer_cb(uint8_t __unused rhport, uint8_t __unused ep_addr, xfer_result_t __unused result, uint32_t __unused xferred_bytes) {
668727
return true;
669728
}
670729

@@ -686,6 +745,7 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
686745
return &_resetd_driver;
687746
}
688747

748+
689749
#elif defined NO_USB
690750

691751
#warning "NO_USB selected. No output to Serial will occur!"

0 commit comments

Comments
 (0)