2015-06-13 23:44:21 -04:00
|
|
|
#ifndef _usb_h__
|
|
|
|
#define _usb_h__
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <avr/pgmspace.h>
|
|
|
|
|
|
|
|
/**** Standard USB defines ****/
|
|
|
|
|
|
|
|
#define DEVICE_DESCRIPTOR 0x01
|
|
|
|
#define CONFIGURATION_DESCRIPTOR 0x02
|
|
|
|
#define STRING_DESCRIPTOR 0x03
|
|
|
|
#define INTERFACE_DESCRIPTOR 0x04
|
|
|
|
#define ENDPOINT_DESCRIPTOR 0x05
|
|
|
|
#define DEVICE_QUALIFIER_DESCRIPTOR 0x06
|
|
|
|
|
|
|
|
// USB HID 1.11 section 7.1.1
|
|
|
|
#define HID_DESCRIPTOR 0x21
|
|
|
|
#define REPORT_DESCRIPTOR 0x22
|
|
|
|
#define PHYSICAL_DESCRIPTOR 0x23
|
|
|
|
|
|
|
|
#define USB_RQT_IS_HOST_TO_DEVICE(r) (((r) & 0x80) == 0)
|
|
|
|
#define USB_RQT_IS_DEVICE_TO_HOST(r) (((r) & 0x80) == 0x80)
|
|
|
|
#define USB_RQT_HOST_TO_DEVICE 0x00
|
|
|
|
#define USB_RQT_DEVICE_TO_HOST 0x80
|
|
|
|
#define USB_RQT_STANDARD (0x00 << 5)
|
|
|
|
#define USB_RQT_CLASS (0x01 << 5)
|
|
|
|
#define USB_RQT_VENDOR (0x02 << 5)
|
|
|
|
#define USB_RQT_TYPE_MASK (0x03 << 5)
|
|
|
|
#define USB_RQT_RECIPIENT_DEVICE 0x00
|
|
|
|
#define USB_RQT_RECIPIENT_INTERFACE 0x01
|
|
|
|
#define USB_RQT_RECIPIENT_ENDPOINT 0x02
|
|
|
|
#define USB_RQT_RECIPIENT_OTHER 0x03
|
|
|
|
#define USB_RQT_RECIPIENT_MASK 0x1F
|
|
|
|
|
|
|
|
#define USB_RQ_GET_STATUS 0x00
|
|
|
|
#define USB_RQ_CLEAR_FEATURE 0x01
|
|
|
|
#define USB_RQ_SET_FEATURE 0x03
|
|
|
|
#define USB_RQ_SET_ADDRESS 0x05
|
|
|
|
#define USB_RQ_GET_DESCRIPTOR 0x06
|
|
|
|
#define USB_RQ_SET_DESCRIPTOR 0x07
|
|
|
|
#define USB_RQ_GET_CONFIGURATION 0x08
|
|
|
|
#define USB_RQ_SET_CONFIGURATION 0x09
|
|
|
|
#define USB_RQ_GET_INTERFACE 0x0A
|
|
|
|
#define USB_RQ_SET_INTERFACE 0x0B
|
|
|
|
|
|
|
|
/* If the one you need is missing, add it. For values,
|
|
|
|
* see: http://www.usb.org/developers/defined_class
|
|
|
|
*/
|
|
|
|
#define USB_DEVICE_CLASS_AUDIO 0x01
|
|
|
|
#define USB_DEVICE_CLASS_CDC 0x02
|
|
|
|
#define USB_DEVICE_CLASS_HID 0x03
|
|
|
|
#define USB_DEVICE_CLASS_MASS_STORAGE 0x04
|
|
|
|
#define USB_DEVICE_CLASS_HUB 0x05
|
|
|
|
#define USB_DEVICE_CLASS_VENDOR 0xFF
|
|
|
|
|
|
|
|
struct usb_request {
|
|
|
|
uint8_t bmRequestType;
|
|
|
|
uint8_t bRequest;
|
|
|
|
uint16_t wValue;
|
|
|
|
uint16_t wIndex;
|
|
|
|
uint16_t wLength;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct usb_device_descriptor {
|
|
|
|
uint8_t bLength;
|
|
|
|
uint8_t bDescriptorType; // DEVICE_DESCRIPTOR
|
|
|
|
uint16_t bcdUSB;
|
|
|
|
uint8_t bDeviceClass; // class code
|
|
|
|
uint8_t bDeviceSubClass;
|
|
|
|
uint8_t bDeviceProtocol;
|
|
|
|
uint8_t bMaxPacketSize; // Max packet size for endpoint zero
|
|
|
|
uint16_t idVendor;
|
|
|
|
uint16_t idProduct;
|
|
|
|
uint16_t bcdDevice;
|
|
|
|
uint8_t iManufacturer;
|
|
|
|
uint8_t iProduct;
|
|
|
|
uint8_t iSerialNumber;
|
|
|
|
uint8_t bNumConfigurations;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define CFG_DESC_ATTR_RESERVED 0x80
|
|
|
|
#define CFG_DESC_ATTR_SELF_POWERED 0x40
|
|
|
|
#define CFG_DESC_ATTR_REMOTE_WAKEUP 0x20
|
|
|
|
struct usb_configuration_descriptor {
|
|
|
|
uint8_t bLength; // sizeof(struct usb_configuration_descriptor)
|
|
|
|
uint8_t bDescriptorType; // CONFIGURATION_DESCRIPTOR
|
|
|
|
uint16_t wTotalLength; // for all descriptors in this configuration. (Cfg, interface, endpoint, class)
|
|
|
|
uint8_t bNumInterfaces;
|
|
|
|
uint8_t bConfigurationValue; // for SET_CONFIGURATION argument(must be >= 1)
|
|
|
|
uint8_t iConfiguration; // String descriptor index
|
|
|
|
uint8_t bmAttributes; // D7 (set to one), D6 Selft-powred, D5 remote wakeup
|
|
|
|
uint8_t bMaxPower; // in 2mA units
|
|
|
|
};
|
|
|
|
|
|
|
|
struct usb_interface_descriptor {
|
|
|
|
uint8_t bLength;
|
|
|
|
uint8_t bDescriptorType; // INTERFACE_DESCRIPTOR
|
|
|
|
uint8_t bInterfaceNumber;
|
|
|
|
uint8_t bAlternateSetting;
|
|
|
|
uint8_t bNumEndpoints;
|
|
|
|
uint8_t bInterfaceClass;
|
|
|
|
uint8_t bInterfaceSubClass;
|
|
|
|
uint8_t bInterfaceProtocol;
|
|
|
|
uint8_t iInterface; // String descriptor index
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TRANSFER_TYPE_CONTROL 0x0
|
|
|
|
#define TRANSFER_TYPE_ISOCHRONOUS 0x1
|
|
|
|
#define TRANSFER_TYPE_BULK 0x2
|
|
|
|
#define TRANSFER_TYPE_INT 0x3
|
|
|
|
#define LS_FS_INTERVAL_MS(v) ((v)) // At low/full speed, 1 ms units
|
|
|
|
#define HS_INTERVAL_US(v) ((v)/125) // At high speed, .125us units
|
|
|
|
struct usb_endpoint_descriptor {
|
|
|
|
uint8_t bLength;
|
|
|
|
uint8_t bDescriptorType;
|
|
|
|
uint8_t bEndpointAddress;
|
|
|
|
uint8_t bmAttributes;
|
|
|
|
uint16_t wMaxPacketsize;
|
|
|
|
uint8_t bInterval;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct usb_string_descriptor_header {
|
|
|
|
uint8_t bLength;
|
|
|
|
uint8_t bDescriptorType;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* HID 1.11 section 4.2 */
|
|
|
|
#define HID_SUBCLASS_NONE 0
|
|
|
|
#define HUD_SUBCLASS_BOOT 1
|
|
|
|
|
|
|
|
/* HID 1.11 section 4.3 */
|
|
|
|
#define HID_PROTOCOL_NONE 0
|
|
|
|
#define HID_PROTOCOL_KEYBOARD 1
|
|
|
|
#define HID_PROTOCOL_MOUSE 2
|
|
|
|
|
|
|
|
/* Other values defined at HID 1.11, 6.2.1 */
|
|
|
|
#define HID_COUNTRY_NOT_SUPPORTED 0x00
|
|
|
|
|
|
|
|
struct usb_hid_descriptor {
|
|
|
|
uint8_t bLength;
|
|
|
|
uint8_t bDescriptorType;
|
|
|
|
uint16_t bcdHid;
|
|
|
|
uint8_t bCountryCode;
|
|
|
|
uint8_t bNumDescriptors;
|
|
|
|
|
|
|
|
uint8_t bClassDescriptorType;
|
|
|
|
uint16_t wClassDescriptorLength;
|
|
|
|
// Note: At least one descriptor (REPORT) is
|
|
|
|
// required. Additional descriptors
|
|
|
|
// are declared as above (type, length) and
|
|
|
|
// appended to the HID descriptor.
|
|
|
|
};
|
|
|
|
|
|
|
|
#define HID_CLSRQ_GET_REPORT 0x01
|
|
|
|
#define HID_CLSRQ_GET_IDLE 0x02
|
|
|
|
#define HID_CLSRQ_GET_PROTOCOL 0x03
|
|
|
|
#define HID_CLSRQ_SET_REPORT 0x09
|
|
|
|
#define HID_CLSRQ_SET_IDLE 0x0A
|
|
|
|
#define HID_CLSRQ_SET_PROTOCOL 0x0B
|
|
|
|
|
|
|
|
#define HID_REPORT_TYPE_INPUT 0x01
|
|
|
|
#define HID_REPORT_TYPE_OUTPUT 0x02
|
|
|
|
#define HID_REPORT_TYPE_FEATURE 0x03
|
|
|
|
|
|
|
|
/**** API ****/
|
|
|
|
|
|
|
|
#define USB_PARAM_FLAG_DEVDESC_PROGMEM 1
|
|
|
|
#define USB_PARAM_FLAG_CONFDESC_PROGMEM 2
|
|
|
|
#define USB_PARAM_FLAG_REPORTDESC_PROGMEM 4
|
|
|
|
|
2015-08-16 00:43:28 -04:00
|
|
|
#define MAX_HID_INTERFACES 2
|
|
|
|
|
|
|
|
struct usb_hid_parameters {
|
|
|
|
uint16_t reportdesc_len;
|
|
|
|
const unsigned char *reportdesc;
|
|
|
|
|
|
|
|
// Warning: Called from interrupt handler. Implement accordingly.
|
|
|
|
uint16_t (*getReport)(struct usb_request *rq, const uint8_t **dat);
|
|
|
|
uint8_t (*setReport)(const struct usb_request *rq, const uint8_t *dat, uint16_t len);
|
|
|
|
};
|
|
|
|
|
2015-06-13 23:44:21 -04:00
|
|
|
struct usb_parameters {
|
|
|
|
uint8_t flags;
|
|
|
|
|
|
|
|
const struct usb_device_descriptor *devdesc;
|
|
|
|
|
|
|
|
const void *configdesc;
|
|
|
|
// length including all descriptors returned together
|
|
|
|
// for getdescriptor(config). (i.e. Config descriptor +
|
|
|
|
// interface descritor + hid and endpoints)
|
|
|
|
uint16_t configdesc_ttllen;
|
|
|
|
|
|
|
|
uint8_t num_strings;
|
|
|
|
const wchar_t *const *strings;
|
|
|
|
|
2015-08-16 00:43:28 -04:00
|
|
|
uint8_t n_hid_interfaces;
|
|
|
|
struct usb_hid_parameters hid_params[MAX_HID_INTERFACES];
|
2015-06-13 23:44:21 -04:00
|
|
|
};
|
|
|
|
|
2015-10-17 17:43:44 -04:00
|
|
|
char usb_interruptReady(void);
|
2015-06-13 23:44:21 -04:00
|
|
|
void usb_interruptSend(void *data, int len); // EP1
|
|
|
|
void usb_init(const struct usb_parameters *params);
|
|
|
|
void usb_doTasks(void);
|
|
|
|
void usb_shutdown(void);
|
|
|
|
|
|
|
|
|
|
|
|
#endif // _usb_h__
|