Richard Collins / USBHostControllerDriver
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UsbStructures.h Source File

UsbStructures.h

00001 /**
00002     A host controller driver from the mBed device.
00003     Copyright (C) 2012  Richard e Collins - richard.collins@linux.com
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017     
00018     This is just a container header for all the stuctures I use in talking to the usb device and host controller.
00019     Some are real packets sent, some are structures used by the hardware host controller.
00020     
00021     Some of the objects here maybe accessed by the Host controller.
00022     Some are here just for the driver. I could have 'hid' them in the driver
00023     but did not so to keep the code less cluttered and more readable.
00024 
00025 */
00026 
00027 #ifndef __USB_STRUCTURES_H__
00028 #define __USB_STRUCTURES_H__
00029 
00030 namespace USB
00031 {
00032 
00033 /**
00034  * The device descriptor of a USB device represents the entire device.
00035  * As a result a USB device can only have one device descriptor.
00036  * It specifies some basic, yet important information about the device such as the supported USB version, maximum packet size,
00037  * vendor and product IDs and the number of possible configurations the device can have.
00038  * 
00039  * The bcdUSB field reports the highest version of USB the device supports.
00040  *      The value is in binary coded decimal with a format of 0xJJMN where JJ is the major version number, M is the minor version number and N is the sub minor version number.
00041  *      e.g. USB 2.0 is reported as 0x0200, USB 1.1 as 0x0110 and USB 1.0 as 0x0100.
00042  * 
00043  * The bDeviceClass, bDeviceSubClass and bDeviceProtocol are used by the operating system to find a class driver for your device.
00044  *      Typically only the bDeviceClass is set at the device level. Most class specifications choose to identify itself at the interface level and as a result set the bDeviceClass as 0x00.
00045  *      This allows for the one device to support multiple classes.
00046  * 
00047  * The bMaxPacketSize field reports the maximum packet size for endpoint zero. All devices must support endpoint zero.
00048  * 
00049  * The idVendor and idProduct are used by the operating system to find a driver for your device. The Vendor ID is assigned by the USB-IF.
00050  * 
00051  * The bcdDevice has the same format than the bcdUSB and is used to provide a device version number. This value is assigned by the developer.
00052  * 
00053  * Three string descriptors exist to provide details of the manufacturer, product and serial number.
00054  *      There is no requirement to have string descriptors. If no string descriptor is present, a index of zero should be used.
00055  * 
00056  * bNumConfigurations defines the number of configurations the device supports at its current speed.
00057  */
00058 struct DeviceDescription
00059 {
00060     uint8_t  length;            //Size of the Descriptor in Bytes (18 bytes)
00061     uint8_t  descriptorType;    //Device Descriptor (0x01)
00062     uint16_t usbVersion;            //USB Specification Number which device complies too. BCD format.
00063     uint8_t  deviceClass;      //Class Code (Assigned by USB Org) If equal to Zero, each interface specifies it&#65533;s own class code. If equal to 0xFF, the class code is vendor specified. Otherwise field is valid Class Code.
00064     uint8_t  deviceSubClass;   //Subclass Code (Assigned by USB Org)
00065     uint8_t  deviceProtocol;   //Protocol Code (Assigned by USB Org)
00066     uint8_t  maxPacketSize;    //Maximum Packet Size for Zero Endpoint. Valid Sizes are 8, 16, 32, 64
00067     uint16_t idVendor;          //Vendor ID (Assigned by USB Org)
00068     uint16_t idProduct;         //Product ID (Assigned by Manufacturer)
00069     uint16_t deviceVersion;         //Device Release Number BCD Format.
00070     uint8_t  manufacturerName;     //Index of Manufacturer String Descriptor
00071     uint8_t  productName;          //Index of Product String Descriptor
00072     uint8_t  serialNumber;     //Index of Serial Number String Descriptor
00073     uint8_t  numConfigurations;//Number of Possible Configurations
00074 };
00075 
00076 /**
00077  * A USB device can have several different configurations although the majority of devices are simple and only have one.
00078  * The configuration descriptor specifies how the device is powered, what the maximum power consumption is, the number of interfaces it has.
00079  * Therefore it is possible to have two configurations, one for when the device is bus powered and another when it is mains powered.
00080  * As this is a "header" to the Interface descriptors, its also feasible to have one configuration using a different transfer mode to that of another configuration.
00081  * Once all the configurations have been examined by the host, the host will send a SetConfiguration command with a non zero value
00082  * which matches the bConfigurationValue of one of the configurations. This is used to select the desired configuration.
00083  */
00084 struct ConfigurationDescription
00085 {
00086     uint8_t length;             // Size of Descriptor in Bytes
00087     uint8_t type;               // Configuration Descriptor
00088     uint16_t totalLength;       // Total length in bytes of data returned
00089     uint8_t numInterfaces;      // Number of Interfaces
00090     uint8_t configID;           // Value to use as an argument to select this configuration
00091     uint8_t configStringIndex;  // Index of String Descriptor describing this configuration
00092     uint8_t attributes;         // D7 Reserved, set to 1. (USB 1.0 Bus Powered) D6 Self Powered D5 Remote Wakeup D4..0 Reserved, set to 0.
00093     uint8_t maxPower;           // Maximum Power Consumption in 2mA units
00094 };
00095 
00096 /**
00097  * USB interface association descriptor (IAD) allows the device to group interfaces that belong to a function. This topic describes how a client driver can determine whether the device contains an IAD for a function.
00098  * The Universal Serial Bus Specification, revision 2.0, does not support grouping more than one interface of a composite device within a single function. However, the USB Device Working Group (DWG) created USB device classes that allow for functions with multiple interfaces, and the USB Implementor's Forum issued an Engineering Change Notification (ECN) that defines a mechanism for grouping interfaces.
00099  * The ECN specifies a USB descriptor, called the Interface Association Descriptor (IAD), that allows hardware manufacturers to define groupings of interfaces.
00100  */
00101 struct InterfaceAssociation
00102 {
00103     uint8_t length;
00104     uint8_t descriptorType;
00105     uint8_t firstInterface;
00106     uint8_t interfaceCount;
00107     uint8_t functionClass;
00108     uint8_t functionSubClass;
00109     uint8_t functionProtocol;
00110     uint8_t function;
00111 };
00112 
00113 /**
00114  * 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. The interface descriptor conforms to the following format,
00115  */
00116 struct InterfaceDescription
00117 {
00118     uint8_t length;             //Size of Descriptor in Bytes (9 Bytes)
00119     uint8_t descriptorType;     //Interface Descriptor (0x04)
00120     uint8_t interfaceNumber;    //Number of Interface
00121     uint8_t alternateSetting;   //Value used to select alternative setting
00122     uint8_t numEndpoints;       //Number of Endpoints used for this interface
00123     uint8_t interfaceClass;     //Class Code (Assigned by USB Org)
00124     uint8_t interfaceSubClass;  //Subclass Code (Assigned by USB Org)
00125     uint8_t interfaceProtocol;  //Protocol Code (Assigned by USB Org)
00126     uint8_t interface;          //Index of String Descriptor Describing this interface
00127 };
00128 
00129 /**
00130  * Endpoint descriptors are used to describe endpoints other than endpoint zero.
00131  * Endpoint zero is always assumed to be a control endpoint and is configured before any descriptors are even requested.
00132  * The host will use the information returned from these descriptors to determine the bandwidth requirements of the bus.
00133  */
00134 struct EndpointDescription
00135 {
00136     uint8_t length;             //Size of Descriptor in Bytes (7 bytes)
00137     uint8_t descriptorType;     //Endpoint Descriptor (0x05)
00138     uint8_t endpointAddress;    //Endpoint Address Bits 0..3b Endpoint Number. Bits 4..6b Reserved. Set to Zero Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
00139     uint8_t attributes;         //Bits 0..1 Transfer Type 00 = Control 01 = Isochronous 10 = Bulk 11 = Interrupt
00140                                 //Bits 2..7 are reserved. If Isochronous endpoint, 
00141                                 //Bits 3..2 = Synchronisation Type (Iso Mode) 00 = No Synchonisation 01 = Asynchronous 10 = Adaptive 11 = Synchronous
00142                                 //Bits 5..4 = Usage Type (Iso Mode) 00 = Data Endpoint 01 = Feedback Endpoint 10 = Explicit Feedback Data Endpoint 11 = Reserved
00143     uint16_t maxPacketSize;     //Maximum Packet Size this endpoint is capable of sending or receiving
00144     uint8_t interval;           //Interval for polling endpoint data transfers. Value in frame counts. Ignored for Bulk & Control Endpoints. Isochronous must equal 1 and field may range from 1 to 255 for interrupt endpoints.
00145 };
00146 
00147 /**
00148  * For the transfer descriptors, endpoint descriptors and setup structures I 'allocate' and use one of these ojects from a pool of memory.
00149  * The pool is a linked list with each node being 16 bytes in size.
00150  * This gives excelent allocate and object deallocation speed, also allows one pool for all types used giving very good memory utilisation.
00151  * Memory pools are used extensivly in software where the allocation size is constant and frequent and high speed is required.
00152  * For examples a 'bullet' object in a game. Using the normal memory allocator would cause a significant cpu load.
00153  */
00154 struct LinkedListItem
00155 {
00156     LinkedListItem* next;
00157     uint32_t padding[7];//So struct is 32 bytes in size.
00158 };
00159 
00160 /**
00161  * Inhert this object and implemet the callback function.
00162  * Then pass this object to the IO functions if you need a callback.
00163  * This is a test.
00164  */
00165 struct TransferCallback
00166 {
00167     /**
00168      * Called when a transfer has been completed that had a callback ID set.
00169      * Any other transfers without a callback ID will not trigger this.
00170      */
00171     virtual void onReceive(int deviceID, int endpoint, int status,const uint8_t* data, int length) = 0;
00172 };
00173 
00174 /**
00175  * There are fields that are read/write by the HC. The unused portion of this
00176  * Dword must either not be written by Host Controller or must be read,
00177  * and then written back unmodified. The Host Controller Driver should not modify any
00178  * portion of the transfer descriptor while it is accessible to the HC.
00179  * As well as using the first 18bits that are garnteed not to be altered by the host
00180  * I have made this structure 32 bytes in size. (helps with keeping it 16 byte aligned)
00181  * The extra 16 bytes are for when there is a callback defined for an interupt transfer or a
00182  * bulk transfer called with a callback. The host will not change the extra 16 bytes.
00183  * Because of the extra size this stuct comes from it's own memory pool.
00184  */
00185 struct TransferDescriptor
00186 {
00187     /**
00188      * The next 18 bits are unused by the controller and the spec says that they should not be
00189      * modified by the host controller. So this means we can use it as a way to 'mark'
00190      * a transfer so that when it is returned having been completed we can resolve
00191      * who it was for.
00192      */
00193     volatile unsigned deviceID:18;
00194         
00195     /**
00196      * If this bit is 0, then the last data packet to a TD from an endpoint must
00197      * exactly fill the defined data buffer. If the bit is 1, then the last data
00198      * packet may be smaller than the defined buffer without causing an error
00199      * condition on the TD.
00200      */
00201     volatile unsigned bufferRounding:1;
00202     
00203     /**
00204      * This 2-bit field indicates the direction of data flow and the PID to be used
00205      * for the token. This field is only relevant to the HC if the D field in the ED
00206      * was set to 00b or 11b indicating that the PID determination is deferred to
00207      * the TD. The encoding of the bits within the byte for this field are:
00208      *
00209      * Code
00210      * 00b SETUP - to endpoint
00211      * 01b OUT - to endpoint
00212      * 10b IN - from endpoint
00213      * 11b Reserved
00214      */
00215     volatile unsigned direction:2;
00216     
00217     /**
00218      * This field contains the interrupt delay count for this TD. When a TD is
00219      * complete the HC may wait for DelayInterrupt frames before generating
00220      * an interrupt. If DelayInterrupt is 111b, then there is no interrupt
00221      * associated with completion of this TD
00222      */
00223     volatile unsigned delayInterrupt:3;
00224     
00225     /**
00226      * This 2-bit field is used to generate/compare the data PID value (DATA0 or DATA1).
00227      * It is updated after each successful transmission/reception of
00228      * a data packet. The MSb of this field is &#65533;0&#65533; when the data toggle value is
00229      * acquired from the toggleCarry field in the ED and &#65533;1&#65533; when the data
00230      * toggle value is taken from the LSb of this field.
00231      */
00232     volatile unsigned dataToggle:2;
00233     
00234     /**
00235      * For each transmission error, this value is incremented. If ErrorCount is
00236      * 2 and another error occurs, the error type is recorded in the
00237      * ConditionCode field and placed on the done queue. When a
00238      * transaction completes without error, ErrorCount is reset to 0.
00239      */
00240     unsigned errorCount:2;
00241     
00242     /**
00243      * This field contains the status of the last attempted transaction.
00244      */
00245     unsigned conditionCode:4;
00246     
00247     /**
00248      * Contains the physical address of the next memory location that will be
00249      * accessed for transfer to/from the endpoint. A value of 0 indicates a zero-
00250      * length data packet or that all bytes have been transferred.
00251      */
00252     const uint8_t* CurrentBufferPointer;
00253 
00254     /**
00255      * his entry points to the next TD on the list of TDs linked to this endpoint
00256      */
00257     TransferDescriptor *nextTD;
00258     
00259     /**
00260      * Contains physical address of the last byte in the buffer for this TD
00261      */
00262     const uint8_t* bufferEnd;
00263     
00264     /**
00265      * Extra 16 bytes for the callback info.
00266      */
00267      
00268     /**
00269      * If not NULL then called when a transfer is completed.
00270      */
00271     TransferCallback* transferCallback;
00272     
00273     /**
00274      * The pointer to the start of the data being transfered or recived.
00275      */
00276     const uint8_t* data;
00277     
00278     /**
00279      * The length of the transfer.
00280      */
00281     int length;
00282     uint8_t ep;
00283     uint8_t transferType;
00284     uint8_t pad1;
00285     uint8_t pad2;
00286 };
00287 
00288 /**
00289  * Host Controller Endpoint Descriptor.
00290  * An Endpoint Descriptor (ED) is a 16-byte, memory resident structure that must be aligned to a
00291  * 16-byte boundary. The Host Controller traverses lists of EDs and if there are TDs linked to an
00292  * ED, the Host Controller performs the indicated transfer.
00293  */
00294 struct EndpointDescriptor
00295 {    
00296     /**
00297      * This is the USB address of the function containing the endpoint that this ED controls
00298      * In the docs this is called 'FunctionAddress' but it is for our use for when the controller
00299      * passes the object back to us.
00300      * unsigned functionAddress:7;
00301      *
00302      * This is the USB address of the endpoint within the function.
00303      * unsigned endpointNumber:4;
00304      * 
00305      * unsigned D:2;
00306      * unsigned S:1;
00307      * unsigned K:1;
00308      * unsigned F:1;
00309      *     
00310      * This field indicates the maximum number of bytes that can be sent to or received from the endpoint in a single data packet
00311      * unsigned maximumPacketSize:11;
00312      *
00313      * unsigned padding:5;
00314      */
00315     uint32_t control;  
00316 
00317     unsigned padding0:4;
00318     unsigned TailTD:28;       //physical pointer to HC_TRANSFER_DESCRIPTOR
00319     
00320 //    TransferDescriptor* HeadTD;       //flags + phys ptr to HC_TRANSFER_DESCRIPTOR
00321     unsigned H:1;
00322     unsigned C:1;
00323     unsigned ZERO:2;
00324     unsigned HeadTD:28;
00325 
00326     EndpointDescriptor* NextEP;      //phys ptr to HC_ENDPOINT_DESCRIPTOR
00327 };
00328 
00329 /*
00330  * Size is kept to no more than 32 bytes so that I can use the pool of memory in
00331  * the host controller driver and so not use any of the main 32k of ram.
00332  */
00333 struct Device
00334 {
00335     /**
00336      * When we allocated a device with give it an ID and then set the USB device's ID with the set address command.
00337      */
00338     int id;
00339     
00340     uint8_t lowspeed;
00341     uint8_t controlTransferDirToHost;//LIBUSB_ENDPOINT_IN when set
00342     uint8_t controlTransferState;     //See enum ControlTransferState, the control transfer has several states it can be in.
00343     uint8_t padding;
00344     
00345     /**
00346      * This is the packet size of endpoint zero the docs say valid Sizes are 8, 16, 32, 64. This info could be out of date.
00347      */
00348     int endpointZeroMaxPacketSize;
00349     
00350     /**
00351      * This data is used whilst there is a control transfer in progress.
00352      * When finished controlTransferDataLength will be the number of bytes recived.
00353      */
00354     const uint8_t* controlTransferData;
00355     int controlTransferDataLength;
00356     
00357     /**
00358      * The first language ID I find from string index zero. Makes life easier.
00359      * Used in getting the descriptor strings.
00360      */
00361     int languageID;
00362     
00363     /*
00364      * If a transfer requires a callback when done then this will have the transfers here.
00365      * If this is the case then the transfer is only free'd after the callback has been called instead of when the interupt is called.
00366      * Because of this it is important that the applicaition calls the Update function of the driver at least once a second.
00367      * Failure to do so whilst issueing many transfers will cause the memory pool to be exhausted.
00368      */
00369     TransferDescriptor* pendingCallbacks;
00370     
00371     /**
00372      * When not -1 then will block the transfer until it is -1 again.
00373      */
00374     int blockOnEP;
00375 };
00376 
00377 /**
00378  * request_type of setup packet defined as....
00379     * 0 = Device
00380     * 1 = Interface
00381     * 2 = Endpoint
00382     * 3 = Other
00383     * 4..31 Reserved
00384     unsigned recipient:5;
00385     
00386     * 0 = Standard
00387     * 1 = Class
00388     * 2 = Vendor
00389     * 3 = Reserved.
00390     unsigned type:2;
00391      
00392     * 0 = Host to device.
00393     * 1 = Device to host.
00394     unsigned transferDirection:1;
00395 */
00396 struct SetupPacket
00397 {
00398     uint8_t requestType;
00399     uint8_t request;
00400     uint16_t value;
00401     uint16_t index;
00402     
00403     /**
00404      * The number of bytes in the data phase.
00405      */
00406     uint16_t length;
00407 };
00408 
00409 
00410 /**
00411  * The Host Controller Communications Area (HCCA) is a 256-byte structure of system memory
00412  * that is used by system software to send and receive specific control and status information to and
00413  * from the HC. This structure must be located on a 256-byte boundary. System software must
00414  * write the address of this structure in HcHCCA in the HC. This structure allows the software to
00415  * direct the HC&#65533;s functions without having to read from the Host Controller except in unusual
00416  * circumstances (e.g., error conditions). Normal interaction with the Host Controller can be
00417  * accomplished by reading values from this structure that were written by the Host Controller and
00418  * by writing to the HC&#65533;s operation registers.
00419  * 
00420  */
00421 struct HostControllerCommunicationsArea
00422 {
00423     /**
00424      * These 32 Dwords are pointers to interrupt EDs
00425      */
00426     uint32_t interruptTable[32];
00427     
00428     /**
00429      * Contains the current frame number. This value
00430      * is updated by the HC before it begins
00431      * processing the periodic lists for the frame.
00432      */
00433     uint16_t frameNumber;
00434     
00435     /**
00436      * When the HC updates HccaFrameNumber, it sets this word to 0.
00437      */
00438     uint16_t pad1;
00439     
00440     /**
00441      * When the HC reaches the end of a frame and
00442      * its deferred interrupt register is 0, it writes the
00443      * current value of its HcDoneHead to this
00444      * location and generates an interrupt if interrupts
00445      * are enabled. This location is not written by the
00446      * HC again until software clears the WD bit in
00447      * the HcInterruptStatus register. This protocol provides an interlocked exchange of the Done Queue.
00448      * The LSb of this entry is set to 1 to indicate
00449      * whether an unmasked HcInterruptStatus was
00450      * set when HccaDoneHead was written.
00451      * I don't process this in the interupt but in the driver update.
00452      * The interupt flags the driver that stuff is done.
00453      */
00454     struct TransferDescriptor* doneHead;
00455     
00456     /**
00457      * Reserved for use by HC, also makes the data after this 16 byte aligned.
00458      */
00459     uint8_t reserved[120];
00460     
00461     /**
00462      * I have added onto the end of this alligned struct some extra data that I don't want to be taken out
00463      * of the main 32k of main ram.
00464      */
00465      
00466     /**
00467      * Device zero is used for enumeration and setup when a usb device is inserted. 
00468      */
00469     Device deviceZero;
00470      
00471     /**
00472      * My memory pool of 32 byte objects that MUST be aligned on a 16byte boundry.
00473      * So don't move this entry or add stuff before it!
00474      * It is 32 bytes as the transfer descriptor needs an extra 16 bytes for my
00475      * driver so I can do callbacks when a transfer is complete.
00476      * Without it then I would need some kind of horrid lookup table and code that could add bugs.
00477      * This way it is nice, clean, and simple.
00478      */
00479     LinkedListItem memoryPool[32];
00480          
00481     /**
00482      * And now some scratch ram to used when I am reciving strings.
00483      */
00484     uint8_t scratchRam[256];
00485 };
00486 
00487 
00488 };//end namespace USB
00489 
00490 #endif //#ifndef__USB_STRUCTURES_H__
00491