Committer:
RichardUK
Date:
Wed Sep 19 16:39:23 2012 +0000
Revision:
1:4461071ed964
Parent:
0:63d45df56584
Child:
2:33e7ce63dd6d
Updated with all the latest code.

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 1:4461071ed964 163 */
RichardUK 1:4461071ed964 164 struct TransferCallback
RichardUK 1:4461071ed964 165 {
RichardUK 1:4461071ed964 166 /**
RichardUK 1:4461071ed964 167 * Called when a transfer has been completed that had a callback ID set.
RichardUK 1:4461071ed964 168 * Any other transfers without a callback ID will not trigger this.
RichardUK 1:4461071ed964 169 */
RichardUK 1:4461071ed964 170 virtual void onReceive(int deviceID, int endpoint, int status,const uint8_t* data, int length) = 0;
RichardUK 0:63d45df56584 171 };
RichardUK 0:63d45df56584 172
RichardUK 0:63d45df56584 173 /**
RichardUK 0:63d45df56584 174 * There are fields that are read/write by the HC. The unused portion of this
RichardUK 0:63d45df56584 175 * Dword must either not be written by Host Controller or must be read,
RichardUK 0:63d45df56584 176 * and then written back unmodified. The Host Controller Driver should not modify any
RichardUK 0:63d45df56584 177 * portion of the transfer descriptor while it is accessible to the HC.
RichardUK 0:63d45df56584 178 * As well as using the first 18bits that are garnteed not to be altered by the host
RichardUK 0:63d45df56584 179 * I have made this structure 32 bytes in size. (helps with keeping it 16 byte aligned)
RichardUK 0:63d45df56584 180 * The extra 16 bytes are for when there is a callback defined for an interupt transfer or a
RichardUK 0:63d45df56584 181 * bulk transfer called with a callback. The host will not change the extra 16 bytes.
RichardUK 0:63d45df56584 182 * Because of the extra size this stuct comes from it's own memory pool.
RichardUK 0:63d45df56584 183 */
RichardUK 0:63d45df56584 184 struct TransferDescriptor
RichardUK 0:63d45df56584 185 {
RichardUK 0:63d45df56584 186 /**
RichardUK 0:63d45df56584 187 * The next 18 bits are unused by the controller and the spec says that they should not be
RichardUK 0:63d45df56584 188 * modified by the host controller. So this means we can use it as a way to 'mark'
RichardUK 0:63d45df56584 189 * a transfer so that when it is returned having been completed we can resolve
RichardUK 0:63d45df56584 190 * who it was for.
RichardUK 0:63d45df56584 191 */
RichardUK 0:63d45df56584 192 volatile unsigned deviceID:18;
RichardUK 0:63d45df56584 193
RichardUK 0:63d45df56584 194 /**
RichardUK 0:63d45df56584 195 * If this bit is 0, then the last data packet to a TD from an endpoint must
RichardUK 0:63d45df56584 196 * exactly fill the defined data buffer. If the bit is 1, then the last data
RichardUK 0:63d45df56584 197 * packet may be smaller than the defined buffer without causing an error
RichardUK 0:63d45df56584 198 * condition on the TD.
RichardUK 0:63d45df56584 199 */
RichardUK 0:63d45df56584 200 volatile unsigned bufferRounding:1;
RichardUK 0:63d45df56584 201
RichardUK 0:63d45df56584 202 /**
RichardUK 0:63d45df56584 203 * This 2-bit field indicates the direction of data flow and the PID to be used
RichardUK 0:63d45df56584 204 * for the token. This field is only relevant to the HC if the D field in the ED
RichardUK 0:63d45df56584 205 * was set to 00b or 11b indicating that the PID determination is deferred to
RichardUK 0:63d45df56584 206 * the TD. The encoding of the bits within the byte for this field are:
RichardUK 0:63d45df56584 207 *
RichardUK 0:63d45df56584 208 * Code
RichardUK 0:63d45df56584 209 * 00b SETUP - to endpoint
RichardUK 0:63d45df56584 210 * 01b OUT - to endpoint
RichardUK 0:63d45df56584 211 * 10b IN - from endpoint
RichardUK 0:63d45df56584 212 * 11b Reserved
RichardUK 0:63d45df56584 213 */
RichardUK 0:63d45df56584 214 volatile unsigned direction:2;
RichardUK 0:63d45df56584 215
RichardUK 0:63d45df56584 216 /**
RichardUK 0:63d45df56584 217 * This field contains the interrupt delay count for this TD. When a TD is
RichardUK 0:63d45df56584 218 * complete the HC may wait for DelayInterrupt frames before generating
RichardUK 0:63d45df56584 219 * an interrupt. If DelayInterrupt is 111b, then there is no interrupt
RichardUK 0:63d45df56584 220 * associated with completion of this TD
RichardUK 0:63d45df56584 221 */
RichardUK 0:63d45df56584 222 volatile unsigned delayInterrupt:3;
RichardUK 0:63d45df56584 223
RichardUK 0:63d45df56584 224 /**
RichardUK 0:63d45df56584 225 * This 2-bit field is used to generate/compare the data PID value (DATA0 or DATA1).
RichardUK 0:63d45df56584 226 * It is updated after each successful transmission/reception of
RichardUK 0:63d45df56584 227 * a data packet. The MSb of this field is &#65533;0&#65533; when the data toggle value is
RichardUK 0:63d45df56584 228 * acquired from the toggleCarry field in the ED and &#65533;1&#65533; when the data
RichardUK 0:63d45df56584 229 * toggle value is taken from the LSb of this field.
RichardUK 0:63d45df56584 230 */
RichardUK 0:63d45df56584 231 volatile unsigned dataToggle:2;
RichardUK 0:63d45df56584 232
RichardUK 0:63d45df56584 233 /**
RichardUK 0:63d45df56584 234 * For each transmission error, this value is incremented. If ErrorCount is
RichardUK 0:63d45df56584 235 * 2 and another error occurs, the error type is recorded in the
RichardUK 0:63d45df56584 236 * ConditionCode field and placed on the done queue. When a
RichardUK 0:63d45df56584 237 * transaction completes without error, ErrorCount is reset to 0.
RichardUK 0:63d45df56584 238 */
RichardUK 1:4461071ed964 239 unsigned errorCount:2;
RichardUK 0:63d45df56584 240
RichardUK 0:63d45df56584 241 /**
RichardUK 0:63d45df56584 242 * This field contains the status of the last attempted transaction.
RichardUK 0:63d45df56584 243 */
RichardUK 1:4461071ed964 244 unsigned conditionCode:4;
RichardUK 0:63d45df56584 245
RichardUK 0:63d45df56584 246 /**
RichardUK 0:63d45df56584 247 * Contains the physical address of the next memory location that will be
RichardUK 0:63d45df56584 248 * accessed for transfer to/from the endpoint. A value of 0 indicates a zero-
RichardUK 0:63d45df56584 249 * length data packet or that all bytes have been transferred.
RichardUK 0:63d45df56584 250 */
RichardUK 1:4461071ed964 251 const uint8_t* CurrentBufferPointer;
RichardUK 0:63d45df56584 252
RichardUK 0:63d45df56584 253 /**
RichardUK 0:63d45df56584 254 * his entry points to the next TD on the list of TDs linked to this endpoint
RichardUK 1:4461071ed964 255 */
RichardUK 1:4461071ed964 256 TransferDescriptor *nextTD;
RichardUK 0:63d45df56584 257
RichardUK 0:63d45df56584 258 /**
RichardUK 0:63d45df56584 259 * Contains physical address of the last byte in the buffer for this TD
RichardUK 0:63d45df56584 260 */
RichardUK 1:4461071ed964 261 const uint8_t* bufferEnd;
RichardUK 0:63d45df56584 262
RichardUK 0:63d45df56584 263 /**
RichardUK 0:63d45df56584 264 * Extra 16 bytes for the callback info.
RichardUK 1:4461071ed964 265 */
RichardUK 1:4461071ed964 266
RichardUK 1:4461071ed964 267 /**
RichardUK 1:4461071ed964 268 * If not NULL then called when a transfer is completed.
RichardUK 1:4461071ed964 269 */
RichardUK 1:4461071ed964 270 TransferCallback* transferCallback;
RichardUK 1:4461071ed964 271
RichardUK 1:4461071ed964 272 /**
RichardUK 1:4461071ed964 273 * The pointer to the start of the data being transfered or recived.
RichardUK 1:4461071ed964 274 */
RichardUK 1:4461071ed964 275 const uint8_t* data;
RichardUK 1:4461071ed964 276
RichardUK 1:4461071ed964 277 /**
RichardUK 1:4461071ed964 278 * The length of the transfer.
RichardUK 1:4461071ed964 279 */
RichardUK 1:4461071ed964 280 int length;
RichardUK 1:4461071ed964 281 uint8_t ep;
RichardUK 1:4461071ed964 282 uint8_t transferType;
RichardUK 1:4461071ed964 283 uint8_t pad1;
RichardUK 1:4461071ed964 284 uint8_t pad2;
RichardUK 0:63d45df56584 285 };
RichardUK 0:63d45df56584 286
RichardUK 0:63d45df56584 287 /**
RichardUK 0:63d45df56584 288 * Host Controller Endpoint Descriptor.
RichardUK 0:63d45df56584 289 * An Endpoint Descriptor (ED) is a 16-byte, memory resident structure that must be aligned to a
RichardUK 0:63d45df56584 290 * 16-byte boundary. The Host Controller traverses lists of EDs and if there are TDs linked to an
RichardUK 0:63d45df56584 291 * ED, the Host Controller performs the indicated transfer.
RichardUK 0:63d45df56584 292 */
RichardUK 0:63d45df56584 293 struct EndpointDescriptor
RichardUK 0:63d45df56584 294 {
RichardUK 0:63d45df56584 295 /**
RichardUK 0:63d45df56584 296 * This is the USB address of the function containing the endpoint that this ED controls
RichardUK 0:63d45df56584 297 * In the docs this is called 'FunctionAddress' but it is for our use for when the controller
RichardUK 0:63d45df56584 298 * passes the object back to us.
RichardUK 0:63d45df56584 299 * unsigned functionAddress:7;
RichardUK 0:63d45df56584 300 *
RichardUK 0:63d45df56584 301 * This is the USB address of the endpoint within the function.
RichardUK 0:63d45df56584 302 * unsigned endpointNumber:4;
RichardUK 0:63d45df56584 303 *
RichardUK 0:63d45df56584 304 * unsigned D:2;
RichardUK 0:63d45df56584 305 * unsigned S:1;
RichardUK 0:63d45df56584 306 * unsigned K:1;
RichardUK 0:63d45df56584 307 * unsigned F:1;
RichardUK 0:63d45df56584 308 *
RichardUK 0:63d45df56584 309 * 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 310 * unsigned maximumPacketSize:11;
RichardUK 0:63d45df56584 311 *
RichardUK 0:63d45df56584 312 * unsigned padding:5;
RichardUK 0:63d45df56584 313 */
RichardUK 0:63d45df56584 314 uint32_t control;
RichardUK 0:63d45df56584 315
RichardUK 1:4461071ed964 316 unsigned padding0:4;
RichardUK 1:4461071ed964 317 unsigned TailTD:28; //physical pointer to HC_TRANSFER_DESCRIPTOR
RichardUK 1:4461071ed964 318
RichardUK 1:4461071ed964 319 // TransferDescriptor* HeadTD; //flags + phys ptr to HC_TRANSFER_DESCRIPTOR
RichardUK 1:4461071ed964 320 unsigned H:1;
RichardUK 1:4461071ed964 321 unsigned C:1;
RichardUK 1:4461071ed964 322 unsigned ZERO:2;
RichardUK 1:4461071ed964 323 unsigned HeadTD:28;
RichardUK 1:4461071ed964 324
RichardUK 1:4461071ed964 325 EndpointDescriptor* NextEP; //phys ptr to HC_ENDPOINT_DESCRIPTOR
RichardUK 0:63d45df56584 326 };
RichardUK 0:63d45df56584 327
RichardUK 0:63d45df56584 328 /*
RichardUK 1:4461071ed964 329 * Size is kept to no more than 32 bytes so that I can use the pool of memory in
RichardUK 0:63d45df56584 330 * the host controller driver and so not use any of the main 32k of ram.
RichardUK 0:63d45df56584 331 */
RichardUK 0:63d45df56584 332 struct Device
RichardUK 0:63d45df56584 333 {
RichardUK 0:63d45df56584 334 /**
RichardUK 0:63d45df56584 335 * 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 336 */
RichardUK 1:4461071ed964 337 int id;
RichardUK 0:63d45df56584 338
RichardUK 1:4461071ed964 339 uint8_t lowspeed;
RichardUK 1:4461071ed964 340 uint8_t controlTransferDirToHost;//LIBUSB_ENDPOINT_IN when set
RichardUK 1:4461071ed964 341 uint8_t controlTransferState; //See enum ControlTransferState, the control transfer has several states it can be in.
RichardUK 1:4461071ed964 342 uint8_t padding;
RichardUK 0:63d45df56584 343
RichardUK 0:63d45df56584 344 /**
RichardUK 1:4461071ed964 345 * 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 346 */
RichardUK 1:4461071ed964 347 int endpointZeroMaxPacketSize;
RichardUK 0:63d45df56584 348
RichardUK 0:63d45df56584 349 /**
RichardUK 0:63d45df56584 350 * This data is used whilst there is a control transfer in progress.
RichardUK 0:63d45df56584 351 * When finished controlTransferDataLength will be the number of bytes recived.
RichardUK 0:63d45df56584 352 */
RichardUK 0:63d45df56584 353 const uint8_t* controlTransferData;
RichardUK 1:4461071ed964 354 int controlTransferDataLength;
RichardUK 0:63d45df56584 355
RichardUK 0:63d45df56584 356 /**
RichardUK 0:63d45df56584 357 * The first language ID I find from string index zero. Makes life easier.
RichardUK 0:63d45df56584 358 * Used in getting the descriptor strings.
RichardUK 0:63d45df56584 359 */
RichardUK 1:4461071ed964 360 int languageID;
RichardUK 1:4461071ed964 361
RichardUK 1:4461071ed964 362 /*
RichardUK 1:4461071ed964 363 * If a transfer requires a callback when done then this will have the transfers here.
RichardUK 1:4461071ed964 364 * 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 365 * Because of this it is important that the applicaition calls the Update function of the driver at least once a second.
RichardUK 1:4461071ed964 366 * Failure to do so whilst issueing many transfers will cause the memory pool to be exhausted.
RichardUK 1:4461071ed964 367 */
RichardUK 1:4461071ed964 368 TransferDescriptor* pendingCallbacks;
RichardUK 0:63d45df56584 369
RichardUK 0:63d45df56584 370 /**
RichardUK 1:4461071ed964 371 * When not -1 then will block the transfer until it is -1 again.
RichardUK 0:63d45df56584 372 */
RichardUK 1:4461071ed964 373 int blockOnEP;
RichardUK 0:63d45df56584 374 };
RichardUK 0:63d45df56584 375
RichardUK 0:63d45df56584 376 /**
RichardUK 0:63d45df56584 377 * request_type of setup packet defined as....
RichardUK 0:63d45df56584 378 * 0 = Device
RichardUK 0:63d45df56584 379 * 1 = Interface
RichardUK 0:63d45df56584 380 * 2 = Endpoint
RichardUK 0:63d45df56584 381 * 3 = Other
RichardUK 0:63d45df56584 382 * 4..31 Reserved
RichardUK 0:63d45df56584 383 unsigned recipient:5;
RichardUK 0:63d45df56584 384
RichardUK 0:63d45df56584 385 * 0 = Standard
RichardUK 0:63d45df56584 386 * 1 = Class
RichardUK 0:63d45df56584 387 * 2 = Vendor
RichardUK 0:63d45df56584 388 * 3 = Reserved.
RichardUK 0:63d45df56584 389 unsigned type:2;
RichardUK 0:63d45df56584 390
RichardUK 0:63d45df56584 391 * 0 = Host to device.
RichardUK 0:63d45df56584 392 * 1 = Device to host.
RichardUK 0:63d45df56584 393 unsigned transferDirection:1;
RichardUK 0:63d45df56584 394 */
RichardUK 0:63d45df56584 395 struct SetupPacket
RichardUK 0:63d45df56584 396 {
RichardUK 0:63d45df56584 397 uint8_t requestType;
RichardUK 0:63d45df56584 398 uint8_t request;
RichardUK 0:63d45df56584 399 uint16_t value;
RichardUK 0:63d45df56584 400 uint16_t index;
RichardUK 0:63d45df56584 401
RichardUK 0:63d45df56584 402 /**
RichardUK 0:63d45df56584 403 * The number of bytes in the data phase.
RichardUK 0:63d45df56584 404 */
RichardUK 0:63d45df56584 405 uint16_t length;
RichardUK 0:63d45df56584 406 };
RichardUK 0:63d45df56584 407
RichardUK 0:63d45df56584 408
RichardUK 0:63d45df56584 409 /**
RichardUK 0:63d45df56584 410 * The Host Controller Communications Area (HCCA) is a 256-byte structure of system memory
RichardUK 0:63d45df56584 411 * that is used by system software to send and receive specific control and status information to and
RichardUK 0:63d45df56584 412 * from the HC. This structure must be located on a 256-byte boundary. System software must
RichardUK 0:63d45df56584 413 * write the address of this structure in HcHCCA in the HC. This structure allows the software to
RichardUK 0:63d45df56584 414 * direct the HC&#65533;s functions without having to read from the Host Controller except in unusual
RichardUK 0:63d45df56584 415 * circumstances (e.g., error conditions). Normal interaction with the Host Controller can be
RichardUK 0:63d45df56584 416 * accomplished by reading values from this structure that were written by the Host Controller and
RichardUK 0:63d45df56584 417 * by writing to the HC&#65533;s operation registers.
RichardUK 0:63d45df56584 418 *
RichardUK 0:63d45df56584 419 */
RichardUK 0:63d45df56584 420 struct HostControllerCommunicationsArea
RichardUK 0:63d45df56584 421 {
RichardUK 0:63d45df56584 422 /**
RichardUK 0:63d45df56584 423 * These 32 Dwords are pointers to interrupt EDs
RichardUK 0:63d45df56584 424 */
RichardUK 0:63d45df56584 425 uint32_t interruptTable[32];
RichardUK 0:63d45df56584 426
RichardUK 0:63d45df56584 427 /**
RichardUK 0:63d45df56584 428 * Contains the current frame number. This value
RichardUK 0:63d45df56584 429 * is updated by the HC before it begins
RichardUK 0:63d45df56584 430 * processing the periodic lists for the frame.
RichardUK 0:63d45df56584 431 */
RichardUK 0:63d45df56584 432 uint16_t frameNumber;
RichardUK 0:63d45df56584 433
RichardUK 0:63d45df56584 434 /**
RichardUK 0:63d45df56584 435 * When the HC updates HccaFrameNumber, it sets this word to 0.
RichardUK 0:63d45df56584 436 */
RichardUK 0:63d45df56584 437 uint16_t pad1;
RichardUK 0:63d45df56584 438
RichardUK 0:63d45df56584 439 /**
RichardUK 0:63d45df56584 440 * When the HC reaches the end of a frame and
RichardUK 0:63d45df56584 441 * its deferred interrupt register is 0, it writes the
RichardUK 0:63d45df56584 442 * current value of its HcDoneHead to this
RichardUK 0:63d45df56584 443 * location and generates an interrupt if interrupts
RichardUK 0:63d45df56584 444 * are enabled. This location is not written by the
RichardUK 0:63d45df56584 445 * HC again until software clears the WD bit in
RichardUK 0:63d45df56584 446 * the HcInterruptStatus register. This protocol provides an interlocked exchange of the Done Queue.
RichardUK 0:63d45df56584 447 * The LSb of this entry is set to 1 to indicate
RichardUK 0:63d45df56584 448 * whether an unmasked HcInterruptStatus was
RichardUK 0:63d45df56584 449 * set when HccaDoneHead was written.
RichardUK 0:63d45df56584 450 * I don't process this in the interupt but in the driver update.
RichardUK 0:63d45df56584 451 * The interupt flags the driver that stuff is done.
RichardUK 0:63d45df56584 452 */
RichardUK 0:63d45df56584 453 struct TransferDescriptor* doneHead;
RichardUK 0:63d45df56584 454
RichardUK 0:63d45df56584 455 /**
RichardUK 0:63d45df56584 456 * Reserved for use by HC, also makes the data after this 16 byte aligned.
RichardUK 0:63d45df56584 457 */
RichardUK 0:63d45df56584 458 uint8_t reserved[120];
RichardUK 0:63d45df56584 459
RichardUK 0:63d45df56584 460 /**
RichardUK 0:63d45df56584 461 * 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 462 * of the main 32k of main ram.
RichardUK 0:63d45df56584 463 */
RichardUK 0:63d45df56584 464
RichardUK 0:63d45df56584 465 /**
RichardUK 0:63d45df56584 466 * Device zero is used for enumeration and setup when a usb device is inserted.
RichardUK 0:63d45df56584 467 */
RichardUK 0:63d45df56584 468 Device deviceZero;
RichardUK 0:63d45df56584 469
RichardUK 0:63d45df56584 470 /**
RichardUK 1:4461071ed964 471 * My memory pool of 32 byte objects that MUST be aligned on a 16byte boundry.
RichardUK 0:63d45df56584 472 * So don't move this entry or add stuff before it!
RichardUK 1:4461071ed964 473 * It is 32 bytes as the transfer descriptor needs an extra 16 bytes for my
RichardUK 1:4461071ed964 474 * driver so I can do callbacks when a transfer is complete.
RichardUK 1:4461071ed964 475 * Without it then I would need some kind of horrid lookup table and code that could add bugs.
RichardUK 1:4461071ed964 476 * This way it is nice, clean, and simple.
RichardUK 0:63d45df56584 477 */
RichardUK 1:4461071ed964 478 LinkedListItem memoryPool[32];
RichardUK 1:4461071ed964 479
RichardUK 0:63d45df56584 480 /**
RichardUK 0:63d45df56584 481 * And now some scratch ram to used when I am reciving strings.
RichardUK 0:63d45df56584 482 */
RichardUK 0:63d45df56584 483 uint8_t scratchRam[256];
RichardUK 0:63d45df56584 484 };
RichardUK 0:63d45df56584 485
RichardUK 0:63d45df56584 486
RichardUK 0:63d45df56584 487 };//end namespace USB
RichardUK 0:63d45df56584 488
RichardUK 0:63d45df56584 489 #endif //#ifndef__USB_STRUCTURES_H__
RichardUK 0:63d45df56584 490