Created
October 3, 2016 17:48
-
-
Save leopck/aadf4d8c7362d8f4b353740e41a54fa7 to your computer and use it in GitHub Desktop.
usb_config.h for Joystick over espusb (Still work in progress; doesn't work)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _USB_CONFIG_H | |
#define _USB_CONFIG_H | |
//Defines the number of endpoints for this device. (Always add one for EP0) | |
#define ENDPOINTS 5 | |
//Defines a pin that is useful for debugging USB on a logic analyzer | |
//#define DEBUGPIN 2 | |
//DPLUS and DMINUS are not actually used except for setting things up. | |
#define DPLUS 5 | |
#define DMINUS 4 | |
//This is what's used in the assembly | |
#define DMINUSBASE DMINUS //Must be D- first, then D+ second. | |
#define PERIPHSDPLUS PERIPHS_IO_MUX_GPIO5_U | |
#define PERIPHSDMINUS PERIPHS_IO_MUX_GPIO4_U | |
#define FUNCDPLUS FUNC_GPIO5 | |
#define FUNCDMINUS FUNC_GPIO4 | |
#endif | |
#ifdef INSTANCE_DESCRIPTORS | |
//Taken from http://www.usbmadesimple.co.uk/ums_ms_desc_dev.htm | |
static const uint8_t device_descriptor[] = { | |
18, //Length | |
1, //Type (Device) | |
0x10, 0x01, //Spec | |
0x0, //Device Class | |
0x0, //Device Subclass | |
0x0, //Device Protocol (000 = use config descriptor) | |
0x08, //Max packet size for EP0 (This has to be 8 because of the USB Low-Speed Standard) | |
0xcd, 0xab, //ID Vendor //TODO: register this in http://pid.codes/howto/ or somewhere. | |
0x66, 0x82, //ID Product | |
0x02, 0x00, //ID Rev | |
1, //Manufacturer string | |
2, //Product string | |
0, //Serial string | |
1, //Max number of configurations | |
}; | |
static const uint8_t config_descriptor[] = { //Mostly stolen from a USB mouse I found. | |
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 | |
9, // bLength; | |
2, // bDescriptorType; | |
//Need to adjust this accordingly if we add more devices | |
0x5A, 0x00, // wTotalLength | |
//34, 0x00, //for just the one descriptor | |
//Need to adjust this accordingly if we add more devices maybe???? | |
0x02, // bNumInterfaces (Normally 1) | |
0x01, // bConfigurationValue | |
0x00, // iConfiguration | |
0x80, // bmAttributes (was 0xa0) | |
0x64, // bMaxPower (200mA) | |
//Interface Descriptor:: Mouse | |
9, // bLength | |
4, // bDescriptorType | |
0, // bInterfaceNumber (unused, would normally be used for HID) | |
0, // bAlternateSetting | |
1, // bNumEndpoints | |
0x03, // bInterfaceClass (0x03 = HID) | |
0x01, // bInterfaceSubClass | |
0x02, // bInterfaceProtocol (Mouse) | |
0, // iInterface | |
//HID Descriptor | |
9, // bLength | |
0x21, // bDescriptorType (HID) | |
0x10,0x01, //bcd 1.1 | |
0x00, //country code | |
0x01, //Num descriptors | |
0x22, //DescriptorType[0] (HID) | |
52, 0x00, //Descriptor length XXX This looks wrong!!! | |
//Endpoint Descriptor 1 | |
7, //endpoint descriptor (For endpoint 1) | |
0x05, //Endpoint Descriptor (Must be 5) | |
0x81, //Endpoint Address bEndpointAddress (IN Endpoint) | |
0x03, //Attributes bmAttributes (Transfer: Interrupt / Synch: None / Usage: Data) | |
0x04, 0x00, //Size wMaxPacketSize (4 Bytes) | |
10, //Interval (Was 0x0a) | |
//Interface Descriptor:: Keyboard (It is unusual that this would be here) | |
9, // bLength | |
4, // bDescriptorType | |
1, // bInterfaceNumber = 1 instead of 0 -- well make it second. | |
0, // bAlternateSetting | |
1, // bNumEndpoints | |
0x03, // bInterfaceClass (0x03 = HID) | |
0x01, // bInterfaceSubClass | |
0x01, // bInterfaceProtocol (??) | |
0, // iInterface | |
9, // bLength | |
0x21, // bDescriptorType (HID) | |
0x10,0x01, //bcd 1.1 | |
0x00, //country code | |
0x01, //Num descriptors | |
0x22, //DescriptorType[0] (HID) | |
63, 0x00, //Descriptor length XXX This looks wrong!!! | |
7, //endpoint descriptor (For endpoint 1) | |
0x05, //Endpoint Descriptor (Must be 5) | |
0x82, //Endpoint Address | |
0x03, //Attributes | |
0x08, 0x00, //Size (8 bytes) | |
10, //Interval (Was 0x0a) | |
//Interface Descriptor:: Joystick | |
0x09,// bLength | |
0x04,// bDescriptorType | |
//Need to adjust this accordingly if we add more devices :: bInterfaceNumber is like an ID so must be unique | |
0x02,// bInterfaceNumber | |
0x00,// bAlternateSetting | |
0x02,// bNumEndPoints | |
0x03,// bInterfaceClass (Human Interface Device Class) | |
0x00,// bInterfaceSubClass | |
0x00,// bInterfaceProtocol | |
0x00,// iInterface | |
//HID Descriptor | |
0x09,// bLength | |
0x21,// bDescriptorType | |
0x10,0x01,// bcdHID | |
0x00,// bCountryCode | |
0x01,// bNumDescriptors | |
0x22,// bDescriptorType (Report descriptor) | |
// 0x3F,0x05,// bDescriptorLength | |
61, 0x00,// bDescriptorLength | |
//Endpoint Descriptor IN | |
0x07,// bLength | |
0x05,// bDescriptorType | |
0x81,// bEndpointAddress (IN Endpoint) | |
0x03,// bmAttributes (Transfer: Interrupt / Synch: None / Usage: Data) | |
0x40,0x00,// wMaxPacketSize (64 Bytes) | |
0x01,// bInterval | |
//Endpoint Descriptor OUT | |
0x07,// bLength | |
0x05,// bDescriptorType | |
0x02,// bEndpointAddress (OUT Endpoint) | |
0x03,// bmAttributes (Transfer: Interrupt / Synch: None / Usage: Data) | |
0x10,0x00,// wMaxPacketSize (16 Bytes) | |
0x04,// bInterval | |
}; | |
static const uint8_t mouse_hid_desc[52] = { //From http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/ | |
0x05, 0x01, // USAGE_PAGE (Generic Desktop) | |
0x09, 0x02, // USAGE (Mouse) | |
0xa1, 0x01, // COLLECTION (Application) | |
0x09, 0x01, // USAGE (Pointer) | |
0xa1, 0x00, // COLLECTION (Physical) | |
0x05, 0x09, // USAGE_PAGE (Button) | |
0x19, 0x01, // USAGE_MINIMUM (Button 1) | |
0x29, 0x03, // USAGE_MAXIMUM (Button 3) | |
0x15, 0x00, // LOGICAL_MINIMUM (0) | |
0x25, 0x01, // LOGICAL_MAXIMUM (1) | |
0x95, 0x03, // REPORT_COUNT (3) | |
0x75, 0x01, // REPORT_SIZE (1) | |
0x81, 0x02, // INPUT (Data,Var,Abs) | |
0x95, 0x01, // REPORT_COUNT (1) | |
0x75, 0x05, // REPORT_SIZE (5) | |
0x81, 0x03, // INPUT (Cnst,Var,Abs) | |
0x05, 0x01, // USAGE_PAGE (Generic Desktop) | |
0x09, 0x30, // USAGE (X) | |
0x09, 0x31, // USAGE (Y) | |
0x09, 0x38, // USAGE (Y) | |
0x15, 0x81, // LOGICAL_MINIMUM (-127) | |
0x25, 0x7f, // LOGICAL_MAXIMUM (127) | |
0x75, 0x08, // REPORT_SIZE (8) | |
0x95, 0x03, // REPORT_COUNT (3) | |
0x81, 0x06, // INPUT (Data,Var,Rel) | |
0xc0, // END_COLLECTION | |
0xc0 // END_COLLECTIONs | |
}; | |
//From http://codeandlife.com/2012/06/18/usb-hid-keyboard-with-v-usb/ | |
static const uint8_t keyboard_hid_desc[63] = { /* USB report descriptor */ | |
0x05, 0x01, // USAGE_PAGE (Generic Desktop) | |
0x09, 0x06, // USAGE (Keyboard) | |
0xa1, 0x01, // COLLECTION (Application) | |
0x75, 0x01, // REPORT_SIZE (1) | |
0x95, 0x08, // REPORT_COUNT (8) | |
0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes) | |
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)(224) | |
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)(231) | |
0x15, 0x00, // LOGICAL_MINIMUM (0) | |
0x25, 0x01, // LOGICAL_MAXIMUM (1) | |
0x81, 0x02, // INPUT (Data,Var,Abs) ; Modifier byte | |
0x95, 0x01, // REPORT_COUNT (1) | |
0x75, 0x08, // REPORT_SIZE (8) | |
0x81, 0x03, // INPUT (Cnst,Var,Abs) ; Reserved byte | |
0x95, 0x05, // REPORT_COUNT (5) | |
0x75, 0x01, // REPORT_SIZE (1) | |
0x05, 0x08, // USAGE_PAGE (LEDs) | |
0x19, 0x01, // USAGE_MINIMUM (Num Lock) | |
0x29, 0x05, // USAGE_MAXIMUM (Kana) | |
0x91, 0x02, // OUTPUT (Data,Var,Abs) ; LED report | |
0x95, 0x01, // REPORT_COUNT (1) | |
0x75, 0x03, // REPORT_SIZE (3) | |
0x91, 0x03, // OUTPUT (Cnst,Var,Abs) ; LED report padding | |
0x95, 0x06, // REPORT_COUNT (6) | |
0x75, 0x08, // REPORT_SIZE (8) | |
0x15, 0x00, // LOGICAL_MINIMUM (0) | |
0x25, 167, // LOGICAL_MAXIMUM (167) (Normally would be 101, but we want volume buttons) | |
0x05, 0x07, // USAGE_PAGE (Keyboard)(Key Codes) | |
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))(0) | |
0x29, 167, // USAGE_MAXIMUM (Keyboard Application)(101) (Now 167) | |
0x81, 0x00, // INPUT (Data,Ary,Abs) | |
0xc0 // END_COLLECTION | |
}; | |
#if 0 | |
#define USAGE_PAGE(x) 0x05, x | |
#define USAGE(x) 0x09, x | |
#define COLLECTION(x) 0xa1, x | |
#define REPORT_ID(x) 0x85, x | |
#define USAGE_MINIMUM(x) 0x19, x | |
#define USAGE_MAXIMUM(x) 0x29, x | |
#define LOGICAL_MINIMUM(x) 0x15, x | |
#define LOGICAL_MAXIMUM(x) 0x25, x | |
#define REPORT_COUNT(x) 0x95, x | |
#define REPORT_SIZE(x) 0x75, x | |
//http://www.usb.org/developers/hidpage/HID1_11.pdf :: Page 29 - 30 | |
#define DATA(x) x & 0xFE //Set Bit 0 to LOW for Data | |
#define CNST(x) x | 0x01 //Set Bit 0 to HIGH for Constant | |
#define ARRAY(x) x & 0xFD //Set Bit 1 to LOW for Array | |
#define VAR(x) x | 0x02 //Set Bit 1 to HIGH for Variable | |
#define ABS(x) x & 0xFB //Set Bit 2 to LOW for Absolute | |
#define REL(x) x | 0x04 //Set Bit 2 to HIGH for Relative | |
#define INPUT (Data,Var,Abs) | |
#endif | |
//From Microsoft Force Feedback Joystick 2 Reverse Engineered via lsusb | |
static const uint8_t joystick_hid_desc[61] = { /* USB report descriptor */ | |
0x05, 0x01, // USAGE_PAGE (Generic Desktop) | |
0x09, 0x04, // USAGE (Joystick) | |
0xa1, 0x01, // COLLECTION (Application) | |
0x85, 0x01, // REPORT_ID (1) | |
0xa1, 0x02, // COLLECTION (Logical) | |
0x09, 0x32, // USAGE (Z) | |
0x09, 0x31, // USAGE (Y) | |
0x09, 0x30, // USAGE (X) | |
0x15, 0x00, // LOGICAL_MINIMUM (0) | |
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255) | |
0x35, 0x00, // PHYSICAL_MINIMUM (0) | |
0x46, 0xff, 0x00, // PHYSICAL_MAXIMUM (255) | |
0x75, 0x08, // REPORT_SIZE (8) | |
0x95, 0x03, // REPORT_COUNT (3) | |
0x81, 0x02, // INPUT (Data,Var,Abs) | |
0xc0, // END_COLLECTION | |
0x85, 0x02, // REPORT_ID (2) | |
0xa1, 0x02, // COLLECTION (Logical) | |
0x05, 0x09, // USAGE_PAGE (Button) | |
0x29, 0x02, // USAGE_MAXIMUM (Button 2) | |
0x19, 0x01, // USAGE_MINIMUM (Button 1) | |
0x95, 0x02, // REPORT_COUNT (2) | |
0x75, 0x01, // REPORT_SIZE (1) | |
0x25, 0x01, // LOGICAL_MAXIMUM (1) | |
0x15, 0x00, // LOGICAL_MINIMUM (0) | |
0x81, 0x02, // Input (Data, Variable, Absolute) | |
0x95, 0x01, // Report Count (1) | |
0x75, 0x06, // Report Size (6) | |
0x81, 0x01, // Input (Constant) for padding | |
0xc0, // END_COLLECTION | |
0xc0 // END_COLLECTION | |
}; | |
//Ever wonder how you have more than 6 keys down at the same time on a USB keyboard? It's easy. Enumerate two keyboards! | |
#define STR_MANUFACTURER L"CNLohr" | |
#define STR_PRODUCT L"ESPUSB2" | |
#define STR_SERIAL L"000" | |
struct usb_string_descriptor_struct { | |
uint8_t bLength; | |
uint8_t bDescriptorType; | |
uint16_t wString[]; | |
}; | |
const static struct usb_string_descriptor_struct string0 = { | |
4, | |
3, | |
{0x0409} | |
}; | |
const static struct usb_string_descriptor_struct string1 = { | |
sizeof(STR_MANUFACTURER), | |
3, | |
STR_MANUFACTURER | |
}; | |
const static struct usb_string_descriptor_struct string2 = { | |
sizeof(STR_PRODUCT), | |
3, | |
STR_PRODUCT | |
}; | |
const static struct usb_string_descriptor_struct string3 = { | |
sizeof(STR_SERIAL), | |
3, | |
STR_SERIAL | |
}; | |
// This table defines which descriptor data is sent for each specific | |
// request from the host (in wValue and wIndex). | |
const static struct descriptor_list_struct { | |
uint16_t wValue; | |
uint16_t wIndex; | |
const uint8_t *addr; | |
uint8_t length; | |
} descriptor_list[] = { | |
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, | |
{0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, | |
{0x2200, 0x0000, mouse_hid_desc, sizeof(mouse_hid_desc)}, | |
{0x2200, 0x0001, keyboard_hid_desc, sizeof(keyboard_hid_desc)}, | |
{0x2200, 0x0002, joystick_hid_desc, sizeof(joystick_hid_desc)}, | |
{0x0300, 0x0000, (const uint8_t *)&string0, 4}, | |
{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, | |
{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}, | |
{0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL)} | |
}; | |
#define DESCRIPTOR_LIST_ENTRIES ((sizeof(descriptor_list))/(sizeof(struct descriptor_list_struct)) ) | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment