diff --git a/CMakeLists.txt b/CMakeLists.txt index 62095da..750ccac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ target_link_libraries(${PROJECT} pico_stdlib pico_multicore pico_mbedtls + tinyusb_board tinyusb_device ) diff --git a/usb_descriptors.c b/usb_descriptors.c index 7ca4715..2efd843 100644 --- a/usb_descriptors.c +++ b/usb_descriptors.c @@ -25,54 +25,44 @@ */ #include "tusb.h" +#include "bsp/board_api.h" + #include "usb_descriptors.h" -/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. - * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. - * - * Auto ProductID layout's Bitmap: - * [MSB] HID | MSC | CDC [LSB] - */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) - -#define USB_VID 0xCafe -#define USB_BCD 0x0200 //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ tusb_desc_device_t const desc_device = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = USB_BCD, + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = USB_BCD, - // 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) - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, + // 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) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = USB_VID, - .idProduct = USB_PID, - .bcdDevice = 0x0100, + .idVendor = USB_VID, + .idProduct = USB_PID, + .bcdDevice = 0x0100, - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, - .bNumConfigurations = 0x01 + .bNumConfigurations = 0x01 }; // Invoked when received GET DEVICE DESCRIPTOR // Application return pointer to descriptor uint8_t const * tud_descriptor_device_cb(void) { - return (uint8_t const *) &desc_device; + return (uint8_t const *) &desc_device; } @@ -80,17 +70,10 @@ uint8_t const * tud_descriptor_device_cb(void) // Configuration Descriptor //--------------------------------------------------------------------+ -#define EPNUM_CDC_NOTIF 0x81 -#define EPNUM_CDC_OUT 0x02 -#define EPNUM_CDC_IN 0x82 -#define EPNUM_HID 0x83 - -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_DESC_LEN) - uint8_t const desc_hid_report[] = { - TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD)), - TUD_HID_REPORT_DESC_MOUSE( HID_REPORT_ID(REPORT_ID_MOUSE)) + TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD)), + TUD_HID_REPORT_DESC_MOUSE( HID_REPORT_ID(REPORT_ID_MOUSE)) }; @@ -98,10 +81,10 @@ uint8_t const desc_hid_report[] = // full speed configuration uint8_t const desc_fs_configuration[] = { - // Config number, interface count, string index, total length, attribute, power in mA - atttribute 0xa0 enables wakeup - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0xa0, 100), + // Config number, interface count, string index, total length, attribute, power in mA - atttribute 0xa0 enables wakeup + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0xa0, 100), - // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), TUD_HID_DESCRIPTOR(ITF_NUM_HID, 5, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5), }; @@ -111,8 +94,8 @@ uint8_t const desc_fs_configuration[] = // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { - (void) index; // for multiple configurations - return desc_fs_configuration; + (void) index; // for multiple configurations + return desc_fs_configuration; } @@ -123,55 +106,55 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) // array of pointer to string descriptors char const* string_desc_arr [] = { - (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) - "Raspberry Pi", // 1: Manufacturer - "Pico Web Keyboard", // 2: Product - "1234567890123456789", // 3: Serials, should use chip ID - "Pico Web Keyboard CDC", // 4: CDC Interface - "Pico Web Keyboard HID", // 5: HID Keyboard Interface + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "Raspberry Pi", // 1: Manufacturer + "Pico Web Keyboard", // 2: Product + NULL, // 3: Serials, should use chip ID }; -static uint16_t _desc_str[32]; +static uint16_t _desc_str[32+1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void) langid; + (void) langid; - uint8_t chr_count; + uint8_t chr_count; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. - // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + switch (index) { + case 0: // langid + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + case 3: // serial + chr_count = board_usb_get_serial(_desc_str+1, 32); + break; + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; - const char* str = string_desc_arr[index]; + char* str = string_desc_arr[index]; - // Cap at max char - chr_count = (uint8_t) strlen(str); - if ( chr_count > 31 ) chr_count = 31; + // Cap at max char + chr_count = (uint8_t) strlen(str); + if ( chr_count > 31 ) chr_count = 31; - // Convert ASCII string into UTF-16 - for(uint8_t i=0; i