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.
Dependents: F401RE-USBHostMIDI_RecieveExample
Fork of F401RE-USBHost by
Revision 9:7f9f64cf5ded, committed 2014-02-03
- Comitter:
- va009039
- Date:
- Mon Feb 03 13:00:16 2014 +0000
- Parent:
- 8:6463cd1964c0
- Child:
- 10:40c7f6788902
- Commit message:
- add interrupt write transfer.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FATFileSystem.lib Mon Feb 03 13:00:16 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/FATFileSystem/#b6669c987c8e
--- a/USBHost/USBDeviceConnected.cpp Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHost/USBDeviceConnected.cpp Mon Feb 03 13:00:16 2014 +0000
@@ -15,8 +15,7 @@
*/
#include "USBDeviceConnected.h"
-//#include "dbg.h"
-#define USB_DBG(...) while(0)
+#include "dbg.h"
USBDeviceConnected::USBDeviceConnected() {
init();
@@ -35,54 +34,33 @@
device_subclass = 0;
proto = 0;
lowSpeed = false;
- for (int i = 0; i < MAX_INTF; i++) {
- memset((void *)&intf[i], 0, sizeof(INTERFACE));
- intf[i].in_use = false;
- for (int j = 0; j < MAX_ENDPOINT_PER_INTERFACE; j++) {
- intf[i].ep[j] = NULL;
- //strcpy(intf[i].name, "Unknown");
- }
- }
+ intf.clear();
//hub_parent = NULL;
//hub = NULL;
- nb_interf = 0;
-}
-
-INTERFACE * USBDeviceConnected::getInterface(uint8_t index) {
- if (index >= MAX_INTF)
- return NULL;
-
- if (intf[index].in_use)
- return &intf[index];
-
- return NULL;
}
bool USBDeviceConnected::addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) {
- if ((intf_nb >= MAX_INTF) || (intf[intf_nb].in_use)) {
+ USB_DBG("intf_nb=%d", intf_nb);
+ INTERFACE* inter = intf.get(intf_nb);
+ if (inter) {
return false;
- }
- intf[intf_nb].in_use = true;
- intf[intf_nb].intf_class = intf_class;
- intf[intf_nb].intf_subclass = intf_subclass;
- intf[intf_nb].intf_protocol = intf_protocol;
- intf[intf_nb].nb_endpoint = 0;
+ }
+ inter = new INTERFACE;
+ inter->in_use = true;
+ inter->intf_class = intf_class;
+ inter->intf_subclass = intf_subclass;
+ inter->intf_protocol = intf_protocol;
+ intf.put(intf_nb, inter);
return true;
}
bool USBDeviceConnected::addEndpoint(uint8_t intf_nb, USBEndpoint * ept) {
- if ((intf_nb >= MAX_INTF) || (intf[intf_nb].in_use == false) || (intf[intf_nb].nb_endpoint >= MAX_ENDPOINT_PER_INTERFACE)) {
+ INTERFACE* inter = intf.get(intf_nb);
+ if (inter == NULL) {
return false;
}
- intf[intf_nb].nb_endpoint++;
-
- for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
- if (intf[intf_nb].ep[i] == NULL) {
- intf[intf_nb].ep[i] = ept;
- return true;
- }
- }
- return false;
+ inter->ep.push(ept);
+ return true;
}
void USBDeviceConnected::init(uint8_t hub_, uint8_t port_, bool lowSpeed_) {
@@ -102,15 +80,15 @@
USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index) {
- if (intf_nb >= MAX_INTF) {
- return NULL;
- }
- for (int i = 0; i < MAX_ENDPOINT_PER_INTERFACE; i++) {
- if ((intf[intf_nb].ep[i]->getType() == type) && (intf[intf_nb].ep[i]->getDir() == dir)) {
+ USB_DBG("intf_nb=%d", intf_nb);
+ INTERFACE* inter = intf.get(intf_nb);
+ USB_TEST_ASSERT(inter);
+ for (int i = 0; i < inter->ep.size(); i++) {
+ if ((inter->ep.at(i)->getType() == type) && (inter->ep.at(i)->getDir() == dir)) {
if(index) {
index--;
} else {
- return intf[intf_nb].ep[i];
+ return inter->ep.at(i);
}
}
}
@@ -118,8 +96,7 @@
}
USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, uint8_t index) {
- if ((intf_nb >= MAX_INTF) || (index >= MAX_ENDPOINT_PER_INTERFACE)) {
- return NULL;
- }
- return intf[intf_nb].ep[index];
+ INTERFACE* inter = intf.get(intf_nb);
+ USB_TEST_ASSERT(inter);
+ return inter->ep.at(index);
}
--- a/USBHost/USBDeviceConnected.h Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHost/USBDeviceConnected.h Mon Feb 03 13:00:16 2014 +0000
@@ -17,19 +17,25 @@
#include "USBEndpoint.h"
#include "USBHostConf.h"
+#include "myqueue.h"
+#include "mymap.h"
class USBEndpoint;
-typedef struct {
+struct INTERFACE {
+ INTERFACE() {
+ in_use = false;
+ intf_class = 0;
+ intf_subclass = 0;
+ intf_protocol = 0;
+ ep.clear();
+ }
bool in_use;
- uint8_t nb_endpoint;
uint8_t intf_class;
uint8_t intf_subclass;
uint8_t intf_protocol;
- USBEndpoint * ep[MAX_ENDPOINT_PER_INTERFACE];
- //FunctionPointer detach;
- //char name[10];
-} INTERFACE;
+ myqueue<USBEndpoint*>ep;
+};
/**
* USBDeviceConnected class
@@ -83,14 +89,6 @@
bool addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol);
/**
- * Get a specific interface
- *
- * @param index index of the interface to be fetched
- * @returns interface
- */
- INTERFACE * getInterface(uint8_t index);
-
- /**
* Disconnect the device by calling a callback function registered by a driver
*/
void disconnect();
@@ -122,7 +120,7 @@
USBEndpoint* getEpCtl() { return ep_ctl; }
private:
- INTERFACE intf[MAX_INTF];
+ mymap<int,INTERFACE*>intf;
uint8_t hub_nb;
uint8_t port;
uint16_t vid;
--- a/USBHost/USBEndpoint.h Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHost/USBEndpoint.h Mon Feb 03 13:00:16 2014 +0000
@@ -15,17 +15,58 @@
*/
#pragma once
+#include "FunctionPointer.h"
#include "USBHostTypes.h"
#include "USBDeviceConnected.h"
+
class USBDeviceConnected;
+/**
+* USBEndpoint class
+*/
class USBEndpoint {
public:
+ /**
+ * Constructor
+ */
USBEndpoint() : data01_toggle(DATA0),address(0),MaxPacketSize(8) {
dev = NULL;
}
+
+ /**
+ * Attach a member function to call when a transfer is finished
+ *
+ * @param tptr pointer to the object to call the member function on
+ * @param mptr pointer to the member function to be called
+ */
+ template<typename T>
+ inline void attach(T* tptr, void (T::*mptr)(void)) {
+ if((mptr != NULL) && (tptr != NULL)) {
+ rx.attach(tptr, mptr);
+ }
+ }
+
+ /**
+ * Attach a callback called when a transfer is finished
+ *
+ * @param fptr function pointer
+ */
+ inline void attach(void (*fptr)(void)) {
+ if(fptr != NULL) {
+ rx.attach(fptr);
+ }
+ }
+
+ /**
+ * Call the handler associted to the end of a transfer
+ */
+ inline void call() {
+ rx.call();
+ };
+
void setDevice(USBDeviceConnected* _dev) { dev = _dev; }
void setState(uint8_t st){}; // dummy
+ void setBuffer(uint8_t* buf, int size) { buf_start = buf, buf_size = size; }
void setLengthTransferred(int len) { transferred = len; };
void setSize(int size) { MaxPacketSize = size; }
void setType(ENDPOINT_TYPE _type) { type = _type; };
@@ -35,6 +76,8 @@
USBDeviceConnected* getDevice() { return dev; }
ENDPOINT_TYPE getType() { return type; };
int getLengthTransferred() { return transferred; }
+ uint8_t *getBufStart() { return buf_start; }
+ int getBufSize() { return buf_size; }
uint8_t getAddress(){ return address; };
int getSize() { return MaxPacketSize; }
ENDPOINT_DIRECTION getDir() { return (address & 0x80) ? IN : OUT; }
@@ -49,6 +92,12 @@
USBDeviceConnected* dev;
uint8_t data01_toggle; // DATA0,DATA1
uint8_t address;
+
int transferred;
+ uint8_t * buf_start;
+ int buf_size;
+
+ FunctionPointer rx;
+
int MaxPacketSize;
};
--- a/USBHost/USBHALHost.cpp Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHost/USBHALHost.cpp Mon Feb 03 13:00:16 2014 +0000
@@ -23,6 +23,8 @@
#define USB_TEST_ASSERT_FALSE(A) while(0)
#endif
+#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0);
+
#define BD_OWN_MASK (1<<7)
#define BD_DATA01_MASK (1<<6)
#define BD_KEEP_MASK (1<<5)
@@ -138,7 +140,15 @@
bool USBHALHost::wait_attach() {
attach_done = false;
USB0->INTEN = USB_INTEN_ATTACHEN_MASK;
- while(!attach_done);
+ Timer t;
+ t.reset();
+ t.start();
+ while(!attach_done) {
+ if (t.read_ms() > 5*1000) {
+ t.reset();
+ USB_INFO("Please attach USB device.");
+ }
+ }
wait_ms(100);
USB_TEST_ASSERT_FALSE(USB0->CTL & USB_CTL_SE0_MASK);
root_lowSpeed = (USB0->CTL & USB_CTL_JSTATE_MASK) ? false : true;
--- 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();
+}
--- a/USBHost/USBHost.h Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHost/USBHost.h Mon Feb 03 13:00:16 2014 +0000
@@ -5,7 +5,8 @@
#include "USBDeviceConnected.h"
#include "IUSBEnumerator.h"
#include "USBHostConf.h"
-#include "USBEndpoint.h"
+#include "dbg.h"
+#include "myqueue.h"
class USBHost : public USBHALHost {
public:
@@ -43,6 +44,7 @@
* @returns status of the control write
*/
USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len);
+
/**
* Bulk read
*
@@ -96,6 +98,19 @@
USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true);
/**
+ * Isochronous read
+ *
+ * @param dev the isochronous transfer will be done for this device
+ * @param ep USBEndpoint which will be used to write a packet
+ * @param buf pointer on a buffer which will be written
+ * @param len length of the transfer
+ * @param blocking if true, the read is blocking (wait for completion)
+ *
+ * @returns status of the interrupt read
+ */
+ USB_TYPE isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking = true);
+
+ /**
* Enumerate a device.
*
* @param dev device which will be enumerated
@@ -112,7 +127,7 @@
* @returns pointer on the "index" device
*/
USBDeviceConnected * getDevice(uint8_t index) {
- return (index < DeviceLists_count) ? DeviceLists[index] : NULL;
+ return DeviceLists.empty() ? NULL : DeviceLists.at(index);
}
/**
@@ -127,8 +142,13 @@
void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) {
}
- int BulkRead(USBEndpoint*ep, uint8_t* data, int size, int timeout_ms = -1);
- int IsochronousRead(USBEndpoint*ep, uint8_t* data, int size);
+ // KL46Z-USBHost extensions
+ int interruptReadNB(USBEndpoint* ep, uint8_t* data, int size);
+ int interruptWriteNB(USBEndpoint* ep, const uint8_t* data, int size);
+ int bulkReadNB(USBEndpoint*ep, uint8_t* data, int size);
+ int bulkWriteNB(USBEndpoint*ep, const uint8_t* data, int size);
+ int isochronousReadNB(USBEndpoint*ep, uint8_t* data, int size);
+ static void poll();
private:
USBHost();
@@ -136,13 +156,13 @@
virtual bool addDevice(int hub, int port, bool lowSpeed);
void root_enumeration(USBDeviceConnected* dev);
void parseConfDescr(USBDeviceConnected* dev, uint8_t* conf_descr, uint32_t len, IUSBEnumerator* pEnumerator);
- USBDeviceConnected* DeviceLists[MAX_DEVICE_CONNECTED];
- int DeviceLists_count;
+ myqueue<USBDeviceConnected*>DeviceLists;
int ControlRead(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size);
int ControlWrite(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data = NULL, int size = 0);
- int BulkWrite(USBEndpoint*ep, const uint8_t* data, int size);
- int InterruptRead(USBEndpoint*ep, uint8_t* data, int size);
+ int bulkReadBLOCK(USBEndpoint*ep, uint8_t* data, int size, int timeout_ms);
+ void task();
+ myqueue<USBEndpoint*>ep_queue;
// USB HUB
bool Hub(USBDeviceConnected* dev);
--- a/USBHost/USBHostConf.h Fri Jan 31 13:45:07 2014 +0000 +++ b/USBHost/USBHostConf.h Mon Feb 03 13:00:16 2014 +0000 @@ -64,21 +64,6 @@ #define MAX_INTF 4 /* -* Maximum number of endpoints on each interface -*/ -#define MAX_ENDPOINT_PER_INTERFACE 3 - -/* -* Maximum number of endpoint descriptors that can be allocated -*/ -#define MAX_ENDPOINT (MAX_DEVICE_CONNECTED * MAX_INTF * MAX_ENDPOINT_PER_INTERFACE) - -/* -* Maximum number of transfer descriptors that can be allocated -*/ -#define MAX_TD (MAX_ENDPOINT*2) - -/* * usb_thread stack size */ #define USB_THREAD_STACK (256*4 + MAX_HUB_NB*256*4)
--- a/USBHost/USBHostHub.cpp Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHost/USBHostHub.cpp Mon Feb 03 13:00:16 2014 +0000
@@ -1,22 +1,5 @@
#include "USBHost.h"
-#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_DBG_HEX(A,B) debug_hex(A,B)
-extern void debug_hex(uint8_t* buf, int size);
-#else
-#define USB_DBG(...) while(0)
-#define USB_DBG_HEX(A,B) 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 PORT_CONNECTION 0
#define PORT_ENABLE 1
#define PORT_SUSPEND 2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHost/dbg.h Mon Feb 03 13:00:16 2014 +0000
@@ -0,0 +1,93 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef USB_DEBUG_H
+#define USB_DEBUG_H
+
+//Debug is disabled by default
+#ifndef DEBUG
+#define DEBUG 3 /*INFO,ERR,WARN*/
+#endif
+#ifndef DEBUG2
+#define DEBUG2 0
+#endif
+#define DEBUG_TRANSFER 0
+#define DEBUG_EP_STATE 0
+#define DEBUG_EVENT 0
+
+#if (DEBUG > 3)
+#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
+//#define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#define USB_DBG_HEX(A,B) debug_hex(A,B)
+extern void debug_hex(uint8_t* buf, int size);
+#define USB_DBG_ERRSTAT() report.print_errstat();
+#else
+#define USB_DBG(x, ...)
+#define USB_DBG_HEX(A,B) while(0)
+#define USB_DBG_ERRSTAT() while(0)
+#endif
+
+#if (DEBUG2 > 3)
+#define USB_DBG2(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
+#else
+#define USB_DBG2(...) while(0);
+#endif
+
+#if (DEBUG > 2)
+#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");}while(0);
+//#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_INFO(x, ...)
+#endif
+
+#if (DEBUG > 1)
+#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_WARN(x, ...)
+#endif
+
+#if (DEBUG > 0)
+#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_ERR(x, ...)
+#endif
+
+#if (DEBUG_TRANSFER)
+#define USB_DBG_TRANSFER(x, ...) std::printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_DBG_TRANSFER(x, ...)
+#endif
+
+#if (DEBUG_EVENT)
+#define USB_DBG_EVENT(x, ...) std::printf("[USB_EVENT: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
+#else
+#define USB_DBG_EVENT(x, ...)
+#endif
+
+template <bool>struct CtAssert;
+template <>struct CtAssert<true> {};
+#define CTASSERT(A) CtAssert<A>();
+
+#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
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHost/mymap.h Mon Feb 03 13:00:16 2014 +0000
@@ -0,0 +1,53 @@
+#pragma once
+
+template<class K,class T>
+class mymap {
+ struct mypair {
+ K key;
+ T value;
+ };
+public:
+ mymap() {
+ m_size = 0;
+ m_limit = 4;
+ m_buf = new mypair[m_limit];
+ }
+ void put(K key, T value) {
+ int i = find(key);
+ if (i == (-1)) {
+ if (m_size >= m_limit) {
+ int new_limit = m_limit + 4;
+ mypair* new_buf = new mypair[new_limit];
+ for(int i = 0; i < m_size; i++) {
+ new_buf[i] = m_buf[i];
+ }
+ delete[] m_buf;
+ m_buf = new_buf;
+ m_limit = new_limit;
+ }
+ i = m_size++;
+ m_buf[i].key = key;
+ }
+ m_buf[i].value = value;
+ }
+ T get(K key) {
+ int i = find(key);
+ return (i == -1) ? NULL : m_buf[i].value;
+ }
+ bool empty() { return m_size == 0 ? true : false; }
+ int size() { return m_size; }
+ void clear() { m_size = 0; }
+
+private:
+ int find(K key) {
+ for(int i = 0; i < m_size; i++) {
+ if (m_buf[i].key == key) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ int m_limit;
+ int m_size;
+ mypair *m_buf;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHost/myqueue.h Mon Feb 03 13:00:16 2014 +0000
@@ -0,0 +1,48 @@
+#pragma once
+
+template<class T>
+class myqueue {
+public:
+ myqueue() {
+ m_w = m_r = 0;
+ m_size = 0;
+ m_limit = 4;
+ m_buf = new T[m_limit];
+ }
+ void push(T v) {
+ if (m_size >= m_limit) {
+ int new_limit = m_limit + 4;
+ T* new_buf = new T[new_limit];
+ for(int i = 0; i < m_size; i++) {
+ new_buf[i] = m_buf[i];
+ }
+ delete[] m_buf;
+ m_buf = new_buf;
+ m_limit = new_limit;
+ }
+ m_buf[m_w++] = v;
+ if (m_w >= m_limit) {
+ m_w = 0;
+ }
+ m_size++;
+ }
+ T pop() {
+ T v = m_buf[m_r++];
+ if (m_r >= m_limit) {
+ m_r = 0;
+ }
+ m_size--;
+ return v;
+ }
+ bool empty() { return (m_w == m_r) ? true : false; }
+ int size() { return m_size; }
+ void clear() { m_size = 0; }
+ T at(int i) { return m_buf[i]; }
+
+private:
+ int m_limit;
+ int m_size;
+ int m_w;
+ int m_r;
+ T *m_buf;
+};
--- a/USBHostGPS/USBHostGPS.cpp Fri Jan 31 13:45:07 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#include "USBHostGPS.h"
-
-#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)
-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)
-#endif
-
-#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))
-
-#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0);
-
-
-USBHostGPS::USBHostGPS(int baud_)
-{
- host = USBHost::getHostInst();
- init();
- baud = baud_;
-}
-
-void USBHostGPS::init() {
- dev = NULL;
- bulk_in = NULL;
- onUpdate = NULL;
- dev_connected = false;
- gps_device_found = false;
- gps_intf = -1;
-}
-
-bool USBHostGPS::connected() {
- return dev_connected;
-}
-
-bool USBHostGPS::connect() {
-
- if (dev_connected) {
- return true;
- }
-
- for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
- if ((dev = host->getDevice(i)) != NULL) {
- if(host->enumerate(dev, this)) {
- break;
- }
- if (gps_device_found) {
- bulk_in = dev->getEndpoint(gps_intf, BULK_ENDPOINT, IN);
- USB_TEST_ASSERT(bulk_in);
- // stop bit = 1, parity = none, 8bit
- uint8_t data[] = {baud&0xff, baud>>8, baud>>16, baud>>24, 0x00, 0x00, 0x08};
- USB_TYPE rc = host->controlWrite(dev, 0x21, PL2303_SET_LINE_CODING, 0, 0, data, sizeof(data));
- USB_TEST_ASSERT(rc == USB_TYPE_OK);
- USB_INFO("New GPS device: VID:%04x PID:%04x [dev: %p - intf: %d]\n", dev->getVid(), dev->getPid(), dev, gps_intf);
- dev_connected = true;
- return true;
- }
- }
- }
- init();
- return false;
-}
-
-/*virtual*/ void USBHostGPS::setVidPid(uint16_t vid, uint16_t pid)
-{
- USB_DBG("vid:%04x pid:%04x", vid, pid);
- if (pid == 0x2303) {
- gps_device_found = true;
- }
-}
-
-/*virtual*/ bool USBHostGPS::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
-{
- USB_DBG("intf: %d class: %02x %02x %02x", intf_nb, intf_class, intf_subclass, intf_protocol);
- if (gps_device_found) {
- if (gps_intf == -1) {
- gps_intf = intf_nb;
- return true;
- }
- }
- return false;
-}
-
-/*virtual*/ bool USBHostGPS::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
-{
- USB_DBG("intf_nb=%d type=%d dir=%d", intf_nb, type, dir);
- if (gps_device_found) {
- if (intf_nb == gps_intf) {
- if (type == BULK_ENDPOINT && dir == IN) {
- return true;
- }
- }
- }
- return false;
-}
-
--- a/USBHostGPS/USBHostGPS.h Fri Jan 31 13:45:07 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-// Simple USBHost GPS Dongle for FRDM-KL46Z
-#include "USBHost.h"
-
-#define PL2303_SET_LINE_CODING 0x20
-
-class USBHostGPS : public IUSBEnumerator {
-public:
-
- /**
- * Constructor
- */
- USBHostGPS(int baud = 38400);
-
- /**
- * Try to connect a USB GPS device
- *
- * @return true if connection was successful
- */
- bool connect();
-
- /**
- * Check if a USB GPS is connected
- *
- * @returns true if a mouse is connected
- */
- bool connected();
-
- int readNMEA(char* data, int size, int timeout_ms) {
- int result = host->BulkRead(bulk_in, (uint8_t*)data, size, timeout_ms);
- return (result >= 0) ? bulk_in->getLengthTransferred() : 0;
- }
- void attachEvent(void (*ptr)(uint8_t* data, int size)) {
- if (ptr != NULL) {
- onUpdate = ptr;
- }
- }
- void poll() {
- int result = host->BulkRead(bulk_in, buf, sizeof(buf), 0);
- if (result >= 0) {
- if (onUpdate) {
- (*onUpdate)(buf, bulk_in->getLengthTransferred());
- }
- }
- }
-
-protected:
- //From IUSBEnumerator
- virtual void setVidPid(uint16_t vid, uint16_t pid);
- virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
- virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
-
-private:
- USBHost * host;
- USBDeviceConnected* dev;
- USBEndpoint* bulk_in;
- bool dev_connected;
- bool gps_device_found;
- int gps_intf;
- void (*onUpdate)(uint8_t* data, int size);
- uint8_t buf[64];
- int baud;
- void init();
-};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHostHID/USBHostKeyboard.cpp Mon Feb 03 13:00:16 2014 +0000
@@ -0,0 +1,184 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "USBHostKeyboard.h"
+
+#if USBHOST_KEYBOARD
+
+static uint8_t keymap[4][0x39] = {
+ { 0, 0, 0, 0, 'a', 'b' /*0x05*/,
+ 'c', 'd', 'e', 'f', 'g' /*0x0a*/,
+ 'h', 'i', 'j', 'k', 'l'/*0x0f*/,
+ 'm', 'n', 'o', 'p', 'q'/*0x14*/,
+ 'r', 's', 't', 'u', 'v'/*0x19*/,
+ 'w', 'x', 'y', 'z', '1'/*0x1E*/,
+ '2', '3', '4', '5', '6'/*0x23*/,
+ '7', '8', '9', '0', 0x0A /*enter*/, /*0x28*/
+ 0x1B /*escape*/, 0x08 /*backspace*/, 0x09/*tab*/, 0x20/*space*/, '-', /*0x2d*/
+ '=', '[', ']', '\\', '#', /*0x32*/
+ ';', '\'', 0, ',', '.', /*0x37*/
+ '/'},
+
+ /* CTRL MODIFIER */
+ { 0, 0, 0, 0, 0, 0 /*0x05*/,
+ 0, 0, 0, 0, 0 /*0x0a*/,
+ 0, 0, 0, 0, 0/*0x0f*/,
+ 0, 0, 0, 0, 0/*0x14*/,
+ 0, 0, 0, 0, 0/*0x19*/,
+ 0, 0, 0, 0, 0/*0x1E*/,
+ 0, 0, 0, 0, 0/*0x23*/,
+ 0, 0, 0, 0, 0 /*enter*/, /*0x28*/
+ 0, 0, 0, 0, 0, /*0x2d*/
+ 0, 0, 0, 0, 0, /*0x32*/
+ 0, 0, 0, 0, 0, /*0x37*/
+ 0},
+
+ /* SHIFT MODIFIER */
+ { 0, 0, 0, 0, 'A', 'B' /*0x05*/,
+ 'C', 'D', 'E', 'F', 'G' /*0x0a*/,
+ 'H', 'I', 'J', 'K', 'L'/*0x0f*/,
+ 'M', 'N', 'O', 'P', 'Q'/*0x14*/,
+ 'R', 'S', 'T', 'U', 'V'/*0x19*/,
+ 'W', 'X', 'Y', 'Z', '!'/*0x1E*/,
+ '@', '#', '$', '%', '^'/*0x23*/,
+ '&', '*', '(', ')', 0, /*0x28*/
+ 0, 0, 0, 0, 0, /*0x2d*/
+ '+', '{', '}', '|', '~', /*0x32*/
+ ':', '"', 0, '<', '>', /*0x37*/
+ '?'},
+
+ /* ALT MODIFIER */
+ { 0, 0, 0, 0, 0, 0 /*0x05*/,
+ 0, 0, 0, 0, 0 /*0x0a*/,
+ 0, 0, 0, 0, 0/*0x0f*/,
+ 0, 0, 0, 0, 0/*0x14*/,
+ 0, 0, 0, 0, 0/*0x19*/,
+ 0, 0, 0, 0, 0/*0x1E*/,
+ 0, 0, 0, 0, 0/*0x23*/,
+ 0, 0, 0, 0, 0 /*enter*/, /*0x28*/
+ 0, 0, 0, 0, 0, /*0x2d*/
+ 0, 0, 0, 0, 0, /*0x32*/
+ 0, 0, 0, 0, 0, /*0x37*/
+ 0}
+
+};
+
+
+USBHostKeyboard::USBHostKeyboard() {
+ host = USBHost::getHostInst();
+ init();
+}
+
+
+void USBHostKeyboard::init() {
+ dev = NULL;
+ int_in = NULL;
+ report_id = 0;
+ onKey = NULL;
+ onKeyCode = NULL;
+ dev_connected = false;
+ keyboard_intf = -1;
+ keyboard_device_found = false;
+}
+
+bool USBHostKeyboard::connected() {
+ return dev_connected;
+}
+
+
+bool USBHostKeyboard::connect() {
+
+ if (dev_connected) {
+ return true;
+ }
+
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+ if ((dev = host->getDevice(i)) != NULL) {
+
+ if (host->enumerate(dev, this))
+ break;
+
+ if (keyboard_device_found) {
+ int_in = dev->getEndpoint(keyboard_intf, INTERRUPT_ENDPOINT, IN);
+
+ if (!int_in)
+ break;
+
+ USB_INFO("New Keyboard device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, keyboard_intf);
+ dev->setName("Keyboard", keyboard_intf);
+ host->registerDriver(dev, keyboard_intf, this, &USBHostKeyboard::init);
+
+ int_in->attach(this, &USBHostKeyboard::rxHandler);
+ host->interruptRead(dev, int_in, report, int_in->getSize(), false);
+
+ dev_connected = true;
+ return true;
+ }
+ }
+ }
+ init();
+ return false;
+}
+
+void USBHostKeyboard::rxHandler() {
+ int len = int_in->getLengthTransferred();
+ int index = (len == 9) ? 1 : 0;
+ int len_listen = int_in->getSize();
+ uint8_t key = 0;
+ if (len == 8 || len == 9) {
+ uint8_t modifier = (report[index] == 4) ? 3 : report[index];
+ len_listen = len;
+ key = keymap[modifier][report[index + 2]];
+ if (key && onKey) {
+ (*onKey)(key);
+ }
+ if ((report[index + 2] || modifier) && onKeyCode) {
+ (*onKeyCode)(report[index + 2], modifier);
+ }
+ }
+ if (dev && int_in)
+ host->interruptRead(dev, int_in, report, len_listen, false);
+}
+
+/*virtual*/ void USBHostKeyboard::setVidPid(uint16_t vid, uint16_t pid)
+{
+ // we don't check VID/PID for keyboard driver
+}
+
+/*virtual*/ bool USBHostKeyboard::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+ if ((keyboard_intf == -1) &&
+ (intf_class == HID_CLASS) &&
+ (intf_subclass == 0x01) &&
+ (intf_protocol == 0x01)) {
+ keyboard_intf = intf_nb;
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ bool USBHostKeyboard::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+ if (intf_nb == keyboard_intf) {
+ if (type == INTERRUPT_ENDPOINT && dir == IN) {
+ keyboard_device_found = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBHostHID/USBHostKeyboard.h Mon Feb 03 13:00:16 2014 +0000
@@ -0,0 +1,102 @@
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef USBHOSTKEYBOARD_H
+#define USBHOSTKEYBOARD_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_KEYBOARD
+
+#include "USBHost.h"
+
+/**
+ * A class to communicate a USB keyboard
+ */
+class USBHostKeyboard : public IUSBEnumerator {
+public:
+
+ /**
+ * Constructor
+ */
+ USBHostKeyboard();
+
+ /**
+ * Try to connect a keyboard device
+ *
+ * @return true if connection was successful
+ */
+ bool connect();
+
+ /**
+ * Check if a keyboard is connected
+ *
+ * @returns true if a keyboard is connected
+ */
+ bool connected();
+
+ /**
+ * Attach a callback called when a keyboard event is received
+ *
+ * @param ptr function pointer
+ */
+ inline void attach(void (*ptr)(uint8_t key)) {
+ if (ptr != NULL) {
+ onKey = ptr;
+ }
+ }
+
+ /**
+ * Attach a callback called when a keyboard event is received
+ *
+ * @param ptr function pointer
+ */
+ inline void attach(void (*ptr)(uint8_t keyCode, uint8_t modifier)) {
+ if (ptr != NULL) {
+ onKeyCode = ptr;
+ }
+ }
+
+protected:
+ //From IUSBEnumerator
+ virtual void setVidPid(uint16_t vid, uint16_t pid);
+ virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+ virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+ USBHost * host;
+ USBDeviceConnected * dev;
+ USBEndpoint * int_in;
+ uint8_t report[9];
+ int keyboard_intf;
+ bool keyboard_device_found;
+
+ bool dev_connected;
+
+ void rxHandler();
+
+ void (*onKey)(uint8_t key);
+ void (*onKeyCode)(uint8_t key, uint8_t modifier);
+
+ int report_id;
+
+ void init();
+
+};
+
+#endif
+
+#endif
--- a/USBHostHID/USBHostMouse.cpp Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHostHID/USBHostMouse.cpp Mon Feb 03 13:00:16 2014 +0000
@@ -1,175 +1,144 @@
-#include "USBHostMouse.h"
-
-#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_DBG_HEX(A,B) debug_hex(A,B)
-void debug_hex(uint8_t* buf, int size);
-#else
-#define USB_DBG(...) while(0)
-#define USB_DBG_HEX(A,B) while(0)
-#endif
-
-#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))
-
-#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0);
-
-USBHostMouse::USBHostMouse() {
- host = USBHost::getHostInst();
- init();
-}
-
-void USBHostMouse::init() {
- dev = NULL;
- int_in = NULL;
- onUpdate = NULL;
- onButtonUpdate = NULL;
- onXUpdate = NULL;
- onYUpdate = NULL;
- onZUpdate = NULL;
- report_id = 0;
- dev_connected = false;
- mouse_device_found = false;
- mouse_intf = -1;
-
- buttons = 0;
- x = 0;
- y = 0;
- z = 0;
-}
-
-bool USBHostMouse::connected() {
- return dev_connected;
-}
-
-bool USBHostMouse::connect() {
-
- if (dev_connected) {
- return true;
- }
-
- for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
- if ((dev = host->getDevice(i)) != NULL) {
-
- if(host->enumerate(dev, this))
- break;
-
- if (mouse_device_found) {
-
- int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
- USB_DBG("int_in=%p", int_in);
- if (!int_in)
- break;
-
- USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]\n", dev->getVid(), dev->getPid(), dev, mouse_intf);
- dev->setName("Mouse", mouse_intf);
- host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
-
- //int_in->attach(this, &USBHostMouse::rxHandler);
- host->interruptRead(dev, int_in, report, int_in->getSize(), false);
-
- dev_connected = true;
- return true;
- }
- }
- }
- init();
- return false;
-}
-
-/*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid)
-{
- USB_DBG("vid:%04x pid:%04x", vid, pid);
- // we don't check VID/PID for mouse driver
-}
-
-/*virtual*/ bool USBHostMouse::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
-{
- USB_DBG("intf: %d class: %02x %02x %02x", intf_nb, intf_class, intf_subclass, intf_protocol);
- if ((mouse_intf == -1) &&
- (intf_class == HID_CLASS) &&
- (intf_subclass == 0x01) &&
- (intf_protocol == 0x02)) {
- mouse_intf = intf_nb;
- return true;
- }
- return false;
-}
-
-/*virtual*/ bool USBHostMouse::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
-{
- USB_DBG("intf_nb=%d type=%d dir=%d", intf_nb, type, dir);
-
- if (intf_nb == mouse_intf) {
- if (type == INTERRUPT_ENDPOINT && dir == IN) {
- mouse_device_found = true;
- return true;
- }
- }
- return false;
-}
-
-#if 0
-void USBHostMouse::setup() {
- dev = host->getDevice(0);
- if (dev->getClass() == HUB_CLASS) {
- for(int i = 1; ; i++) {
- dev = host->getDevice(i);
- if (dev == NULL) {
- break;
- }
- if (enumeration(dev)) {
- break;
- }
- }
- USB_TEST_ASSERT(ep_int_in);
- } else {
- ep_int_in = NULL;
- }
-}
-
-bool USBHostMouse::enumeration(USBDeviceConnected* dev) {
- // config descriptor
- uint8_t desc[4];
- int rc = host->controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, desc, 4);
- USB_TEST_ASSERT(rc == USB_TYPE_OK);
- USB_DBG_HEX(desc, 4);
-
- int TotalLength = desc[2]|desc[3]<<8;
- uint8_t* buf = new uint8_t[TotalLength];
- rc = host->controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, buf, TotalLength);
- USB_TEST_ASSERT(rc == USB_TYPE_OK);
- //USB_DBG_HEX(buf, TotalLength);
- bool found = false;
- for(int i = 0; i < TotalLength; ) {
- int Length = buf[i];
- uint8_t DescriptorType = buf[i+1];
- if (DescriptorType == 0x04) { // interface
- InterfaceDescriptor* desc = reinterpret_cast<InterfaceDescriptor*>(buf+i);
- if (desc->bInterfaceClass == 0x03) {
- found = true;
- }
- } else if (DescriptorType == 0x05) { // endpoint
- EndpointDescriptor* desc = reinterpret_cast<EndpointDescriptor*>(buf+i);
- if (desc->bmAttributes == 0x03 &&
- (desc->bEndpointAddress & 0x80)) { // interrupt in
- ep_int_in = new USBEndpoint;
- ep_int_in->setDevice(dev);
- ep_int_in->setAddress(desc->bEndpointAddress);
- ep_int_in->setSize(desc->wMaxPacketSize);
- }
- }
- USB_DBG_HEX(buf+i, Length);
- i += Length;
- }
- delete[] buf;
- if (!found) {
- return false;
- }
- int config = 1;
- host->controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0);
- wait_ms(100);
- return true;
-}
-#endif
-
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "USBHostMouse.h"
+
+#if USBHOST_MOUSE
+
+USBHostMouse::USBHostMouse() {
+ host = USBHost::getHostInst();
+ init();
+}
+
+void USBHostMouse::init() {
+ dev = NULL;
+ int_in = NULL;
+ onUpdate = NULL;
+ onButtonUpdate = NULL;
+ onXUpdate = NULL;
+ onYUpdate = NULL;
+ onZUpdate = NULL;
+ report_id = 0;
+ dev_connected = false;
+ mouse_device_found = false;
+ mouse_intf = -1;
+
+ buttons = 0;
+ x = 0;
+ y = 0;
+ z = 0;
+}
+
+bool USBHostMouse::connected() {
+ return dev_connected;
+}
+
+bool USBHostMouse::connect() {
+
+ if (dev_connected) {
+ return true;
+ }
+
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+ if ((dev = host->getDevice(i)) != NULL) {
+
+ if(host->enumerate(dev, this))
+ break;
+
+ if (mouse_device_found) {
+
+ int_in = dev->getEndpoint(mouse_intf, INTERRUPT_ENDPOINT, IN);
+ if (!int_in)
+ break;
+
+ USB_INFO("New Mouse device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, mouse_intf);
+ dev->setName("Mouse", mouse_intf);
+ host->registerDriver(dev, mouse_intf, this, &USBHostMouse::init);
+
+ int_in->attach(this, &USBHostMouse::rxHandler);
+ host->interruptRead(dev, int_in, report, int_in->getSize(), false);
+
+ dev_connected = true;
+ return true;
+ }
+ }
+ }
+ init();
+ return false;
+}
+
+void USBHostMouse::rxHandler() {
+ int len_listen = int_in->getSize();
+
+ if (onUpdate) {
+ (*onUpdate)(report[0] & 0x07, report[1], report[2], report[3]);
+ }
+
+ if (onButtonUpdate && (buttons != (report[0] & 0x07))) {
+ (*onButtonUpdate)(report[0] & 0x07);
+ }
+
+ if (onXUpdate && (x != report[1])) {
+ (*onXUpdate)(report[1]);
+ }
+
+ if (onYUpdate && (y != report[2])) {
+ (*onYUpdate)(report[2]);
+ }
+
+ if (onZUpdate && (z != report[3])) {
+ (*onZUpdate)(report[3]);
+ }
+
+ // update mouse state
+ buttons = report[0] & 0x07;
+ x = report[1];
+ y = report[2];
+ z = report[3];
+
+ if (dev)
+ host->interruptRead(dev, int_in, report, len_listen, false);
+}
+
+/*virtual*/ void USBHostMouse::setVidPid(uint16_t vid, uint16_t pid)
+{
+ // we don't check VID/PID for mouse driver
+}
+
+/*virtual*/ bool USBHostMouse::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+ if ((mouse_intf == -1) &&
+ (intf_class == HID_CLASS) &&
+ (intf_subclass == 0x01) &&
+ (intf_protocol == 0x02)) {
+ mouse_intf = intf_nb;
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ bool USBHostMouse::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+ if (intf_nb == mouse_intf) {
+ if (type == INTERRUPT_ENDPOINT && dir == IN) {
+ mouse_device_found = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+#endif
--- a/USBHostHID/USBHostMouse.h Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHostHID/USBHostMouse.h Mon Feb 03 13:00:16 2014 +0000
@@ -1,88 +1,139 @@
-/* mbed USBHost Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "USBHost.h"
-
-class USBHostMouse : public IUSBEnumerator {
-public:
-
- /**
- * Constructor
- */
- USBHostMouse();
-
- /**
- * Try to connect a mouse device
- *
- * @return true if connection was successful
- */
- bool connect();
-
- /**
- * Check if a mouse is connected
- *
- * @returns true if a mouse is connected
- */
- bool connected();
-
- int readReport(uint8_t* data) {
- int rc = host->interruptRead(dev, int_in, data, 4);
- return rc == USB_TYPE_OK ? 4 : 0;
- }
- void attachEvent(void (*ptr)(uint8_t* data, int size)) {
- if (ptr != NULL) {
- onUpdate = ptr;
- }
- }
- void poll() {
- USB_TYPE rc = host->interruptRead(dev, int_in, report, sizeof(report));
- if (rc == USB_TYPE_OK) {
- if (onUpdate) {
- (*onUpdate)(report, int_in->getLengthTransferred());
- }
- }
- }
-
-protected:
- //From IUSBEnumerator
- virtual void setVidPid(uint16_t vid, uint16_t pid);
- virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
- virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
-
-private:
- USBHost * host;
- USBDeviceConnected * dev;
- USBEndpoint * int_in;
- uint8_t report[4];
-
- bool dev_connected;
- bool mouse_device_found;
- int mouse_intf;
-
- uint8_t buttons;
- int8_t x;
- int8_t y;
- int8_t z;
-
- void (*onUpdate)(uint8_t* data, int size);
- void (*onButtonUpdate)(uint8_t buttons);
- void (*onXUpdate)(int8_t x);
- void (*onYUpdate)(int8_t y);
- void (*onZUpdate)(int8_t z);
- int report_id;
- void init();
-};
-
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef USBHOSTMOUSE_H
+#define USBHOSTMOUSE_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_MOUSE
+
+#include "USBHost.h"
+
+/**
+ * A class to communicate a USB mouse
+ */
+class USBHostMouse : public IUSBEnumerator {
+public:
+
+ /**
+ * Constructor
+ */
+ USBHostMouse();
+
+ /**
+ * Try to connect a mouse device
+ *
+ * @return true if connection was successful
+ */
+ bool connect();
+
+ /**
+ * Check if a mouse is connected
+ *
+ * @returns true if a mouse is connected
+ */
+ bool connected();
+
+ /**
+ * Attach a callback called when a mouse event is received
+ *
+ * @param ptr function pointer
+ */
+ inline void attachEvent(void (*ptr)(uint8_t buttons, int8_t x, int8_t y, int8_t z)) {
+ if (ptr != NULL) {
+ onUpdate = ptr;
+ }
+ }
+
+ /**
+ * Attach a callback called when the button state changes
+ *
+ * @param ptr function pointer
+ */
+ inline void attachButtonEvent(void (*ptr)(uint8_t buttons)) {
+ if (ptr != NULL) {
+ onButtonUpdate = ptr;
+ }
+ }
+
+ /**
+ * Attach a callback called when the X axis value changes
+ *
+ * @param ptr function pointer
+ */
+ inline void attachXEvent(void (*ptr)(int8_t x)) {
+ if (ptr != NULL) {
+ onXUpdate = ptr;
+ }
+ }
+
+ /**
+ * Attach a callback called when the Y axis value changes
+ *
+ * @param ptr function pointer
+ */
+ inline void attachYEvent(void (*ptr)(int8_t y)) {
+ if (ptr != NULL) {
+ onYUpdate = ptr;
+ }
+ }
+
+ /**
+ * Attach a callback called when the Z axis value changes (scrolling)
+ *
+ * @param ptr function pointer
+ */
+ inline void attachZEvent(void (*ptr)(int8_t z)) {
+ if (ptr != NULL) {
+ onZUpdate = ptr;
+ }
+ }
+
+protected:
+ //From IUSBEnumerator
+ virtual void setVidPid(uint16_t vid, uint16_t pid);
+ virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+ virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+private:
+ USBHost * host;
+ USBDeviceConnected * dev;
+ USBEndpoint * int_in;
+ uint8_t report[4];
+
+ bool dev_connected;
+ bool mouse_device_found;
+ int mouse_intf;
+
+ uint8_t buttons;
+ int8_t x;
+ int8_t y;
+ int8_t z;
+
+ void rxHandler();
+ void (*onUpdate)(uint8_t buttons, int8_t x, int8_t y, int8_t z);
+ void (*onButtonUpdate)(uint8_t buttons);
+ void (*onXUpdate)(int8_t x);
+ void (*onYUpdate)(int8_t y);
+ void (*onZUpdate)(int8_t z);
+ int report_id;
+ void init();
+};
+
+#endif
+
+#endif
--- a/USBHostMSD/FATFileSystem.lib Fri Jan 31 13:45:07 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/FATFileSystem/#b6669c987c8e
--- a/USBHostMSD/USBHostMSD.cpp Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHostMSD/USBHostMSD.cpp Mon Feb 03 13:00:16 2014 +0000
@@ -1,352 +1,356 @@
-/* mbed USBHost Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "USBHostMSD.h"
-
-#define CBW_SIGNATURE 0x43425355
-#define CSW_SIGNATURE 0x53425355
-
-#define DEVICE_TO_HOST 0x80
-#define HOST_TO_DEVICE 0x00
-
-#define GET_MAX_LUN (0xFE)
-#define BO_MASS_STORAGE_RESET (0xFF)
-
-USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
-{
- host = USBHost::getHostInst();
- init();
-}
-
-void USBHostMSD::init() {
- dev_connected = false;
- dev = NULL;
- bulk_in = NULL;
- bulk_out = NULL;
- dev_connected = false;
- blockSize = 0;
- blockCount = 0;
- msd_intf = -1;
- msd_device_found = false;
- disk_init = false;
- dev_connected = false;
- nb_ep = 0;
-}
-
-bool USBHostMSD::connected()
-{
- return dev_connected;
-}
-
-bool USBHostMSD::connect()
-{
- if (dev_connected) {
- return true;
- }
-
- for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
- if ((dev = host->getDevice(i)) != NULL) {
-
- //USB_DBG("Trying to connect MSD device dev=%p\n", dev);
-
- if(host->enumerate(dev, this))
- break;
-
- if (msd_device_found) {
- bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
- bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
-
- if (!bulk_in || !bulk_out)
- continue;
-
- USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
- dev->setName("MSD", msd_intf);
- host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
-
- dev_connected = true;
- return true;
- }
- } //if()
- } //for()
- init();
- return false;
-}
-
-/*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid)
-{
- USB_DBG2("vid:%04x pid:%04x", vid, pid);
- // we don't check VID/PID for MSD driver
-}
-
-/*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
-{
- USB_DBG2("intf: %d class: %02x %02x %02x", intf_nb, intf_class, intf_subclass, intf_protocol);
-
- if ((msd_intf == -1) &&
- (intf_class == MSD_CLASS) &&
- (intf_subclass == 0x06) &&
- (intf_protocol == 0x50)) {
- msd_intf = intf_nb;
- return true;
- }
- return false;
-}
-
-/*virtual*/ bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
-{
- USB_DBG2("intf_nb=%d type=%d dir=%d", intf_nb, type, dir);
- if (intf_nb == msd_intf) {
- if (type == BULK_ENDPOINT) {
- nb_ep++;
- if (nb_ep == 2)
- msd_device_found = true;
- return true;
- }
- }
- return false;
-}
-
-int USBHostMSD::testUnitReady() {
- USB_DBG("Test unit ready");
- return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0);
-}
-
-
-int USBHostMSD::readCapacity() {
- USB_DBG("Read capacity");
- uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
- uint8_t result[8];
- int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8);
- if (status == 0) {
- blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
- blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
- USB_INFO("MSD blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", blockCount, blockSize, blockCount*blockSize);
- }
- return status;
-}
-
-
-int USBHostMSD::SCSIRequestSense() {
- USB_DBG("Request sense");
- uint8_t cmd[6] = {0x03,0,0,0,18,0};
- uint8_t result[18];
- int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18);
- return status;
-}
-
-
-int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) {
- USB_DBG("Inquiry");
- uint8_t evpd = (page_code == 0) ? 0 : 1;
- uint8_t cmd[6] = {0x12, (lun << 5) | evpd, page_code, 0, 36, 0};
- uint8_t result[36];
- int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36);
- if (status == 0) {
- char vid_pid[17];
- memcpy(vid_pid, &result[8], 8);
- vid_pid[8] = 0;
- USB_INFO("MSD Vendor ID: %s", vid_pid);
-
- memcpy(vid_pid, &result[16], 16);
- vid_pid[16] = 0;
- USB_INFO("MSD Product ID: %s", vid_pid);
-
- memcpy(vid_pid, &result[32], 4);
- vid_pid[4] = 0;
- USB_INFO("MSD Product rev: %s", vid_pid);
- }
- return status;
-}
-
-int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) {
- // if ep stalled: send clear feature
- if (res == USB_TYPE_STALL_ERROR) {
- res = host->controlWrite(dev,
- USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
- CLEAR_FEATURE,
- 0, ep->getAddress(), NULL, 0);
- // set state to IDLE if clear feature successful
- if (res == USB_TYPE_OK) {
- ep->setState(USB_TYPE_IDLE);
- }
- }
-
- if (res != USB_TYPE_OK)
- return -1;
-
- return 0;
-}
-
-
-int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) {
-
- int res = 0;
-
- cbw.Signature = CBW_SIGNATURE;
- cbw.Tag = 0;
- cbw.DataLength = transfer_len;
- cbw.Flags = flags;
- cbw.LUN = 0;
- cbw.CBLength = cmd_len;
- memset(cbw.CB,0,sizeof(cbw.CB));
- if (cmd) {
- memcpy(cbw.CB,cmd,cmd_len);
- }
-
- // send the cbw
- USB_DBG("Send CBW");
- res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31);
- if (checkResult(res, bulk_out))
- return -1;
-
- // data stage if needed
- if (data) {
- USB_DBG("data stage");
- if (flags == HOST_TO_DEVICE) {
-
- res = host->bulkWrite(dev, bulk_out, data, transfer_len);
- if (checkResult(res, bulk_out))
- return -1;
-
- } else if (flags == DEVICE_TO_HOST) {
-
- res = host->bulkRead(dev, bulk_in, data, transfer_len);
- if (checkResult(res, bulk_in))
- return -1;
- }
- }
-
- // status stage
- csw.Signature = 0;
- USB_DBG("Read CSW");
- res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13);
- if (checkResult(res, bulk_in))
- return -1;
-
- if (csw.Signature != CSW_SIGNATURE) {
- return -1;
- }
-
- USB_DBG("recv csw: status: %d", csw.Status);
-
- // ModeSense?
- if ((csw.Status == 1) && (cmd[0] != 0x03)) {
- USB_DBG("request mode sense");
- return SCSIRequestSense();
- }
-
- // perform reset recovery
- if ((csw.Status == 2) && (cmd[0] != 0x03)) {
-
- // send Bulk-Only Mass Storage Reset request
- res = host->controlWrite( dev,
- USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
- BO_MASS_STORAGE_RESET,
- 0, msd_intf, NULL, 0);
-
- // unstall both endpoints
- res = host->controlWrite( dev,
- USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
- CLEAR_FEATURE,
- 0, bulk_in->getAddress(), NULL, 0);
-
- res = host->controlWrite( dev,
- USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
- CLEAR_FEATURE,
- 0, bulk_out->getAddress(), NULL, 0);
-
- }
-
- return csw.Status;
-}
-
-
-int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) {
- uint8_t cmd[10];
- memset(cmd,0,10);
- cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
-
- cmd[2] = (block >> 24) & 0xff;
- cmd[3] = (block >> 16) & 0xff;
- cmd[4] = (block >> 8) & 0xff;
- cmd[5] = block & 0xff;
-
- cmd[7] = (nbBlock >> 8) & 0xff;
- cmd[8] = nbBlock & 0xff;
-
- return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock);
-}
-
-int USBHostMSD::getMaxLun() {
- uint8_t buf[1], res;
- res = host->controlRead( dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
- 0xfe, 0, msd_intf, buf, 1);
- USB_DBG("max lun: %d", buf[0]);
- return res;
-}
-
-int USBHostMSD::disk_initialize() {
- USB_DBG("FILESYSTEM: init");
- int i, timeout = 10;
-
- //getMaxLun();
-
- for (i = 0; i < timeout; i++) {
- wait_ms(100);
- if (!testUnitReady())
- break;
- }
-
- if (i == timeout) {
- disk_init = false;
- return -1;
- }
-
- inquiry(0, 0);
- disk_init = 1;
- return readCapacity();
-}
-
-int USBHostMSD::disk_write(const uint8_t *buffer, uint64_t block_number) {
- USB_DBG("FILESYSTEM: write block: %lld", block_number);
- if (!disk_init) {
- disk_initialize();
- }
- if (!disk_init)
- return -1;
- return dataTransfer((uint8_t *)buffer, block_number, 1, HOST_TO_DEVICE);
-}
-
-int USBHostMSD::disk_read(uint8_t * buffer, uint64_t block_number) {
- USB_DBG("FILESYSTEM: read block %lld", block_number);
- if (!disk_init) {
- disk_initialize();
- }
- if (!disk_init)
- return -1;
- return dataTransfer((uint8_t *)buffer, block_number, 1, DEVICE_TO_HOST);
-}
-
-uint64_t USBHostMSD::disk_sectors() {
- USB_DBG("FILESYSTEM: sectors");
- if (!disk_init) {
- disk_initialize();
- }
- if (!disk_init)
- return 0;
- return blockCount;
-}
-
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "USBHostMSD.h"
+
+#if USBHOST_MSD
+
+#include "dbg.h"
+
+#define CBW_SIGNATURE 0x43425355
+#define CSW_SIGNATURE 0x53425355
+
+#define DEVICE_TO_HOST 0x80
+#define HOST_TO_DEVICE 0x00
+
+#define GET_MAX_LUN (0xFE)
+#define BO_MASS_STORAGE_RESET (0xFF)
+
+USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir)
+{
+ host = USBHost::getHostInst();
+ init();
+}
+
+void USBHostMSD::init() {
+ dev_connected = false;
+ dev = NULL;
+ bulk_in = NULL;
+ bulk_out = NULL;
+ dev_connected = false;
+ blockSize = 0;
+ blockCount = 0;
+ msd_intf = -1;
+ msd_device_found = false;
+ disk_init = false;
+ dev_connected = false;
+ nb_ep = 0;
+}
+
+
+bool USBHostMSD::connected()
+{
+ return dev_connected;
+}
+
+bool USBHostMSD::connect()
+{
+
+ if (dev_connected) {
+ return true;
+ }
+
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
+ if ((dev = host->getDevice(i)) != NULL) {
+
+ USB_DBG("Trying to connect MSD device\r\n");
+
+ if(host->enumerate(dev, this))
+ break;
+
+ if (msd_device_found) {
+ bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN);
+ bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT);
+
+ if (!bulk_in || !bulk_out)
+ continue;
+
+ USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf);
+ dev->setName("MSD", msd_intf);
+ host->registerDriver(dev, msd_intf, this, &USBHostMSD::init);
+
+ dev_connected = true;
+ return true;
+ }
+ } //if()
+ } //for()
+ init();
+ return false;
+}
+
+/*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid)
+{
+ // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
+{
+ if ((msd_intf == -1) &&
+ (intf_class == MSD_CLASS) &&
+ (intf_subclass == 0x06) &&
+ (intf_protocol == 0x50)) {
+ msd_intf = intf_nb;
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+ if (intf_nb == msd_intf) {
+ if (type == BULK_ENDPOINT) {
+ nb_ep++;
+ if (nb_ep == 2)
+ msd_device_found = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+int USBHostMSD::testUnitReady() {
+ USB_DBG("Test unit ready");
+ return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0);
+}
+
+
+int USBHostMSD::readCapacity() {
+ USB_DBG("Read capacity");
+ uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0};
+ uint8_t result[8];
+ int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8);
+ if (status == 0) {
+ blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3];
+ blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7];
+ USB_INFO("MSD [dev: %p] - blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", dev, blockCount, blockSize, blockCount*blockSize);
+ }
+ return status;
+}
+
+
+int USBHostMSD::SCSIRequestSense() {
+ USB_DBG("Request sense");
+ uint8_t cmd[6] = {0x03,0,0,0,18,0};
+ uint8_t result[18];
+ int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18);
+ return status;
+}
+
+
+int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) {
+ USB_DBG("Inquiry");
+ uint8_t evpd = (page_code == 0) ? 0 : 1;
+ uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0};
+ uint8_t result[36];
+ int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36);
+ if (status == 0) {
+ char vid_pid[17];
+ memcpy(vid_pid, &result[8], 8);
+ vid_pid[8] = 0;
+ USB_INFO("MSD [dev: %p] - Vendor ID: %s", dev, vid_pid);
+
+ memcpy(vid_pid, &result[16], 16);
+ vid_pid[16] = 0;
+ USB_INFO("MSD [dev: %p] - Product ID: %s", dev, vid_pid);
+
+ memcpy(vid_pid, &result[32], 4);
+ vid_pid[4] = 0;
+ USB_INFO("MSD [dev: %p] - Product rev: %s", dev, vid_pid);
+ }
+ return status;
+}
+
+int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) {
+ // if ep stalled: send clear feature
+ if (res == USB_TYPE_STALL_ERROR) {
+ res = host->controlWrite( dev,
+ USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
+ CLEAR_FEATURE,
+ 0, ep->getAddress(), NULL, 0);
+ // set state to IDLE if clear feature successful
+ if (res == USB_TYPE_OK) {
+ ep->setState(USB_TYPE_IDLE);
+ }
+ }
+
+ if (res != USB_TYPE_OK)
+ return -1;
+
+ return 0;
+}
+
+
+int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) {
+
+ int res = 0;
+
+ cbw.Signature = CBW_SIGNATURE;
+ cbw.Tag = 0;
+ cbw.DataLength = transfer_len;
+ cbw.Flags = flags;
+ cbw.LUN = 0;
+ cbw.CBLength = cmd_len;
+ memset(cbw.CB,0,sizeof(cbw.CB));
+ if (cmd) {
+ memcpy(cbw.CB,cmd,cmd_len);
+ }
+
+ // send the cbw
+ USB_DBG("Send CBW");
+ res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31);
+ if (checkResult(res, bulk_out))
+ return -1;
+
+ // data stage if needed
+ if (data) {
+ USB_DBG("data stage");
+ if (flags == HOST_TO_DEVICE) {
+
+ res = host->bulkWrite(dev, bulk_out, data, transfer_len);
+ if (checkResult(res, bulk_out))
+ return -1;
+
+ } else if (flags == DEVICE_TO_HOST) {
+
+ res = host->bulkRead(dev, bulk_in, data, transfer_len);
+ if (checkResult(res, bulk_in))
+ return -1;
+ }
+ }
+
+ // status stage
+ csw.Signature = 0;
+ USB_DBG("Read CSW");
+ res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13);
+ if (checkResult(res, bulk_in))
+ return -1;
+
+ if (csw.Signature != CSW_SIGNATURE) {
+ return -1;
+ }
+
+ USB_DBG("recv csw: status: %d", csw.Status);
+
+ // ModeSense?
+ if ((csw.Status == 1) && (cmd[0] != 0x03)) {
+ USB_DBG("request mode sense");
+ return SCSIRequestSense();
+ }
+
+ // perform reset recovery
+ if ((csw.Status == 2) && (cmd[0] != 0x03)) {
+
+ // send Bulk-Only Mass Storage Reset request
+ res = host->controlWrite( dev,
+ USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
+ BO_MASS_STORAGE_RESET,
+ 0, msd_intf, NULL, 0);
+
+ // unstall both endpoints
+ res = host->controlWrite( dev,
+ USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
+ CLEAR_FEATURE,
+ 0, bulk_in->getAddress(), NULL, 0);
+
+ res = host->controlWrite( dev,
+ USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD,
+ CLEAR_FEATURE,
+ 0, bulk_out->getAddress(), NULL, 0);
+
+ }
+
+ return csw.Status;
+}
+
+
+int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) {
+ uint8_t cmd[10];
+ memset(cmd,0,10);
+ cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A;
+
+ cmd[2] = (block >> 24) & 0xff;
+ cmd[3] = (block >> 16) & 0xff;
+ cmd[4] = (block >> 8) & 0xff;
+ cmd[5] = block & 0xff;
+
+ cmd[7] = (nbBlock >> 8) & 0xff;
+ cmd[8] = nbBlock & 0xff;
+
+ return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock);
+}
+
+int USBHostMSD::getMaxLun() {
+ uint8_t buf[1], res;
+ res = host->controlRead( dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
+ 0xfe, 0, msd_intf, buf, 1);
+ USB_DBG("max lun: %d", buf[0]);
+ return res;
+}
+
+int USBHostMSD::disk_initialize() {
+ USB_DBG("FILESYSTEM: init");
+ /* U16 */int i, timeout = 10;
+
+ getMaxLun();
+
+ for (i = 0; i < timeout; i++) {
+ wait_ms(100); //Thread::wait(100);
+ if (!testUnitReady())
+ break;
+ }
+
+ if (i == timeout) {
+ disk_init = false;
+ return -1;
+ }
+
+ inquiry(0, 0);
+ disk_init = 1;
+ return readCapacity();
+}
+
+int USBHostMSD::disk_write(const uint8_t *buffer, uint64_t block_number) {
+ USB_DBG("FILESYSTEM: write block: %lld", block_number);
+ if (!disk_init) {
+ disk_initialize();
+ }
+ if (!disk_init)
+ return -1;
+ return dataTransfer((uint8_t *)buffer, block_number, 1, HOST_TO_DEVICE);
+}
+
+int USBHostMSD::disk_read(uint8_t * buffer, uint64_t block_number) {
+ USB_DBG("FILESYSTEM: read block %lld", block_number);
+ if (!disk_init) {
+ disk_initialize();
+ }
+ if (!disk_init)
+ return -1;
+ return dataTransfer((uint8_t *)buffer, block_number, 1, DEVICE_TO_HOST);
+}
+
+uint64_t USBHostMSD::disk_sectors() {
+ USB_DBG("FILESYSTEM: sectors");
+ if (!disk_init) {
+ disk_initialize();
+ }
+ if (!disk_init)
+ return 0;
+ return blockCount;
+}
+
+#endif
--- a/USBHostMSD/USBHostMSD.h Fri Jan 31 13:45:07 2014 +0000
+++ b/USBHostMSD/USBHostMSD.h Mon Feb 03 13:00:16 2014 +0000
@@ -1,131 +1,119 @@
-/* mbed USBHost Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef USBHOSTMSD_H
-#define USBHOSTMSD_H
-
-#if _USB_DBG
-#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
-#else
-#define USB_DBG(...) while(0);
-#endif
-
-#if 0
-#define USB_DBG2(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
-#else
-#define USB_DBG2(...) while(0);
-#endif
-
-#if 1
-#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");}while(0);
-#else
-#define USB_INFO(...) while(0);
-#endif
-
-#include "USBHostConf.h"
-#include "USBHost.h"
-#include "FATFileSystem.h"
-
-/**
- * A class to communicate a USB flash disk
- */
-class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
-public:
- /**
- * Constructor
- *
- * @param rootdir mount name
- */
- USBHostMSD(const char * rootdir);
-
- /**
- * Check if a MSD device is connected
- *
- * @return true if a MSD device is connected
- */
- bool connected();
-
- /**
- * Try to connect to a MSD device
- *
- * @return true if connection was successful
- */
- bool connect();
-
-protected:
- //From IUSBEnumerator
- virtual void setVidPid(uint16_t vid, uint16_t pid);
- virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
- virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
-
- // From FATFileSystem
- virtual int disk_initialize();
- virtual int disk_status() {return 0;};
- virtual int disk_read(uint8_t * buffer, uint64_t sector);
- virtual int disk_write(const uint8_t * buffer, uint64_t sector);
- virtual int disk_sync() {return 0;};
- virtual uint64_t disk_sectors();
-
-private:
- USBHost * host;
- USBDeviceConnected * dev;
- bool dev_connected;
- USBEndpoint * bulk_in;
- USBEndpoint * bulk_out;
- uint8_t nb_ep;
-
- // Bulk-only CBW
- typedef __packed struct {
- uint32_t Signature;
- uint32_t Tag;
- uint32_t DataLength;
- uint8_t Flags;
- uint8_t LUN;
- uint8_t CBLength;
- uint8_t CB[16];
- } CBW;
-
- // Bulk-only CSW
- typedef __packed struct {
- uint32_t Signature;
- uint32_t Tag;
- uint32_t DataResidue;
- uint8_t Status;
- } CSW;
-
- CBW cbw;
- CSW csw;
-
- int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len);
- int testUnitReady();
- int readCapacity();
- int inquiry(uint8_t lun, uint8_t page_code);
- int SCSIRequestSense();
- int dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction);
- int checkResult(uint8_t res, USBEndpoint * ep);
- int getMaxLun();
-
- int blockSize;
- uint64_t blockCount;
-
- int msd_intf;
- bool msd_device_found;
- bool disk_init;
-
- void init();
-};
-
-#endif
+/* mbed USBHost Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef USBHOSTMSD_H
+#define USBHOSTMSD_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_MSD
+
+#include "USBHost.h"
+#include "FATFileSystem.h"
+
+/**
+ * A class to communicate a USB flash disk
+ */
+class USBHostMSD : public IUSBEnumerator, public FATFileSystem {
+public:
+ /**
+ * Constructor
+ *
+ * @param rootdir mount name
+ */
+ USBHostMSD(const char * rootdir);
+
+ /**
+ * Check if a MSD device is connected
+ *
+ * @return true if a MSD device is connected
+ */
+ bool connected();
+
+ /**
+ * Try to connect to a MSD device
+ *
+ * @return true if connection was successful
+ */
+ bool connect();
+
+protected:
+ //From IUSBEnumerator
+ virtual void setVidPid(uint16_t vid, uint16_t pid);
+ virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
+ virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used
+
+ // From FATFileSystem
+ virtual int disk_initialize();
+ virtual int disk_status() {return 0;};
+ virtual int disk_read(uint8_t * buffer, uint64_t sector);
+ virtual int disk_write(const uint8_t * buffer, uint64_t sector);
+ virtual int disk_sync() {return 0;};
+ virtual uint64_t disk_sectors();
+
+private:
+ USBHost * host;
+ USBDeviceConnected * dev;
+ bool dev_connected;
+ USBEndpoint * bulk_in;
+ USBEndpoint * bulk_out;
+ uint8_t nb_ep;
+
+ // Bulk-only CBW
+ typedef struct {
+ uint32_t Signature;
+ uint32_t Tag;
+ uint32_t DataLength;
+ uint8_t Flags;
+ uint8_t LUN;
+ uint8_t CBLength;
+ uint8_t CB[16];
+ } PACKED CBW;
+
+ // Bulk-only CSW
+ typedef struct {
+ uint32_t Signature;
+ uint32_t Tag;
+ uint32_t DataResidue;
+ uint8_t Status;
+ } PACKED CSW;
+
+ CBW cbw;
+ CSW csw;
+
+ int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len);
+ int testUnitReady();
+ int readCapacity();
+ int inquiry(uint8_t lun, uint8_t page_code);
+ int SCSIRequestSense();
+ int dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction);
+ int checkResult(uint8_t res, USBEndpoint * ep);
+ int getMaxLun();
+
+ int blockSize;
+ uint64_t blockCount;
+
+ int msd_intf;
+ bool msd_device_found;
+ bool disk_init;
+
+ void init();
+
+};
+
+#endif
+
+#endif
