Committer:
RichardUK
Date:
Sun Jul 08 20:18:58 2012 +0000
Revision:
0:63d45df56584
Child:
1:4461071ed964
Fixed memory leak where endpoints were being allocated over and over again. Now only allocates on first use.

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 I have written this lib for two reasons, 1 so that I have code that I know works and 2 because I wanted to learn USB.
RichardUK 0:63d45df56584 19 The first release is unfinished due to the lack of time to test all the transfer types. As and when I find time
RichardUK 0:63d45df56584 20 to implement the other parts I will update the lib. I hope this should be finished by June 2012. I 'hope' ;)
RichardUK 0:63d45df56584 21
RichardUK 0:63d45df56584 22 Some of the comments and enums / structs taken from the libusb project. libusb.org
RichardUK 0:63d45df56584 23
RichardUK 0:63d45df56584 24 Also borrowed some bits from http://www.beyondlogic.org/usbnutshell A very good read.
RichardUK 0:63d45df56584 25
RichardUK 0:63d45df56584 26 Another good read. http://www.usbmadesimple.co.uk/ums_4.htm (took some comments from here too)
RichardUK 0:63d45df56584 27
RichardUK 0:63d45df56584 28 I also used the code in USBHost as a reference although it is a little unstructured and has some bad coding habbits in to so I would recommend advoiding that code.
RichardUK 0:63d45df56584 29 */
RichardUK 0:63d45df56584 30
RichardUK 0:63d45df56584 31
RichardUK 0:63d45df56584 32 #ifndef __USBHOST_H__
RichardUK 0:63d45df56584 33 #define __USBHOST_H__
RichardUK 0:63d45df56584 34
RichardUK 0:63d45df56584 35 #include "UsbHostController.h"
RichardUK 0:63d45df56584 36 #include "UsbEnums.h"
RichardUK 0:63d45df56584 37 #include "UsbStructures.h"
RichardUK 0:63d45df56584 38
RichardUK 0:63d45df56584 39 namespace USB
RichardUK 0:63d45df56584 40 {
RichardUK 0:63d45df56584 41
RichardUK 0:63d45df56584 42
RichardUK 0:63d45df56584 43
RichardUK 0:63d45df56584 44 #define MAX_DEVICES 4
RichardUK 0:63d45df56584 45 #define DEFAULT_TIMEOUT 500
RichardUK 0:63d45df56584 46
RichardUK 0:63d45df56584 47 //Some forward definitions of types. Done so we don't have to include all the headers. Helps to stop include spaghetti.
RichardUK 0:63d45df56584 48 struct HostController;
RichardUK 0:63d45df56584 49 struct Device;
RichardUK 0:63d45df56584 50 struct DeviceDescriptor;
RichardUK 0:63d45df56584 51
RichardUK 0:63d45df56584 52 struct Host : HostControllerMessages
RichardUK 0:63d45df56584 53 {
RichardUK 0:63d45df56584 54
RichardUK 0:63d45df56584 55 Host();
RichardUK 0:63d45df56584 56 ~Host();
RichardUK 0:63d45df56584 57
RichardUK 0:63d45df56584 58 /**
RichardUK 0:63d45df56584 59 * Polls the driver so it can get some if it's non interupt work done.
RichardUK 0:63d45df56584 60 */
RichardUK 0:63d45df56584 61 virtual void Update();
RichardUK 0:63d45df56584 62
RichardUK 0:63d45df56584 63 /**
RichardUK 0:63d45df56584 64 * Fetches the device description, this is the basic structure returned by the device.
RichardUK 0:63d45df56584 65 */
RichardUK 0:63d45df56584 66 int getDeviceDescriptor(int deviceID,DeviceDescription &description);
RichardUK 0:63d45df56584 67
RichardUK 0:63d45df56584 68 /**
RichardUK 0:63d45df56584 69 * The memory pointer returned is a block of memory for the configurtaion and it's interfaces and their endpoints as one block.
RichardUK 0:63d45df56584 70 */
RichardUK 0:63d45df56584 71 const uint8_t* getConfigurationDescriptor(int deviceID,int index);
RichardUK 0:63d45df56584 72
RichardUK 0:63d45df56584 73 /**
RichardUK 0:63d45df56584 74 * Fetches the string at the passed index.
RichardUK 0:63d45df56584 75 */
RichardUK 0:63d45df56584 76 const char* getStringDescriptor(int deviceID,int index);
RichardUK 0:63d45df56584 77
RichardUK 0:63d45df56584 78 /**
RichardUK 0:63d45df56584 79 * Sets the configuration to be used.
RichardUK 0:63d45df56584 80 */
RichardUK 0:63d45df56584 81 int setConfiguration(int deviceID,int configuration);
RichardUK 0:63d45df56584 82
RichardUK 0:63d45df56584 83 /**
RichardUK 0:63d45df56584 84 * Perform a USB control transfer.
RichardUK 0:63d45df56584 85 * The direction of the transfer is inferred from the requestType field of the setup packet.
RichardUK 0:63d45df56584 86 * Function is blocking, will return with result or fail on error or timeout.
RichardUK 0:63d45df56584 87 *
RichardUK 0:63d45df56584 88 * TODO: Code needs error codes and error checking such as is the data size larger than the EP allows (ok don't need to check as the device will respond with multiple packets)
RichardUK 0:63d45df56584 89 *
RichardUK 0:63d45df56584 90 * @param device a handle for the device to communicate with
RichardUK 0:63d45df56584 91 * @param requestType the request type field for the setup packet
RichardUK 0:63d45df56584 92 * @param bRequest the request field for the setup packet
RichardUK 0:63d45df56584 93 * @param value the value field for the setup packet
RichardUK 0:63d45df56584 94 * @param index the index field for the setup packet
RichardUK 0:63d45df56584 95 * @param data a suitably-sized data buffer for either input or output (depending on direction bits within requestType)
RichardUK 0:63d45df56584 96 * @param length the length field for the setup packet. The data buffer should be at least this size.
RichardUK 0:63d45df56584 97 * @param timeout timeout (in millseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0. (currently does nothing)
RichardUK 0:63d45df56584 98 */
RichardUK 0:63d45df56584 99 int ControlTransfer(int deviceID,uint8_t requestType, uint8_t request, uint16_t value, uint16_t index,const uint8_t *data, uint16_t length, uint32_t timeout);
RichardUK 0:63d45df56584 100
RichardUK 0:63d45df56584 101 /**
RichardUK 0:63d45df56584 102 * Perform a USB bulk transfer.
RichardUK 0:63d45df56584 103 * The direction of the transfer is inferred from the direction bits of the endpoint address.
RichardUK 0:63d45df56584 104 * For bulk reads, the length field indicates the maximum length of data you are expecting to receive. If less data arrives than expected, this function will return that data, so be sure to check the transferred output parameter.
RichardUK 0:63d45df56584 105 * You should also check the transferred parameter for bulk writes. Not all of the data may have been written.
RichardUK 0:63d45df56584 106 * Also check transferred when dealing with a timeout error code. libusb may have to split your transfer into a number of chunks to satisfy underlying O/S requirements, meaning that the timeout may expire after the first few chunks have completed. libusb is careful not to lose any data that may have been transferred; do not assume that timeout conditions indicate a complete lack of I/O.
RichardUK 0:63d45df56584 107 *
RichardUK 0:63d45df56584 108 * @param device A handle for the device to communicate with
RichardUK 0:63d45df56584 109 * @param endpoint The address of a valid endpoint to communicate with
RichardUK 0:63d45df56584 110 * @param data A suitably-sized data buffer for either input or output (depending on endpoint)
RichardUK 0:63d45df56584 111 * @param length For bulk writes, the number of bytes from data to be sent. for bulk reads, the maximum number of bytes to receive into the data buffer.
RichardUK 0:63d45df56584 112 * @param callbackID If set then when the transfer is complete the callback will be called with this ID and the information about the transfer.
RichardUK 0:63d45df56584 113 */
RichardUK 0:63d45df56584 114 int BulkTransfer(int device,uint8_t endpoint,const uint8_t* data,int length,int callbackID = 0);
RichardUK 0:63d45df56584 115
RichardUK 0:63d45df56584 116 /**
RichardUK 0:63d45df56584 117 * When a usb device is connected this is called.
RichardUK 0:63d45df56584 118 */
RichardUK 0:63d45df56584 119 virtual void onConnected(int deviceID,const DeviceDescription& description) = 0;
RichardUK 0:63d45df56584 120
RichardUK 0:63d45df56584 121 /**
RichardUK 0:63d45df56584 122 * Called when a device disconnects from the system.
RichardUK 0:63d45df56584 123 */
RichardUK 0:63d45df56584 124 virtual void onDisconnected(int deviceID) = 0;
RichardUK 0:63d45df56584 125
RichardUK 0:63d45df56584 126 /**
RichardUK 0:63d45df56584 127 * Called when a transfer has been completed that had a callback ID set.
RichardUK 0:63d45df56584 128 * Any other transfers without a callback ID will not trigger this.
RichardUK 0:63d45df56584 129 */
RichardUK 0:63d45df56584 130 virtual void onReceive(int deviceID,int callbackID, int endpoint, int status, uint8_t* data, int length) = 0;
RichardUK 0:63d45df56584 131
RichardUK 0:63d45df56584 132 protected:
RichardUK 0:63d45df56584 133
RichardUK 0:63d45df56584 134 virtual void AddDevice(int hub,int port,int hubPortStatus);
RichardUK 0:63d45df56584 135 virtual void TransferDone(TransferDescriptor *transfer);
RichardUK 0:63d45df56584 136
RichardUK 0:63d45df56584 137 private:
RichardUK 0:63d45df56584 138 HostController* driver;
RichardUK 0:63d45df56584 139 Device *devices[MAX_DEVICES];
RichardUK 0:63d45df56584 140
RichardUK 0:63d45df56584 141 /**
RichardUK 0:63d45df56584 142 * The way the hardware and the spec is designed there is only one device in setup mode.
RichardUK 0:63d45df56584 143 * This device will be the only one to respond to requests.
RichardUK 0:63d45df56584 144 * To keep the code simple, that is not having a different code path for device zero
RichardUK 0:63d45df56584 145 * I use this struct for the init phase.
RichardUK 0:63d45df56584 146 */
RichardUK 0:63d45df56584 147 Device* deviceZero;
RichardUK 0:63d45df56584 148
RichardUK 0:63d45df56584 149 /**
RichardUK 0:63d45df56584 150 * Allocates the device from the memory pool on the driver and put it in our array.
RichardUK 0:63d45df56584 151 * Because the array size is fixed (for speed and memory) this function may return NULL
RichardUK 0:63d45df56584 152 * when more than MAX_DEVICES is connected.
RichardUK 0:63d45df56584 153 */
RichardUK 0:63d45df56584 154 Device* AllocateDevice(int endpointZeroMaxPacketSize,int hubPortStatus);
RichardUK 0:63d45df56584 155
RichardUK 0:63d45df56584 156 void SendControlTransferData(Device* device,int dataToggle);
RichardUK 0:63d45df56584 157 void SendControlTransferAcknowledge(Device* device,int dataToggle);
RichardUK 0:63d45df56584 158
RichardUK 0:63d45df56584 159 /**
RichardUK 0:63d45df56584 160 * ID is one based, array is zero based. Device zero is the host controller and a reserved ID as per the host controller spec.
RichardUK 0:63d45df56584 161 * Returns the device or NULL if the ID is invalid or device is now disconnected. (device pointer will be NULL when disconnected)
RichardUK 0:63d45df56584 162 * If deviceID is zero then a pointer to the 'deviceZero' object is returned.
RichardUK 0:63d45df56584 163 */
RichardUK 0:63d45df56584 164 Device* getDevice(int deviceID);
RichardUK 0:63d45df56584 165
RichardUK 0:63d45df56584 166
RichardUK 0:63d45df56584 167 };//class Controller
RichardUK 0:63d45df56584 168
RichardUK 0:63d45df56584 169 };//namespace USB
RichardUK 0:63d45df56584 170
RichardUK 0:63d45df56584 171 #endif