diff --git a/CMakeLists.txt b/CMakeLists.txt index d20c37dca..559840023 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ target_include_directories(debugprobe PRIVATE src) target_compile_definitions (debugprobe PRIVATE PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1 + PICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE=1 ) option (DEBUG_ON_PICO "Compile firmware for the Pico instead of Debug Probe" OFF) @@ -71,6 +72,7 @@ endif () target_link_libraries(debugprobe PRIVATE pico_multicore pico_stdlib + pico_usb_reset_interface pico_unique_id tinyusb_device tinyusb_board diff --git a/src/tusb_edpt_handler.c b/src/tusb_edpt_handler.c index 67698684b..07ce1fb10 100644 --- a/src/tusb_edpt_handler.c +++ b/src/tusb_edpt_handler.c @@ -282,10 +282,15 @@ usbd_class_driver_t const _dap_edpt_driver = #endif }; +static usbd_class_driver_t const _edpt_drivers[] = { + _dap_edpt_driver, + pico_usb_reset_interface_driver, +}; + // Add the custom driver to the tinyUSB stack usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) { - *driver_count = 1; - return &_dap_edpt_driver; + *driver_count = sizeof(_edpt_drivers) / sizeof(_edpt_drivers[0]); + return _edpt_drivers; } diff --git a/src/tusb_edpt_handler.h b/src/tusb_edpt_handler.h index be1fdd0fa..c72651429 100644 --- a/src/tusb_edpt_handler.h +++ b/src/tusb_edpt_handler.h @@ -12,6 +12,8 @@ #include "device/usbd_pvt.h" #include "DAP_config.h" +#include "pico/usb_reset_interface_device.h" + #define DAP_INTERFACE_SUBCLASS 0x00 #define DAP_INTERFACE_PROTOCOL 0x00 diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 7adec8d35..324cb7595 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -28,6 +28,7 @@ #include "tusb.h" #include "get_serial.h" #include "probe_config.h" +#include "pico/usb_reset_interface_device.h" //--------------------------------------------------------------------+ // Device Descriptors @@ -71,6 +72,7 @@ enum ITF_NUM_PROBE, // Old versions of Keil MDK only look at interface 0 ITF_NUM_CDC_COM, ITF_NUM_CDC_DATA, + ITF_NUM_RESET, ITF_NUM_TOTAL }; @@ -83,7 +85,7 @@ enum #if (PROBE_DEBUG_PROTOCOL == PROTO_DAP_V1) #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_INOUT_DESC_LEN) #else -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_VENDOR_DESC_LEN + TUD_RPI_RESET_DESC_LEN) #endif static uint8_t const desc_hid_report[] = @@ -113,6 +115,8 @@ uint8_t desc_configuration[] = #endif // Interface 1 + 2 TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_COM, 6, CDC_NOTIFICATION_EP_NUM, 64, CDC_DATA_OUT_EP_NUM, CDC_DATA_IN_EP_NUM, 64), + // Reset interface + TUD_RPI_RESET_DESCRIPTOR(ITF_NUM_RESET, 7), }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -122,7 +126,7 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { (void) index; // for multiple configurations /* Hack in CAP_BREAK support */ - desc_configuration[CONFIG_TOTAL_LEN - TUD_CDC_DESC_LEN + 8 + 9 + 5 + 5 + 4 - 1] = 0x6; + desc_configuration[CONFIG_TOTAL_LEN - TUD_RPI_RESET_DESC_LEN - TUD_CDC_DESC_LEN + 8 + 9 + 5 + 5 + 4 - 1] = 0x6; return desc_configuration; } @@ -140,6 +144,7 @@ char const* string_desc_arr [] = "CMSIS-DAP v1 Interface", // 4: Interface descriptor for HID transport "CMSIS-DAP v2 Interface", // 5: Interface descriptor for Bulk transport "CDC-ACM UART Interface", // 6: Interface descriptor for CDC + "Reset", // 7: Interface descriptor for Reset }; static uint16_t _desc_str[32]; @@ -198,7 +203,8 @@ will insert "DeviceInterfaceGUIDs" multistring property. https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ (Section Microsoft OS compatibility descriptors) */ -#define MS_OS_20_DESC_LEN 0xB2 +#define MS_OS_FEATURE_DESC_LEN 0xA0 +#define MS_OS_20_DESC_LEN (0x0A + 0x08 + MS_OS_FEATURE_DESC_LEN + RPI_RESET_MS_OS_20_DESC_LEN) #define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) @@ -220,14 +226,14 @@ uint8_t const desc_ms_os_20[] = 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_PROBE, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08), + U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_PROBE, 0, U16_TO_U8S_LE(MS_OS_FEATURE_DESC_LEN), // 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(MS_OS_FEATURE_DESC_LEN-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, @@ -236,7 +242,9 @@ uint8_t const desc_ms_os_20[] = '{', 0x00, 'C', 0x00, 'D', 0x00, 'B', 0x00, '3', 0x00, 'B', 0x00, '5', 0x00, 'A', 0x00, 'D', 0x00, '-', 0x00, '2', 0x00, '9', 0x00, '3', 0x00, 'B', 0x00, '-', 0x00, '4', 0x00, '6', 0x00, '6', 0x00, '3', 0x00, '-', 0x00, 'A', 0x00, 'A', 0x00, '3', 0x00, '6', 0x00, '-', 0x00, '1', 0x00, 'A', 0x00, 'A', 0x00, 'E', 0x00, '4', 0x00, - '6', 0x00, '4', 0x00, '6', 0x00, '3', 0x00, '7', 0x00, '7', 0x00, '6', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00 + '6', 0x00, '4', 0x00, '6', 0x00, '3', 0x00, '7', 0x00, '7', 0x00, '6', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, + + RPI_RESET_MS_OS_20_DESCRIPTOR(ITF_NUM_RESET) }; TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");