this is the Peter Barrett USBHostShell program, a bit modified for being a bit more talkactive, just to let u know how the USB protocol layer is going on, and all the data trasnfers. Also there is a small implementation of HID descriptors, but not functional... yet :S the aim is to at least implement the gamepad HID, and make an array of function pointer to each HID function

Dependencies:   mbed

Committer:
Sergio
Date:
Mon Sep 13 12:40:05 2010 +0000
Revision:
0:e1e03118b8fe

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergio 0:e1e03118b8fe 1
Sergio 0:e1e03118b8fe 2 /*
Sergio 0:e1e03118b8fe 3 I changed a bit the code but all credit goes to the amazing work of :
Sergio 0:e1e03118b8fe 4
Sergio 0:e1e03118b8fe 5 Copyright (c) 2010 Peter Barrett
Sergio 0:e1e03118b8fe 6
Sergio 0:e1e03118b8fe 7 Permission is hereby granted, free of charge, to any person obtaining a copy
Sergio 0:e1e03118b8fe 8 of this software and associated documentation files (the "Software"), to deal
Sergio 0:e1e03118b8fe 9 in the Software without restriction, including without limitation the rights
Sergio 0:e1e03118b8fe 10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Sergio 0:e1e03118b8fe 11 copies of the Software, and to permit persons to whom the Software is
Sergio 0:e1e03118b8fe 12 furnished to do so, subject to the following conditions:
Sergio 0:e1e03118b8fe 13
Sergio 0:e1e03118b8fe 14 The above copyright notice and this permission notice shall be included in
Sergio 0:e1e03118b8fe 15 all copies or substantial portions of the Software.
Sergio 0:e1e03118b8fe 16
Sergio 0:e1e03118b8fe 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Sergio 0:e1e03118b8fe 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Sergio 0:e1e03118b8fe 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Sergio 0:e1e03118b8fe 20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Sergio 0:e1e03118b8fe 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Sergio 0:e1e03118b8fe 22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Sergio 0:e1e03118b8fe 23 THE SOFTWARE.
Sergio 0:e1e03118b8fe 24 */
Sergio 0:e1e03118b8fe 25
Sergio 0:e1e03118b8fe 26 #ifndef USBHOST_H
Sergio 0:e1e03118b8fe 27 #define USBHOST_H
Sergio 0:e1e03118b8fe 28
Sergio 0:e1e03118b8fe 29 #ifndef u8
Sergio 0:e1e03118b8fe 30 typedef unsigned char u8;
Sergio 0:e1e03118b8fe 31 typedef unsigned short u16;
Sergio 0:e1e03118b8fe 32 typedef unsigned long u32;
Sergio 0:e1e03118b8fe 33
Sergio 0:e1e03118b8fe 34 typedef char s8;
Sergio 0:e1e03118b8fe 35 typedef short s16;
Sergio 0:e1e03118b8fe 36 typedef char s32;
Sergio 0:e1e03118b8fe 37 #endif
Sergio 0:e1e03118b8fe 38
Sergio 0:e1e03118b8fe 39 #define ENDPOINT_CONTROL 0
Sergio 0:e1e03118b8fe 40 #define ENDPOINT_ISOCRONOUS 1
Sergio 0:e1e03118b8fe 41 #define ENDPOINT_BULK 2
Sergio 0:e1e03118b8fe 42 #define ENDPOINT_INTERRUPT 3
Sergio 0:e1e03118b8fe 43
Sergio 0:e1e03118b8fe 44 #define DESCRIPTOR_TYPE_DEVICE 1
Sergio 0:e1e03118b8fe 45 #define DESCRIPTOR_TYPE_CONFIGURATION 2
Sergio 0:e1e03118b8fe 46 #define DESCRIPTOR_TYPE_STRING 3
Sergio 0:e1e03118b8fe 47 #define DESCRIPTOR_TYPE_INTERFACE 4
Sergio 0:e1e03118b8fe 48 #define DESCRIPTOR_TYPE_ENDPOINT 5
Sergio 0:e1e03118b8fe 49
Sergio 0:e1e03118b8fe 50 #define DESCRIPTOR_TYPE_HID 0x21
Sergio 0:e1e03118b8fe 51 #define DESCRIPTOR_TYPE_REPORT 0x22
Sergio 0:e1e03118b8fe 52 #define DESCRIPTOR_TYPE_PHYSICAL 0x23
Sergio 0:e1e03118b8fe 53 #define DESCRIPTOR_TYPE_HUB 0x29
Sergio 0:e1e03118b8fe 54
Sergio 0:e1e03118b8fe 55 enum USB_CLASS_CODE
Sergio 0:e1e03118b8fe 56 {
Sergio 0:e1e03118b8fe 57 CLASS_DEVICE,
Sergio 0:e1e03118b8fe 58 CLASS_AUDIO,
Sergio 0:e1e03118b8fe 59 CLASS_COMM_AND_CDC_CONTROL,
Sergio 0:e1e03118b8fe 60 CLASS_HID,
Sergio 0:e1e03118b8fe 61 CLASS_PHYSICAL = 0x05,
Sergio 0:e1e03118b8fe 62 CLASS_STILL_IMAGING,
Sergio 0:e1e03118b8fe 63 CLASS_PRINTER,
Sergio 0:e1e03118b8fe 64 CLASS_MASS_STORAGE,
Sergio 0:e1e03118b8fe 65 CLASS_HUB,
Sergio 0:e1e03118b8fe 66 CLASS_CDC_DATA,
Sergio 0:e1e03118b8fe 67 CLASS_SMART_CARD,
Sergio 0:e1e03118b8fe 68 CLASS_CONTENT_SECURITY = 0x0D,
Sergio 0:e1e03118b8fe 69 CLASS_VIDEO = 0x0E,
Sergio 0:e1e03118b8fe 70 CLASS_DIAGNOSTIC_DEVICE = 0xDC,
Sergio 0:e1e03118b8fe 71 CLASS_WIRELESS_CONTROLLER = 0xE0,
Sergio 0:e1e03118b8fe 72 CLASS_MISCELLANEOUS = 0xEF,
Sergio 0:e1e03118b8fe 73 CLASS_APP_SPECIFIC = 0xFE,
Sergio 0:e1e03118b8fe 74 CLASS_VENDOR_SPECIFIC = 0xFF
Sergio 0:e1e03118b8fe 75 };
Sergio 0:e1e03118b8fe 76 //CLASS=0x00=DEVICE // This means that the use of the device comes in the Interface Descriptors
Sergio 0:e1e03118b8fe 77
Sergio 0:e1e03118b8fe 78 #define DEVICE_TO_HOST 0x80
Sergio 0:e1e03118b8fe 79 #define HOST_TO_DEVICE 0x00
Sergio 0:e1e03118b8fe 80 #define REQUEST_TYPE_CLASS 0x20
Sergio 0:e1e03118b8fe 81 #define RECIPIENT_DEVICE 0x00
Sergio 0:e1e03118b8fe 82 #define RECIPIENT_INTERFACE 0x01
Sergio 0:e1e03118b8fe 83 #define RECIPIENT_ENDPOINT 0x02
Sergio 0:e1e03118b8fe 84 #define RECIPIENT_OTHER 0x03
Sergio 0:e1e03118b8fe 85
Sergio 0:e1e03118b8fe 86 #define GET_STATUS 0
Sergio 0:e1e03118b8fe 87 #define CLEAR_FEATURE 1
Sergio 0:e1e03118b8fe 88 #define SET_FEATURE 3
Sergio 0:e1e03118b8fe 89 #define SET_ADDRESS 5
Sergio 0:e1e03118b8fe 90 #define GET_DESCRIPTOR 6
Sergio 0:e1e03118b8fe 91 #define SET_DESCRIPTOR 7
Sergio 0:e1e03118b8fe 92 #define GET_CONFIGURATION 8
Sergio 0:e1e03118b8fe 93 #define SET_CONFIGURATION 9
Sergio 0:e1e03118b8fe 94 #define GET_INTERFACE 10
Sergio 0:e1e03118b8fe 95 #define SET_INTERFACE 11
Sergio 0:e1e03118b8fe 96 #define SYNCH_FRAME 11
Sergio 0:e1e03118b8fe 97
Sergio 0:e1e03118b8fe 98 // -5 is nak
Sergio 0:e1e03118b8fe 99 /*
Sergio 0:e1e03118b8fe 100 0010 ACK Handshake
Sergio 0:e1e03118b8fe 101 1010 NAK Handshake
Sergio 0:e1e03118b8fe 102 1110 STALL Handshake
Sergio 0:e1e03118b8fe 103 0110 NYET (No Response Yet)
Sergio 0:e1e03118b8fe 104 */
Sergio 0:e1e03118b8fe 105
Sergio 0:e1e03118b8fe 106 #define IO_PENDING -100
Sergio 0:e1e03118b8fe 107 #define ERR_ENDPOINT_NONE_LEFT -101
Sergio 0:e1e03118b8fe 108 #define ERR_ENDPOINT_NOT_FOUND -102
Sergio 0:e1e03118b8fe 109 #define ERR_DEVICE_NOT_FOUND -103
Sergio 0:e1e03118b8fe 110 #define ERR_DEVICE_NONE_LEFT -104
Sergio 0:e1e03118b8fe 111 #define ERR_HUB_INIT_FAILED -105
Sergio 0:e1e03118b8fe 112 #define ERR_INTERFACE_NOT_FOUND -106
Sergio 0:e1e03118b8fe 113
Sergio 0:e1e03118b8fe 114
Sergio 0:e1e03118b8fe 115 //prefixeds indicators:
Sergio 0:e1e03118b8fe 116 // b = byte(8bits)
Sergio 0:e1e03118b8fe 117 // w = word(16bits)
Sergio 0:e1e03118b8fe 118 // bm= bit map
Sergio 0:e1e03118b8fe 119 // bcd = binary-coded-decimal
Sergio 0:e1e03118b8fe 120 // i = index
Sergio 0:e1e03118b8fe 121 // id = identifier.
Sergio 0:e1e03118b8fe 122
Sergio 0:e1e03118b8fe 123 // bDescriptorType values:
Sergio 0:e1e03118b8fe 124 // 01h device
Sergio 0:e1e03118b8fe 125 // 02h configuration
Sergio 0:e1e03118b8fe 126 // 03h string -just for optional descriptive test
Sergio 0:e1e03118b8fe 127 // 04h interface
Sergio 0:e1e03118b8fe 128 // 05h endpoint
Sergio 0:e1e03118b8fe 129 // 06h device_qualifier -for devices theat support both full and high speeds.
Sergio 0:e1e03118b8fe 130 // 07h other_speed_configuration
Sergio 0:e1e03118b8fe 131 // 08h interface_powr
Sergio 0:e1e03118b8fe 132 // 09h OTG -for On-The-Go devices only
Sergio 0:e1e03118b8fe 133 // 0Ah debug
Sergio 0:e1e03118b8fe 134 // 0Bh interface association -for composite devices
Sergio 0:e1e03118b8fe 135
Sergio 0:e1e03118b8fe 136
Sergio 0:e1e03118b8fe 137 // This is the device decriptor:
Sergio 0:e1e03118b8fe 138 typedef struct
Sergio 0:e1e03118b8fe 139 {
Sergio 0:e1e03118b8fe 140 u8 bLength; // the length in bytes of the descriptor
Sergio 0:e1e03118b8fe 141 u8 bDescriptorType; //descriptor! (01h)
Sergio 0:e1e03118b8fe 142 u16 bcdUSB; // usb specs version
Sergio 0:e1e03118b8fe 143 // usb 2.0 -> 0x0200
Sergio 0:e1e03118b8fe 144 // usb 1.1 -> 0x0110
Sergio 0:e1e03118b8fe 145 // usb 1.0 -> 0x0100
Sergio 0:e1e03118b8fe 146 u8 bDeviceClass; //class code
Sergio 0:e1e03118b8fe 147 u8 bDeviceSubClass; //subclass code
Sergio 0:e1e03118b8fe 148 u8 bDeviceProtocol; //protocol code
Sergio 0:e1e03118b8fe 149 u8 bMaxPacketSize; //maximun packet size for endpoint 0
Sergio 0:e1e03118b8fe 150 u16 idVendor; //vendor ID
Sergio 0:e1e03118b8fe 151 u16 idProduct; //product ID
Sergio 0:e1e03118b8fe 152 u16 bcdDevice; // device release number
Sergio 0:e1e03118b8fe 153 u8 iManufacturer; //index that points a string describing the manufacturer. zero if no string description.
Sergio 0:e1e03118b8fe 154 u8 iProduct; //index that points a string describing the product. zero if no string decription
Sergio 0:e1e03118b8fe 155 u8 iSerialNumber; //index to a string with the serial number.
Sergio 0:e1e03118b8fe 156 u8 bNumConfigurations; //number of possible configurations.
Sergio 0:e1e03118b8fe 157 } DeviceDescriptor; // 16 bytes
Sergio 0:e1e03118b8fe 158
Sergio 0:e1e03118b8fe 159
Sergio 0:e1e03118b8fe 160 //after retrieving the device decriptor the host can
Sergio 0:e1e03118b8fe 161 //ask for device configuration.
Sergio 0:e1e03118b8fe 162 //When the configuration descriptor is read, it returns
Sergio 0:e1e03118b8fe 163 //the entire configuration hierarchy which includes all
Sergio 0:e1e03118b8fe 164 //related interface and endpoint descriptors.
Sergio 0:e1e03118b8fe 165 // The wTotalLength field reflects the number of bytes in the hierarchy.
Sergio 0:e1e03118b8fe 166 typedef struct
Sergio 0:e1e03118b8fe 167 {
Sergio 0:e1e03118b8fe 168 u8 bLength; //length in bytes of the descriptor
Sergio 0:e1e03118b8fe 169 u8 bDescriptorType; // the constant CONFIGURATION (02h)
Sergio 0:e1e03118b8fe 170 u16 wTotalLength;
Sergio 0:e1e03118b8fe 171 u8 bNumInterfaces; //specifies the number of interfaces present for this configuration.
Sergio 0:e1e03118b8fe 172 u8 bConfigurationValue; //is used by the SetConfiguration request to select this configuration.
Sergio 0:e1e03118b8fe 173 u8 iConfiguration; // Index of String Descriptor describing this configuration
Sergio 0:e1e03118b8fe 174 u8 bmAttributes; // Bitmap D7 Reserved, set to 1. (USB 1.0 Bus Powered),D6 Self Powered,D5 Remote Wakeup,D4..0 = 0
Sergio 0:e1e03118b8fe 175 u8 bMaxPower; // Maximum Power Consumption in 2mA units
Sergio 0:e1e03118b8fe 176 } ConfigurationDescriptor;
Sergio 0:e1e03118b8fe 177
Sergio 0:e1e03118b8fe 178
Sergio 0:e1e03118b8fe 179 // the InterfaceDescriptor provides information
Sergio 0:e1e03118b8fe 180 //or features implemented.
Sergio 0:e1e03118b8fe 181 //The interface descriptor could be seen as a header
Sergio 0:e1e03118b8fe 182 // or grouping of the endpoints into a functional group
Sergio 0:e1e03118b8fe 183 // performing a single feature of the device.
Sergio 0:e1e03118b8fe 184 typedef struct
Sergio 0:e1e03118b8fe 185 {
Sergio 0:e1e03118b8fe 186 u8 bLength; //descriptor size in bytes.
Sergio 0:e1e03118b8fe 187 u8 bDescriptorType; // the constant INTERFACE (04h)
Sergio 0:e1e03118b8fe 188 u8 bInterfaceNumber; //number identifing this interface
Sergio 0:e1e03118b8fe 189 u8 bAlternateSetting; //Can be used to specify alternative interfaces.
Sergio 0:e1e03118b8fe 190 //These alternative interfaces can be selected with the Set Interface request.
Sergio 0:e1e03118b8fe 191 u8 bNumEndpoints; //number of endpoint supported, not counting the endpoint 0
Sergio 0:e1e03118b8fe 192 u8 bInterfaceClass; //class code
Sergio 0:e1e03118b8fe 193 //bInterfaceClass values:
Sergio 0:e1e03118b8fe 194 //01 Audio
Sergio 0:e1e03118b8fe 195 //02 Comunication interface
Sergio 0:e1e03118b8fe 196 //03 HID-> Human Interface Device
Sergio 0:e1e03118b8fe 197 //05 Physical
Sergio 0:e1e03118b8fe 198 //06 Image
Sergio 0:e1e03118b8fe 199 //07 Printer
Sergio 0:e1e03118b8fe 200 //08 Mass storage
Sergio 0:e1e03118b8fe 201 //09 Hub
Sergio 0:e1e03118b8fe 202 //0A Data interface
Sergio 0:e1e03118b8fe 203 //0B Smart Card
Sergio 0:e1e03118b8fe 204 //0D Content security
Sergio 0:e1e03118b8fe 205 //0E Video
Sergio 0:e1e03118b8fe 206 //DC diagnostic divice
Sergio 0:e1e03118b8fe 207 //E0 wirelless controler
Sergio 0:e1e03118b8fe 208 //FE Application specific
Sergio 0:e1e03118b8fe 209 //FF vendor specific
Sergio 0:e1e03118b8fe 210 u8 bInterfaceSubClass; //subclass code
Sergio 0:e1e03118b8fe 211 u8 bInterfaceProtocol; //protocol code
Sergio 0:e1e03118b8fe 212 u8 iInterface; // Index of String Descriptor Describing this interface
Sergio 0:e1e03118b8fe 213 } InterfaceDescriptor;
Sergio 0:e1e03118b8fe 214
Sergio 0:e1e03118b8fe 215
Sergio 0:e1e03118b8fe 216 //Each endpoint in an interface descriptor must have
Sergio 0:e1e03118b8fe 217 //an endpoint descriptor.
Sergio 0:e1e03118b8fe 218 //Endpoint descriptors are used to describe endpoints
Sergio 0:e1e03118b8fe 219 //other than endpoint zero. Endpoint zero is always
Sergio 0:e1e03118b8fe 220 //assumed to be a control endpoint and is configured
Sergio 0:e1e03118b8fe 221 // before any descriptors are even requested. The host
Sergio 0:e1e03118b8fe 222 // will use the information returned from these descriptors
Sergio 0:e1e03118b8fe 223 // to determine the bandwidth requirements of the bus.
Sergio 0:e1e03118b8fe 224 typedef struct
Sergio 0:e1e03118b8fe 225 {
Sergio 0:e1e03118b8fe 226 u8 bLength; //descriptor size in bytes.
Sergio 0:e1e03118b8fe 227 u8 bDescriptorType; //the constant ENDPOINT(05h)
Sergio 0:e1e03118b8fe 228 u8 bEndpointAddress; //Endpoint number and direction
Sergio 0:e1e03118b8fe 229 // Bits 0:3 endpoint, Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
Sergio 0:e1e03118b8fe 230 u8 bmAttributes; //specifies the transfer type.
Sergio 0:e1e03118b8fe 231 // Bits 0:1 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
Sergio 0:e1e03118b8fe 232 u16 wMaxPacketSize; //maximun packet size supported.
Sergio 0:e1e03118b8fe 233 u8 bInterval; // Interval for polling endpoint data transfers.
Sergio 0:e1e03118b8fe 234 } EndpointDescriptor;
Sergio 0:e1e03118b8fe 235
Sergio 0:e1e03118b8fe 236 typedef struct {
Sergio 0:e1e03118b8fe 237 u8 bLength;
Sergio 0:e1e03118b8fe 238 u8 bDescriptorType; //(0x21h)
Sergio 0:e1e03118b8fe 239 u16 bcdHID; // HID specs release number
Sergio 0:e1e03118b8fe 240 u8 bCountryCode; //0X00 for no country-code
Sergio 0:e1e03118b8fe 241 u8 bNumDescriptors;//the number of class descriptors that
Sergio 0:e1e03118b8fe 242 //are subordinated to this descriptor.
Sergio 0:e1e03118b8fe 243 u8 bDescriptorType2; //2? the type of descriptor that is subordinated
Sergio 0:e1e03118b8fe 244 //to the class descriptor. Minimun 1, due it
Sergio 0:e1e03118b8fe 245 //has to have at least 1 report descriptor and/Or
Sergio 0:e1e03118b8fe 246 //one or more phsical descriptors.
Sergio 0:e1e03118b8fe 247 //A report descriptionr (required) is type 22h.
Sergio 0:e1e03118b8fe 248 u16 wDescriptorLength;
Sergio 0:e1e03118b8fe 249
Sergio 0:e1e03118b8fe 250 //u8 bDescriptorTyepe; //<- Optional; The type of descriptor that follows
Sergio 0:e1e03118b8fe 251 //A physical descriptior is 0x23h
Sergio 0:e1e03118b8fe 252 //u16 wDescriptorLength2;
Sergio 0:e1e03118b8fe 253
Sergio 0:e1e03118b8fe 254 } HIDDescriptor;
Sergio 0:e1e03118b8fe 255
Sergio 0:e1e03118b8fe 256 //============================================================================
Sergio 0:e1e03118b8fe 257 //============================================================================
Sergio 0:e1e03118b8fe 258
Sergio 0:e1e03118b8fe 259
Sergio 0:e1e03118b8fe 260 void USBInit();
Sergio 0:e1e03118b8fe 261 void USBLoop();
Sergio 0:e1e03118b8fe 262 u8* USBGetBuffer(u32* len);
Sergio 0:e1e03118b8fe 263
Sergio 0:e1e03118b8fe 264 // Optional callback for transfers, called at interrupt time
Sergio 0:e1e03118b8fe 265 typedef void (*USBCallback)(int device, int endpoint, int status, u8* data, int len, void* userData);
Sergio 0:e1e03118b8fe 266
Sergio 0:e1e03118b8fe 267 // Transfers
Sergio 0:e1e03118b8fe 268 int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback = 0, void* userData = 0);
Sergio 0:e1e03118b8fe 269 int USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0);
Sergio 0:e1e03118b8fe 270 int USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0);
Sergio 0:e1e03118b8fe 271
Sergio 0:e1e03118b8fe 272 // Standard Device methods
Sergio 0:e1e03118b8fe 273 int GetDescriptor(int device, int descType, int descIndex, u8* data, int length);
Sergio 0:e1e03118b8fe 274 int GetString(int device, int index, char* dst, int length);
Sergio 0:e1e03118b8fe 275 int SetAddress(int device, int new_addr);
Sergio 0:e1e03118b8fe 276 int SetConfiguration(int device, int configNum);
Sergio 0:e1e03118b8fe 277 int SetInterface(int device, int ifNum, int altNum);
Sergio 0:e1e03118b8fe 278
Sergio 0:e1e03118b8fe 279 // Implemented to notify app of the arrival of a device
Sergio 0:e1e03118b8fe 280 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc);
Sergio 0:e1e03118b8fe 281
Sergio 0:e1e03118b8fe 282 #endif