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