diff --git a/CMakeLists.txt b/CMakeLists.txt index 8999287..5fed187 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,14 +15,8 @@ target_sources(${PROJECT} PRIVATE main_host.c usb_descriptors.c hyperx_elite2.c - # can use 'tinyusb_pico_pio_usb' library later when pico-sdk is updated - ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c - ${PICO_TINYUSB_PATH}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c ) - - - # print memory usage, enable all warnings target_link_options(${PROJECT} PRIVATE -Xlinker --print-memory-usage) target_compile_options(${PROJECT} PRIVATE ) #-Wall -Wextra @@ -36,8 +30,10 @@ target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) target_link_libraries(${PROJECT} PRIVATE pico_stdlib pico_pio_usb + tinyusb_board tinyusb_device tinyusb_host + tinyusb_pico_pio_usb hardware_adc ) diff --git a/build/hyperx_kb_rgb.uf2 b/build/hyperx_kb_rgb.uf2 index eb60347..f8e9cd7 100644 Binary files a/build/hyperx_kb_rgb.uf2 and b/build/hyperx_kb_rgb.uf2 differ diff --git a/hyperx_elite2.h b/hyperx_elite2.h index da8ba67..d125425 100644 --- a/hyperx_elite2.h +++ b/hyperx_elite2.h @@ -5,7 +5,7 @@ enum { HYPERX_KEYBOARD_VID = 0x0951, HYPERX_ELITE2_PID = 0x1711, - NUM_KEYS = 129, + NUM_KEYS = 128, BUF_SIZE = 64, NUM_PACKETS = 10, NKRO_BUF_SIZE = 15, diff --git a/tusb_config.h b/tusb_config.h index 7f1a1e8..e730790 100644 --- a/tusb_config.h +++ b/tusb_config.h @@ -65,11 +65,24 @@ // DEVICE CONFIGURATION //-------------------------------------------------------------------- +//------------------------- Board Specific -------------------------- + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUD_MAX_SPEED +#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + #ifndef CFG_TUD_ENDPOINT0_SIZE #define CFG_TUD_ENDPOINT0_SIZE 64 #endif -//------------- CLASS -------------// +//-----------------------Driver configuration------------------------- + #define CFG_TUD_CDC 1 #define CFG_TUD_HID 1 @@ -87,6 +100,20 @@ // HOST CONFIGURATION //-------------------------------------------------------------------- +//------------------------- Board Specific -------------------------- + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 1 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-----------------------Driver configuration------------------------- + // Size of buffer to hold descriptors and other data used for enumeration #define CFG_TUH_ENUMERATION_BUFSIZE 256 diff --git a/usb_descriptors.c b/usb_descriptors.c index 3447d5a..84a2b78 100644 --- a/usb_descriptors.c +++ b/usb_descriptors.c @@ -25,54 +25,43 @@ */ #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,29 +69,24 @@ 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_NKRO( HID_REPORT_ID(REPORT_ID_KEYBOARD)), - TUD_HID_REPORT_DESC_MEDIA( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL)), + TUD_HID_REPORT_DESC_NKRO( HID_REPORT_ID(REPORT_ID_KEYBOARD)), + TUD_HID_REPORT_DESC_MEDIA( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL)), }; // full speed configuration uint8_t const desc_fs_configuration[] = { - // Config number, interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), // 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), + 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), }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -110,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; } @@ -122,53 +106,53 @@ 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 HyperX RGB Controller", // 2: Product - "1234567890123456789", // 3: Serials, should use chip ID - "Pico HyperX RGB Controller CDC", // 4: CDC Interface - "Pico HyperX RGB Controller Keyboard",// 5: HID Keyboard Interface - "Pico HyperX RGB Controller Rollover",// 6: HID Keyboard Rollover Keys + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "Raspberry Pi", // 1: Manufacturer + "Pico HyperX RGB Controller", // 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