@@ -147,8 +147,8 @@ void USBClass::removeEntry(Entry **head, unsigned int localid) {
147147unsigned 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
614633static 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