diff options
author | Jun Wako <wakojun@gmail.com> | 2015-04-24 16:26:14 +0900 |
---|---|---|
committer | Jun Wako <wakojun@gmail.com> | 2015-04-24 16:26:14 +0900 |
commit | 1fe4406f374291ab2e86e95a97341fd9c475fcb8 (patch) | |
tree | 1be0e16b4b07b5a31ea97ec50a9eb13a288c3d27 /tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule | |
parent | a20ef7052c6e937d2f7672dd59456e55a5c08296 (diff) |
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5
git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
Diffstat (limited to 'tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule')
7 files changed, 1021 insertions, 0 deletions
diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/IUSBHostSerial.h b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/IUSBHostSerial.h new file mode 100644 index 0000000000..5814fdd883 --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/IUSBHostSerial.h @@ -0,0 +1,95 @@ +/* IUSBHostSerial.h */ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef IUSBHOSTSERIAL_H_ +#define IUSBHOSTSERIAL_H_ + +/** + * Generic interface to abstract 3G dongles' impl + */ + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +#include "IUSBHostSerialListener.h" + +// This is needed by some versions of GCC +#undef putc +#undef getc + +class IUSBHostSerial { +public: + + enum IrqType { + RxIrq, + TxIrq + }; + + /* + * Get a char from the dongle's serial interface + */ + virtual int getc() = 0; + + /* + * Put a char to the dongle's serial interface + */ + virtual int putc(int c) = 0; + + /* + * Read a packet from the dongle's serial interface, to be called after multiple getc() calls + */ + virtual int readPacket() = 0; + + /* + * Write a packet to the dongle's serial interface, to be called after multiple putc() calls + */ + virtual int writePacket() = 0; + + /** + * Check the number of bytes available. + * + * @returns the number of bytes available + */ + virtual int readable() = 0; + + /** + * Check the free space in output. + * + * @returns the number of bytes available + */ + virtual int writeable() = 0; + + /** + * Attach a handler to call when a packet is received / when a packet has been transmitted. + * + * @param pListener instance of the listener deriving from the IUSBHostSerialListener + */ + virtual void attach(IUSBHostSerialListener* pListener) = 0; + + /** + * Enable or disable readable/writeable callbacks + */ + virtual void setupIrq(bool en, IrqType irq = RxIrq) = 0; + +}; + +#endif /* USBHOST_3GMODULE */ + +#endif /* IUSBHOSTSERIAL_H_ */ diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/IUSBHostSerialListener.h b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/IUSBHostSerialListener.h new file mode 100644 index 0000000000..525b734637 --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/IUSBHostSerialListener.h @@ -0,0 +1,37 @@ +/* IUSBHostSerialListener.h */ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef IUSBHOSTSERIALLISTENER_H_ +#define IUSBHOSTSERIALLISTENER_H_ + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +class IUSBHostSerialListener +{ +public: + virtual void readable() = 0; //Called when new data is available + virtual void writeable() = 0; //Called when new space is available +}; + +#endif /* USBHOST_3GMODULE */ + +#endif /* IUSBHOSTSERIALLISTENER_H_ */ diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongle.cpp b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongle.cpp new file mode 100644 index 0000000000..49cafb7cc3 --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongle.cpp @@ -0,0 +1,235 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +#include "dbg.h" +#include <stdint.h> +#include "rtos.h" + +#include "WANDongle.h" +#include "WANDongleInitializer.h" + +WANDongle::WANDongle() : m_pInitializer(NULL), m_serialCount(0), m_totalInitializers(0) +{ + host = USBHost::getHostInst(); + init(); +} + + +bool WANDongle::connected() { + return dev_connected; +} + +bool WANDongle::tryConnect() +{ + //FIXME should run on USB thread + + USB_DBG("Trying to connect device"); + + if (dev_connected) { + USB_DBG("Device is already connected!"); + return true; + } + + m_pInitializer = NULL; + + //Protect from concurrent access from USB thread + USBHost::Lock lock(host); + + for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) + { + if ((dev = host->getDevice(i)) != NULL) + { + m_pInitializer = NULL; //Will be set in setVidPid callback + + USB_DBG("Enumerate"); + int ret = host->enumerate(dev, this); + if(ret) + { + return false; + } + + USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid()); + + if(m_pInitializer) //If an initializer has been found + { + USB_DBG("m_pInitializer=%p", m_pInitializer); + USB_DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid()); + USB_DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid()); + if ((dev->getVid() == m_pInitializer->getSerialVid()) && (dev->getPid() == m_pInitializer->getSerialPid())) + { + USB_DBG("The dongle is in virtual serial mode"); + host->registerDriver(dev, 0, this, &WANDongle::init); + m_serialCount = m_pInitializer->getSerialPortCount(); + if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS ) + { + m_serialCount = WANDONGLE_MAX_SERIAL_PORTS; + } + for(int j = 0; j < m_serialCount; j++) + { + USB_DBG("Connecting serial port #%d", j+1); + USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, false)); + USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, true)); + m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) ); + } + + USB_DBG("Device connected"); + + dev_connected = true; + + + return true; + } + else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid())) + { + USB_DBG("Vodafone K3370 dongle detected in MSD mode"); + //Try to switch + if( m_pInitializer->switchMode(dev) ) + { + USB_DBG("Switched OK"); + return false; //Will be connected on a next iteration + } + else + { + USB_ERR("Could not switch mode"); + return false; + } + } + } //if() + } //if() + } //for() + return false; +} + +bool WANDongle::disconnect() +{ + dev_connected = false; + for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++) + { + m_serial[i].disconnect(); + } + return true; +} + +int WANDongle::getDongleType() +{ + if( m_pInitializer != NULL ) + { + return m_pInitializer->getType(); + } + else + { + return WAN_DONGLE_TYPE_UNKNOWN; + } +} + +IUSBHostSerial& WANDongle::getSerial(int index) +{ + return m_serial[index]; +} + +int WANDongle::getSerialCount() +{ + return m_serialCount; +} + +//Private methods +void WANDongle::init() +{ + m_pInitializer = NULL; + dev_connected = false; + for(int i = 0; i < WANDONGLE_MAX_SERIAL_PORTS; i++) + { + m_serial[i].init(host); + } +} + + +/*virtual*/ void WANDongle::setVidPid(uint16_t vid, uint16_t pid) +{ + WANDongleInitializer* initializer; + + for(int i = 0; i < m_totalInitializers; i++) + { + initializer = m_Initializers[i]; + USB_DBG("initializer=%p", initializer); + USB_DBG("initializer->getSerialVid()=%04x", initializer->getSerialVid()); + USB_DBG("initializer->getSerialPid()=%04x", initializer->getSerialPid()); + if ((dev->getVid() == initializer->getSerialVid()) && (dev->getPid() == initializer->getSerialPid())) + { + USB_DBG("The dongle is in virtual serial mode"); + m_pInitializer = initializer; + break; + } + else if ((dev->getVid() == initializer->getMSDVid()) && (dev->getPid() == initializer->getMSDPid())) + { + USB_DBG("Dongle detected in MSD mode"); + m_pInitializer = initializer; + break; + } + initializer++; + } //for + if(m_pInitializer) + { + m_pInitializer->setVidPid(vid, pid); + } +} + +/*virtual*/ bool WANDongle::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(m_pInitializer) + { + return m_pInitializer->parseInterface(intf_nb, intf_class, intf_subclass, intf_protocol); + } + else + { + return false; + } +} + +/*virtual*/ bool WANDongle::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + if(m_pInitializer) + { + return m_pInitializer->useEndpoint(intf_nb, type, dir); + } + else + { + return false; + } +} + + +bool WANDongle::addInitializer(WANDongleInitializer* pInitializer) +{ + if (m_totalInitializers >= WANDONGLE_MAX_INITIALIZERS) + return false; + m_Initializers[m_totalInitializers++] = pInitializer; + return true; +} + +WANDongle::~WANDongle() +{ + for(int i = 0; i < m_totalInitializers; i++) + delete m_Initializers[i]; +} + +#endif /* USBHOST_3GMODULE */ diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongle.h b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongle.h new file mode 100644 index 0000000000..960b8bcfbe --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongle.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef WANDONGLE_H +#define WANDONGLE_H + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +#include "USBHost.h" +#include "IUSBHostSerial.h" + +#include "rtos.h" + +#include "WANDongleSerialPort.h" +#include "WANDongleInitializer.h" +#include "IUSBEnumerator.h" + +#define WANDONGLE_MAX_OUTEP_SIZE 64 +#define WANDONGLE_MAX_INEP_SIZE 64 + +/** A class to use a WAN (3G/LTE) access dongle + * + */ +class WANDongle : public IUSBEnumerator { +public: + /* + * Constructor + * + * @param rootdir mount name + */ + WANDongle(); + + /* + * Destructor + */ + virtual ~WANDongle(); + + /* + * Check if a serial port device is connected + * + * @return true if a serial device is connected + */ + bool connected(); + + /* + * Try to connect device + * + * * @return true if connection was successful + */ + bool tryConnect(); + + /* + * Disconnect device + * + * * @return true if disconnection was successful + */ + bool disconnect(); + + int getDongleType(); + + IUSBHostSerial& getSerial(int index); + int getSerialCount(); + bool addInitializer(WANDongleInitializer* pInitializer); + + //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 + +protected: + USBHost * host; + USBDeviceConnected * dev; + bool dev_connected; + + WANDongleInitializer* m_pInitializer; + + void init(); + + WANDongleSerialPort m_serial[WANDONGLE_MAX_SERIAL_PORTS]; + int m_serialCount; + + int m_totalInitializers; + WANDongleInitializer* m_Initializers[WANDONGLE_MAX_INITIALIZERS]; +}; + +#endif /* USBHOST_3GMODULE */ + +#endif diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleInitializer.h b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleInitializer.h new file mode 100644 index 0000000000..2f0a4a37c7 --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleInitializer.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef WANDONGLEINITIALIZER_H +#define WANDONGLEINITIALIZER_H + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +#include <stdint.h> + +#include "USBHost.h" +#include "IUSBEnumerator.h" + +// [TODO] move these declarations to a proper place +#define WANDONGLE_MAX_SERIAL_PORTS 2 +#define WANDONGLE_MAX_INITIALIZERS 6 + +#define WAN_DONGLE_TYPE_UNKNOWN (-1) + +class WANDongleInitializer : public IUSBEnumerator +{ +protected: + WANDongleInitializer(USBHost* pHost) { m_pHost = pHost; } + USBHost* m_pHost; + uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS]; + +public: + virtual ~WANDongleInitializer() {} + virtual uint16_t getMSDVid() = 0; + virtual uint16_t getMSDPid() = 0; + + virtual uint16_t getSerialVid() = 0; + virtual uint16_t getSerialPid() = 0; + + virtual bool switchMode(USBDeviceConnected* pDev) = 0; + + virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) { + return pDev->getEndpoint(m_serialIntfMap[serialPortNumber], BULK_ENDPOINT, tx ? OUT : IN, 0); + } + + virtual int getSerialPortCount() = 0; + + virtual void setVidPid(uint16_t vid, uint16_t pid) = 0; + + virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed + + virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used + + virtual int getType() = 0; + + virtual uint8_t getSerialIntf(int index) { return m_serialIntfMap[index]; } +}; + +#endif /* USBHOST_3GMODULE */ + +#endif diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleSerialPort.cpp b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleSerialPort.cpp new file mode 100644 index 0000000000..96343f15cc --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleSerialPort.cpp @@ -0,0 +1,340 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +#define __DEBUG__ 0 +#ifndef __MODULE__ +#define __MODULE__ "WANDongleSerialPort.cpp" +#endif + +#include "dbg.h" +#include <stdint.h> +#include "rtos.h" + +#include "WANDongleSerialPort.h" + +WANDongleSerialPort::WANDongleSerialPort() : cb_tx_en(false), cb_rx_en(false), listener(NULL) +{ + reset(); +} + +void WANDongleSerialPort::init(USBHost* pHost) +{ + host = pHost; +} + +void WANDongleSerialPort::reset() +{ + tx_mtx.lock(); + rx_mtx.lock(); + + bulk_in = NULL; + bulk_out = NULL; + + buf_out_len = 0; + max_out_size = 0; + lock_tx = false; + cb_tx_pending = false; + + buf_in_len = 0; + buf_in_read_pos = 0; + lock_rx = false; + cb_rx_pending = false; + + tx_mtx.unlock(); + rx_mtx.unlock(); +} + +int WANDongleSerialPort::readPacket() +{ + USB_DBG("Read packet on %p", this); + rx_mtx.lock(); + if(lock_rx) + { + USB_ERR("Fail"); + rx_mtx.unlock(); + return -1; + } + + if( bulk_in == NULL ) + { + USB_WARN("Port is disconnected"); + rx_mtx.unlock(); + return -1; + } + + lock_rx = true; //Receiving + rx_mtx.unlock(); +// USB_DBG("readPacket"); + //lock_rx.lock(); + USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer + if(res != USB_TYPE_PROCESSING) + { + //lock_rx.unlock(); + USB_ERR("host->bulkRead() returned %d", res); + Thread::wait(100); + return -1; + } + return 0; +} + +int WANDongleSerialPort::writePacket() +{ + tx_mtx.lock(); + if(lock_tx) + { + USB_ERR("Fail"); + tx_mtx.unlock(); + return -1; + } + + if( bulk_out == NULL ) + { + USB_WARN("Port is disconnected"); + tx_mtx.unlock(); + return -1; + } + + lock_tx = true; //Transmitting + tx_mtx.unlock(); +// USB_DBG("writePacket"); + + //lock_tx.lock(); + USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer + if(res != USB_TYPE_PROCESSING) + { + //lock_tx.unlock(); + USB_ERR("host->bulkWrite() returned %d", res); + Thread::wait(100); + return -1; + } + return 0; +} + +int WANDongleSerialPort::putc(int c) +{ + tx_mtx.lock(); + if(!lock_tx) + { + if(buf_out_len < max_out_size) + { + buf_out[buf_out_len] = (uint8_t)c; + buf_out_len++; + } + } + else + { + USB_ERR("CAN'T WRITE!"); + } + tx_mtx.unlock(); + return c; +} + +int WANDongleSerialPort::getc() +{ + rx_mtx.lock(); + int c = 0; + if(!lock_rx) + { + if(buf_in_read_pos < buf_in_len) + { + c = (int)buf_in[buf_in_read_pos]; + buf_in_read_pos++; + } + } + else + { + USB_ERR("CAN'T READ!"); + } + rx_mtx.unlock(); + return c; +} + +int WANDongleSerialPort::readable() +{ + rx_mtx.lock(); + if (lock_rx) + { + rx_mtx.unlock(); + return 0; + } + + /* if( !lock_rx.trylock() ) + { + return 0; + }*/ + int res = buf_in_len - buf_in_read_pos; + //lock_rx.unlock(); + rx_mtx.unlock(); + return res; +} + +int WANDongleSerialPort::writeable() +{ + tx_mtx.lock(); + if (lock_tx) + { + tx_mtx.unlock(); + return 0; + } + + /*if( !lock_tx.trylock() ) + { + return 0; + }*/ + int res = max_out_size - buf_out_len; + tx_mtx.unlock(); + //lock_tx.unlock(); + return res; +} + +void WANDongleSerialPort::attach(IUSBHostSerialListener* pListener) +{ + if(pListener == NULL) + { + setupIrq(false, RxIrq); + setupIrq(false, TxIrq); + } + listener = pListener; + if(pListener != NULL) + { + setupIrq(true, RxIrq); + setupIrq(true, TxIrq); + } +} + +void WANDongleSerialPort::setupIrq(bool en, IrqType irq /*= RxIrq*/) +{ + switch(irq) + { + case RxIrq: + rx_mtx.lock(); + cb_rx_en = en; + if(en && cb_rx_pending) + { + cb_rx_pending = false; + rx_mtx.unlock(); + listener->readable(); //Process the interrupt that was raised + } + else + { + rx_mtx.unlock(); + } + break; + case TxIrq: + tx_mtx.lock(); + cb_tx_en = en; + if(en && cb_tx_pending) + { + cb_tx_pending = false; + tx_mtx.unlock(); + listener->writeable(); //Process the interrupt that was raised + } + else + { + tx_mtx.unlock(); + } + break; + } +} + + +void WANDongleSerialPort::connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp ) +{ + dev = pDev; + bulk_in = pInEp; + bulk_out = pOutEp; + max_out_size = bulk_out->getSize(); + if( max_out_size > WANDONGLE_MAX_OUTEP_SIZE ) + { + max_out_size = WANDONGLE_MAX_OUTEP_SIZE; + } + bulk_in->attach(this, &WANDongleSerialPort::rxHandler); + bulk_out->attach(this, &WANDongleSerialPort::txHandler); + readPacket(); //Start receiving data +} + +void WANDongleSerialPort::disconnect( ) +{ + reset(); +} + +//Private methods + + +void WANDongleSerialPort::rxHandler() +{ + if (((USBEndpoint *) bulk_in)->getState() == USB_TYPE_IDLE) //Success + { + buf_in_read_pos = 0; + buf_in_len = ((USBEndpoint *) bulk_in)->getLengthTransferred(); //Update length + //lock_rx.unlock(); + rx_mtx.lock(); + lock_rx = false; //Transmission complete + if(cb_rx_en) + { + rx_mtx.unlock(); + listener->readable(); //Call handler from the IRQ context + //readPacket() should be called by the handler subsequently once the buffer has been emptied + } + else + { + cb_rx_pending = true; //Queue the callback + rx_mtx.unlock(); + } + + } + else //Error, try reading again + { + //lock_rx.unlock(); + USB_DBG("Trying again"); + readPacket(); + } +} + +void WANDongleSerialPort::txHandler() +{ + if (((USBEndpoint *) bulk_out)->getState() == USB_TYPE_IDLE) //Success + { + tx_mtx.lock(); + buf_out_len = 0; //Reset length + lock_tx = false; //Transmission complete + //lock_tx.unlock(); + if(cb_tx_en) + { + tx_mtx.unlock(); + listener->writeable(); //Call handler from the IRQ context + //writePacket() should be called by the handler subsequently once the buffer has been filled + } + else + { + cb_tx_pending = true; //Queue the callback + tx_mtx.unlock(); + } + } + else //Error, try reading again + { + //lock_tx.unlock(); + writePacket(); + } +} + +#endif /* USBHOST_3GMODULE */ diff --git a/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleSerialPort.h b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleSerialPort.h new file mode 100644 index 0000000000..7c79d17341 --- /dev/null +++ b/tool/mbed/mbed-sdk/libraries/USBHost/USBHost3GModule/WANDongleSerialPort.h @@ -0,0 +1,133 @@ +/* Copyright (c) 2010-2012 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef WANDONGLESERIALPORT_H +#define WANDONGLESERIALPORT_H + +#include "USBHostConf.h" + +#ifdef USBHOST_3GMODULE + +#include "USBHost.h" +#include "IUSBHostSerial.h" + +#include "rtos.h" + + +#define WANDONGLE_MAX_OUTEP_SIZE 64 +#define WANDONGLE_MAX_INEP_SIZE 64 + +/** A class to use a WAN (3G/LTE) access dongle + * + */ +class WANDongleSerialPort : public IUSBHostSerial { +public: + /* + * Constructor + * + */ + WANDongleSerialPort(); + + void init( USBHost* pHost ); + + void connect( USBDeviceConnected* pDev, USBEndpoint* pInEp, USBEndpoint* pOutEp ); + + void disconnect( ); + + /* + * Get a char from the dongle's serial interface + */ + virtual int getc(); + + /* + * Put a char to the dongle's serial interface + */ + virtual int putc(int c); + + /* + * Read a packet from the dongle's serial interface, to be called after multiple getc() calls + */ + virtual int readPacket(); + + /* + * Write a packet to the dongle's serial interface, to be called after multiple putc() calls + */ + virtual int writePacket(); + + /** + * Check the number of bytes available. + * + * @returns the number of bytes available + */ + virtual int readable(); + + /** + * Check the free space in output. + * + * @returns the number of bytes available + */ + virtual int writeable(); + + /** + * Attach a handler to call when a packet is received / when a packet has been transmitted. + * + * @param pListener instance of the listener deriving from the IUSBHostSerialListener + */ + virtual void attach(IUSBHostSerialListener* pListener); + + /** + * Enable or disable readable/writeable callbacks + */ + virtual void setupIrq(bool en, IrqType irq = RxIrq); + + +protected: + USBEndpoint * bulk_in; + USBEndpoint * bulk_out; + USBHost * host; + USBDeviceConnected * dev; + + uint8_t buf_out[WANDONGLE_MAX_OUTEP_SIZE]; + volatile uint32_t buf_out_len; + uint32_t max_out_size; + volatile bool lock_tx; + volatile bool cb_tx_en; + volatile bool cb_tx_pending; + Mutex tx_mtx; + + uint8_t buf_in[WANDONGLE_MAX_INEP_SIZE]; + volatile uint32_t buf_in_len; + volatile uint32_t buf_in_read_pos; + volatile bool lock_rx; + volatile bool cb_rx_en; + volatile bool cb_rx_pending; + Mutex rx_mtx; + + IUSBHostSerialListener* listener; + + void reset(); + + void rxHandler(); + void txHandler(); + +}; + +#endif /* USBHOST_3GMODULE */ + +#endif + |