Diff: UsbHost.cpp
- Revision:
- 1:4461071ed964
- Parent:
- 0:63d45df56584
diff -r 63d45df56584 -r 4461071ed964 UsbHost.cpp
--- a/UsbHost.cpp Sun Jul 08 20:18:58 2012 +0000
+++ b/UsbHost.cpp Wed Sep 19 16:39:23 2012 +0000
@@ -24,12 +24,14 @@
#include "UsbStructures.h"
#include "UsbEnums.h"
-//Do #if 0 to enable debug log on the host controller driver.
-#if 1
-#undef DEBUG
-#define DEBUG(...) do {} while(0)
+#if 0
+#define DEBUGV DEBUG
+#else
+#define DEBUGV(...) do {} while(0)
#endif
+
+
namespace USB
{
@@ -57,10 +59,11 @@
if( devices[n] == NULL )
{
devices[n] = (Device *)driver->AllocateMemoryPoolItem();
+ memset(devices[n],0,sizeof(Device));
devices[n]->id = (uint8_t)(n+1);//The device is +1 as device 0 is the host controller.
devices[n]->endpointZeroMaxPacketSize = endpointZeroMaxPacketSize;
devices[n]->lowspeed = (hubPortStatus&ROOTHUB_LOW_SPEED_DEVICE_ATTACHED) ? 1 : 0;
-
+ devices[n]->blockOnEP = -1;
return devices[n];
}
}
@@ -69,7 +72,7 @@
void Host::SendControlTransferData(Device* device,int dataToggle)
{
- driver->QueueControlTransferStage(
+ driver->QueueControlTransfer(
device->id,
device->controlTransferDirToHost == 1 ? TDD_IN : TDD_OUT,
0,
@@ -85,7 +88,7 @@
void Host::SendControlTransferAcknowledge(Device* device,int dataToggle)
{
//Send empty packet to ACK.
- driver->QueueControlTransferStage(
+ driver->QueueControlTransfer(
device->id,
device->controlTransferDirToHost == 0 ? TDD_IN : TDD_OUT,
0,
@@ -115,6 +118,29 @@
void Host::Update()
{
driver->Update();
+ //Now the host has been updated service any outstanding transfers.
+ for(int n = 0 ; n < MAX_DEVICES ; n++ )
+ {
+ if( devices[n] != NULL && devices[n]->pendingCallbacks != NULL )
+ {
+ TransferDescriptor *transfer = devices[n]->pendingCallbacks;
+ devices[n]->pendingCallbacks = NULL;
+
+ while( transfer )
+ {
+ TransferDescriptor *next = transfer->nextTD;
+// DEBUG("onReceive (0x%08x) (0x%08x)",transfer,next);
+
+
+ int deviceEP = transfer->ep | (transfer->direction == TDD_IN ? 0x80 : 0);
+ int reciveLength = transfer->CurrentBufferPointer - transfer->data;
+ transfer->transferCallback->onReceive(devices[n]->id,deviceEP,0,transfer->data,reciveLength);
+
+ driver->FreeMemoryPoolItem(transfer);
+ transfer = next;
+ }
+ }
+ }
}
int Host::getDeviceDescriptor(int deviceID,DeviceDescription &description)
@@ -164,7 +190,7 @@
*/
int Host::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)
{
- DEBUG("ControlTransfer");
+ DEBUGV("ControlTransfer");
Device* device = getDevice(deviceID);
@@ -183,35 +209,39 @@
sp->index = index;
sp->length = length;
- DEBUG("Setup %d %d %d %d %d",sp->requestType,sp->request,sp->value,sp->index,sp->length);
+ DEBUGV("Setup %d %d %d %d %d",sp->requestType,sp->request,sp->value,sp->index,sp->length);
- driver->QueueControlTransferStage(deviceID,TDD_SETUP,0,device->endpointZeroMaxPacketSize,device->lowspeed,TOGGLE_DATA0,(const uint8_t*)sp,sizeof(SetupPacket));
+ driver->QueueControlTransfer(deviceID,TDD_SETUP,0,device->endpointZeroMaxPacketSize,device->lowspeed,TOGGLE_DATA0,(const uint8_t*)sp,sizeof(SetupPacket));
while(device->controlTransferState != CTS_IDLE)
{
- wait_ms(100);
+ wait_ms(50);
};
//Free this up.
driver->FreeMemoryPoolItem(sp);
- DEBUG("Done, recived %d",controlTransferDataLength);
+ DEBUGV("Done, recived %d",controlTransferDataLength);
return 0;
}
-int Host::BulkTransfer(int deviceID,uint8_t endpoint,const uint8_t* data,int length,int callbackID)
+int Host::BulkTransfer(int deviceID,uint8_t endpoint,const uint8_t* data,int length,TransferCallback* callback)
{
- DEBUG("ControlTransfer");
+ DEBUGV("BulkTransfer Device(%d) EP(%d) Len(%d) CB(0x%08x)",deviceID,endpoint,length,callback);
Device* device = getDevice(deviceID);
-/*
- driver->QueueControlTransferStage(deviceID,(endpoint&LIBUSB_ENDPOINT_IN) ? TDD_IN : TDD_OUT,endpoint,device->endpointZeroMaxPacketSize,device->lowspeed,TOGGLE_DATA0,data,length);
+ device->blockOnEP = endpoint;
+
+ driver->QueueBulkTransfer(deviceID,(endpoint&LIBUSB_ENDPOINT_IN) ? TDD_IN : TDD_OUT,endpoint&0x7f,device->endpointZeroMaxPacketSize,device->lowspeed,callback,data,length);
- while(device->controlTransferState != CTS_IDLE)
+ if( callback == NULL )
{
- wait_ms(100);
- };
- */
+ while( device->blockOnEP == endpoint )
+ {
+ driver->Update();
+ wait_ms(100);
+ }
+ }
return 0;
}
@@ -239,29 +269,29 @@
//Using device 0 for the setup and enum phase of the newley connected device.
//We do this just to get some info on the device and then send a 'set address' command.
//At that point we'll start using it's real ID.
- DEBUG("Getting endpoint zero maxPacketSize");
+ DEBUGV("Getting endpoint zero maxPacketSize");
ControlTransfer(0,LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR,(LIBUSB_DT_DEVICE << 8), 0, (uint8_t*)&description,8,DEFAULT_TIMEOUT);
//Now allocate the device and it's ID.
- DEBUG("Allocating device");
+ DEBUGV("Allocating device");
Device* device = AllocateDevice(description.maxPacketSize,hubPortStatus);
//Now correct the endpoint's max packet size. Needs this for when we setup the endpoint descriptor for a transfer.
- DEBUG("endpointZeroMaxPacketSize(%d)",device->endpointZeroMaxPacketSize);
+ DEBUGV("endpointZeroMaxPacketSize(%d)",device->endpointZeroMaxPacketSize);
//Set the devices new address.
- DEBUG("Setting device address to %d",device->id);
+ DEBUGV("Setting device address to %d",device->id);
ControlTransfer(0,LIBUSB_ENDPOINT_OUT | LIBUSB_RECIPIENT_DEVICE, LIBUSB_REQUEST_SET_ADDRESS, device->id,0,NULL,0,DEFAULT_TIMEOUT);
//New ID is now set, so we can free the object used when it was called device zero.
driver->DetachDevice(0);
//Now fetch the full device description.
- DEBUG("Getting device description");
+ DEBUGV("Getting device description");
getDeviceDescriptor(device->id,description);
- DEBUG("idVendor(0x%04x) idProduct(0x%04x)",description.idVendor,description.idProduct);
+ DEBUGV("idVendor(0x%04x) idProduct(0x%04x)",description.idVendor,description.idProduct);
//Get the language ID.
uint16_t* lang = (uint16_t*)driver->AllocateMemoryPoolItem();
@@ -281,35 +311,53 @@
void Host::TransferDone(TransferDescriptor *transfer)
{
- DEBUG("TransferDone, device(%d) errorCount(%d) status(%d) direction(%d) dataToggle(%d)",transfer->deviceID,transfer->errorCount,transfer->conditionCode,transfer->direction,transfer->dataToggle);
+ //This is the endpoint with the dir encoded into it, the way it is done to the applicaition coder.
+ //Needed when we are blocking for a non interput transfer to finish.
+ int epDir = transfer->ep | (transfer->direction==TDD_IN?0x80:0);
+ DEBUGV("TransferDone, device(%d) ep(%d) errorCount(%d) status(%d) direction(%d) dataToggle(%d)",transfer->deviceID,epDir,transfer->errorCount,transfer->conditionCode,transfer->direction,transfer->dataToggle);
//Get the device this TD that has just been done for.
Device* device = getDevice(transfer->deviceID);
- //See if this was a setup packet, if so do we have data to ask for, if not then just ack the transaction.
- //TODO: Error checking!
- switch( device->controlTransferState )
+ if( transfer->transferType == TT_CONTROL )
{
- case CTS_SETUP:
- if( device->controlTransferData != NULL )
+ //See if this was a setup packet, if so do we have data to ask for, if not then just ack the transaction.
+ //TODO: Error checking!
+ switch( device->controlTransferState )
{
- SendControlTransferData(device,transfer->dataToggle);
- }
- else
- {
+ case CTS_SETUP:
+ if( device->controlTransferData != NULL )
+ {
+ SendControlTransferData(device,transfer->dataToggle);
+ }
+ else
+ {
+ SendControlTransferAcknowledge(device,transfer->dataToggle);
+ }
+ break;
+
+ case CTS_DATA:
+ controlTransferDataLength = (transfer->bufferEnd - device->controlTransferData) + 1;
SendControlTransferAcknowledge(device,transfer->dataToggle);
+ break;
+
+ case CTS_ACK:
+ device->controlTransferState = CTS_IDLE;
+ break;
}
- break;
-
- case CTS_DATA:
- controlTransferDataLength = (transfer->bufferEnd - device->controlTransferData) + 1;
- SendControlTransferAcknowledge(device,transfer->dataToggle);
- break;
+ }
+
+ if( transfer->transferCallback != NULL )
+ {
+ transfer->nextTD = device->pendingCallbacks;
+ device->pendingCallbacks = transfer;
+ }
+
+ if( device->blockOnEP == epDir )
+ {
+ device->blockOnEP = -1;
+ }
- case CTS_ACK:
- device->controlTransferState = CTS_IDLE;
- break;
- }
}
};//namespace USB