From 849681724af698c77b01a615595418ba2efd543e Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Thu, 1 Oct 2020 11:51:33 -0500 Subject: [PATCH 1/9] create N functions and inlines for multi hid interfaces --- src/class/hid/hid_device.c | 24 ++++++++--------- src/class/hid/hid_device.h | 53 ++++++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 10267d734..04ea31326 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -70,17 +70,17 @@ static inline hidd_interface_t* get_interface_by_itfnum(uint8_t itf_num) //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_hid_ready(void) +bool tud_hid_n_ready(uint8_t itf) { - uint8_t const itf = 0; + //uint8_t const itf = 0; uint8_t const ep_in = _hidd_itf[itf].ep_in; return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in); } -bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len) +bool tud_hid_n_report(uint8_t itf, uint8_t report_id, void const* report, uint8_t len) { uint8_t const rhport = 0; - uint8_t const itf = 0; + //uint8_t const itf = 0; hidd_interface_t * p_hid = &_hidd_itf[itf]; // claim endpoint @@ -104,16 +104,16 @@ bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len) return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len); } -bool tud_hid_boot_mode(void) +bool tud_hid_n_boot_mode(uint8_t itf) { - uint8_t itf = 0; + //uint8_t itf = 0; return _hidd_itf[itf].boot_mode; } //--------------------------------------------------------------------+ // KEYBOARD API //--------------------------------------------------------------------+ -bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) +bool tud_hid_n_keyboard_report(uint8_t itf, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { hid_keyboard_report_t report; @@ -127,13 +127,13 @@ bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycod tu_memclr(report.keycode, 6); } - return tud_hid_report(report_id, &report, sizeof(report)); + return tud_hid_n_report(itf, report_id, &report, sizeof(report)); } //--------------------------------------------------------------------+ // MOUSE APPLICATION API //--------------------------------------------------------------------+ -bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +bool tud_hid_n_mouse_report(uint8_t itf, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { hid_mouse_report_t report = { @@ -144,7 +144,7 @@ bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y .pan = horizontal }; - return tud_hid_report(report_id, &report, sizeof(report)); + return tud_hid_n_report(itf, report_id, &report, sizeof(report)); } //--------------------------------------------------------------------+ @@ -197,7 +197,7 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint1 p_hid->boot_mode = false; // default mode is REPORT p_hid->itf_num = desc_itf->bInterfaceNumber; - + // Use offsetof to avoid pointer to the odd/misaligned address memcpy(&p_hid->report_desc_len, (uint8_t*) p_hid->hid_descriptor + offsetof(tusb_hid_descriptor_hid_t, wReportLength), 2); diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 1e584e4c9..e6961515c 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -50,25 +50,35 @@ #endif //--------------------------------------------------------------------+ -// Application API +// Application API (Multiple Ports) +// CFG_TUD_HID > 1 //--------------------------------------------------------------------+ // Check if the interface is ready to use -bool tud_hid_ready(void); +bool tud_hid_n_ready(uint8_t itf); // Check if current mode is Boot (true) or Report (false) -bool tud_hid_boot_mode(void); +bool tud_hid_n_boot_mode(uint8_t itf); // Send report to host -bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len); +bool tud_hid_n_report(uint8_t itf, uint8_t report_id, void const* report, uint8_t len); // KEYBOARD: convenient helper to send keyboard report if application // use template layout report as defined by hid_keyboard_report_t -bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); +bool tud_hid_n_keyboard_report(uint8_t itf, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); // MOUSE: convenient helper to send mouse report if application // use template layout report as defined by hid_mouse_report_t -bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); +bool tud_hid_n_mouse_report(uint8_t itf, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); + +//--------------------------------------------------------------------+ +// Application API (Single Port) +//--------------------------------------------------------------------+ +static inline bool tud_hid_ready(void); +static inline bool tud_hid_boot_mode(void); +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len); +static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); +static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); //--------------------------------------------------------------------+ // Callbacks (Weak is optional) @@ -95,6 +105,34 @@ TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t boot_mode); // - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms). TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ +static inline bool tud_hid_ready(void) +{ + return tud_hid_n_ready(0); +} + +static inline bool tud_hid_boot_mode(void) +{ + return tud_hid_n_boot_mode(0); +} + +static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len) +{ + return tud_hid_n_report(0, report_id, report, len); +} + +static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) +{ + return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); +} + +static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) +{ + return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + /* --------------------------------------------------------------------+ * HID Report Descriptor Template * @@ -318,4 +356,3 @@ bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t e #endif #endif /* _TUSB_HID_DEVICE_H_ */ - From b7208d6f7e97e724853eb5d0e512a23005cc8790 Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Thu, 1 Oct 2020 12:51:48 -0500 Subject: [PATCH 2/9] add index to report descriptor callback. this is breaking and needs to be reviewed --- src/class/hid/hid_device.c | 2 +- src/class/hid/hid_device.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 04ea31326..b4c75e3fb 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -237,7 +237,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request } else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { - uint8_t const * desc_report = tud_hid_descriptor_report_cb(); + uint8_t const * desc_report = tud_hid_descriptor_report_cb((uint8_t) request->wIndex); tud_control_xfer(rhport, request, (void*) desc_report, p_hid->report_desc_len); } else diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index e6961515c..1873c4f09 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -86,7 +86,8 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8 // Invoked when received GET HID REPORT DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint8_t const * tud_hid_descriptor_report_cb(void); +// TODO Talk about this change... because it is breaking. Might be better way to handle. +uint8_t const * tud_hid_descriptor_report_cb(uint8_t desc_index); // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. From e21ab8d4a97ee909511cd096b440bf6255ca2c74 Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Thu, 1 Oct 2020 13:15:37 -0500 Subject: [PATCH 3/9] create hid multiple interface example --- .../device/hid_multipleinterface/Makefile | 12 + .../device/hid_multipleinterface/src/main.c | 208 ++++++++++++++++++ .../hid_multipleinterface/src/tusb_config.h | 110 +++++++++ .../src/usb_descriptors.c | 189 ++++++++++++++++ .../src/usb_descriptors.h | 34 +++ 5 files changed, 553 insertions(+) create mode 100644 examples/device/hid_multipleinterface/Makefile create mode 100644 examples/device/hid_multipleinterface/src/main.c create mode 100644 examples/device/hid_multipleinterface/src/tusb_config.h create mode 100644 examples/device/hid_multipleinterface/src/usb_descriptors.c create mode 100644 examples/device/hid_multipleinterface/src/usb_descriptors.h diff --git a/examples/device/hid_multipleinterface/Makefile b/examples/device/hid_multipleinterface/Makefile new file mode 100644 index 000000000..69b633fea --- /dev/null +++ b/examples/device/hid_multipleinterface/Makefile @@ -0,0 +1,12 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../rules.mk diff --git a/examples/device/hid_multipleinterface/src/main.c b/examples/device/hid_multipleinterface/src/main.c new file mode 100644 index 000000000..985d87246 --- /dev/null +++ b/examples/device/hid_multipleinterface/src/main.c @@ -0,0 +1,208 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +#include "usb_descriptors.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +void led_blinking_task(void); +void hid_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + tusb_init(); + + while (1) + { + tud_task(); // tinyusb device task + led_blinking_task(); + + hid_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// Invoked when usb bus is suspended +// remote_wakeup_en : if host allow us to perform remote wakeup +// Within 7ms, device must draw an average of current less than 2.5 mA from bus +void tud_suspend_cb(bool remote_wakeup_en) +{ + (void) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +//--------------------------------------------------------------------+ +// USB HID +//--------------------------------------------------------------------+ + +void hid_task(void) +{ + //Set up interfaces + const uint8_t keyboard_interface = 0; + const uint8_t mouse_interface = 1; + + // Poll every 10ms + const uint32_t interval_ms = 10; + static uint32_t start_ms = 0; + + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + uint32_t const btn = board_button_read(); + + // Remote wakeup + if ( tud_suspended() && btn ) + { + // Wake up host if we are in suspend mode + // and REMOTE_WAKEUP feature is enabled by host + tud_remote_wakeup(); + } + + /*------------- Keyboard -------------*/ + if ( tud_hid_n_ready(keyboard_interface) ) + { + // use to avoid send multiple consecutive zero report for keyboard + static bool has_key = false; + + if ( btn ) + { + uint8_t keycode[6] = { 0 }; + keycode[0] = HID_KEY_A; + + tud_hid_n_keyboard_report(keyboard_interface, REPORT_ID_KEYBOARD, 0, keycode); + + has_key = true; + }else + { + // send empty key report if previously has key pressed + if (has_key) tud_hid_n_keyboard_report(keyboard_interface, REPORT_ID_KEYBOARD, 0, NULL); + has_key = false; + } + } + + /*------------- Mouse -------------*/ + if ( tud_hid_n_ready(mouse_interface) ) + { + if ( btn ) + { + int8_t const delta = 5; + + // no button, right + down, no scroll pan + tud_hid_n_mouse_report(mouse_interface, REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0); + + // delay a bit before attempt to send keyboard report + board_delay(10); + } + } +} + + +// Invoked when received GET_REPORT control request +// Application must fill buffer report's content and return its length. +// Return zero will cause the stack to STALL request +uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) +{ + // TODO not Implemented + (void) report_id; + (void) report_type; + (void) buffer; + (void) reqlen; + + return 0; +} + +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +{ + // TODO set LED based on CAPLOCK, NUMLOCK etc... + (void) report_id; + (void) report_type; + (void) buffer; + (void) bufsize; +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + static uint32_t start_ms = 0; + static bool led_state = false; + + // Blink every interval ms + if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/device/hid_multipleinterface/src/tusb_config.h b/examples/device/hid_multipleinterface/src/tusb_config.h new file mode 100644 index 000000000..9056d5173 --- /dev/null +++ b/examples/device/hid_multipleinterface/src/tusb_config.h @@ -0,0 +1,110 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by board.mk +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +// RHPort max operational speed can defined by board.mk +// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +#ifndef BOARD_DEVICE_RHPORT_SPEED + #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #else + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #endif +#endif + +// Device mode with rhport and speed defined by board.mk +#if BOARD_DEVICE_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + +// This example doesn't use an RTOS +#define CFG_TUSB_OS OPT_OS_NONE + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//------------- CLASS -------------// +#define CFG_TUD_HID 2 +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_VENDOR 0 + +// HID buffer size Should be sufficient to hold ID (if any) + Data +#define CFG_TUD_HID_EP_BUFSIZE 16 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_multipleinterface/src/usb_descriptors.c b/examples/device/hid_multipleinterface/src/usb_descriptors.c new file mode 100644 index 000000000..f8423bdd1 --- /dev/null +++ b/examples/device/hid_multipleinterface/src/usb_descriptors.c @@ -0,0 +1,189 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.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) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .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; +} + +//--------------------------------------------------------------------+ +// HID Report Descriptor +//--------------------------------------------------------------------+ + +uint8_t const desc_hid_report1[] = +{ + TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD) ) +}; + +uint8_t desc_hid_report2[] = +{ + TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE) ) +}; + +// Invoked when received GET HID REPORT DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_hid_descriptor_report_cb(uint8_t desc_index) +{ + if (desc_index == 0) + { + return desc_hid_report1; + } + else if (desc_index == 1) + { + return desc_hid_report2; + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +enum +{ + ITF_NUM_HID1, + ITF_NUM_HID2, + ITF_NUM_TOTAL +}; + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_HID_DESC_LEN) + +#define EPNUM_HID1 0x81 +#define EPNUM_HID2 0x82 + +uint8_t const desc_configuration[] = +{ + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + + // Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID1, 4, HID_PROTOCOL_NONE, sizeof(desc_hid_report1), EPNUM_HID1, CFG_TUD_HID_EP_BUFSIZE, 10), + TUD_HID_DESCRIPTOR(ITF_NUM_HID2, 5, HID_PROTOCOL_NONE, sizeof(desc_hid_report2), EPNUM_HID2, CFG_TUD_HID_EP_BUFSIZE, 10) +}; + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// 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_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials, should use chip ID + "Keyboard Interface", // 4: Interface 1 String + "Mouse Interface", // 5: Interface 2 String +}; + +static uint16_t _desc_str[32]; + +// 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; + + 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 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) chr_count = 31; + + // Convert ASCII string into UTF-16 + for(uint8_t i=0; i Date: Thu, 1 Oct 2020 13:37:54 -0500 Subject: [PATCH 4/9] Add pipeline task for example --- .github/workflows/build.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index da1f9e5e0..e2db8f775 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,7 +9,7 @@ jobs: steps: - name: Setup Ruby uses: actions/setup-ruby@v1 - + - name: Checkout TinyUSB uses: actions/checkout@v2 @@ -35,13 +35,14 @@ jobs: - 'device/hid_composite' - 'device/hid_composite_freertos' - 'device/hid_generic_inout' + - 'device/hid_multipleinterface' - 'device/midi_test' - 'device/msc_dual_lun' - 'device/net_lwip_webserver' - 'device/usbtmc' - 'device/webusb_serial' - 'host/cdc_msc_hid' - + steps: - name: Setup Python uses: actions/setup-python@v1 @@ -79,7 +80,7 @@ jobs: with: # Cannot do submodule checkout here since LWIP's git server cannot checkout unadventised commits (it must use tags) submodules: 'false' - + - name: Checkout Submodules run: | git submodule sync --recursive From 081af79009dc40ab41be9976d22629c7d251a50d Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Fri, 2 Oct 2020 16:02:00 -0500 Subject: [PATCH 5/9] fix simple pull request comments. Implement descriptor index hack. --- .../device/hid_multipleinterface/src/main.c | 8 ++--- .../src/usb_descriptors.c | 5 ++- .../src/usb_descriptors.h | 34 ------------------- src/class/hid/hid_device.c | 20 ++++++++--- src/class/hid/hid_device.h | 5 ++- 5 files changed, 25 insertions(+), 47 deletions(-) delete mode 100644 examples/device/hid_multipleinterface/src/usb_descriptors.h diff --git a/examples/device/hid_multipleinterface/src/main.c b/examples/device/hid_multipleinterface/src/main.c index 985d87246..2efb1f5cb 100644 --- a/examples/device/hid_multipleinterface/src/main.c +++ b/examples/device/hid_multipleinterface/src/main.c @@ -30,8 +30,6 @@ #include "bsp/board.h" #include "tusb.h" -#include "usb_descriptors.h" - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -138,13 +136,13 @@ void hid_task(void) uint8_t keycode[6] = { 0 }; keycode[0] = HID_KEY_A; - tud_hid_n_keyboard_report(keyboard_interface, REPORT_ID_KEYBOARD, 0, keycode); + tud_hid_n_keyboard_report(keyboard_interface, 0, 0, keycode); has_key = true; }else { // send empty key report if previously has key pressed - if (has_key) tud_hid_n_keyboard_report(keyboard_interface, REPORT_ID_KEYBOARD, 0, NULL); + if (has_key) tud_hid_n_keyboard_report(keyboard_interface, 0, 0, NULL); has_key = false; } } @@ -157,7 +155,7 @@ void hid_task(void) int8_t const delta = 5; // no button, right + down, no scroll pan - tud_hid_n_mouse_report(mouse_interface, REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0); + tud_hid_n_mouse_report(mouse_interface, 0, 0x00, delta, delta, 0, 0); // delay a bit before attempt to send keyboard report board_delay(10); diff --git a/examples/device/hid_multipleinterface/src/usb_descriptors.c b/examples/device/hid_multipleinterface/src/usb_descriptors.c index f8423bdd1..a1a98c773 100644 --- a/examples/device/hid_multipleinterface/src/usb_descriptors.c +++ b/examples/device/hid_multipleinterface/src/usb_descriptors.c @@ -24,7 +24,6 @@ */ #include "tusb.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. @@ -73,12 +72,12 @@ uint8_t const * tud_descriptor_device_cb(void) uint8_t const desc_hid_report1[] = { - TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD) ) + TUD_HID_REPORT_DESC_KEYBOARD() }; uint8_t desc_hid_report2[] = { - TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE) ) + TUD_HID_REPORT_DESC_MOUSE() }; // Invoked when received GET HID REPORT DESCRIPTOR diff --git a/examples/device/hid_multipleinterface/src/usb_descriptors.h b/examples/device/hid_multipleinterface/src/usb_descriptors.h deleted file mode 100644 index 6992d3349..000000000 --- a/examples/device/hid_multipleinterface/src/usb_descriptors.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef USB_DESCRIPTORS_H_ -#define USB_DESCRIPTORS_H_ - -enum -{ - REPORT_ID_KEYBOARD = 1, - REPORT_ID_MOUSE -}; - -#endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index b4c75e3fb..9e1c5fd33 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -67,12 +67,21 @@ static inline hidd_interface_t* get_interface_by_itfnum(uint8_t itf_num) return NULL; } +static inline uint8_t get_descindex_by_itfnum(uint8_t itf_num) +{ + for (uint8_t i=0; i < CFG_TUD_HID; i++ ) + { + if ( itf_num == _hidd_itf[i].itf_num ) return i; + } + + return 0; +} + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ bool tud_hid_n_ready(uint8_t itf) { - //uint8_t const itf = 0; uint8_t const ep_in = _hidd_itf[itf].ep_in; return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in); } @@ -80,7 +89,6 @@ bool tud_hid_n_ready(uint8_t itf) bool tud_hid_n_report(uint8_t itf, uint8_t report_id, void const* report, uint8_t len) { uint8_t const rhport = 0; - //uint8_t const itf = 0; hidd_interface_t * p_hid = &_hidd_itf[itf]; // claim endpoint @@ -106,7 +114,6 @@ bool tud_hid_n_report(uint8_t itf, uint8_t report_id, void const* report, uint8_ bool tud_hid_n_boot_mode(uint8_t itf) { - //uint8_t itf = 0; return _hidd_itf[itf].boot_mode; } @@ -237,7 +244,12 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request } else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { - uint8_t const * desc_report = tud_hid_descriptor_report_cb((uint8_t) request->wIndex); + #if CFG_TUD_HID>1 + uint8_t const calculated_desc_index = get_descindex_by_itfnum((uint8_t) request->wIndex); + uint8_t const * desc_report = tud_hid_descriptor_report_cb(calculated_desc_index); + #else + uint8_t const * desc_report = tud_hid_descriptor_report_cb(); + #endif tud_control_xfer(rhport, request, (void*) desc_report, p_hid->report_desc_len); } else diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 1873c4f09..30d99ce47 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -86,8 +86,11 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8 // Invoked when received GET HID REPORT DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -// TODO Talk about this change... because it is breaking. Might be better way to handle. +#if CFG_TUD_HID>1 uint8_t const * tud_hid_descriptor_report_cb(uint8_t desc_index); +#else +uint8_t const * tud_hid_descriptor_report_cb(void); +#endif // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. From ed94e944c98d0f0318233a1fda01d947baa72ca9 Mon Sep 17 00:00:00 2001 From: Peter Lawrence <12226419+majbthrd@users.noreply.github.com> Date: Wed, 7 Oct 2020 13:15:58 -0500 Subject: [PATCH 6/9] mimxrt1010_evk: double stack size to allow net_lwip_webserver to run --- hw/bsp/mimxrt1010_evk/board.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/bsp/mimxrt1010_evk/board.mk b/hw/bsp/mimxrt1010_evk/board.mk index 4dc11693a..db4ab249b 100644 --- a/hw/bsp/mimxrt1010_evk/board.mk +++ b/hw/bsp/mimxrt1010_evk/board.mk @@ -19,6 +19,9 @@ MCU_DIR = hw/mcu/nxp/sdk/devices/MIMXRT1011 # All source paths should be relative to the top level. LD_FILE = $(MCU_DIR)/gcc/MIMXRT1011xxxxx_flexspi_nor.ld +LDFLAGS += \ + -Wl,--defsym,__stack_size__=0x800 \ + SRC_C += \ $(MCU_DIR)/system_MIMXRT1011.c \ $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ From db3fe97f62f22747df2c79a841bc1fb235f2f89e Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Wed, 7 Oct 2020 20:36:00 -0500 Subject: [PATCH 7/9] fix variable names. add itf n callbacks to multihid --- .../device/hid_multipleinterface/src/main.c | 6 +++-- .../src/usb_descriptors.c | 6 ++--- src/class/hid/hid_device.c | 22 ++++++++++++++++--- src/class/hid/hid_device.h | 10 ++++++++- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/examples/device/hid_multipleinterface/src/main.c b/examples/device/hid_multipleinterface/src/main.c index 2efb1f5cb..b1957b9fc 100644 --- a/examples/device/hid_multipleinterface/src/main.c +++ b/examples/device/hid_multipleinterface/src/main.c @@ -167,9 +167,10 @@ void hid_task(void) // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request -uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) +uint16_t tud_hid_n_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented + (void) itf; (void) report_id; (void) report_type; (void) buffer; @@ -180,9 +181,10 @@ uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) -void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +void tud_hid_n_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { // TODO set LED based on CAPLOCK, NUMLOCK etc... + (void) itf; (void) report_id; (void) report_type; (void) buffer; diff --git a/examples/device/hid_multipleinterface/src/usb_descriptors.c b/examples/device/hid_multipleinterface/src/usb_descriptors.c index a1a98c773..396d22621 100644 --- a/examples/device/hid_multipleinterface/src/usb_descriptors.c +++ b/examples/device/hid_multipleinterface/src/usb_descriptors.c @@ -83,13 +83,13 @@ uint8_t desc_hid_report2[] = // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_hid_descriptor_report_cb(uint8_t desc_index) +uint8_t const * tud_hid_n_descriptor_report_cb(uint8_t itf) { - if (desc_index == 0) + if (itf == 0) { return desc_hid_report1; } - else if (desc_index == 1) + else if (itf == 1) { return desc_hid_report2; } diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 9e1c5fd33..ffd495306 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -67,7 +67,7 @@ static inline hidd_interface_t* get_interface_by_itfnum(uint8_t itf_num) return NULL; } -static inline uint8_t get_descindex_by_itfnum(uint8_t itf_num) +static inline uint8_t get_hid_index_by_itfnum(uint8_t itf_num) { for (uint8_t i=0; i < CFG_TUD_HID; i++ ) { @@ -230,6 +230,10 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) request->wIndex ); TU_ASSERT(p_hid); + #if CFG_TUD_HID>1 + uint8_t const hid_itf = get_hid_index_by_itfnum((uint8_t) request->wIndex); + #endif + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { //------------- STD Request -------------// @@ -245,8 +249,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request else if (request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { #if CFG_TUD_HID>1 - uint8_t const calculated_desc_index = get_descindex_by_itfnum((uint8_t) request->wIndex); - uint8_t const * desc_report = tud_hid_descriptor_report_cb(calculated_desc_index); + uint8_t const * desc_report = tud_hid_n_descriptor_report_cb(hid_itf); #else uint8_t const * desc_report = tud_hid_descriptor_report_cb(); #endif @@ -268,7 +271,11 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); + #if CFG_TUD_HID>1 + uint16_t xferlen = tud_hid_n_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength); + #else uint16_t xferlen = tud_hid_get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength); + #endif TU_ASSERT( xferlen > 0 ); tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen); @@ -336,7 +343,12 @@ bool hidd_control_complete(uint8_t rhport, tusb_control_request_t const * p_requ uint8_t const report_type = tu_u16_high(p_request->wValue); uint8_t const report_id = tu_u16_low(p_request->wValue); + #if CFG_TUD_HID>1 + uint8_t const hid_itf = get_hid_index_by_itfnum((uint8_t)p_request->wIndex); + tud_hid_n_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength); + #else tud_hid_set_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength); + #endif } return true; @@ -358,7 +370,11 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (ep_addr == p_hid->ep_out) { + #if CFG_TUD_HID>1 + tud_hid_n_set_report_cb(itf, 0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes); + #else tud_hid_set_report_cb(0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes); + #endif TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 30d99ce47..4b8cb17d5 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -87,7 +87,7 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8 // Invoked when received GET HID REPORT DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete #if CFG_TUD_HID>1 -uint8_t const * tud_hid_descriptor_report_cb(uint8_t desc_index); +uint8_t const * tud_hid_n_descriptor_report_cb(uint8_t itf); #else uint8_t const * tud_hid_descriptor_report_cb(void); #endif @@ -95,11 +95,19 @@ uint8_t const * tud_hid_descriptor_report_cb(void); // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request +#if CFG_TUD_HID>1 +uint16_t tud_hid_n_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); +#else uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); +#endif // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) +#if CFG_TUD_HID>1 +void tud_hid_n_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); +#else void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); +#endif // Invoked when received SET_PROTOCOL request ( mode switch Boot <-> Report ) TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t boot_mode); From 298aa1b669a5c77f991c8161ba4c7d84f7a2b674 Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Thu, 8 Oct 2020 11:59:12 -0500 Subject: [PATCH 8/9] Cleanup per review on PR --- .../hid_multipleinterface/src/tusb_config.h | 2 +- .../src/usb_descriptors.c | 18 +++++++++--------- src/class/hid/hid_device.c | 4 +++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/examples/device/hid_multipleinterface/src/tusb_config.h b/examples/device/hid_multipleinterface/src/tusb_config.h index 9056d5173..412f9b004 100644 --- a/examples/device/hid_multipleinterface/src/tusb_config.h +++ b/examples/device/hid_multipleinterface/src/tusb_config.h @@ -101,7 +101,7 @@ #define CFG_TUD_VENDOR 0 // HID buffer size Should be sufficient to hold ID (if any) + Data -#define CFG_TUD_HID_EP_BUFSIZE 16 +#define CFG_TUD_HID_EP_BUFSIZE 8 #ifdef __cplusplus } diff --git a/examples/device/hid_multipleinterface/src/usb_descriptors.c b/examples/device/hid_multipleinterface/src/usb_descriptors.c index 396d22621..dd8ef7120 100644 --- a/examples/device/hid_multipleinterface/src/usb_descriptors.c +++ b/examples/device/hid_multipleinterface/src/usb_descriptors.c @@ -75,7 +75,7 @@ uint8_t const desc_hid_report1[] = TUD_HID_REPORT_DESC_KEYBOARD() }; -uint8_t desc_hid_report2[] = +uint8_t const desc_hid_report2[] = { TUD_HID_REPORT_DESC_MOUSE() }; @@ -86,15 +86,15 @@ uint8_t desc_hid_report2[] = uint8_t const * tud_hid_n_descriptor_report_cb(uint8_t itf) { if (itf == 0) - { - return desc_hid_report1; - } - else if (itf == 1) - { - return desc_hid_report2; - } + { + return desc_hid_report1; + } + else if (itf == 1) + { + return desc_hid_report2; + } - return 0; + return NULL; } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ffd495306..09daa0309 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -74,7 +74,7 @@ static inline uint8_t get_hid_index_by_itfnum(uint8_t itf_num) if ( itf_num == _hidd_itf[i].itf_num ) return i; } - return 0; + return 0xFF; } //--------------------------------------------------------------------+ @@ -232,6 +232,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request #if CFG_TUD_HID>1 uint8_t const hid_itf = get_hid_index_by_itfnum((uint8_t) request->wIndex); + TU_VERIFY(hid_itf<0xFF, 0); #endif if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) @@ -345,6 +346,7 @@ bool hidd_control_complete(uint8_t rhport, tusb_control_request_t const * p_requ #if CFG_TUD_HID>1 uint8_t const hid_itf = get_hid_index_by_itfnum((uint8_t)p_request->wIndex); + TU_VERIFY(hid_itf<0xFF, 0); tud_hid_n_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength); #else tud_hid_set_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength); From a4ba1f08275bc6fe8ce1f73d24f353861839cce7 Mon Sep 17 00:00:00 2001 From: Zachery Littell Date: Thu, 8 Oct 2020 12:08:13 -0500 Subject: [PATCH 9/9] Fix tu_verify args --- src/class/hid/hid_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 09daa0309..45b6aaaca 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -232,7 +232,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * request #if CFG_TUD_HID>1 uint8_t const hid_itf = get_hid_index_by_itfnum((uint8_t) request->wIndex); - TU_VERIFY(hid_itf<0xFF, 0); + TU_VERIFY(hid_itf<0xFF); #endif if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) @@ -346,7 +346,7 @@ bool hidd_control_complete(uint8_t rhport, tusb_control_request_t const * p_requ #if CFG_TUD_HID>1 uint8_t const hid_itf = get_hid_index_by_itfnum((uint8_t)p_request->wIndex); - TU_VERIFY(hid_itf<0xFF, 0); + TU_VERIFY(hid_itf<0xFF); tud_hid_n_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength); #else tud_hid_set_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength);