diff options
Diffstat (limited to 'tusb_callbacks.c')
-rw-r--r-- | tusb_callbacks.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tusb_callbacks.c b/tusb_callbacks.c new file mode 100644 index 0000000..84214c9 --- /dev/null +++ b/tusb_callbacks.c @@ -0,0 +1,141 @@ +/* tinyusb */ +#include "bsp/board_api.h" +#include "tusb.h" + +/* local */ +#include "tusb_helpers.h" + +#define NUM_INTERFACES CFG_TUD_HID +#define NUM_CONFIGS 1 + +enum { + STRID_LANGID = 0, + STRID_MANUF, + STRID_PRODUCT, + STRID_SERIAL, + + STRID_NONE = 0, +}; + +/** + * Return a pointer to the USB "String Descriptor" (see USB 2.0 §9.6.7 + * "String"). + */ +uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + static uint16_t desc[0xFF/2]; + static const max_u16len = (sizeof desc / sizeof desc[0]) - 1; + + static uint16_t const langids[] = { + LANGID_EN_US, + }; + + size_t bytelen = 0; + if (index == 0) { + memcpy(&desc[1], langids, sizeof langids); + bytelen = sizeof langids; + } else { + switch (langid) { + case LANGID_EN_US: + switch (index) { + case STRID_MANUF: bytelen = 2 * utf16_strncpy(&desc[1], UTF16("Umorpha Systems"), max_u16len); break; + case STRID_PRODUCT: bytelen = 2 * utf16_strncpy(&desc[1], UTF16("SBC-Harness Keyboard"), max_u16len); break; + case STRID_SERIAL: bytelen = 2 * board_usb_get_serial(&desc[1], max_u16len); break; + default: + return NULL; + }; + default: + return NULL; + } + } + assert(bytelen <= 0xFF-2); + desc[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2+bytelen)); + return desc; +} + +/** + * Return a pointer to the USB "Device Descriptor" (see USB 2.0 §9.6.1 + * "Device") as a byte-array. + */ +uint8_t const *tud_decriptor_device_cb(void) { + /* Our device descriptor is static, so just declare it as a + * static const. */ + static tusb_desc_device_t const desc = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x200, /* USB 2.0 */ + + /* Use the "base device class", which means to use information + * form interface descriptors instead of a global device + * descriptor. */ + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + + .idVendor = 0xCAFE, /* Vendor ID (assigned by the USB-IF) */ + .idProduct = 0x4001, /* Product ID (assigned by the manufacturer) */ + .bcdDevice = 0x0100, /* Device release number */ + + .iManufacturer = STRID_MANUF /* Index of string descriptor describing manufacturer */ + .iProduct = STRID_PRODUCT, /* Index of string descriptor describing product */ + .iSerialNumber = STRID_SERIAL, /* Index of string descriptor describing the device's serial number */ + + .bNumConfigurations = NUM_CONFIGS, /* Number of possible configurations */ + }; + return (uint8_t const *) &desc; +} + +/** + * A USB-HID "Report Descriptor" (see USB-HID 1.11 §6.2.2 "Report + * Descriptor") describing a keyboard. + */ +static uint8_t const hid_report_descriptor_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD() }; + +/** + * Return a pointer to the USB config "Configuration Descriptor" (see + * USB 2.0 §9.6.4 "Configuration") for the given index. + */ +uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { + static uint8_t const configs[NUM_CONFIGS][] = { + { + /* USB configuration descriptor header (USB 2.0 §9.6.4 "Configuration") */ + TUD_CONFIG_DESCRIPTOR( + 1, /* bConfigurationValue ; Value to use as an argument to the SetConfiguration() request to select this configuration */ + NUM_INTERFACES, /* bNumInterfaces ; Number of interfaces supported by this configuration */ + STRID_NONE, /* iConfiguration ; Index of string descriptor describing this configuration */ + TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN, /* wTotalLength ; Total lenggth of data returned for this configuration */ + TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, /* bmAttributes ; Bitmap of flags (self-powered and remote-wakeup are the only flags defined in USB 2.0) */ + 100), /* bMaxPower (in mA) ; Maximum power consumption of the device when in this configuration */ + /* USB-HID input-only descriptor; consisting of 3 parts: + * 1. an interface descriptor (USB 2.0 §9.6.5 "Interface"), + * 2. a class-specific (class=HID) descriptor of type HID (USB-HID 1.11 §6.2.1 "HID Descriptor"), + * 3. an endpoint descriptor for inputs (USB 2.0 §9.6.6 "Endpoint"). + * The TUD_HID_DESCRIPTOR() macro takes care of this for us. */ + TUD_HID_DESCRIPTOR( + 0, /* interface : bInterfaceNumber ; Number of this interface (0-indexed) */ + STRID_NONE, /* interface : iInterface ; Index of string descriptor describing this interface */ + HID_ITF_PROTOCOL_KEYBOARD, /* interface : bInterfaceProtocol ; see USB-HID 1.11 §4.3 "Protocols" */ + sizeof(hid_report_descriptor_keyboard), /* hid : wDescriptorLength ; Total size of report descriptor */ + TUD_ENDPOINT_IN | 1, /* endpoint : bEndpointAddress ; Direction | endpoint number (arbitrary?) */ + CFG_TUD_HID_EP_BUFSIZE, /* endpoint : wMaxPacketSize ; Maximum packet size this endpoint is capable of sending or receiving */ + 10), /* endpoint : bInterval ; poll interval (in milliseconds?) */ + }, + }; + if (index >= sizeof config / sizeof configs[0]) + return NULL; + return configs[index]; +} + +/** + * Return a pointer to the HID "Report Descriptor" (see USB-HID 1.11 + * §6.2.2 "Report Descriptor") for the given index. + */ +uint8_t const *tud_hid_descriptor_report_cb(uint8_t index) { + static uint8_t const *reports[NUM_INTERFACES] = { + hid_report_descriptor_keyboard, + }; + if (index >= sizeof reports / sizeof reports[0]) + return NULL; + return reports[index]; +} |