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

USBHost.h

Committer:
Sergio
Date:
2010-09-13
Revision:
0:e1e03118b8fe

File content as of revision 0:e1e03118b8fe:


/*
I changed a bit the code but all credit goes to the amazing work of :

Copyright (c) 2010 Peter Barrett

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifndef USBHOST_H
#define USBHOST_H

#ifndef u8
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;

typedef char s8;
typedef short s16;
typedef char s32;
#endif

#define ENDPOINT_CONTROL 0
#define ENDPOINT_ISOCRONOUS 1
#define ENDPOINT_BULK 2
#define ENDPOINT_INTERRUPT 3

#define  DESCRIPTOR_TYPE_DEVICE            1
#define  DESCRIPTOR_TYPE_CONFIGURATION    2
#define  DESCRIPTOR_TYPE_STRING            3
#define  DESCRIPTOR_TYPE_INTERFACE        4
#define  DESCRIPTOR_TYPE_ENDPOINT        5

#define DESCRIPTOR_TYPE_HID         0x21
#define DESCRIPTOR_TYPE_REPORT      0x22
#define DESCRIPTOR_TYPE_PHYSICAL    0x23
#define DESCRIPTOR_TYPE_HUB         0x29

enum USB_CLASS_CODE
{
    CLASS_DEVICE,  
    CLASS_AUDIO,
    CLASS_COMM_AND_CDC_CONTROL,
    CLASS_HID,
    CLASS_PHYSICAL = 0x05,
    CLASS_STILL_IMAGING,
    CLASS_PRINTER,
    CLASS_MASS_STORAGE,
    CLASS_HUB,
    CLASS_CDC_DATA,
    CLASS_SMART_CARD,
    CLASS_CONTENT_SECURITY = 0x0D,
    CLASS_VIDEO = 0x0E,
    CLASS_DIAGNOSTIC_DEVICE = 0xDC,
    CLASS_WIRELESS_CONTROLLER = 0xE0,
    CLASS_MISCELLANEOUS = 0xEF,
    CLASS_APP_SPECIFIC = 0xFE,
    CLASS_VENDOR_SPECIFIC = 0xFF
};
//CLASS=0x00=DEVICE // This means that the use of the device comes in the Interface Descriptors

#define  DEVICE_TO_HOST         0x80
#define  HOST_TO_DEVICE         0x00
#define  REQUEST_TYPE_CLASS     0x20
#define  RECIPIENT_DEVICE       0x00
#define  RECIPIENT_INTERFACE    0x01
#define  RECIPIENT_ENDPOINT        0x02
#define  RECIPIENT_OTHER        0x03

#define  GET_STATUS                0
#define  CLEAR_FEATURE            1
#define  SET_FEATURE            3
#define  SET_ADDRESS            5
#define  GET_DESCRIPTOR            6
#define  SET_DESCRIPTOR            7
#define  GET_CONFIGURATION        8
#define  SET_CONFIGURATION        9
#define  GET_INTERFACE            10
#define  SET_INTERFACE            11
#define  SYNCH_FRAME            11

//        -5 is nak
/*
0010 ACK Handshake
1010 NAK Handshake
1110 STALL Handshake
0110 NYET (No Response Yet)
*/

#define IO_PENDING -100
#define ERR_ENDPOINT_NONE_LEFT -101
#define ERR_ENDPOINT_NOT_FOUND -102
#define ERR_DEVICE_NOT_FOUND -103
#define ERR_DEVICE_NONE_LEFT -104
#define ERR_HUB_INIT_FAILED -105
#define ERR_INTERFACE_NOT_FOUND -106


//prefixeds indicators:
//  b = byte(8bits)
//  w = word(16bits)
//  bm= bit map
//  bcd = binary-coded-decimal
//  i = index
//  id = identifier.

   // bDescriptorType values:
          //    01h device  
          //    02h configuration
          //    03h string -just for optional descriptive test
          //    04h interface
          //    05h endpoint
          //    06h device_qualifier -for devices theat support both full and high speeds. 
          //    07h other_speed_configuration
          //    08h interface_powr
          //    09h OTG -for On-The-Go devices only
          //    0Ah debug
          //    0Bh interface association -for composite devices


// This is the device decriptor:
typedef struct
{
    u8    bLength; // the length in bytes of the descriptor
    u8    bDescriptorType; //descriptor! (01h)
    u16 bcdUSB; // usb specs version
               // usb 2.0 -> 0x0200
               // usb 1.1 -> 0x0110
               // usb 1.0 -> 0x0100
    u8 bDeviceClass; //class code
    u8 bDeviceSubClass; //subclass code
    u8 bDeviceProtocol; //protocol code
    u8 bMaxPacketSize;  //maximun packet size for endpoint 0
    u16 idVendor; //vendor ID
    u16 idProduct; //product ID
    u16 bcdDevice;    // device release number
    u8 iManufacturer; //index that points a string describing the manufacturer. zero if no string description.
    u8 iProduct; //index that points a string describing the product. zero if no string decription
    u8 iSerialNumber; //index to a string with the serial number.
    u8 bNumConfigurations; //number of possible configurations.
} DeviceDescriptor;    // 16 bytes


