sxkbd

Firmware for RP2040-based corne split keyboard
git clone https://git.sinitax.com/sinitax/sxkbd
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

usb_descriptors.c (5638B)


      1 #include "hid.h"
      2 
      3 #include "class/hid/hid_device.h"
      4 #include "tusb.h"
      5 #include "tusb_types.h"
      6 
      7 #define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
      8 
      9 #define CONFIG_TOTAL_LEN \
     10 	(TUD_CONFIG_DESC_LEN + 2 * TUD_HID_DESC_LEN + TUD_CDC_DESC_LEN)
     11 
     12 /* MCU-specific! */
     13 #define EPNUM_HID_KBD    0x81
     14 #define EPNUM_HID_MISC   0x82
     15 #define EPNUM_CDC_NOTIF  0x84
     16 #define EPNUM_CDC_IN     0x85
     17 #define EPNUM_CDC_OUT    0x05
     18 
     19 /* NOTE: same VID/PID with different interface can cause issues! */
     20 
     21 enum {
     22 	ITF_NUM_HID_KBD,
     23 	ITF_NUM_HID_MISC,
     24 	ITF_NUM_CDC,
     25 	ITF_NUM_CDC_DATA,
     26 	ITF_NUM_TOTAL
     27 };
     28 
     29 static const tusb_desc_device_t desc_device = {
     30 	.bLength            = sizeof(tusb_desc_device_t),
     31 	.bDescriptorType    = TUSB_DESC_DEVICE,
     32 	.bcdUSB             = 0x200,
     33 
     34 	.bDeviceClass       = 0x00,
     35 	.bDeviceSubClass    = 0x00,
     36 	.bDeviceProtocol    = 0x00,
     37 
     38 	.bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE,
     39 
     40 	.idVendor           = 0x1209,
     41 	.idProduct          = 0xDEF0,
     42 	.bcdDevice          = 0x0100,
     43 
     44 	.iManufacturer      = 0x01,
     45 	.iProduct           = 0x02,
     46 	.iSerialNumber      = 0x03,
     47 
     48 	.bNumConfigurations = 0x01
     49 };
     50 
     51 static const uint8_t desc_hid_kbd_report[] = {
     52 	TUD_HID_REPORT_DESC_KEYBOARD()
     53 };
     54 
     55 static const uint8_t desc_hid_misc_report[] = {
     56 	TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE)),
     57 	TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(REPORT_ID_CONSUMER)),
     58 	TUD_HID_REPORT_DESC_SYSTEM_CONTROL(HID_REPORT_ID(REPORT_ID_SYSTEM)),
     59 	TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(REPORT_ID_GAMEPAD))
     60 };
     61 
     62 static const uint8_t desc_fs_configuration[] = {
     63 	/* Config number, interface count, string index,
     64 	 * total length, attribute, power in mA */
     65 	TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN,
     66 		TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
     67 
     68 	/* Interface number, string index, protocol, report descriptor len,
     69 	 * EP In address, size & polling interval */
     70 	TUD_HID_DESCRIPTOR(ITF_NUM_HID_KBD, 5, HID_ITF_PROTOCOL_KEYBOARD,
     71 		sizeof(desc_hid_kbd_report), EPNUM_HID_KBD, 8, 1),
     72 	TUD_HID_DESCRIPTOR(ITF_NUM_HID_MISC, 6, HID_ITF_PROTOCOL_NONE,
     73 		sizeof(desc_hid_misc_report), EPNUM_HID_MISC, 16, 1),
     74 
     75 	/* Interface number, string index, EP notification address and size,
     76 	 * EP data address (out, in) and size */
     77 	TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8,
     78 		EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
     79 };
     80 
     81 #if TUD_OPT_HIGH_SPEED
     82 static const uint8_t desc_hs_configuration[] = {
     83 	/* Config number, interface count, string index,
     84 	 * total length, attribute, power in mA */
     85 	TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN,
     86 		TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
     87 
     88 	/* Interface number, string index, protocol, report descriptor len,
     89 	 * EP In address, size & polling interval */
     90 	TUD_HID_DESCRIPTOR(ITF_NUM_HID_KBD, 5, HID_ITF_PROTOCOL_KEYBOARD,
     91 		sizeof(desc_hid_kbd_report), EPNUM_HID_KBD, 8, 1),
     92 	TUD_HID_DESCRIPTOR(ITF_NUM_HID_MISC, 6, HID_ITF_PROTOCOL_NONE,
     93 		sizeof(desc_hid_misc_report), EPNUM_HID_MISC, 16, 1),
     94 
     95 	/* Interface number, string index, EP notification address and size,
     96 	 * EP data address (out, in) and size */
     97 	TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8,
     98 		EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
     99 };
    100 
    101 static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
    102 
    103 static const tusb_desc_device_qualifier_t desc_device_qualifier =
    104 {
    105 	.bLength            = sizeof(tusb_desc_device_qualifier_t),
    106 	.bDescriptorType    = TUSB_DESC_DEVICE_QUALIFIER,
    107 	.bcdUSB             = 0x200,
    108 
    109 	.bDeviceClass       = 0x00,
    110 	.bDeviceSubClass    = 0x00,
    111 	.bDeviceProtocol    = 0x00,
    112 
    113 	.bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE,
    114 	.bNumConfigurations = 0x01,
    115 	.bReserved          = 0x00
    116 };
    117 #endif
    118 
    119 static const char *string_desc_arr[] = {
    120 	[0] = "\x07\x04",       /* LangID: German (0x0407) */
    121 	[1] = "SNX",            /* Manufacturer */
    122 	[2] = "SXKBD Keyboard", /* Product */
    123 	[3] = "000001",         /* Serial Number */
    124 	[4] = "CDC",
    125 	[5] = "HID-KBD",
    126 	[6] = "HID-MISC"
    127 };
    128 
    129 static uint16_t _desc_str[32];
    130 
    131 const uint8_t *
    132 tud_descriptor_device_cb(void)
    133 {
    134 	return (const uint8_t *) &desc_device;
    135 }
    136 
    137 const uint8_t *
    138 tud_hid_descriptor_report_cb(uint8_t instance)
    139 {
    140 	if (instance == INST_HID_KBD)
    141 		return desc_hid_kbd_report;
    142 	else
    143 		return desc_hid_misc_report;
    144 }
    145 
    146 const uint8_t *
    147 tud_descriptor_configuration_cb(uint8_t instance)
    148 {
    149 #if TUD_OPT_HIGH_SPEED
    150 	if (tud_speed_get() == TUSB_SPEED_HIGH)
    151 		return desc_hs_configuration;
    152 	else
    153 		return desc_fs_configuration;
    154 #else
    155 	return desc_fs_configuration;
    156 #endif
    157 }
    158 
    159 const uint16_t *
    160 tud_descriptor_string_cb(uint8_t index, uint16_t langid)
    161 {
    162 	const char *str;
    163 	uint8_t i, chr_count;
    164 
    165 	if (index == 0) {
    166 		memcpy(&_desc_str[1], string_desc_arr[0], 2);
    167 		chr_count = 1;
    168 	} else {
    169 		if (index >= ARRLEN(string_desc_arr))
    170 			return NULL;
    171 
    172 		str = string_desc_arr[index];
    173 
    174 		chr_count = (uint8_t) strlen(str);
    175 		if (chr_count > 31) chr_count = 31;
    176 
    177 		/* Convert ASCII string into UTF-16 */
    178 		for (i = 0; i < chr_count; i++)
    179 			_desc_str[i+1] = str[i];
    180 	}
    181 
    182 	/* first byte is length (including header), second byte is type */
    183 	_desc_str[0] = (uint8_t) (2 * chr_count + 2);
    184 	_desc_str[0] |= (uint16_t) (TUSB_DESC_STRING << 8);
    185 
    186 	return _desc_str;
    187 }
    188 
    189 #if TUD_OPT_HIGH_SPEED
    190 const uint8_t *
    191 tud_descriptor_device_qualifier_cb(void)
    192 {
    193 	return (const uint8_t *) &desc_device_qualifier;
    194 }
    195 
    196 const uint8_t *
    197 tud_descriptor_other_speed_configuration_cb(uint8_t instance)
    198 {
    199 	if (tud_speed_get() == TUSB_SPEED_HIGH) {
    200 		memcpy(desc_other_speed_config, desc_hs_configuration,
    201 			CONFIG_TOTAL_LEN);
    202 	} else {
    203 		memcpy(desc_other_speed_config, desc_fs_configuration,
    204 			CONFIG_TOTAL_LEN);
    205 	}
    206 
    207 	desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG;
    208 
    209 	return desc_other_speed_config;
    210 }
    211 #endif