diff options
| author | Louis Burda <quent.burda@gmail.com> | 2022-11-20 19:26:20 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2022-11-20 19:26:20 +0100 |
| commit | 7f1cf3407ab3ba4827053133a7a47901ce763c61 (patch) | |
| tree | 85f5d8030fb6810b83cbb3a2590108d8888feb5b /src | |
| parent | 7162946544630859face4ef3e397c16d823028f5 (diff) | |
| download | sxkbd-7f1cf3407ab3ba4827053133a7a47901ce763c61.tar.gz sxkbd-7f1cf3407ab3ba4827053133a7a47901ce763c61.zip | |
Integrate tinyUSB composite HID example
Diffstat (limited to 'src')
| -rw-r--r-- | src/board.h | 8 | ||||
| -rw-r--r-- | src/main.c | 137 | ||||
| -rw-r--r-- | src/tusb_config.h | 2 | ||||
| -rw-r--r-- | src/usb_descriptors.c | 46 |
4 files changed, 164 insertions, 29 deletions
diff --git a/src/board.h b/src/board.h index 38775b7..77d1840 100644 --- a/src/board.h +++ b/src/board.h @@ -4,4 +4,12 @@ #define ONBOARD_LED_PIN 25 +#define REPORT_ID_MIN REPORT_ID_KEYBOARD +enum { + REPORT_ID_KEYBOARD = 1, + REPORT_ID_MOUSE, + REPORT_ID_CONSUMER_CONTROL, + REPORT_ID_MAX +}; + extern struct neopix onboard_led; @@ -1,5 +1,7 @@ #include "board.h" #include "class/cdc/cdc_device.h" +#include "class/hid/hid.h" +#include "device/usbd.h" #include "neopix.h" #include "util.h" @@ -24,7 +26,10 @@ void stub_stdio_write(const char *buf, int len); void stub_stdio_flush(void); int stub_stdio_read(char *buf, int len); -void led_blinking_task(void); +bool send_hid_report(int id, bool state); + +void hid_task(void); +void blink_task(void); static struct stdio_driver usb_stdio = { .out_chars = stub_stdio_write, @@ -35,6 +40,8 @@ static struct stdio_driver usb_stdio = { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; +static bool hit_state = false; + struct neopix onboard_led; int @@ -51,7 +58,8 @@ main(void) while (true) { tud_task(); - led_blinking_task(); + blink_task(); + hid_task(); } return 0; @@ -114,7 +122,6 @@ tud_cdc_rx_cb(uint8_t itf) (void) itf; } -/* Invoked on GET_REPORT */ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) @@ -128,7 +135,6 @@ tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, return 0; } -/* Invoked on SET_REPORT or receive on OUT with (Report ID = 0, Type = 0) */ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) @@ -136,21 +142,136 @@ tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, (void) itf; (void) report_id; (void) report_type; + (void) buffer; + (void) bufsize; +} + +void +tud_hid_report_complete_cb(uint8_t instance, + uint8_t const *report, uint8_t len) +{ + uint8_t id; + + (void) instance; + (void) report; + (void) len; + + for (id = report[0] + 1; id < REPORT_ID_MAX; id++) { + if (send_hid_report(id, hit_state)) + break; + } +} + +bool +send_keyboard_report(bool state) +{ + static bool cleared = true; + uint8_t keycode[6] = { 0 }; + + if (state) { + keycode[0] = HID_KEY_A; + tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode); + cleared = false; + return true; + } else if (!cleared) { + tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); + cleared = true; + return true; + } + + return false; +} + +bool +send_mouse_report(bool state) +{ + if (state) { + tud_hid_mouse_report(REPORT_ID_MOUSE, 0, 10, 10, 0, 0); + return true; + } + + return false; +} + +bool +send_consumer_control_report(bool state) +{ + static bool cleared = true; + uint16_t report; + + if (state) { + report = HID_USAGE_CONSUMER_VOLUME_DECREMENT; + tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &report, 2); + cleared = false; + return true; + } else if (!cleared) { + report = 0; + tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &report, 2); + cleared = true; + return true; + } - tud_hid_report(0, buffer, bufsize); + return false; +} + +bool +send_hid_report(int id, bool state) +{ + switch (id) { + case REPORT_ID_KEYBOARD: + return send_keyboard_report(state); + case REPORT_ID_MOUSE: + return send_mouse_report(state); + case REPORT_ID_CONSUMER_CONTROL: + return send_consumer_control_report(state); + } + + return false; +} + +void +send_hid_report_timed(void) +{ + const uint32_t period_ms = 1000; + static uint32_t start_ms = 0; + + if (!tud_hid_ready()) return; + + hit_state = (board_millis() - start_ms < period_ms); + if (hit_state) start_ms += period_ms; + + send_hid_report(REPORT_ID_MIN, hit_state); } void -led_blinking_task(void) +hid_task(void) +{ + const uint32_t poll_ms = 10; + static uint32_t start_ms = 0; + + if (board_millis() - start_ms < poll_ms) + return; + start_ms += poll_ms; + + // if (tud_suspended()) { + // tud_remote_wakeup(); + // return; + // } + + send_hid_report_timed(); +} + +void +blink_task(void) { static uint32_t start_ms = 0; static bool state = false; if (board_millis() - start_ms < blink_interval_ms) return; + start_ms += blink_interval_ms; + state ^= true; neopix_put(&onboard_led, neopix_u32rgb(255 * state, 0, 255 * state)); - start_ms += blink_interval_ms; - state ^= true; } diff --git a/src/tusb_config.h b/src/tusb_config.h index cd251d6..31bdac7 100644 --- a/src/tusb_config.h +++ b/src/tusb_config.h @@ -46,6 +46,8 @@ extern "C" { #define CFG_TUD_MIDI 0 #define CFG_TUD_VENDOR 0 +#define CFG_TUD_HID_EP_BUFSIZE 16 + #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c index 8372c2a..8b648ef 100644 --- a/src/usb_descriptors.c +++ b/src/usb_descriptors.c @@ -1,32 +1,32 @@ +#include "board.h" + +#include "class/hid/hid_device.h" #include "tusb.h" #include "tusb_types.h" #define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) -/* same VID/PID with difference interface can cause issues! */ +/* same VID/PID with different interface can cause issues! */ #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 0xC0FE +#define USB_VID 0xC0FF #define USB_BCD 0x0200 #define CONFIG_TOTAL_LEN \ - (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_INOUT_DESC_LEN) - -#define EPNUM_HID 0x01 + (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_HID_DESC_LEN) /* MCU-specific! */ #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_IN 0x82 -#define EPNUM_MSC_OUT 0x03 -#define EPNUM_MSC_IN 0x83 +#define EPNUM_HID 0x83 enum { ITF_NUM_CDC, - ITF_NUM_CTC_DATA, + ITF_NUM_CDC_DATA, ITF_NUM_HID, ITF_NUM_TOTAL }; @@ -36,9 +36,9 @@ tusb_desc_device_t const desc_device = { .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, @@ -54,13 +54,16 @@ tusb_desc_device_t const desc_device = { }; uint8_t const desc_hid_report[] = { - TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_EP_BUFSIZE) + 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_CONSUMER(HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL)) }; 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), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), /* Interface number, string index, EP notification address and size, * EP data address (out, in) and size */ @@ -68,16 +71,17 @@ uint8_t const desc_fs_configuration[] = { EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), /* Interface number, string index, protocol, report descriptor len, - * EP In & Out address, size & polling interval */ - TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 5, HID_ITF_PROTOCOL_NONE, - sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, 64, 10) + * EP In address, size & polling interval */ + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 5, HID_ITF_PROTOCOL_NONE, + sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5) }; #if TUD_OPT_HIGH_SPEED uint8_t const desc_hs_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), + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), /* Interface number, string index, EP notification address and size, * EP data address (out, in) and size */ @@ -85,9 +89,9 @@ uint8_t const desc_hs_configuration[] = { EPNUM_CDC_OUT, EPNUM_CDC_IN, 512), /* Interface number, string index, protocol, report descriptor len, - * EP In & Out address, size & polling interval */ - TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 5, HID_ITF_PROTOCOL_NONE, - sizeof(desc_hid_report), EPNUM_HID, 0x80 | EPNUM_HID, 512, 10) + * EP In address, size & polling interval */ + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 5, HID_ITF_PROTOCOL_NONE, + sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5) }; uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; @@ -109,7 +113,7 @@ tusb_desc_device_qualifier_t const desc_device_qualifier = #endif char const *string_desc_arr[] = { - [0] = (const char[]) { 0x09, 0x04 }, /* supported language is English */ + [0] = (const char[]) { 0x09, 0x04 }, /* Supported language is English */ [1] = "TinyUSB", /* Manufacturer */ [2] = "TinyUSB Device", /* Product */ [3] = "123456", /* Serials, should use chip ID */ |
