Skip to content

Instantly share code, notes, and snippets.

@leopck
Created October 3, 2016 17:48
Show Gist options
  • Save leopck/aadf4d8c7362d8f4b353740e41a54fa7 to your computer and use it in GitHub Desktop.
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)
#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