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
Fork of USBHost by
Revision 19:bd46ea19486b, committed 2013-12-16
- Comitter:
- mbed_official
- Date:
- Mon Dec 16 09:00:18 2013 +0000
- Parent:
- 18:37c948cf0dbf
- Child:
- 20:8f510a2502ef
- Commit message:
- Synchronized with git revision 170ac6562b7b2b5bb43f8ecf82b2af18b37eeb9c
Full URL: https://github.com/mbedmicro/mbed/commit/170ac6562b7b2b5bb43f8ecf82b2af18b37eeb9c/
improve USB host library and cellular modem stack
Changed in this revision
--- a/USBHost/USBHostConf.h Thu Oct 17 10:15:19 2013 +0100 +++ b/USBHost/USBHostConf.h Mon Dec 16 09:00:18 2013 +0000 @@ -49,7 +49,7 @@ #define USBHOST_MOUSE 1 /* -* Enable USBHostSerial +* Enable USBHostSerial or USBHostMultiSerial (if set > 1) */ #define USBHOST_SERIAL 1
--- a/USBHost/dbg.h Thu Oct 17 10:15:19 2013 +0100
+++ b/USBHost/dbg.h Mon Dec 16 09:00:18 2013 +0000
@@ -18,17 +18,35 @@
#define USB_DEBUG_H
//Debug is disabled by default
-#define DEBUG 0
+#define DEBUG 3 /*INFO,ERR,WARN*/
#define DEBUG_TRANSFER 0
#define DEBUG_EP_STATE 0
#define DEBUG_EVENT 0
-#if (DEBUG)
+#if (DEBUG > 3)
#define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#else
#define USB_DBG(x, ...)
#endif
+#if (DEBUG > 2)
+#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
@@ -41,9 +59,6 @@
#define USB_DBG_EVENT(x, ...)
#endif
-#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
-#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
-#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__);
#endif
--- a/USBHostSerial/USBHostSerial.cpp Thu Oct 17 10:15:19 2013 +0100
+++ b/USBHostSerial/USBHostSerial.cpp Mon Dec 16 09:00:18 2013 +0000
@@ -20,27 +20,17 @@
#include "dbg.h"
-#define SET_LINE_CODING 0x20
+#define CHECK_INTERFACE(cls,subcls,proto) \
+ (((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \
+ ((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ )
-USBHostSerial::USBHostSerial(): circ_buf() {
- host = USBHost::getHostInst();
- size_bulk_in = 0;
- size_bulk_out = 0;
- init();
-}
+#if (USBHOST_SERIAL <= 1)
-void USBHostSerial::init() {
- dev = NULL;
- bulk_in = NULL;
- bulk_out = NULL;
+USBHostSerial::USBHostSerial()
+{
+ host = USBHost::getHostInst();
+ ports_found = 0;
dev_connected = false;
- serial_intf = -1;
- serial_device_found = false;
- line_coding.baudrate = 9600;
- line_coding.data_bits = 8;
- line_coding.parity = None;
- line_coding.stop_bits = 1;
- circ_buf.flush();
}
bool USBHostSerial::connected()
@@ -48,49 +38,219 @@
return dev_connected;
}
+void USBHostSerial::disconnect(void)
+{
+ ports_found = 0;
+ dev = NULL;
+}
+
bool USBHostSerial::connect() {
- if (dev_connected) {
- return true;
+ if (dev)
+ {
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+ {
+ USBDeviceConnected* d = host->getDevice(i);
+ if (dev == d)
+ return true;
+ }
+ disconnect();
}
- for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
- if ((dev = host->getDevice(i)) != NULL) {
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+ {
+ USBDeviceConnected* d = host->getDevice(i);
+ if (d != NULL) {
- USB_DBG("Trying to connect serial device\r\n");
-
- if(host->enumerate(dev, this))
+ USB_DBG("Trying to connect serial device \r\n");
+ if(host->enumerate(d, this))
break;
- if (serial_device_found) {
- bulk_in = dev->getEndpoint(serial_intf, BULK_ENDPOINT, IN);
- bulk_out = dev->getEndpoint(serial_intf, BULK_ENDPOINT, OUT);
-
- if (!bulk_in || !bulk_out)
- break;
-
- USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
- dev->setName("Serial", serial_intf);
- host->registerDriver(dev, serial_intf, this, &USBHostSerial::init);
-
- baud(9600);
-
- size_bulk_in = bulk_in->getSize();
- size_bulk_out = bulk_out->getSize();
-
- bulk_in->attach(this, &USBHostSerial::rxHandler);
- bulk_out->attach(this, &USBHostSerial::txHandler);
-
- host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
- dev_connected = true;
- return true;
+ USBEndpoint* bulk_in = d->getEndpoint(port_intf, BULK_ENDPOINT, IN);
+ USBEndpoint* bulk_out = d->getEndpoint(port_intf, BULK_ENDPOINT, OUT);
+ if (bulk_in && bulk_out)
+ {
+ USBHostSerialPort::connect(host,d,port_intf,bulk_in, bulk_out);
+ dev = d;
}
}
}
- init();
+ return dev != NULL;
+}
+
+/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid)
+{
+ // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostSerial::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 ((ports_found < USBHOST_MAXSERIAL) &&
+ CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
+ port_intf = intf_nb;
+ ports_found = true;
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+ if (ports_found && (intf_nb == port_intf)) {
+ if (type == BULK_ENDPOINT)
+ return true;
+ }
return false;
}
-void USBHostSerial::rxHandler() {
+#else // (USBHOST_SERIAL > 1)
+
+//------------------------------------------------------------------------------
+
+USBHostMultiSerial::USBHostMultiSerial()
+{
+ host = USBHost::getHostInst();
+ dev = NULL;
+ memset(ports, NULL, sizeof(ports));
+ ports_found = 0;
+ dev_connected = false;
+}
+
+USBHostMultiSerial::~USBHostMultiSerial()
+{
+ disconnect();
+}
+
+bool USBHostMultiSerial::connected()
+{
+ return dev_connected;
+}
+
+void USBHostMultiSerial::disconnect(void)
+{
+ for (int port = 0; port < USBHOST_SERIAL; port ++)
+ {
+ if (ports[port])
+ {
+ delete ports[port];
+ ports[port] = NULL;
+ }
+ }
+ ports_found = 0;
+ dev = NULL;
+}
+
+bool USBHostMultiSerial::connect() {
+
+ if (dev)
+ {
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+ {
+ USBDeviceConnected* d = host->getDevice(i);
+ if (dev == d)
+ return true;
+ }
+ disconnect();
+ }
+ for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++)
+ {
+ USBDeviceConnected* d = host->getDevice(i);
+ if (d != NULL) {
+
+ USB_DBG("Trying to connect serial device \r\n");
+ if(host->enumerate(d, this))
+ break;
+
+ for (int port = 0; port < ports_found; port ++)
+ {
+ USBEndpoint* bulk_in = d->getEndpoint(port_intf[port], BULK_ENDPOINT, IN);
+ USBEndpoint* bulk_out = d->getEndpoint(port_intf[port], BULK_ENDPOINT, OUT);
+ if (bulk_in && bulk_out)
+ {
+ ports[port] = new USBHostSerialPort();
+ if (ports[port])
+ {
+ ports[port]->connect(host,d,port_intf[port],bulk_in, bulk_out);
+ dev = d;
+ }
+ }
+ }
+ }
+ }
+ return dev != NULL;
+}
+
+/*virtual*/ void USBHostMultiSerial::setVidPid(uint16_t vid, uint16_t pid)
+{
+ // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USBHostMultiSerial::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 ((ports_found < USBHOST_SERIAL) &&
+ CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
+ port_intf[ports_found++] = intf_nb;
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ bool USBHostMultiSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
+{
+ if ((ports_found > 0) && (intf_nb == port_intf[ports_found-1])) {
+ if (type == BULK_ENDPOINT)
+ return true;
+ }
+ return false;
+}
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#define SET_LINE_CODING 0x20
+
+USBHostSerialPort::USBHostSerialPort(): circ_buf()
+{
+ init();
+}
+
+void USBHostSerialPort::init(void)
+{
+ host = NULL;
+ dev = NULL;
+ serial_intf = NULL;
+ size_bulk_in = 0;
+ size_bulk_out = 0;
+ bulk_in = NULL;
+ bulk_out = NULL;
+ line_coding.baudrate = 9600;
+ line_coding.data_bits = 8;
+ line_coding.parity = None;
+ line_coding.stop_bits = 1;
+ circ_buf.flush();
+}
+
+void USBHostSerialPort::connect(USBHost* _host, USBDeviceConnected * _dev,
+ uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out)
+{
+ host = _host;
+ dev = _dev;
+ serial_intf = _serial_intf;
+ bulk_in = _bulk_in;
+ bulk_out = _bulk_out;
+
+ USB_INFO("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, serial_intf);
+ dev->setName("Serial", serial_intf);
+ host->registerDriver(dev, serial_intf, this, &USBHostSerialPort::init);
+ //baud(9600);
+ size_bulk_in = bulk_in->getSize();
+ size_bulk_out = bulk_out->getSize();
+ bulk_in->attach(this, &USBHostSerialPort::rxHandler);
+ bulk_out->attach(this, &USBHostSerialPort::txHandler);
+ host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+}
+
+void USBHostSerialPort::rxHandler() {
if (bulk_in) {
int len = bulk_in->getLengthTransferred();
if (bulk_in->getState() == USB_TYPE_IDLE) {
@@ -103,7 +263,7 @@
}
}
-void USBHostSerial::txHandler() {
+void USBHostSerialPort::txHandler() {
if (bulk_out) {
if (bulk_out->getState() == USB_TYPE_IDLE) {
tx.call();
@@ -111,7 +271,7 @@
}
}
-int USBHostSerial::_putc(int c) {
+int USBHostSerialPort::_putc(int c) {
if (bulk_out) {
if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) {
return 1;
@@ -120,12 +280,12 @@
return -1;
}
-void USBHostSerial::baud(int baudrate) {
+void USBHostSerialPort::baud(int baudrate) {
line_coding.baudrate = baudrate;
format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits);
}
-void USBHostSerial::format(int bits, Parity parity, int stop_bits) {
+void USBHostSerialPort::format(int bits, Parity parity, int stop_bits) {
line_coding.data_bits = bits;
line_coding.parity = parity;
line_coding.stop_bits = (stop_bits == 1) ? 0 : 2;
@@ -137,7 +297,7 @@
0, serial_intf, (uint8_t *)&line_coding, 7);
}
-int USBHostSerial::_getc() {
+int USBHostSerialPort::_getc() {
uint8_t c = 0;
if (bulk_in == NULL) {
init();
@@ -148,37 +308,36 @@
return c;
}
+int USBHostSerialPort::writeBuf(const char* b, int s)
+{
+ int c = 0;
+ if (bulk_out)
+ {
+ while (c < s)
+ {
+ int i = (s < size_bulk_out) ? s : size_bulk_out;
+ if (host->bulkWrite(dev, bulk_out, (uint8_t *)(b+c), i) == USB_TYPE_OK)
+ c += i;
+ }
+ }
+ return s;
+}
-uint8_t USBHostSerial::available() {
+int USBHostSerialPort::readBuf(char* b, int s)
+{
+ int i = 0;
+ if (bulk_in)
+ {
+ for (i = 0; i < s; )
+ b[i++] = getc();
+ }
+ return i;
+}
+
+uint8_t USBHostSerialPort::available() {
return circ_buf.available();
}
-/*virtual*/ void USBHostSerial::setVidPid(uint16_t vid, uint16_t pid)
-{
- // we don't check VID/PID for MSD driver
-}
-/*virtual*/ bool USBHostSerial::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 ((serial_intf == -1) &&
- (intf_class == SERIAL_CLASS) &&
- (intf_subclass == 0x00) &&
- (intf_protocol == 0x00)) {
- serial_intf = intf_nb;
- return true;
- }
- return false;
-}
-
-/*virtual*/ bool USBHostSerial::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
-{
- if (intf_nb == serial_intf) {
- if (type == BULK_ENDPOINT) {
- serial_device_found = true;
- return true;
- }
- }
- return false;
-}
#endif
--- a/USBHostSerial/USBHostSerial.h Thu Oct 17 10:15:19 2013 +0100
+++ b/USBHostSerial/USBHostSerial.h Mon Dec 16 09:00:18 2013 +0000
@@ -28,12 +28,12 @@
/**
* A class to communicate a USB virtual serial port
*/
-class USBHostSerial : public IUSBEnumerator, public Stream {
+class USBHostSerialPort : public Stream {
public:
/**
* Constructor
*/
- USBHostSerial();
+ USBHostSerialPort();
enum IrqType {
RxIrq,
@@ -48,20 +48,9 @@
Space
};
- /**
- * Check if a virtual serial port is connected
- *
- * @returns true if a serial device is connected
- */
- bool connected();
-
- /**
- * Try to connect a serial device
- *
- * @return true if connection was successful
- */
- bool connect();
-
+ void connect(USBHost* _host, USBDeviceConnected * _dev,
+ uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out);
+
/**
* Check the number of bytes available.
*
@@ -111,34 +100,29 @@
/** Set the transmission format used by the Serial port
*
* @param bits The number of bits in a word (default = 8)
- * @param parity The parity used (USBHostSerial::None, USBHostSerial::Odd, USBHostSerial::Even, USBHostSerial::Mark, USBHostSerial::Space; default = USBHostSerial::None)
+ * @param parity The parity used (USBHostSerialPort::None, USBHostSerialPort::Odd, USBHostSerialPort::Even, USBHostSerialPort::Mark, USBHostSerialPort::Space; default = USBHostSerialPort::None)
* @param stop The number of stop bits (1 or 2; default = 1)
*/
- void format(int bits = 8, Parity parity = USBHostSerial::None, int stop_bits = 1);
-
+ void format(int bits = 8, Parity parity = USBHostSerialPort::None, int stop_bits = 1);
+ virtual int writeBuf(const char* b, int s);
+ virtual int readBuf(char* b, int s);
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
-
virtual int _getc();
virtual int _putc(int c);
private:
USBHost * host;
USBDeviceConnected * dev;
+
USBEndpoint * bulk_in;
USBEndpoint * bulk_out;
uint32_t size_bulk_in;
uint32_t size_bulk_out;
- bool dev_connected;
-
void init();
- MtxCircBuffer<uint8_t, 64> circ_buf;
+ MtxCircBuffer<uint8_t, 128> circ_buf;
uint8_t buf[64];
@@ -156,10 +140,91 @@
FunctionPointer rx;
FunctionPointer tx;
- int serial_intf;
- bool serial_device_found;
+ uint8_t serial_intf;
+};
+
+#if (USBHOST_SERIAL <= 1)
+
+class USBHostSerial : public IUSBEnumerator, public USBHostSerialPort
+{
+public:
+ USBHostSerial();
+
+ /**
+ * Try to connect a serial device
+ *
+ * @return true if connection was successful
+ */
+ bool connect();
+
+ void disconnect();
+
+ /**
+ * Check if a any serial port is connected
+ *
+ * @returns true if a serial device is connected
+ */
+ bool connected();
+
+protected:
+ USBHost* host;
+ USBDeviceConnected* dev;
+ uint8_t port_intf;
+ int ports_found;
+
+ //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:
+ bool dev_connected;
+};
+
+#else // (USBHOST_SERIAL > 1)
+class USBHostMultiSerial : public IUSBEnumerator {
+public:
+ USBHostMultiSerial();
+ virtual ~USBHostMultiSerial();
+
+ USBHostSerialPort* getPort(int port)
+ {
+ return port < USBHOST_SERIAL ? ports[port] : NULL;
+ }
+
+ /**
+ * Try to connect a serial device
+ *
+ * @return true if connection was successful
+ */
+ bool connect();
+
+ void disconnect();
+
+ /**
+ * Check if a any serial port is connected
+ *
+ * @returns true if a serial device is connected
+ */
+ bool connected();
+
+protected:
+ USBHost* host;
+ USBDeviceConnected* dev;
+ USBHostSerialPort* ports[USBHOST_SERIAL];
+ uint8_t port_intf[USBHOST_SERIAL];
+ int ports_found;
+
+ //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:
+ bool dev_connected;
};
+#endif // (USBHOST_SERIAL <= 1)
#endif
