Committer:
RichardUK
Date:
Wed Sep 19 16:44:32 2012 +0000
Revision:
2:33e7ce63dd6d
Parent:
1:4461071ed964
Testing lib update to another project.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
RichardUK 0:63d45df56584 1 /**
RichardUK 0:63d45df56584 2 A host controller driver from the mBed device.
RichardUK 0:63d45df56584 3 Copyright (C) 2012 Richard e Collins - richard.collins@linux.com
RichardUK 0:63d45df56584 4
RichardUK 0:63d45df56584 5 This program is free software: you can redistribute it and/or modify
RichardUK 0:63d45df56584 6 it under the terms of the GNU General Public License as published by
RichardUK 0:63d45df56584 7 the Free Software Foundation, either version 3 of the License, or
RichardUK 0:63d45df56584 8 (at your option) any later version.
RichardUK 0:63d45df56584 9
RichardUK 0:63d45df56584 10 This program is distributed in the hope that it will be useful,
RichardUK 0:63d45df56584 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
RichardUK 0:63d45df56584 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
RichardUK 0:63d45df56584 13 GNU General Public License for more details.
RichardUK 0:63d45df56584 14
RichardUK 0:63d45df56584 15 You should have received a copy of the GNU General Public License
RichardUK 0:63d45df56584 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
RichardUK 0:63d45df56584 17
RichardUK 0:63d45df56584 18 This is just a container header for all the stuctures I use in talking to the usb device and host controller.
RichardUK 0:63d45df56584 19 Some are real packets sent, some are structures used by the hardware host controller.
RichardUK 0:63d45df56584 20
RichardUK 0:63d45df56584 21 Some of the objects here maybe accessed by the Host controller.
RichardUK 0:63d45df56584 22 Some are here just for the driver. I could have 'hid' them in the driver
RichardUK 0:63d45df56584 23 but did not so to keep the code less cluttered and more readable.
RichardUK 0:63d45df56584 24
RichardUK 0:63d45df56584 25 */
RichardUK 0:63d45df56584 26
RichardUK 0:63d45df56584 27 #ifndef __USB_STRUCTURES_H__
RichardUK 0:63d45df56584 28 #define __USB_STRUCTURES_H__
RichardUK 0:63d45df56584 29
RichardUK 0:63d45df56584 30 namespace USB
RichardUK 0:63d45df56584 31 {
RichardUK 0:63d45df56584 32
RichardUK 0:63d45df56584 33 /**
RichardUK 0:63d45df56584 34 * The device descriptor of a USB device represents the entire device.
RichardUK 0:63d45df56584 35 * As a result a USB device can only have one device descriptor.
RichardUK 0:63d45df56584 36 * It specifies some basic, yet important information about the device such as the supported USB version, maximum packet size,
RichardUK 0:63d45df56584 37 * vendor and product IDs and the number of possible configurations the device can have.
RichardUK 0:63d45df56584 38 *
RichardUK 0:63d45df56584 39 * The bcdUSB field reports the highest version of USB the device supports.
RichardUK 0:63d45df56584 40 * 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.
RichardUK 0:63d45df56584 41 * e.g. USB 2.0 is reported as 0x0200, USB 1.1 as 0x0110 and USB 1.0 as 0x0100.
RichardUK 0:63d45df56584 42 *
RichardUK 0:63d45df56584 43 * The bDeviceClass, bDeviceSubClass and bDeviceProtocol are used by the operating system to find a class driver for your device.
RichardUK 0:63d45df56584 44 * 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.
RichardUK 0:63d45df56584 45 * This allows for the one device to support multiple classes.
RichardUK 0:63d45df56584 46 *
RichardUK 0:63d45df56584 47 * The bMaxPacketSize field reports the maximum packet size for endpoint zero. All devices must support endpoint zero.
RichardUK 0:63d45df56584 48 *
RichardUK 0:63d45df56584 49 * 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.
RichardUK 0:63d45df56584 50 *
RichardUK 0:63d45df56584 51 * 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.
RichardUK 0:63d45df56584 52 *
RichardUK 0:63d45df56584 53 * Three string descriptors exist to provide details of the manufacturer, product and serial number.
RichardUK 0:63d45df56584 54 * There is no requirement to have string descriptors. If no string descriptor is present, a index of zero should be used.
RichardUK 0:63d45df56584 55 *
RichardUK 0:63d45df56584 56 * bNumConfigurations defines the number of configurations the device supports at its current speed.
RichardUK 0:63d45df56584 57 */
RichardUK 0:63d45df56584 58 struct DeviceDescription
RichardUK 0:63d45df56584 59 {
RichardUK 0:63d45df56584 60 uint8_t length; //Size of the Descriptor in Bytes (18 bytes)
RichardUK 0:63d45df56584 61 uint8_t descriptorType; //Device Descriptor (0x01)
RichardUK 0:63d45df56584 62 uint16_t usbVersion; //USB Specification Number which device complies too. BCD format.
RichardUK 0:63d45df56584 63 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.
RichardUK 0:63d45df56584 64 uint8_t deviceSubClass; //Subclass Code (Assigned by USB Org)
RichardUK 0:63d45df56584 65 uint8_t deviceProtocol; //Protocol Code (Assigned by USB Org)
RichardUK 0:63d45df56584 66 uint8_t maxPacketSize; //Maximum Packet Size for Zero Endpoint. Valid Sizes are 8, 16, 32, 64
RichardUK 0:63d45df56584 67 uint16_t idVendor; //Vendor ID (Assigned by USB Org)
RichardUK 0:63d45df56584 68 uint16_t idProduct; //Product ID (Assigned by Manufacturer)
RichardUK 0:63d45df56584 69 uint16_t deviceVersion; //Device Release Number BCD Format.
RichardUK 0:63d45df56584 70 uint8_t manufacturerName; //Index of Manufacturer String Descriptor
RichardUK 0:63d45df56584 71 uint8_t productName; //Index of Product String Descriptor
RichardUK 0:63d45df56584 72 uint8_t serialNumber; //Index of Serial Number String Descriptor
RichardUK 0:63d45df56584 73 uint8_t numConfigurations;//Number of Possible Configurations
RichardUK 0:63d45df56584 74 };
RichardUK 0:63d45df56584 75
RichardUK 0:63d45df56584 76 /**
RichardUK 0:63d45df56584 77 * A USB device can have several different configurations although the majority of devices are simple and only have one.
RichardUK 0:63d45df56584 78 * The configuration descriptor specifies how the device is powered, what the maximum power consumption is, the number of interfaces it has.
RichardUK 0:63d45df56584 79 * Therefore it is possible to have two configurations, one for when the device is bus powered and another when it is mains powered.
RichardUK 0:63d45df56584 80 * 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.
RichardUK 0:63d45df56584 81 * Once all the configurations have been examined by the host, the host will send a SetConfiguration command with a non zero value
RichardUK 0:63d45df56584 82 * which matches the bConfigurationValue of one of the configurations. This is used to select the desired configuration.
RichardUK 0:63d45df56584 83 */
RichardUK 0:63d45df56584 84 struct ConfigurationDescription
RichardUK 0:63d45df56584 85 {
RichardUK 0:63d45df56584 86 uint8_t length; // Size of Descriptor in Bytes
RichardUK 0:63d45df56584 87 uint8_t type; // Configuration Descriptor
RichardUK 0:63d45df56584 88 uint16_t totalLength; // Total length in bytes of data returned
RichardUK 0:63d45df56584 89 uint8_t numInterfaces; // Number of Interfaces
RichardUK 0:63d45df56584 90 uint8_t configID; // Value to use as an argument to select this configuration
RichardUK 0:63d45df56584 91 uint8_t configStringIndex; // Index of String Descriptor describing this configuration
RichardUK 0:63d45df56584 92 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.
RichardUK 0:63d45df56584 93 uint8_t maxPower; // Maximum Power Consumption in 2mA units
RichardUK 0:63d45df56584 94 };
RichardUK 0:63d45df56584 95
RichardUK 0:63d45df56584 96 /**
RichardUK 0:63d45df56584 97 * 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.
RichardUK 0:63d45df56584 98 * 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.
RichardUK 0:63d45df56584 99 * The ECN specifies a USB descriptor, called the Interface Association Descriptor (IAD), that allows hardware manufacturers to define groupings of interfaces.
RichardUK 0:63d45df56584 100 */
RichardUK 0:63d45df56584 101 struct InterfaceAssociation
RichardUK 0:63d45df56584 102 {
RichardUK 0:63d45df56584 103 uint8_t length;
RichardUK 0:63d45df56584 104 uint8_t descriptorType;
RichardUK 0:63d45df56584 105 uint8_t firstInterface;
RichardUK 0:63d45df56584 106 uint8_t interfaceCount;
RichardUK 0:63d45df56584 107 uint8_t functionClass;
RichardUK 0:63d45df56584 108 uint8_t functionSubClass;
RichardUK 0:63d45df56584 109 uint8_t functionProtocol;
RichardUK 0:63d45df56584 110 uint8_t function;
RichardUK 0:63d45df56584 111 };
RichardUK 0:63d45df56584 112
RichardUK 0:63d45df56584 113 /**
RichardUK 0:63d45df56584 114 * 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,
RichardUK 0:63d45df56584 115 */
RichardUK 0:63d45df56584 116 struct InterfaceDescription
RichardUK 0:63d45df56584 117 {
RichardUK 0:63d45df56584 118 uint8_t length; //Size of Descriptor in Bytes (9 Bytes)
RichardUK 0:63d45df56584 119 uint8_t descriptorType; //Interface Descriptor (0x04)
RichardUK 0:63d45df56584 120 uint8_t interfaceNumber; //Number of Interface
RichardUK 0:63d45df56584 121 uint8_t alternateSetting; //Value used to select alternative setting
RichardUK 0:63d45df56584 122 uint8_t numEndpoints; //Number of Endpoints used for this interface
RichardUK 0:63d45df56584 123 uint8_t interfaceClass; //Class Code (Assigned by USB Org)
RichardUK 0:63d45df56584 124 uint8_t interfaceSubClass; //Subclass Code (Assigned by USB Org)
RichardUK 0:63d45df56584 125 uint8_t interfaceProtocol; //Protocol Code (Assigned by USB Org)
RichardUK 0:63d45df56584 126 uint8_t interface; //Index of String Descriptor Describing this interface
RichardUK 0:63d45df56584 127 };
RichardUK 0:63d45df56584 128
RichardUK 0:63d45df56584 129 /**
RichardUK 0:63d45df56584 130 * Endpoint descriptors are used to describe endpoints other than endpoint zero.
RichardUK 0:63d45df56584 131 * Endpoint zero is always assumed to be a control endpoint and is configured before any descriptors are even requested.
RichardUK 0:63d45df56584 132 * The host will use the information returned from these descriptors to determine the bandwidth requirements of the bus.
RichardUK 0:63d45df56584 133 */
RichardUK 0:63d45df56584 134 struct EndpointDescription
RichardUK 0:63d45df56584 135 {
RichardUK 0:63d45df56584 136 uint8_t length; //Size of Descriptor in Bytes (7 bytes)
RichardUK 0:63d45df56584 137 uint8_t descriptorType; //Endpoint Descriptor (0x05)
RichardUK 0:63d45df56584 138 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)
RichardUK 0:63d45df56584 139 uint8_t attributes; //Bits 0..1 Transfer Type 00 = Control 01 = Isochronous 10 = Bulk 11 = Interrupt
RichardUK 0:63d45df56584 140 //Bits 2..7 are reserved. If Isochronous endpoint,
RichardUK 0:63d45df56584 141 //Bits 3..2 = Synchronisation Type (Iso Mode) 00 = No Synchonisation 01 = Asynchronous 10 = Adaptive 11 = Synchronous
RichardUK 0:63d45df56584 142 //Bits 5..4 = Usage Type (Iso Mode) 00 = Data Endpoint 01 = Feedback Endpoint 10 = Explicit Feedback Data Endpoint 11 = Reserved
RichardUK 0:63d45df56584 143 uint16_t maxPacketSize; //Maximum Packet Size this endpoint is capable of sending or receiving
RichardUK 0:63d45df56584 144 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.
RichardUK 0:63d45df56584 145 };
RichardUK 0:63d45df56584 146
RichardUK 0:63d45df56584 147 /**
RichardUK 0:63d45df56584 148 * For the transfer descriptors, endpoint descriptors and setup structures I 'allocate' and use one of these ojects from a pool of memory.
RichardUK 0:63d45df56584 149 * The pool is a linked list with each node being 16 bytes in size.
RichardUK 0:63d45df56584 150 * This gives excelent allocate and object deallocation speed, also allows one pool for all types used giving very good memory utilisation.
RichardUK 0:63d45df56584 151 * Memory pools are used extensivly in software where the allocation size is constant and frequent and high speed is required.
RichardUK 0:63d45df56584 152 * For examples a 'bullet' object in a game. Using the normal memory allocator would cause a significant cpu load.
RichardUK 0:63d45df56584 153 */
RichardUK 0:63d45df56584 154 struct LinkedListItem
RichardUK 0:63d45df56584 155 {
RichardUK 0:63d45df56584 156 LinkedListItem* next;
RichardUK 1:4461071ed964 157 uint32_t padding[7];//So struct is 32 bytes in size.
RichardUK 1:4461071ed964 158 };
RichardUK 1:4461071ed964 159
RichardUK 1:4461071ed964 160 /**
RichardUK 1:4461071ed964 161 * Inhert this object and implemet the callback function.
RichardUK 1:4461071ed964 162 * Then pass this object to the IO functions if you need a callback.
RichardUK 2:33e7ce63dd6d 163 * This is a test.
RichardUK 1:4461071ed964 164 */
RichardUK 1:4461071ed964 165 struct TransferCallback
RichardUK 1:4461071ed964 166 {
RichardUK 1:4461071ed964 167 /**
RichardUK 1:4461071ed964 168 * Called when a transfer has been completed that had a callback ID set.
RichardUK 1:4461071ed964 169 * Any other transfers without a callback ID will not trigger this.
RichardUK 1:4461071ed964 170 */
RichardUK 1:4461071ed964 171 virtual void onReceive(int deviceID, int endpoint, int status,const uint8_t* data, int length) = 0;
RichardUK 0:63d45df56584 172 };
RichardUK 0:63d45df56584 173
RichardUK 0:63d45df56584 174 /**
RichardUK 0:63d45df56584 175 * There are fields that are read/write by the HC. The unused portion of this
RichardUK 0:63d45df56584 176 * Dword must either not be written by Host Controller or must be read,
RichardUK 0:63d45df56584 177 * and then written back unmodified. The Host Controller Driver should not modify any
RichardUK 0:63d45df56584 178 * portion of the transfer descriptor while it is accessible to the HC.
RichardUK 0:63d45df56584 179 * As well as using the first 18bits that are garnteed not to be altered by the host
RichardUK 0:63d45df56584 180 * I have made this structure 32 bytes in size. (helps with keeping it 16 byte aligned)
RichardUK 0:63d45df56584 181 * The extra 16 bytes are for when there is a callback defined for an interupt transfer or a
RichardUK 0:63d45df56584 182 * bulk transfer called with a callback. The host will not change the extra 16 bytes.
RichardUK 0:63d45df56584 183 * Because of the extra size this stuct comes from it's own memory pool.
RichardUK 0:63d45df56584 184 */
RichardUK 0:63d45df56584 185 struct TransferDescriptor
RichardUK 0:63d45df56584 186 {
RichardUK 0:63d45df56584 187 /**
RichardUK 0:63d45df56584 188 * The next 18 bits are unused by the controller and the spec says that they should not be
RichardUK 0:63d45df56584 189 * modified by the host controller. So this means we can use it as a way to 'mark'
RichardUK 0:63d45df56584 190 * a transfer so that when it is returned having been completed we can resolve
RichardUK 0:63d45df56584 191 * who it was for.
RichardUK 0:63d45df56584 192 */
RichardUK 0:63d45df56584 193 volatile unsigned deviceID:18;
RichardUK 0:63d45df56584 194
RichardUK 0:63d45df56584 195 /**
RichardUK 0:63d45df56584 196 * If this bit is 0, then the last data packet to a TD from an endpoint must
RichardUK 0:63d45df56584 197 * exactly fill the defined data buffer. If the bit is 1, then the last data
RichardUK 0:63d45df56584 198 * packet may be smaller than the defined buffer without causing an error
RichardUK 0:63d45df56584 199 * condition on the TD.
RichardUK 0:63d45df56584 200 */
RichardUK 0:63d45df56584 201 volatile unsigned bufferRounding:1;
RichardUK 0:63d45df56584 202
RichardUK 0:63d45df56584 203 /**
RichardUK 0:63d45df56584 204 * This 2-bit field indicates the direction of data flow and the PID to be used
RichardUK 0:63d45df56584 205 * for the token. This field is only relevant to the HC if the D field in the ED
RichardUK 0:63d45df56584 206 * was set to 00b or 11b indicating that the PID determination is deferred to
RichardUK 0:63d45df56584 207 * the TD. The encoding of the bits within the byte for this field are:
RichardUK 0:63d45df56584 208 *
RichardUK 0:63d45df56584 209 * Code
RichardUK 0:63d45df56584 210 * 00b SETUP - to endpoint
RichardUK 0:63d45df56584 211 * 01b OUT - to endpoint
RichardUK 0:63d45df56584 212 * 10b IN - from endpoint
RichardUK 0:63d45df56584 213 * 11b Reserved
RichardUK 0:63d45df56584 214 */
RichardUK 0:63d45df56584 215 volatile unsigned direction:2;
RichardUK 0:63d45df56584 216
RichardUK 0:63d45df56584 217 /**
RichardUK 0:63d45df56584 218 * This field contains the interrupt delay count for this TD. When a TD is
RichardUK 0:63d45df56584 219 * complete the HC may wait for DelayInterrupt frames before generating
RichardUK 0:63d45df56584 220 * an interrupt. If DelayInterrupt is 111b, then there is no interrupt
RichardUK 0:63d45df56584 221 * associated with completion of this TD
RichardUK 0:63d45df56584 222 */
RichardUK 0:63d45df56584 223 volatile unsigned delayInterrupt:3;
RichardUK 0:63d45df56584 224
RichardUK 0:63d45df56584 225 /**
RichardUK 0:63d45df56584 226 * This 2-bit field is used to generate/compare the data PID value (DATA0 or DATA1).
RichardUK 0:63d45df56584 227 * It is updated after each successful transmission/reception of
RichardUK 0:63d45df56584 228 * a data packet. The MSb of this field is &#65533;0&#65533; when the data toggle value is
RichardUK 0:63d45df56584 229 * acquired from the toggleCarry field in the ED and &#65533;1&#65533; when the data
RichardUK 0:63d45df56584 230 * toggle value is taken from the LSb of this field.
RichardUK 0:63d45df56584 231 */
RichardUK 0:63d45df56584 232 volatile unsigned dataToggle:2;
RichardUK 0:63d45df56584 233
RichardUK 0:63d45df56584 234 /**
RichardUK 0:63d45df56584 235 * For each transmission error, this value is incremented. If ErrorCount is
RichardUK 0:63d45df56584 236 * 2 and another error occurs, the error type is recorded in the
RichardUK 0:63d45df56584 237 * ConditionCode field and placed on the done queue. When a
RichardUK 0:63d45df56584 238 * transaction completes without error, ErrorCount is reset to 0.
RichardUK 0:63d45df56584 239 */
RichardUK 1:4461071ed964 240 unsigned errorCount:2;
RichardUK 0:63d45df56584 241
RichardUK 0:63d45df56584 242 /**
RichardUK 0:63d45df56584 243 * This field contains the status of the last attempted transaction.
RichardUK 0:63d45df56584 244 */
RichardUK 1:4461071ed964 245 unsigned conditionCode:4;
RichardUK 0:63d45df56584 246
RichardUK 0:63d45df56584 247 /**
RichardUK 0:63d45df56584 248 * Contains the physical address of the next memory location that will be
RichardUK 0:63d45df56584 249 * accessed for transfer to/from the endpoint. A value of 0 indicates a zero-
RichardUK 0:63d45df56584 250 * length data packet or that all bytes have been transferred.
RichardUK 0:63d45df56584 251 */
RichardUK 1:4461071ed964 252 const uint8_t* CurrentBufferPointer;
RichardUK 0:63d45df56584 253
RichardUK 0:63d45df56584 254 /**
RichardUK 0:63d45df56584 255 * his entry points to the next TD on the list of TDs linked to this endpoint
RichardUK 1:4461071ed964 256 */
RichardUK 1:4461071ed964 257 TransferDescriptor *nextTD;
RichardUK 0:63d45df56584 258
RichardUK 0:63d45df56584 259 /**
RichardUK 0:63d45df56584 260 * Contains physical address of the last byte in the buffer for this TD
RichardUK 0:63d45df56584 261 */
RichardUK 1:4461071ed964 262 const uint8_t* bufferEnd;
RichardUK 0:63d45df56584 263
RichardUK 0:63d45df56584 264 /**
RichardUK 0:63d45df56584 265 * Extra 16 bytes for the callback info.
RichardUK 1:4461071ed964 266 */
RichardUK 1:4461071ed964 267
RichardUK 1:4461071ed964 268 /**
RichardUK 1:4461071ed964 269 * If not NULL then called when a transfer is completed.
RichardUK 1:4461071ed964 270 */
RichardUK 1:4461071ed964 271 TransferCallback* transferCallback;
RichardUK 1:4461071ed964 272
RichardUK 1:4461071ed964 273 /**
RichardUK 1:4461071ed964 274 * The pointer to the start of the data being transfered or recived.
RichardUK 1:4461071ed964 275 */
RichardUK 1:4461071ed964 276 const uint8_t* data;
RichardUK 1:4461071ed964 277
RichardUK 1:4461071ed964 278 /**
RichardUK 1:4461071ed964 279 * The length of the transfer.
RichardUK 1:4461071ed964 280 */
RichardUK 1:4461071ed964 281 int length;
RichardUK 1:4461071ed964 282 uint8_t ep;
RichardUK 1:4461071ed964 283 uint8_t transferType;
RichardUK 1:4461071ed964 284 uint8_t pad1;
RichardUK 1:4461071ed964 285 uint8_t pad2;
RichardUK 0:63d45df56584 286 };
RichardUK 0:63d45df56584 287
RichardUK 0:63d45df56584 288 /**
RichardUK 0:63d45df56584 289 * Host Controller Endpoint Descriptor.
RichardUK 0:63d45df56584 290 * An Endpoint Descriptor (ED) is a 16-byte, memory resident structure that must be aligned to a
RichardUK 0:63d45df56584 291 * 16-byte boundary. The Host Controller traverses lists of EDs and if there are TDs linked to an
RichardUK 0:63d45df56584 292 * ED, the Host Controller performs the indicated transfer.
RichardUK 0:63d45df56584 293 */
RichardUK 0:63d45df56584 294 struct EndpointDescriptor
RichardUK 0:63d45df56584 295 {
RichardUK 0:63d45df56584 296 /**
RichardUK 0:63d45df56584 297 * This is the USB address of the function containing the endpoint that this ED controls
RichardUK 0:63d45df56584 298 * In the docs this is called 'FunctionAddress' but it is for our use for when the controller
RichardUK 0:63d45df56584 299 * passes the object back to us.
RichardUK 0:63d45df56584 300 * unsigned functionAddress:7;
RichardUK 0:63d45df56584 301 *
RichardUK 0:63d45df56584 302 * This is the USB address of the endpoint within the function.
RichardUK 0:63d45df56584 303 * unsigned endpointNumber:4;
RichardUK 0:63d45df56584 304 *
RichardUK 0:63d45df56584 305 * unsigned D:2;
RichardUK 0:63d45df56584 306 * unsigned S:1;
RichardUK 0:63d45df56584 307 * unsigned K:1;
RichardUK 0:63d45df56584 308 * unsigned F:1;
RichardUK 0:63d45df56584 309 *
RichardUK 0:63d45df56584 310 * This field indicates the maximum number of bytes that can be sent to or received from the endpoint in a single data packet
RichardUK 0:63d45df56584 311 * unsigned maximumPacketSize:11;
RichardUK 0:63d45df56584 312 *
RichardUK 0:63d45df56584 313 * unsigned padding:5;
RichardUK 0:63d45df56584 314 */
RichardUK 0:63d45df56584 315 uint32_t control;
RichardUK 0:63d45df56584 316
RichardUK 1:4461071ed964 317 unsigned padding0:4;
RichardUK 1:4461071ed964 318 unsigned TailTD:28; //physical pointer to HC_TRANSFER_DESCRIPTOR
RichardUK 1:4461071ed964 319
RichardUK 1:4461071ed964 320 // TransferDescriptor* HeadTD; //flags + phys ptr to HC_TRANSFER_DESCRIPTOR
RichardUK 1:4461071ed964 321 unsigned H:1;
RichardUK 1:4461071ed964 322 unsigned C:1;
RichardUK 1:4461071ed964 323 unsigned ZERO:2;
RichardUK 1:4461071ed964 324 unsigned HeadTD:28;
RichardUK 1:4461071ed964 325
RichardUK 1:4461071ed964 326 EndpointDescriptor* NextEP; //phys ptr to HC_ENDPOINT_DESCRIPTOR
RichardUK 0:63d45df56584 327 };
RichardUK 0:63d45df56584 328
RichardUK 0:63d45df56584 329 /*
RichardUK 1:4461071ed964 330 * Size is kept to no more than 32 bytes so that I can use the pool of memory in
RichardUK 0:63d45df56584 331 * the host controller driver and so not use any of the main 32k of ram.
RichardUK 0:63d45df56584 332 */
RichardUK 0:63d45df56584 333 struct Device
RichardUK 0:63d45df56584 334 {
RichardUK 0:63d45df56584 335 /**
RichardUK 0:63d45df56584 336 * When we allocated a device with give it an ID and then set the USB device's ID with the set address command.
RichardUK 0:63d45df56584 337 */
RichardUK 1:4461071ed964 338 int id;
RichardUK 0:63d45df56584 339
RichardUK 1:4461071ed964 340 uint8_t lowspeed;
RichardUK 1:4461071ed964 341 uint8_t controlTransferDirToHost;//LIBUSB_ENDPOINT_IN when set
RichardUK 1:4461071ed964 342 uint8_t controlTransferState; //See enum ControlTransferState, the control transfer has several states it can be in.
RichardUK 1:4461071ed964 343 uint8_t padding;
RichardUK 0:63d45df56584 344
RichardUK 0:63d45df56584 345 /**
RichardUK 1:4461071ed964 346 * 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.
RichardUK 0:63d45df56584 347 */
RichardUK 1:4461071ed964 348 int endpointZeroMaxPacketSize;
RichardUK 0:63d45df56584 349
RichardUK 0:63d45df56584 350 /**
RichardUK 0:63d45df56584 351 * This data is used whilst there is a control transfer in progress.
RichardUK 0:63d45df56584 352 * When finished controlTransferDataLength will be the number of bytes recived.
RichardUK 0:63d45df56584 353 */
RichardUK 0:63d45df56584 354 const uint8_t* controlTransferData;
RichardUK 1:4461071ed964 355 int controlTransferDataLength;
RichardUK 0:63d45df56584 356
RichardUK 0:63d45df56584 357 /**
RichardUK 0:63d45df56584 358 * The first language ID I find from string index zero. Makes life easier.
RichardUK 0:63d45df56584 359 * Used in getting the descriptor strings.
RichardUK 0:63d45df56584 360 */
RichardUK 1:4461071ed964 361 int languageID;
RichardUK 1:4461071ed964 362
RichardUK 1:4461071ed964 363 /*
RichardUK 1:4461071ed964 364 * If a transfer requires a callback when done then this will have the transfers here.
RichardUK 1:4461071ed964 365 * 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.
RichardUK 1:4461071ed964 366 * Because of this it is important that the applicaition calls the Update function of the driver at least once a second.
RichardUK 1:4461071ed964 367 * Failure to do so whilst issueing many transfers will cause the memory pool to be exhausted.
RichardUK 1:4461071ed964 368 */
RichardUK 1:4461071ed964 369 TransferDescriptor* pendingCallbacks;
RichardUK 0:63d45df56584 370
RichardUK 0:63d45df56584 371 /**
RichardUK 1:4461071ed964 372 * When not -1 then will block the transfer until it is -1 again.
RichardUK 0:63d45df56584 373 */
RichardUK 1:4461071ed964 374 int blockOnEP;
RichardUK 0:63d45df56584 375 };
RichardUK 0:63d45df56584 376
RichardUK 0:63d45df56584 377 /**
RichardUK 0:63d45df56584 378 * request_type of setup packet defined as....
RichardUK 0:63d45df56584 379 * 0 = Device
RichardUK 0:63d45df56584 380 * 1 = Interface
RichardUK 0:63d45df56584 381 * 2 = Endpoint
RichardUK 0:63d45df56584 382 * 3 = Other
RichardUK 0:63d45df56584 383 * 4..31 Reserved
RichardUK 0:63d45df56584 384 unsigned recipient:5;
RichardUK 0:63d45df56584 385
RichardUK 0:63d45df56584 386 * 0 = Standard
RichardUK 0:63d45df56584 387 * 1 = Class
RichardUK 0:63d45df56584 388 * 2 = Vendor
RichardUK 0:63d45df56584 389 * 3 = Reserved.
RichardUK 0:63d45df56584 390 unsigned type:2;
RichardUK 0:63d45df56584 391
RichardUK 0:63d45df56584 392 * 0 = Host to device.
RichardUK 0:63d45df56584 393 * 1 = Device to host.
RichardUK 0:63d45df56584 394 unsigned transferDirection:1;
RichardUK 0:63d45df56584 395 */
RichardUK 0:63d45df56584 396 struct SetupPacket
RichardUK 0:63d45df56584 397 {
RichardUK 0:63d45df56584 398 uint8_t requestType;
RichardUK 0:63d45df56584 399 uint8_t request;
RichardUK 0:63d45df56584 400 uint16_t value;
RichardUK 0:63d45df56584 401 uint16_t index;
RichardUK 0:63d45df56584 402
RichardUK 0:63d45df56584 403 /**
RichardUK 0:63d45df56584 404 * The number of bytes in the data phase.
RichardUK 0:63d45df56584 405 */
RichardUK 0:63d45df56584 406 uint16_t length;
RichardUK 0:63d45df56584 407 };
RichardUK 0:63d45df56584 408
RichardUK 0:63d45df56584 409
RichardUK 0:63d45df56584 410 /**
RichardUK 0:63d45df56584 411 * The Host Controller Communications Area (HCCA) is a 256-byte structure of system memory
RichardUK 0:63d45df56584 412 * that is used by system software to send and receive specific control and status information to and
RichardUK 0:63d45df56584 413 * from the HC. This structure must be located on a 256-byte boundary. System software must
RichardUK 0:63d45df56584 414 * write the address of this structure in HcHCCA in the HC. This structure allows the software to
RichardUK 0:63d45df56584 415 * direct the HC&#65533;s functions without having to read from the Host Controller except in unusual
RichardUK 0:63d45df56584 416 * circumstances (e.g., error conditions). Normal interaction with the Host Controller can be
RichardUK 0:63d45df56584 417 * accomplished by reading values from this structure that were written by the Host Controller and
RichardUK 0:63d45df56584 418 * by writing to the HC&#65533;s operation registers.
RichardUK 0:63d45df56584 419 *
RichardUK 0:63d45df56584 420 */
RichardUK 0:63d45df56584 421 struct HostControllerCommunicationsArea
RichardUK 0:63d45df56584 422 {
RichardUK 0:63d45df56584 423 /**
RichardUK 0:63d45df56584 424 * These 32 Dwords are pointers to interrupt EDs
RichardUK 0:63d45df56584 425 */
RichardUK 0:63d45df56584 426 uint32_t interruptTable[32];
RichardUK 0:63d45df56584 427
RichardUK 0:63d45df56584 428 /**
RichardUK 0:63d45df56584 429 * Contains the current frame number. This value
RichardUK 0:63d45df56584 430 * is updated by the HC before it begins
RichardUK 0:63d45df56584 431 * processing the periodic lists for the frame.
RichardUK 0:63d45df56584 432 */
RichardUK 0:63d45df56584 433 uint16_t frameNumber;
RichardUK 0:63d45df56584 434
RichardUK 0:63d45df56584 435 /**
RichardUK 0:63d45df56584 436 * When the HC updates HccaFrameNumber, it sets this word to 0.
RichardUK 0:63d45df56584 437 */
RichardUK 0:63d45df56584 438 uint16_t pad1;
RichardUK 0:63d45df56584 439
RichardUK 0:63d45df56584 440 /**
RichardUK 0:63d45df56584 441 * When the HC reaches the end of a frame and
RichardUK 0:63d45df56584 442 * its deferred interrupt register is 0, it writes the
RichardUK 0:63d45df56584 443 * current value of its HcDoneHead to this
RichardUK 0:63d45df56584 444 * location and generates an interrupt if interrupts
RichardUK 0:63d45df56584 445 * are enabled. This location is not written by the
RichardUK 0:63d45df56584 446 * HC again until software clears the WD bit in
RichardUK 0:63d45df56584 447 * the HcInterruptStatus register. This protocol provides an interlocked exchange of the Done Queue.
RichardUK 0:63d45df56584 448 * The LSb of this entry is set to 1 to indicate
RichardUK 0:63d45df56584 449 * whether an unmasked HcInterruptStatus was
RichardUK 0:63d45df56584 450 * set when HccaDoneHead was written.
RichardUK 0:63d45df56584 451 * I don't process this in the interupt but in the driver update.
RichardUK 0:63d45df56584 452 * The interupt flags the driver that stuff is done.
RichardUK 0:63d45df56584 453 */
RichardUK 0:63d45df56584 454 struct TransferDescriptor* doneHead;
RichardUK 0:63d45df56584 455
RichardUK 0:63d45df56584 456 /**
RichardUK 0:63d45df56584 457 * Reserved for use by HC, also makes the data after this 16 byte aligned.
RichardUK 0:63d45df56584 458 */
RichardUK 0:63d45df56584 459 uint8_t reserved[120];
RichardUK 0:63d45df56584 460
RichardUK 0:63d45df56584 461 /**
RichardUK 0:63d45df56584 462 * I have added onto the end of this alligned struct some extra data that I don't want to be taken out
RichardUK 0:63d45df56584 463 * of the main 32k of main ram.
RichardUK 0:63d45df56584 464 */
RichardUK 0:63d45df56584 465
RichardUK 0:63d45df56584 466 /**
RichardUK 0:63d45df56584 467 * Device zero is used for enumeration and setup when a usb device is inserted.
RichardUK 0:63d45df56584 468 */
RichardUK 0:63d45df56584 469 Device deviceZero;
RichardUK 0:63d45df56584 470
RichardUK 0:63d45df56584 471 /**
RichardUK 1:4461071ed964 472 * My memory pool of 32 byte objects that MUST be aligned on a 16byte boundry.
RichardUK 0:63d45df56584 473 * So don't move this entry or add stuff before it!
RichardUK 1:4461071ed964 474 * It is 32 bytes as the transfer descriptor needs an extra 16 bytes for my
RichardUK 1:4461071ed964 475 * driver so I can do callbacks when a transfer is complete.
RichardUK 1:4461071ed964 476 * Without it then I would need some kind of horrid lookup table and code that could add bugs.
RichardUK 1:4461071ed964 477 * This way it is nice, clean, and simple.
RichardUK 0:63d45df56584 478 */
RichardUK 1:4461071ed964 479 LinkedListItem memoryPool[32];
RichardUK 1:4461071ed964 480
RichardUK 0:63d45df56584 481 /**
RichardUK 0:63d45df56584 482 * And now some scratch ram to used when I am reciving strings.
RichardUK 0:63d45df56584 483 */
RichardUK 0:63d45df56584 484 uint8_t scratchRam[256];
RichardUK 0:63d45df56584 485 };
RichardUK 0:63d45df56584 486
RichardUK 0:63d45df56584 487
RichardUK 0:63d45df56584 488 };//end namespace USB
RichardUK 0:63d45df56584 489
RichardUK 0:63d45df56584 490 #endif //#ifndef__USB_STRUCTURES_H__
RichardUK 0:63d45df56584 491