Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FATFileSystem mbed-rtos mbed
Fork of USBHost by
Diff: USBHost/USBHost.cpp
- Revision:
- 24:868cbfe611a7
- Parent:
- 23:759ec18ee1a7
- Child:
- 34:028508fd50fa
diff -r 759ec18ee1a7 -r 868cbfe611a7 USBHost/USBHost.cpp
--- a/USBHost/USBHost.cpp Fri Mar 07 16:00:46 2014 +0000
+++ b/USBHost/USBHost.cpp Tue Jun 03 11:30:38 2014 +0100
@@ -47,7 +47,7 @@
* - call the callback attached to the endpoint where the td is attached
*/
void USBHost::usb_process() {
-
+
bool controlListState;
bool bulkListState;
bool interruptListState;
@@ -60,29 +60,29 @@
#if DEBUG_TRANSFER
uint8_t * buf_transfer;
#endif
-
+
#if MAX_HUB_NB
uint8_t k;
#endif
-
+
while(1) {
osEvent evt = mail_usb_event.get();
-
+
if (evt.status == osEventMail) {
-
+
message_t * usb_msg = (message_t*)evt.value.p;
-
+
switch (usb_msg->event_id) {
-
+
// a new device has been connected
case DEVICE_CONNECTED_EVENT:
too_many_hub = false;
buf[4] = 0;
-
+
do
{
Lock lock(this);
-
+
for (i = 0; i < MAX_DEVICE_CONNECTED; i++) {
if (!deviceInUse[i]) {
USB_DBG_EVENT("new device connected: %p\r\n", &devices[i]);
@@ -92,68 +92,68 @@
break;
}
}
-
+
if (i == MAX_DEVICE_CONNECTED) {
USB_ERR("Too many device connected!!\r\n");
continue;
}
-
+
if (!controlEndpointAllocated) {
control = newEndpoint(CONTROL_ENDPOINT, OUT, 0x08, 0x00);
addEndpoint(NULL, 0, (USBEndpoint*)control);
controlEndpointAllocated = true;
}
-
+
#if MAX_HUB_NB
if (usb_msg->hub_parent)
devices[i].setHubParent((USBHostHub *)(usb_msg->hub_parent));
#endif
-
+
for (j = 0; j < timeout_set_addr; j++) {
-
+
resetDevice(&devices[i]);
-
+
// set size of control endpoint
devices[i].setSizeControlEndpoint(8);
-
+
devices[i].activeAddress(false);
-
+
// get first 8 bit of device descriptor
// and check if we deal with a hub
USB_DBG("usb_thread read device descriptor on dev: %p\r\n", &devices[i]);
res = getDeviceDescriptor(&devices[i], buf, 8);
-
+
if (res != USB_TYPE_OK) {
USB_ERR("usb_thread could not read dev descr");
continue;
}
-
+
// set size of control endpoint
devices[i].setSizeControlEndpoint(buf[7]);
-
+
// second step: set an address to the device
res = setAddress(&devices[i], devices[i].getAddress());
-
+
if (res != USB_TYPE_OK) {
USB_ERR("SET ADDR FAILED");
continue;
}
devices[i].activeAddress(true);
USB_DBG("Address of %p: %d", &devices[i], devices[i].getAddress());
-
+
// try to read again the device descriptor to check if the device
// answers to its new address
res = getDeviceDescriptor(&devices[i], buf, 8);
-
+
if (res == USB_TYPE_OK) {
break;
}
-
+
Thread::wait(100);
}
-
+
USB_INFO("New device connected: %p [hub: %d - port: %d]", &devices[i], usb_msg->hub, usb_msg->port);
-
+
#if MAX_HUB_NB
if (buf[4] == HUB_CLASS) {
for (k = 0; k < MAX_HUB_NB; k++) {
@@ -169,49 +169,49 @@
break;
}
}
-
+
if (k == MAX_HUB_NB) {
USB_ERR("Too many hubs connected!!\r\n");
too_many_hub = true;
}
}
-
+
if (usb_msg->hub_parent)
((USBHostHub *)(usb_msg->hub_parent))->deviceConnected(&devices[i]);
#endif
-
+
if ((i < MAX_DEVICE_CONNECTED) && !too_many_hub) {
deviceInUse[i] = true;
}
-
+
} while(0);
-
+
break;
-
+
// a device has been disconnected
case DEVICE_DISCONNECTED_EVENT:
-
+
do
{
Lock lock(this);
-
+
controlListState = disableList(CONTROL_ENDPOINT);
bulkListState = disableList(BULK_ENDPOINT);
interruptListState = disableList(INTERRUPT_ENDPOINT);
-
+
idx = findDevice(usb_msg->hub, usb_msg->port, (USBHostHub *)(usb_msg->hub_parent));
if (idx != -1) {
freeDevice((USBDeviceConnected*)&devices[idx]);
}
-
+
if (controlListState) enableList(CONTROL_ENDPOINT);
if (bulkListState) enableList(BULK_ENDPOINT);
if (interruptListState) enableList(INTERRUPT_ENDPOINT);
-
+
} while(0);
-
+
break;
-
+
// a td has been processed
// call callback on the ed associated to the td
// we are not in ISR -> users can use printf in their callback method
@@ -241,7 +241,7 @@
}
break;
}
-
+
mail_usb_event.free(usb_msg);
}
}
@@ -272,7 +272,7 @@
for (uint8_t j = 0; j < MAX_INTF; j++)
deviceAttachedDriver[i][j] = false;
}
-
+
#if MAX_HUB_NB
for (uint8_t i = 0; i < MAX_HUB_NB; i++) {
hubs[i].setHost(this);
@@ -313,7 +313,7 @@
tdList = (volatile HCTD*)td->nextTD; //Dequeue element now as it could be modified below
if (td->ep != NULL) {
USBEndpoint * ep = (USBEndpoint *)(td->ep);
-
+
if (((HCTD *)td)->control >> 28) {
state = ((HCTD *)td)->control >> 28;
} else {
@@ -321,9 +321,9 @@
ep->setLengthTransferred((uint32_t)td->currBufPtr - (uint32_t)ep->getBufStart());
state = 16 /*USB_TYPE_IDLE*/;
}
-
+
ep->unqueueTransfer(td);
-
+
if (ep->getType() != CONTROL_ENDPOINT) {
// callback on the processed td will be called from the usb_thread (not in ISR)
message_t * usb_msg = mail_usb_event.alloc();
@@ -360,7 +360,7 @@
if (deviceInited[idx])
return;
}
-
+
message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_CONNECTED_EVENT;
usb_msg->hub = hub;
@@ -384,7 +384,7 @@
} else {
return;
}
-
+
message_t * usb_msg = mail_usb_event.alloc();
usb_msg->event_id = DEVICE_DISCONNECTED_EVENT;
usb_msg->hub = hub;
@@ -397,7 +397,7 @@
{
USBEndpoint * ep = NULL;
HCED * ed = NULL;
-
+
#if MAX_HUB_NB
if (dev->getClass() == HUB_CLASS) {
if (dev->hub == NULL) {
@@ -412,13 +412,13 @@
}
}
}
-
+
// notify hub parent that this device has been disconnected
if (dev->getHubParent())
dev->getHubParent()->deviceDisconnected(dev);
-
+
#endif
-
+
int idx = findDevice(dev);
if (idx != -1) {
deviceInUse[idx] = false;
@@ -481,7 +481,7 @@
updateInterruptHeadED(0);
headInterruptEndpoint = current->nextEndpoint();
}
-
+
// modify tail
switch (current->getType()) {
case BULK_ENDPOINT:
@@ -553,7 +553,7 @@
deviceReset[index] = true;
return USB_TYPE_OK;
}
-
+
return USB_TYPE_ERROR;
}
@@ -577,7 +577,7 @@
if ((dev != NULL) && dev->getSpeed()) {
ep->setSpeed(dev->getSpeed());
}
-
+
ep->setIntfNb(intf_nb);
// queue the new USBEndpoint on the ED list
@@ -626,7 +626,7 @@
default:
return false;
}
-
+
ep->dev = dev;
dev->addEndpoint(intf_nb, ep);
@@ -733,7 +733,7 @@
ed->queueTransfer();
printList(type);
enableList(type);
-
+
td_mutex.unlock();
return USB_TYPE_PROCESSING;
@@ -750,7 +750,7 @@
0, buf, MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf));
if (len_dev_descr)
*len_dev_descr = MIN(DEVICE_DESCRIPTOR_LENGTH, max_len_buf);
-
+
return t;
}
@@ -772,10 +772,10 @@
}
total_conf_descr_length = buf[2] | (buf[3] << 8);
total_conf_descr_length = MIN(max_len_buf, total_conf_descr_length);
-
+
if (len_conf_descr)
*len_conf_descr = total_conf_descr_length;
-
+
USB_DBG("TOTAL_LENGTH: %d \t NUM_INTERF: %d", total_conf_descr_length, buf[4]);
return controlRead( dev,
@@ -792,7 +792,7 @@
SET_ADDRESS,
address,
0, NULL, 0);
-
+
}
USB_TYPE USBHost::setConfiguration(USBDeviceConnected * dev, uint8_t conf)
@@ -821,18 +821,18 @@
{
uint16_t total_conf_descr_length = 0;
USB_TYPE res;
-
+
do
{
Lock lock(this);
-
+
// don't enumerate a device which all interfaces are registered to a specific driver
int index = findDevice(dev);
-
+
if (index == -1) {
return USB_TYPE_ERROR;
}
-
+
uint8_t nb_intf_attached = numberDriverAttached(dev);
USB_DBG("dev: %p nb_intf: %d", dev, dev->getNbIntf());
USB_DBG("dev: %p nb_intf_attached: %d", dev, nb_intf_attached);
@@ -840,9 +840,9 @@
USB_DBG("Don't enumerate dev: %p because all intf are registered with a driver", dev);
return USB_TYPE_OK;
}
-
+
USB_DBG("Enumerate dev: %p", dev);
-
+
// third step: get the whole device descriptor to see vid, pid
res = getDeviceDescriptor(dev, data, DEVICE_DESCRIPTOR_LENGTH);
@@ -850,7 +850,7 @@
USB_DBG("GET DEV DESCR FAILED");
return res;
}
-
+
dev->setClass(data[4]);
dev->setSubClass(data[5]);
dev->setProtocol(data[6]);
@@ -877,7 +877,7 @@
// only set configuration if not enumerated before
if (!dev->isEnumerated()) {
-
+
USB_DBG("Set configuration 1 on dev: %p", dev);
// sixth step: set configuration (only 1 supported)
res = setConfiguration(dev, 1);
@@ -887,12 +887,12 @@
return res;
}
}
-
+
dev->setEnumerated();
// Now the device is enumerated!
USB_DBG("dev %p is enumerated\r\n", dev);
-
+
} while(0);
// Some devices may require this delay
@@ -991,17 +991,17 @@
}
USB_TYPE USBHost::generalTransfer(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking, ENDPOINT_TYPE type, bool write) {
-
+
#if DEBUG_TRANSFER
const char * type_str = (type == BULK_ENDPOINT) ? "BULK" : ((type == INTERRUPT_ENDPOINT) ? "INTERRUPT" : "ISOCHRONOUS");
USB_DBG_TRANSFER("----- %s %s [dev: %p - %s - hub: %d - port: %d - addr: %d - ep: %02X]------", type_str, (write) ? "WRITE" : "READ", dev, dev->getName(ep->getIntfNb()), dev->getHub(), dev->getPort(), dev->getAddress(), ep->getAddress());
#endif
-
+
Lock lock(this);
-
+
USB_TYPE res;
ENDPOINT_DIRECTION dir = (write) ? OUT : IN;
-
+
if (dev == NULL) {
USB_ERR("dev NULL");
return USB_TYPE_ERROR;
@@ -1026,7 +1026,7 @@
USB_ERR("[ep: %p - dev: %p] USBEndpoint addr and device addr don't match", ep, ep->dev);
return USB_TYPE_ERROR;
}
-
+
#if DEBUG_TRANSFER
if (write) {
USB_DBG_TRANSFER("%s WRITE buffer", type_str);
@@ -1038,19 +1038,19 @@
addTransfer(ep, buf, len);
if (blocking) {
-
+
ep->ep_queue.get();
res = ep->getState();
-
+
USB_DBG_TRANSFER("%s TRANSFER res: %s on ep: %p\r\n", type_str, ep->getStateString(), ep);
-
+
if (res != USB_TYPE_IDLE) {
return res;
}
-
+
return USB_TYPE_OK;
}
-
+
return USB_TYPE_PROCESSING;
}
