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: USB400Serial_Hello MFT_IoT_demo_USB400 USB400J_app_board_demo
Revision 0:0dd5d1e4cf71, committed 2014-12-03
- Comitter:
- nanashino
- Date:
- Wed Dec 03 06:18:10 2014 +0000
- Commit message:
- initial version
Changed in this revision
| USB400Serial.cpp | Show annotated file Show diff for this revision Revisions of this file |
| USB400Serial.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 0dd5d1e4cf71 USB400Serial.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USB400Serial.cpp Wed Dec 03 06:18:10 2014 +0000
@@ -0,0 +1,262 @@
+/* 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.
+ */
+
+/* USB400Serial Library
+ * Modified mujirushi.org
+ */
+
+#include "USB400Serial.h"
+
+#if USBHOST_SERIAL
+
+#include "dbg.h"
+
+#define CHECK_INTERFACE(cls,subcls,proto) 1 // \
+// (((cls == 0xFF) && (subcls == 0xFF) && (proto == 0xFF)) /* QUALCOM CDC */ || \
+// ((cls == SERIAL_CLASS) && (subcls == 0x00) && (proto == 0x00)) /* STANDARD CDC */ )
+
+#if (USBHOST_SERIAL <= 1)
+
+USB400Serial::USB400Serial()
+{
+ host = USBHost::getHostInst();
+ ports_found = 0;
+ dev_connected = false;
+}
+
+bool USB400Serial::connected()
+{
+ return dev;
+// return dev_connected;
+}
+
+void USB400Serial::disconnect(void)
+{
+ ports_found = 0;
+ dev = NULL;
+}
+
+bool USB400Serial::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;
+
+ 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) {
+ USB400SerialPort::connect(host,d,port_intf,bulk_in, bulk_out);
+ dev = d;
+ }
+ }
+ }
+ return dev != NULL;
+}
+
+/*virtual*/ void USB400Serial::setVidPid(uint16_t vid, uint16_t pid)
+{
+ // we don't check VID/PID for MSD driver
+}
+
+/*virtual*/ bool USB400Serial::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 &&
+ CHECK_INTERFACE(intf_class, intf_subclass, intf_protocol)) {
+ port_intf = intf_nb;
+ ports_found = true;
+ return true;
+ }
+ return false;
+}
+
+/*virtual*/ bool USB400Serial::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;
+}
+
+#else // (USBHOST_SERIAL > 1)
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#define SET_LINE_CODING 0x20
+
+USB400SerialPort::USB400SerialPort(): circ_buf()
+{
+ init();
+}
+
+void USB400SerialPort::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 USB400SerialPort::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, &USB400SerialPort::init);
+ baud(9600); //
+ size_bulk_in = bulk_in->getSize();
+ size_bulk_out = bulk_out->getSize();
+ bulk_in->attach(this, &USB400SerialPort::rxHandler);
+ bulk_out->attach(this, &USB400SerialPort::txHandler);
+ host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+}
+
+void USB400SerialPort::rxHandler()
+{
+ if (bulk_in) {
+ int len = bulk_in->getLengthTransferred();
+ if (bulk_in->getState() == USB_TYPE_IDLE) {
+ if(len > 2) {
+ for (int i = 2; i < len; i++) {
+ circ_buf.queue(buf[i]);
+ }
+ }
+// for (int i = 0; i < len; i++) {
+// circ_buf.queue(buf[i]);
+// }
+ rx.call();
+ host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
+ }
+ }
+}
+
+void USB400SerialPort::txHandler()
+{
+ if (bulk_out) {
+ if (bulk_out->getState() == USB_TYPE_IDLE) {
+ tx.call();
+ }
+ }
+}
+
+int USB400SerialPort::_putc(int c)
+{
+ if (bulk_out) {
+ if (host->bulkWrite(dev, bulk_out, (uint8_t *)&c, 1) == USB_TYPE_OK) {
+ return 1;
+ }
+ }
+ return -1;
+}
+
+void USB400SerialPort::baud(int baudrate)
+{
+ line_coding.baudrate = baudrate;
+ format(line_coding.data_bits, (Parity)line_coding.parity, line_coding.stop_bits);
+}
+
+void USB400SerialPort::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;
+
+ // set line coding
+ host->controlWrite( dev, 0x40, 0, 0, 0, NULL, 0);
+ host->controlWrite( dev, 0x40, 0, 1, 0, NULL, 0);
+ host->controlWrite( dev, 0x40, 0, 2, 0, NULL, 0);
+ host->controlWrite( dev, 0x40, 2, 0x0000, 0, NULL, 0); // flow control none
+ host->controlWrite( dev, 0x40, 3, 0xC034, 0, NULL, 0); // baudrate 57600
+ host->controlWrite( dev, 0x40, 4, 0x0008, 0, NULL, 0); // data bit 8, parity none, stop bit 1, tx off
+
+// host->controlWrite( dev,
+// USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS,
+// SET_LINE_CODING,
+// 0, serial_intf, (uint8_t *)&line_coding, 7);
+}
+
+int USB400SerialPort::_getc()
+{
+ uint8_t c = 0;
+ if (bulk_in == NULL) {
+ init();
+ return -1;
+ }
+ while (circ_buf.isEmpty());
+ circ_buf.dequeue(&c);
+ return c;
+}
+
+int USB400SerialPort::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;
+}
+
+int USB400SerialPort::readBuf(char* b, int s)
+{
+ int i = 0;
+ if (bulk_in) {
+ for (i = 0; i < s; )
+ b[i++] = getc();
+ }
+ return i;
+}
+
+uint8_t USB400SerialPort::available()
+{
+ return circ_buf.available();
+}
+
+
+
+#endif
diff -r 000000000000 -r 0dd5d1e4cf71 USB400Serial.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USB400Serial.h Wed Dec 03 06:18:10 2014 +0000
@@ -0,0 +1,195 @@
+/* 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.
+ */
+
+/* USB400Serial Library
+ * Modified mujirushi.org
+ */
+
+#ifndef USB400SERIAL_H
+#define USB400SERIAL_H
+
+#include "USBHostConf.h"
+
+#if USBHOST_SERIAL
+
+#include "USBHost.h"
+#include "Stream.h"
+#include "MtxCircBuffer.h"
+
+/**
+ * A class to communicate a USB virtual serial port
+ */
+class USB400SerialPort : public Stream
+{
+public:
+ /**
+ * Constructor
+ */
+ USB400SerialPort();
+
+ enum IrqType {
+ RxIrq,
+ TxIrq
+ };
+
+ enum Parity {
+ None = 0,
+ Odd,
+ Even,
+ Mark,
+ Space
+ };
+
+ void connect(USBHost* _host, USBDeviceConnected * _dev,
+ uint8_t _serial_intf, USBEndpoint* _bulk_in, USBEndpoint* _bulk_out);
+
+ /**
+ * Check the number of bytes available.
+ *
+ * @returns the number of bytes available
+ */
+ uint8_t available();
+
+ /**
+ * Attach a member function to call when a packet is received.
+ *
+ * @param tptr pointer to the object to call the member function on
+ * @param mptr pointer to the member function to be called
+ * @param irq irq type
+ */
+ template<typename T>
+ inline void attach(T* tptr, void (T::*mptr)(void), IrqType irq = RxIrq) {
+ if ((mptr != NULL) && (tptr != NULL)) {
+ if (irq == RxIrq) {
+ rx.attach(tptr, mptr);
+ } else {
+ tx.attach(tptr, mptr);
+ }
+ }
+ }
+
+ /**
+ * Attach a callback called when a packet is received
+ *
+ * @param ptr function pointer
+ */
+ inline void attach(void (*fn)(void), IrqType irq = RxIrq) {
+ if (fn != NULL) {
+ if (irq == RxIrq) {
+ rx.attach(fn);
+ } else {
+ tx.attach(fn);
+ }
+ }
+ }
+
+ /** Set the baud rate of the serial port
+ *
+ * @param baudrate The baudrate of the serial port (default = 9600).
+ */
+ void baud(int baudrate = 9600);
+
+ /** 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 (USB400SerialPort::None, USB400SerialPort::Odd, USB400SerialPort::Even, USB400SerialPort::Mark, USB400SerialPort::Space; default = USB400SerialPort::None)
+ * @param stop The number of stop bits (1 or 2; default = 1)
+ */
+ void format(int bits = 8, Parity parity = USB400SerialPort::None, int stop_bits = 1);
+ virtual int writeBuf(const char* b, int s);
+ virtual int readBuf(char* b, int s);
+
+protected:
+ 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;
+
+ void init();
+
+ MtxCircBuffer<uint8_t, 128> circ_buf;
+
+ uint8_t buf[64];
+
+ typedef struct {
+ uint32_t baudrate;
+ uint8_t stop_bits;
+ uint8_t parity;
+ uint8_t data_bits;
+ } PACKED LINE_CODING;
+
+ LINE_CODING line_coding;
+
+ void rxHandler();
+ void txHandler();
+ FunctionPointer rx;
+ FunctionPointer tx;
+
+ uint8_t serial_intf;
+};
+
+#if (USBHOST_SERIAL <= 1)
+
+class USB400Serial : public IUSBEnumerator, public USB400SerialPort
+{
+public:
+ USB400Serial();
+
+ /**
+ * 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)
+
+#endif // (USBHOST_SERIAL <= 1)
+
+#endif
+
+#endif