File content as of revision 2:33e7ce63dd6d:
/**
A host controller driver from the mBed device.
Copyright (C) 2012 Richard e Collins - richard.collins@linux.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __USB_HOST_CONTROLLER_H__
#define __USB_HOST_CONTROLLER_H__
#include <stdint.h>
namespace USB
{
struct HostControllerCommunicationsArea;
struct LinkedListItem;
struct EndpointDescriptor;
struct TransferDescriptor;
struct Device;
struct TransferCallback;
struct HostControllerMessages
{
/**
* Called when a device has been connected to a hub, be it the root controller hub or a usb hub.
*/
virtual void AddDevice(int hub,int port,int hubPortStatus) = 0;
/**
* Called when a transfer has been done. Depending on the transfer type it may be called a few times for one high level action.
* For example a ControlTransfer can cause 3 replies, one for the setup packet, one for the data and one for the ack knollage msg.
*/
virtual void TransferDone(TransferDescriptor *transfer) = 0;
};
struct HostController
{
struct
{
unsigned newDeviceConnected:1;
unsigned unrecoverableError:1;
}flags;
/*
* The number of the pool items currently allocated by the system.
*/
int numAllocatedPoolItems;
uint32_t USBInterupt();
protected:
friend class Host;
/**
* Returns the singleton used for interacting with the root hub controller.
*/
static HostController *get();
/**
* Once started never stopped, as the memory is in reserved space there is nothing gained in stopping it.
*/
void Init(HostControllerMessages *messageCallback,Device*& deviceZero);
/**
* Handles state changes from interupts and calls functions from results interupt transfers.
* 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.
*/
void Update();
/**
* The memory returned is 16 bytes in size.
*/
void *AllocateMemoryPoolItem();
/**
* An item that had preveslly been allocated from a call to 'AllocateMemoryPoolItem'.
*/
void FreeMemoryPoolItem(void *item);
/*
* Allocates an endpoint to use in a USB data transfer.
*/
EndpointDescriptor *GetEndpointDescriptor(EndpointDescriptor** headED,uint32_t functionAddress,int endpointNumber,int maximumPacketSize,int lowspeed);
/*
* Allocates a transfer descriptor to use in a USB data transfer.
* direction == 0 for SETUP, == 1 for OUT (to device) and == 2 for IN (from device)
* dataToggle == 0 for DATA0 and == 1 for DATA1
*/
TransferDescriptor *AllocateTransferDescriptor(int deviceID,int direction,const uint8_t* data,int dataLength);
/**
* Adds the endpoint to the host controller so that the next frame it will be processed for control transfers.
*/
void QueueControlTransfer(int deviceID,int direction,int endpointNumber,int maximumPacketSize,int lowspeed,int dataToggle,const uint8_t* data,int dataLength);
/**
* Adds the endpoint to the host controller so that the next frame it will be processed for bulk transfers.
*/
void QueueBulkTransfer(int deviceID,int direction,int endpointNumber,int maximumPacketSize,int lowspeed,TransferCallback* callback,const uint8_t* data,int dataLength);
/**
* Temp work buffer, not used in this code, the driver, but is used in the host code that calls it.
*/
uint8_t* getScratchRam();
/**
* Return how many of the pool items are being used.
*/
int getNumAllocatedPoolItems()
{
return numAllocatedPoolItems;
}
/*
* Removes all the endpoints associated with this device from the host controller.
*/
void DetachDevice(int deviceID);
private:
/*
* Will be useing the first block of extra SRAM. There are two extra 16k blocks.
* These blocks have their own DMA and so don't interupt the CPU.
* Also as they are seperated from the main 32k of SRAM we are not
* stealing from the heap or the stack.
*
* The LPC1768 contains 64 kB of on-chip static RAM memory. Up to 32 kB of SRAM,
* accessible by the CPU and all three DMA controllers are on a higher-speed bus. Devices
* containing more than 32 kB SRAM have two additional 16 kB SRAM blocks, each situated
* on separate slave ports on the AHB multilayer matrix.
* This architecture allows the possibility for CPU and DMA accesses to be separated in
* such a way that there are few or no delays for the bus masters.
*/
HostControllerCommunicationsArea *commsArea;
/**
* The object that recivies messages from the host controller.
*/
HostControllerMessages *messageCallback;
/**
* This is the linked list object for the memory pool.
*/
LinkedListItem *memoryPoolHead;
/**
* Because of noise on the lines we can get spammed in the usb interupt. (could because I am missing some resisters)
* So what I do is reset this timeout each time we get told the status has changed.
* When it has settled down the timeout will nolonger get reset on so will fire.
* At that point i'll tell the Update function that it needs update the root hub object.
*/
Timeout delayedRootHubStatusChangeTimeout;
/**
* The state of the last status change interupt.
*/
uint32_t hubPortStatus;
/**
* Removes all the endpoints for a given device from the passed list.
*/
void RemoveEndpointsForDevice(int deviceID,EndpointDescriptor **list);
/**
* Adds the endpoint to the host controller so that the next frame it will be processed for transfers.
*/
TransferDescriptor* QueueTransfer(EndpointDescriptor** headED,int deviceID,int direction,int endpointNumber,int maximumPacketSize,int lowspeed,const uint8_t* data,int dataLength);
};//class Controller
};//namespace USB
#endif //#ifndef __USB_HOST_CONTROLLER_H__