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.
Fork of USBHost_DISCO-F746NG by
Diff: USBHost/USBHost.cpp
- Revision:
- 9:7f9f64cf5ded
- Parent:
- 8:6463cd1964c0
- Child:
- 10:40c7f6788902
--- a/USBHost/USBHost.cpp Fri Jan 31 13:45:07 2014 +0000 +++ b/USBHost/USBHost.cpp Mon Feb 03 13:00:16 2014 +0000 @@ -2,34 +2,6 @@ #include "USBHost.h" #include <algorithm> -template <bool>struct CtAssert; -template <>struct CtAssert<true> {}; -#define CTASSERT(A) CtAssert<A>(); - - -#ifdef _USB_DBG -#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0); -#define USB_DBG2(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0); -#define USB_DBG_HEX(A,B) debug_hex(A,B) -#define USB_DBG_ERRSTAT() report.print_errstat(); -void debug_hex(uint8_t* buf, int size); -#else -#define USB_DBG(...) while(0) -#define USB_DBG2(...) while(0) -#define USB_DBG_HEX(A,B) while(0) -#define USB_DBG_ERRSTAT() while(0) -#endif - -#ifdef _USB_TEST -#define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; -#define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A)) -#else -#define USB_TEST_ASSERT(A) while(0) -#define USB_TEST_ASSERT_FALSE(A) while(0) -#endif - -#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0); - USBHost* USBHost::inst = NULL; USBHost* USBHost::getHostInst() @@ -41,8 +13,14 @@ return inst; } +void USBHost::poll() +{ + if (inst) { + inst->task(); + } +} + USBHost::USBHost() { - DeviceLists_count = 0; } /* virtual */ bool USBHost::addDevice(int hub, int port, bool lowSpeed) { @@ -74,12 +52,11 @@ dev->setVid(dev_desc->idVendor); dev->setPid(dev_desc->idProduct); dev->setClass(dev_desc->bDeviceClass); - USB_INFO("hub: %d port: %d speed: %s vid: %04x pid: %04x class: %02x addr: %d\n", + USB_INFO("hub: %d port: %d speed: %s vid: %04x pid: %04x class: %02x addr: %d", hub, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(), dev->getAddress()); - USB_TEST_ASSERT(DeviceLists_count < MAX_DEVICE_CONNECTED); - DeviceLists[DeviceLists_count++] = dev; + DeviceLists.push(dev); if (dev->getClass() == HUB_CLASS) { const int config = 1; @@ -146,7 +123,6 @@ uint32_t index = 0; uint32_t len_desc = 0; uint8_t id = 0; - int nb_endpoints_used = 0; USBEndpoint * ep = NULL; uint8_t intf_nb = 0; bool parsing_intf = false; @@ -156,6 +132,7 @@ while (index < len) { len_desc = conf_descr[index]; id = conf_descr[index+1]; + USB_DBG_HEX(conf_descr+index, len_desc); switch (id) { case CONFIGURATION_DESCRIPTOR: USB_DBG("dev: %p has %d intf", dev, conf_descr[4]); @@ -163,14 +140,10 @@ break; case INTERFACE_DESCRIPTOR: if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) { - if (intf_nb++ <= MAX_INTF) { - current_intf = conf_descr[index + 2]; - dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]); - nb_endpoints_used = 0; - USB_DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", current_intf, dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]); - } else { - USB_DBG("Drop intf..."); - } + intf_nb++; + current_intf = conf_descr[index + 2]; + dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]); + USB_DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", current_intf, dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]); parsing_intf = true; } else { parsing_intf = false; @@ -179,19 +152,16 @@ case ENDPOINT_DESCRIPTOR: ep_desc = reinterpret_cast<EndpointDescriptor*>(conf_descr+index); if (parsing_intf && (intf_nb <= MAX_INTF) ) { - if (nb_endpoints_used < MAX_ENDPOINT_PER_INTERFACE) { - ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03); - ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT; - if(pEnumerator->useEndpoint(current_intf, type, dir)) { - ep = new USBEndpoint; - ep->setDevice(dev); - ep->setType(type); - ep->setAddress(ep_desc->bEndpointAddress); - ep->setSize(ep_desc->wMaxPacketSize); - USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev); - dev->addEndpoint(current_intf, ep); - nb_endpoints_used++; - } + ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03); + ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT; + if(pEnumerator->useEndpoint(current_intf, type, dir)) { + ep = new USBEndpoint; + ep->setDevice(dev); + ep->setType(type); + ep->setAddress(ep_desc->bEndpointAddress); + ep->setSize(ep_desc->wMaxPacketSize); + USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev); + dev->addEndpoint(current_intf, ep); } } break; @@ -223,9 +193,14 @@ return USB_TYPE_ERROR; } -USB_TYPE USBHost::bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking) { - USB_TEST_ASSERT(blocking); - int result = BulkRead(ep, buf, len); +USB_TYPE USBHost::bulkRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { + if (blocking == false) { + ep->setType(BULK_ENDPOINT); + ep->setBuffer(buf, len); + ep_queue.push(ep); + return USB_TYPE_PROCESSING; + } + int result = bulkReadBLOCK(ep, buf, len, -1); if (result >= 0) { return USB_TYPE_OK; } @@ -233,9 +208,9 @@ return USB_TYPE_ERROR; } -USB_TYPE USBHost::bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking) { +USB_TYPE USBHost::bulkWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { USB_TEST_ASSERT(blocking); - int result = BulkWrite(ep, buf, len); + int result = bulkWriteNB(ep, buf, len); if (result >= 0) { return USB_TYPE_OK; } @@ -243,12 +218,32 @@ return USB_TYPE_ERROR; } -USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking) { - int result = InterruptRead(ep, buf, len); - if (result >= 0) { - return USB_TYPE_OK; +USB_TYPE USBHost::interruptRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { + if (blocking == false) { + ep->setType(INTERRUPT_ENDPOINT); + ep->setBuffer(buf, len); + ep_queue.push(ep); + return USB_TYPE_PROCESSING; } - return USB_TYPE_ERROR; + interruptReadNB(ep, buf, len); + return USB_TYPE_OK; +} + +USB_TYPE USBHost::interruptWrite(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { + USB_TEST_ASSERT(blocking); + interruptWriteNB(ep, buf, len); + return USB_TYPE_OK; +} + +USB_TYPE USBHost::isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { + if (blocking == false) { + ep->setType(ISOCHRONOUS_ENDPOINT); + ep->setBuffer(buf, len); + ep_queue.push(ep); + return USB_TYPE_PROCESSING; + } + isochronousReadNB(ep, buf, len); + return USB_TYPE_OK; } int USBHost::ControlRead(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size) { @@ -316,7 +311,8 @@ return write_len; } -int USBHost::InterruptRead(USBEndpoint* ep, uint8_t* data, int size) { +int USBHost::interruptReadNB(USBEndpoint* ep, uint8_t* data, int size) +{ USB_TEST_ASSERT(ep); USBDeviceConnected* dev = ep->getDevice(); USB_TEST_ASSERT(dev); @@ -346,7 +342,43 @@ return read_len; } -int USBHost::BulkRead(USBEndpoint* ep, uint8_t* data, int size, int timeout_ms) { +int USBHost::interruptWriteNB(USBEndpoint* ep, const uint8_t* data, int size) +{ + USB_TEST_ASSERT(ep); + USBDeviceConnected* dev = ep->getDevice(); + USB_TEST_ASSERT(dev); + setAddr(dev->getAddress(), dev->getSpeed()); + setEndpoint(); + const int retryLimit = 0; + int transferred_len = 0; + for(int n = 0; transferred_len < size; n++) { + int size2 = std::min(size-transferred_len, ep->getSize()); + int result = token_out(ep, data+transferred_len, size2, retryLimit); + if (result < 0) { + if (LastStatus == NAK) { + if (n == 0) { + return -1; + } + break; + } + //USB_DBG("token_in result=%d %02x", result, LastStatus); + return result; + } + transferred_len += result; + if (result < ep->getSize()) { + break; + } + } + ep->setLengthTransferred(transferred_len); + return transferred_len; +} + +int USBHost::bulkReadNB(USBEndpoint* ep, uint8_t* data, int size) +{ + return bulkReadBLOCK(ep, data, size, 0); +} + +int USBHost::bulkReadBLOCK(USBEndpoint* ep, uint8_t* data, int size, int timeout_ms) { USB_TEST_ASSERT(ep); USBDeviceConnected* dev = ep->getDevice(); USB_TEST_ASSERT(dev); @@ -381,7 +413,7 @@ return read_len; } -int USBHost::BulkWrite(USBEndpoint* ep, const uint8_t* data, int size) { +int USBHost::bulkWriteNB(USBEndpoint* ep, const uint8_t* data, int size) { USB_TEST_ASSERT(ep); USBDeviceConnected* dev = ep->getDevice(); USB_TEST_ASSERT(dev); @@ -410,7 +442,7 @@ return write_len; } -int USBHost::IsochronousRead(USBEndpoint* ep, uint8_t* data, int size) { +int USBHost::isochronousReadNB(USBEndpoint* ep, uint8_t* data, int size) { USBDeviceConnected* dev = ep->getDevice(); USB_TEST_ASSERT(dev); setAddr(dev->getAddress()); @@ -421,3 +453,30 @@ return result; } +void USBHost::task() +{ + if (ep_queue.empty()) { + return; + } + USBEndpoint* ep = ep_queue.pop(); + USB_TEST_ASSERT(ep); + ep->setLengthTransferred(0); + switch(ep->getType()) { + case INTERRUPT_ENDPOINT: + if (ep->getDir() == IN) { + interruptReadNB(ep, ep->getBufStart(), ep->getBufSize()); + } + break; + case BULK_ENDPOINT: + if (ep->getDir() == IN) { + bulkReadNB(ep, ep->getBufStart(), ep->getBufSize()); + } + break; + case ISOCHRONOUS_ENDPOINT: + if (ep->getDir() == IN) { + isochronousReadNB(ep, ep->getBufStart(), ep->getBufSize()); + } + break; + } + ep->call(); +}