QUELLCODE / C
usb_descriptors.c
pico/usb_descriptors.c
1/*2 * OpenAss: nur privater, experimenteller Gebrauch; auf eigene Verantwortung.3 * Niemals Unternehmensrechner, Produktivsysteme, Industrieanlagen oder4 * sicherheitskritische Systeme anschließen oder bedienen.5 * Haftungshinweis und gesetzliche Grenzen: ../DISCLAIMER.txt.6 */7#include <string.h>8#include "pico/unique_id.h"9#include "tusb.h"10#include "usb_descriptors.h"1112// 0xCAFE is TinyUSB's example VID: development only. Obtain your own allocation13// before distributing commercial devices; never claim a third party's identity.14#ifndef HB_USB_VID15#define HB_USB_VID 0xCAFE16#endif17#ifndef HB_USB_PID18#define HB_USB_PID 0xB00119#endif2021static const tusb_desc_device_t device_descriptor = {22 .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE,23 .bcdUSB = 0x0200, .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0,24 .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .idVendor = HB_USB_VID,25 .idProduct = HB_USB_PID, .bcdDevice = 0x0100,26 .iManufacturer = 1, .iProduct = 2, .iSerialNumber = 3, .bNumConfigurations = 1,27};2829static const uint8_t keyboard_descriptor[] = { TUD_HID_REPORT_DESC_KEYBOARD() };3031// Explicit five-byte report: three button bits, padding, little-endian 16-bit32// X/Y in [0,32767]. Generic Desktop Mouse/Pointer, rather than a tablet digitizer.33static const uint8_t absolute_descriptor[] = {34 0x05,0x01, 0x09,0x02, 0xa1,0x01, 0x09,0x01, 0xa1,0x00,35 0x05,0x09, 0x19,0x01, 0x29,0x03, 0x15,0x00, 0x25,0x01,36 0x95,0x03, 0x75,0x01, 0x81,0x02,37 0x95,0x01, 0x75,0x05, 0x81,0x03,38 0x05,0x01, 0x09,0x30, 0x09,0x31,39 0x15,0x00, 0x26,0xff,0x7f, 0x75,0x10, 0x95,0x02, 0x81,0x02,40 0xc0,0xc0,41};4243// Report mode: buttons, signed dx/dy, wheel and AC Pan. Boot mode is handled in44// main.c with the three-byte boot mouse report required by USB HID.45static const uint8_t relative_descriptor[] = {46 0x05,0x01, 0x09,0x02, 0xa1,0x01, 0x09,0x01, 0xa1,0x00,47 0x05,0x09, 0x19,0x01, 0x29,0x03, 0x15,0x00, 0x25,0x01,48 0x95,0x03, 0x75,0x01, 0x81,0x02,49 0x95,0x01, 0x75,0x05, 0x81,0x03,50 0x05,0x01, 0x09,0x30, 0x09,0x31, 0x09,0x38,51 0x15,0x81, 0x25,0x7f, 0x75,0x08, 0x95,0x03, 0x81,0x06,52 0x05,0x0c, 0x0a,0x38,0x02,53 0x15,0x81, 0x25,0x7f, 0x75,0x08, 0x95,0x01, 0x81,0x06,54 0xc0,0xc0,55};5657#define HB_CONFIG_LENGTH (TUD_CONFIG_DESC_LEN + 3 * TUD_HID_DESC_LEN)58static const uint8_t configuration_descriptor[] = {59 TUD_CONFIG_DESCRIPTOR(1, HB_HID_COUNT, 0, HB_CONFIG_LENGTH, 0, 100),60 TUD_HID_DESCRIPTOR(HB_HID_KEYBOARD, 4, HID_ITF_PROTOCOL_KEYBOARD,61 sizeof(keyboard_descriptor), 0x81, CFG_TUD_HID_EP_BUFSIZE, 1),62 TUD_HID_DESCRIPTOR(HB_HID_ABSOLUTE, 5, HID_ITF_PROTOCOL_NONE,63 sizeof(absolute_descriptor), 0x82, CFG_TUD_HID_EP_BUFSIZE, 1),64 TUD_HID_DESCRIPTOR(HB_HID_RELATIVE, 6, HID_ITF_PROTOCOL_MOUSE,65 sizeof(relative_descriptor), 0x83, CFG_TUD_HID_EP_BUFSIZE, 1),66};6768uint8_t const *tud_descriptor_device_cb(void) { return (const uint8_t *)&device_descriptor; }69uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {70 return index == 0 ? configuration_descriptor : NULL;71}72uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance) {73 switch (instance) {74 case HB_HID_KEYBOARD: return keyboard_descriptor;75 case HB_HID_ABSOLUTE: return absolute_descriptor;76 case HB_HID_RELATIVE: return relative_descriptor;77 default: return NULL;78 }79}8081uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {82 (void)langid;83 static uint16_t buffer[33];84 static const char *const strings[] = {85 NULL, "Hardware Box", "Hardware Box HID v1", NULL,86 "Boot keyboard", "Absolute mouse", "Boot and relative mouse",87 };88 char serial[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2u + 1u];89 size_t length;90 if (index == 0) {91 buffer[1] = 0x0409;92 length = 1u;93 } else {94 const char *text;95 if (index == 3) {96 pico_get_unique_board_id_string(serial, sizeof(serial));97 text = serial;98 } else {99 if (index >= sizeof(strings) / sizeof(strings[0])) return NULL;100 text = strings[index];101 }102 length = strlen(text);103 if (length > 32u) length = 32u;104 for (size_t i = 0; i < length; ++i) buffer[i + 1u] = (uint8_t)text[i];105 }106 buffer[0] = (uint16_t)((TUSB_DESC_STRING << 8u) | (2u * length + 2u));107 return buffer;108}