//after retrieving the device decriptor the host can
//ask for device configuration.
//When the configuration descriptor is read, it returns
//the entire configuration hierarchy which includes all
//related interface and endpoint descriptors.
// The wTotalLength field reflects the number of bytes in the hierarchy.
typedef struct
{
    u8    bLength; //length in bytes of the descriptor
    u8    bDescriptorType; // the constant CONFIGURATION (02h)
    u16    wTotalLength;
    u8    bNumInterfaces; //specifies the number of interfaces present for this configuration.
    u8    bConfigurationValue;   //is used by the SetConfiguration request to select this configuration.
    u8    iConfiguration;            // Index of String Descriptor describing this configuration
    u8    bmAttributes;            // Bitmap D7 Reserved, set to 1. (USB 1.0 Bus Powered),D6 Self Powered,D5 Remote Wakeup,D4..0 = 0
    u8    bMaxPower;                // Maximum Power Consumption in 2mA units
} ConfigurationDescriptor;


// the InterfaceDescriptor provides information
//or features implemented.
//The interface descriptor could be seen as a header
// or grouping of the endpoints into a functional group
// performing a single feature of the device.
typedef struct
{
    u8    bLength; //descriptor size in bytes.
    u8    bDescriptorType; // the constant INTERFACE (04h)
    u8    bInterfaceNumber; //number identifing this interface
    u8    bAlternateSetting; //Can be used to specify alternative interfaces.
                             //These alternative interfaces can be selected with the Set Interface request.
    u8    bNumEndpoints; //number of endpoint supported, not counting the endpoint 0
    u8    bInterfaceClass; //class code
            //bInterfaceClass values:
            //01 Audio
            //02 Comunication interface
            //03 HID-> Human Interface Device
            //05 Physical
            //06 Image
            //07 Printer
            //08 Mass storage
            //09 Hub
            //0A Data interface
            //0B Smart Card
            //0D Content security
            //0E Video
            //DC diagnostic divice
            //E0 wirelless controler
            //FE Application specific
            //FF vendor specific    
    u8    bInterfaceSubClass; //subclass code
    u8    bInterfaceProtocol; //protocol code
    u8    iInterface;                // Index of String Descriptor Describing this interface
} InterfaceDescriptor;


//Each endpoint in an interface descriptor must have
//an endpoint descriptor.
//Endpoint descriptors are used to describe endpoints
//other than endpoint zero. Endpoint zero is always
//assumed to be a control endpoint and is configured
// before any descriptors are even requested. The host
// will use the information returned from these descriptors
// to determine the bandwidth requirements of the bus.
typedef struct
{
    u8    bLength; //descriptor size in bytes.
    u8    bDescriptorType; //the constant ENDPOINT(05h)
    u8    bEndpointAddress; //Endpoint number and direction
       // Bits 0:3 endpoint, Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
    u8    bmAttributes;  //specifies the transfer type.
       // Bits 0:1 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
    u16 wMaxPacketSize; //maximun packet size supported.
    u8    bInterval;   // Interval for polling endpoint data transfers.
} EndpointDescriptor;

typedef struct {
  u8    bLength;
  u8    bDescriptorType; //(0x21h)
  u16   bcdHID; // HID specs release number
  u8    bCountryCode; //0X00 for no country-code
  u8    bNumDescriptors;//the number of class descriptors that
                        //are subordinated to this descriptor.
  u8    bDescriptorType2; //2? the type of descriptor that is subordinated
                          //to the class descriptor. Minimun 1, due it 
                          //has to have at least 1 report descriptor and/Or
                          //one or more phsical descriptors.
                          //A report descriptionr (required) is type 22h.
  u16   wDescriptorLength;
  
  //u8 bDescriptorTyepe;  //<- Optional; The type of descriptor that follows
                          //A physical descriptior is 0x23h
  //u16 wDescriptorLength2;   
  
} HIDDescriptor;
 
//============================================================================
//============================================================================


void USBInit();
void USBLoop();
u8* USBGetBuffer(u32* len);

//    Optional callback for transfers, called at interrupt time
typedef void (*USBCallback)(int device, int endpoint, int status, u8* data, int len, void* userData);

//    Transfers
int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback = 0, void* userData = 0);
int USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0);
int USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0);

//    Standard Device methods
int GetDescriptor(int device, int descType, int descIndex, u8* data, int length);
int GetString(int device, int index, char* dst, int length);
int SetAddress(int device, int new_addr);
int SetConfiguration(int device, int configNum);
int SetInterface(int device, int ifNum, int altNum);

//    Implemented to notify app of the arrival of a device
void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc);

#endif