Committer:
RichardUK
Date:
Wed Sep 19 16:39:23 2012 +0000
Revision:
1:4461071ed964
Parent:
0:63d45df56584
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
RichardUK 0:63d45df56584 19 #ifndef __USB_HOST_CONTROLLER_H__
RichardUK 0:63d45df56584 20 #define __USB_HOST_CONTROLLER_H__
RichardUK 0:63d45df56584 21
RichardUK 0:63d45df56584 22 #include <stdint.h>
RichardUK 0:63d45df56584 23
RichardUK 0:63d45df56584 24 namespace USB
RichardUK 0:63d45df56584 25 {
RichardUK 0:63d45df56584 26
RichardUK 0:63d45df56584 27 struct HostControllerCommunicationsArea;
RichardUK 0:63d45df56584 28 struct LinkedListItem;
RichardUK 0:63d45df56584 29 struct EndpointDescriptor;
RichardUK 0:63d45df56584 30 struct TransferDescriptor;
RichardUK 0:63d45df56584 31 struct Device;
RichardUK 1:4461071ed964 32 struct TransferCallback;
RichardUK 0:63d45df56584 33
RichardUK 0:63d45df56584 34 struct HostControllerMessages
RichardUK 0:63d45df56584 35 {
RichardUK 0:63d45df56584 36 /**
RichardUK 0:63d45df56584 37 * Called when a device has been connected to a hub, be it the root controller hub or a usb hub.
RichardUK 0:63d45df56584 38 */
RichardUK 0:63d45df56584 39 virtual void AddDevice(int hub,int port,int hubPortStatus) = 0;
RichardUK 0:63d45df56584 40
RichardUK 0:63d45df56584 41 /**
RichardUK 0:63d45df56584 42 * Called when a transfer has been done. Depending on the transfer type it may be called a few times for one high level action.
RichardUK 0:63d45df56584 43 * For example a ControlTransfer can cause 3 replies, one for the setup packet, one for the data and one for the ack knollage msg.
RichardUK 0:63d45df56584 44 */
RichardUK 0:63d45df56584 45 virtual void TransferDone(TransferDescriptor *transfer) = 0;
RichardUK 0:63d45df56584 46 };
RichardUK 0:63d45df56584 47
RichardUK 0:63d45df56584 48 struct HostController
RichardUK 0:63d45df56584 49 {
RichardUK 0:63d45df56584 50 struct
RichardUK 0:63d45df56584 51 {
RichardUK 0:63d45df56584 52 unsigned newDeviceConnected:1;
RichardUK 1:4461071ed964 53 unsigned unrecoverableError:1;
RichardUK 0:63d45df56584 54 }flags;
RichardUK 0:63d45df56584 55
RichardUK 0:63d45df56584 56 /*
RichardUK 0:63d45df56584 57 * The number of the pool items currently allocated by the system.
RichardUK 0:63d45df56584 58 */
RichardUK 0:63d45df56584 59 int numAllocatedPoolItems;
RichardUK 0:63d45df56584 60
RichardUK 1:4461071ed964 61 uint32_t USBInterupt();
RichardUK 0:63d45df56584 62
RichardUK 0:63d45df56584 63
RichardUK 0:63d45df56584 64 protected:
RichardUK 0:63d45df56584 65 friend class Host;
RichardUK 0:63d45df56584 66
RichardUK 0:63d45df56584 67 /**
RichardUK 0:63d45df56584 68 * Returns the singleton used for interacting with the root hub controller.
RichardUK 0:63d45df56584 69 */
RichardUK 0:63d45df56584 70 static HostController *get();
RichardUK 0:63d45df56584 71
RichardUK 0:63d45df56584 72 /**
RichardUK 0:63d45df56584 73 * Once started never stopped, as the memory is in reserved space there is nothing gained in stopping it.
RichardUK 0:63d45df56584 74 */
RichardUK 0:63d45df56584 75 void Init(HostControllerMessages *messageCallback,Device*& deviceZero);
RichardUK 0:63d45df56584 76
RichardUK 0:63d45df56584 77 /**
RichardUK 0:63d45df56584 78 * Handles state changes from interupts and calls functions from results interupt transfers.
RichardUK 0:63d45df56584 79 * Has to be done on main thread as I have no control of the callbacks execute time. Don't want to kill the interupt handlers.
RichardUK 0:63d45df56584 80 */
RichardUK 0:63d45df56584 81 void Update();
RichardUK 0:63d45df56584 82
RichardUK 0:63d45df56584 83 /**
RichardUK 0:63d45df56584 84 * The memory returned is 16 bytes in size.
RichardUK 0:63d45df56584 85 */
RichardUK 0:63d45df56584 86 void *AllocateMemoryPoolItem();
RichardUK 0:63d45df56584 87
RichardUK 0:63d45df56584 88 /**
RichardUK 0:63d45df56584 89 * An item that had preveslly been allocated from a call to 'AllocateMemoryPoolItem'.
RichardUK 0:63d45df56584 90 */
RichardUK 0:63d45df56584 91 void FreeMemoryPoolItem(void *item);
RichardUK 0:63d45df56584 92
RichardUK 0:63d45df56584 93 /*
RichardUK 0:63d45df56584 94 * Allocates an endpoint to use in a USB data transfer.
RichardUK 0:63d45df56584 95 */
RichardUK 0:63d45df56584 96 EndpointDescriptor *GetEndpointDescriptor(EndpointDescriptor** headED,uint32_t functionAddress,int endpointNumber,int maximumPacketSize,int lowspeed);
RichardUK 0:63d45df56584 97
RichardUK 0:63d45df56584 98 /*
RichardUK 0:63d45df56584 99 * Allocates a transfer descriptor to use in a USB data transfer.
RichardUK 0:63d45df56584 100 * direction == 0 for SETUP, == 1 for OUT (to device) and == 2 for IN (from device)
RichardUK 0:63d45df56584 101 * dataToggle == 0 for DATA0 and == 1 for DATA1
RichardUK 0:63d45df56584 102 */
RichardUK 1:4461071ed964 103 TransferDescriptor *AllocateTransferDescriptor(int deviceID,int direction,const uint8_t* data,int dataLength);
RichardUK 0:63d45df56584 104
RichardUK 0:63d45df56584 105 /**
RichardUK 0:63d45df56584 106 * Adds the endpoint to the host controller so that the next frame it will be processed for control transfers.
RichardUK 0:63d45df56584 107 */
RichardUK 1:4461071ed964 108 void QueueControlTransfer(int deviceID,int direction,int endpointNumber,int maximumPacketSize,int lowspeed,int dataToggle,const uint8_t* data,int dataLength);
RichardUK 1:4461071ed964 109
RichardUK 1:4461071ed964 110 /**
RichardUK 1:4461071ed964 111 * Adds the endpoint to the host controller so that the next frame it will be processed for bulk transfers.
RichardUK 1:4461071ed964 112 */
RichardUK 1:4461071ed964 113 void QueueBulkTransfer(int deviceID,int direction,int endpointNumber,int maximumPacketSize,int lowspeed,TransferCallback* callback,const uint8_t* data,int dataLength);
RichardUK 0:63d45df56584 114
RichardUK 0:63d45df56584 115 /**
RichardUK 0:63d45df56584 116 * Temp work buffer, not used in this code, the driver, but is used in the host code that calls it.
RichardUK 0:63d45df56584 117 */
RichardUK 0:63d45df56584 118 uint8_t* getScratchRam();
RichardUK 0:63d45df56584 119
RichardUK 0:63d45df56584 120 /**
RichardUK 0:63d45df56584 121 * Return how many of the pool items are being used.
RichardUK 0:63d45df56584 122 */
RichardUK 0:63d45df56584 123 int getNumAllocatedPoolItems()
RichardUK 0:63d45df56584 124 {
RichardUK 0:63d45df56584 125 return numAllocatedPoolItems;
RichardUK 0:63d45df56584 126 }
RichardUK 0:63d45df56584 127
RichardUK 0:63d45df56584 128 /*
RichardUK 0:63d45df56584 129 * Removes all the endpoints associated with this device from the host controller.
RichardUK 0:63d45df56584 130 */
RichardUK 0:63d45df56584 131 void DetachDevice(int deviceID);
RichardUK 0:63d45df56584 132
RichardUK 0:63d45df56584 133 private:
RichardUK 0:63d45df56584 134 /*
RichardUK 0:63d45df56584 135 * Will be useing the first block of extra SRAM. There are two extra 16k blocks.
RichardUK 0:63d45df56584 136 * These blocks have their own DMA and so don't interupt the CPU.
RichardUK 0:63d45df56584 137 * Also as they are seperated from the main 32k of SRAM we are not
RichardUK 0:63d45df56584 138 * stealing from the heap or the stack.
RichardUK 0:63d45df56584 139 *
RichardUK 0:63d45df56584 140 * The LPC1768 contains 64 kB of on-chip static RAM memory. Up to 32 kB of SRAM,
RichardUK 0:63d45df56584 141 * accessible by the CPU and all three DMA controllers are on a higher-speed bus. Devices
RichardUK 0:63d45df56584 142 * containing more than 32 kB SRAM have two additional 16 kB SRAM blocks, each situated
RichardUK 0:63d45df56584 143 * on separate slave ports on the AHB multilayer matrix.
RichardUK 0:63d45df56584 144 * This architecture allows the possibility for CPU and DMA accesses to be separated in
RichardUK 0:63d45df56584 145 * such a way that there are few or no delays for the bus masters.
RichardUK 0:63d45df56584 146 */
RichardUK 0:63d45df56584 147 HostControllerCommunicationsArea *commsArea;
RichardUK 0:63d45df56584 148
RichardUK 0:63d45df56584 149 /**
RichardUK 0:63d45df56584 150 * The object that recivies messages from the host controller.
RichardUK 0:63d45df56584 151 */
RichardUK 0:63d45df56584 152 HostControllerMessages *messageCallback;
RichardUK 0:63d45df56584 153
RichardUK 0:63d45df56584 154
RichardUK 0:63d45df56584 155 /**
RichardUK 0:63d45df56584 156 * This is the linked list object for the memory pool.
RichardUK 0:63d45df56584 157 */
RichardUK 0:63d45df56584 158 LinkedListItem *memoryPoolHead;
RichardUK 0:63d45df56584 159
RichardUK 0:63d45df56584 160
RichardUK 0:63d45df56584 161 /**
RichardUK 0:63d45df56584 162 * Because of noise on the lines we can get spammed in the usb interupt. (could because I am missing some resisters)
RichardUK 0:63d45df56584 163 * So what I do is reset this timeout each time we get told the status has changed.
RichardUK 0:63d45df56584 164 * When it has settled down the timeout will nolonger get reset on so will fire.
RichardUK 0:63d45df56584 165 * At that point i'll tell the Update function that it needs update the root hub object.
RichardUK 0:63d45df56584 166 */
RichardUK 0:63d45df56584 167 Timeout delayedRootHubStatusChangeTimeout;
RichardUK 0:63d45df56584 168
RichardUK 0:63d45df56584 169 /**
RichardUK 0:63d45df56584 170 * The state of the last status change interupt.
RichardUK 0:63d45df56584 171 */
RichardUK 0:63d45df56584 172 uint32_t hubPortStatus;
RichardUK 0:63d45df56584 173
RichardUK 0:63d45df56584 174 /**
RichardUK 0:63d45df56584 175 * Removes all the endpoints for a given device from the passed list.
RichardUK 0:63d45df56584 176 */
RichardUK 0:63d45df56584 177 void RemoveEndpointsForDevice(int deviceID,EndpointDescriptor **list);
RichardUK 0:63d45df56584 178
RichardUK 1:4461071ed964 179 /**
RichardUK 1:4461071ed964 180 * Adds the endpoint to the host controller so that the next frame it will be processed for transfers.
RichardUK 1:4461071ed964 181 */
RichardUK 1:4461071ed964 182 TransferDescriptor* QueueTransfer(EndpointDescriptor** headED,int deviceID,int direction,int endpointNumber,int maximumPacketSize,int lowspeed,const uint8_t* data,int dataLength);
RichardUK 1:4461071ed964 183
RichardUK 1:4461071ed964 184
RichardUK 0:63d45df56584 185 };//class Controller
RichardUK 0:63d45df56584 186
RichardUK 0:63d45df56584 187 };//namespace USB
RichardUK 0:63d45df56584 188
RichardUK 0:63d45df56584 189 #endif //#ifndef __USB_HOST_CONTROLLER_H__