I added the Isochronous to USBHost library. The Isochronous code based on the following. http://developer.mbed.org/users/va009039/code/USBHostC270_example/
Dependencies: FATFileSystem mbed-rtos
Fork of USBHost_AddIso by
Revision 18:37c948cf0dbf, committed 2013-10-17
- Comitter:
- mbed_official
- Date:
- Thu Oct 17 10:15:19 2013 +0100
- Parent:
- 17:c7b1b8451598
- Child:
- 19:bd46ea19486b
- Commit message:
- Synchronized with git revision 7585a23e6c29c41da4793a46a746ac3ec743b780
Changed in this revision
--- a/USBHost3GModule/IUSBHostSerial.h Wed Oct 16 14:15:18 2013 +0100 +++ b/USBHost3GModule/IUSBHostSerial.h Thu Oct 17 10:15:19 2013 +0100 @@ -30,6 +30,10 @@ #include "IUSBHostSerialListener.h" +// This is needed by some versions of GCC +#undef putc +#undef getc + class IUSBHostSerial { public:
--- a/USBHost3GModule/USBSerialStream.cpp Wed Oct 16 14:15:18 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* USBSerialStream.cpp */ -/* Copyright (C) 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. - */ - -#define __DEBUG__ 0 -#ifndef __MODULE__ -#define __MODULE__ "USBSerialStream.cpp" -#endif - -#include "core/fwk.h" - -#include <cstring> - -#include "USBSerialStream.h" - - -USBSerialStream::USBSerialStream(IUSBHostSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true), -m_availableSphre(1), m_spaceSphre(1), m_inBuf() -{ - m_availableSphre.wait(); - m_spaceSphre.wait(); - //Attach interrupts - m_serial.attach(this); -} - -/*virtual*/ USBSerialStream::~USBSerialStream() -{ - m_serial.attach(NULL); -} - -//0 for non-blocking (returns immediately), -1 for infinite blocking -/*virtual*/ int USBSerialStream::read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout/*=osWaitForever*/) -{ - DBG("Trying to read at most %d chars", maxLength); - int ret = waitAvailable(timeout); - if(ret) - { - WARN("Error %d while waiting for incoming data", ret); - return ret; - } - int a = available(); //Prevent macro issues - int readLen = MIN( a, maxLength ); - *pLength = readLen; - - setupReadableISR(false); - while(readLen--) - { - m_inBuf.dequeue(buf); - buf++; - } - setupReadableISR(true); - DBG("Read %d chars successfully", *pLength); - return OK; -} - -/*virtual*/ size_t USBSerialStream::available() -{ - setupReadableISR(false); //m_inBuf.available() is not reentrant - size_t len = m_inBuf.available(); - setupReadableISR(true); - return len; -} - -/*virtual*/ int USBSerialStream::waitAvailable(uint32_t timeout/*=osWaitForever*/) //Wait for data to be available -{ - int ret; - if(available()) //Is data already available? - { - while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available - return OK; - } - - DBG("Waiting for data availability %d ms (-1 is infinite)", timeout); - ret = m_availableSphre.wait(timeout); //Wait for data to arrive or for abort - if(ret <= 0) - { - DBG("Timeout"); - return NET_TIMEOUT; - } - if(!m_inBuf.available()) //Even if abort has been called, return that data is available - { - DBG("Aborted"); - return NET_INTERRUPTED; - } - DBG("Finished waiting"); - while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available - return OK; -} - -/*virtual*/ int USBSerialStream::abortRead() //Abort current reading (or waiting) operation -{ - if( /*!available()*/true ) //If there is data pending, no need to abort - { - m_availableSphre.release(); //Force exiting the waiting state - } - else - { - DBG("Serial is readable"); ; - } - return OK; -} - -void USBSerialStream::setupReadableISR(bool en) -{ - m_serial.setupIrq(en, IUSBHostSerial::RxIrq); -} - -void USBSerialStream::readable() //Callback from m_serial when new data is available -{ - while(m_serial.readable()) - { - m_inBuf.queue(m_serial.getc()); - } - m_serial.readPacket(); //Start read of next packet - m_availableSphre.release(); //Force exiting the waiting state -} - -//0 for non-blocking (returns immediately), -1 for infinite blocking -/*virtual*/ int USBSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=-1*/) -{ - DBG("Trying to write %d chars", length); - do - { - int ret = waitSpace(timeout); - if(ret) - { - WARN("Error %d while waiting for space", ret); - return ret; - } - int s = space(); //Prevent macro issues - int writeLen = MIN( s, length ); - DBG("Writing %d chars", writeLen); - setupWriteableISR(false); - while(writeLen) - { - m_outBuf.queue(*buf); - buf++; - length--; - writeLen--; - } - //If m_serial tx fifo is empty we need to start the packet write - if( m_outBuf.available() && m_serialTxFifoEmpty ) - { - writeable(); - } - setupWriteableISR(true); - } while(length); - - DBG("Write successful"); - return OK; -} - -/*virtual*/ size_t USBSerialStream::space() -{ - setupWriteableISR(false); //m_outBuf.available() is not reentrant - size_t len = CIRCBUF_SIZE - m_outBuf.available(); - setupWriteableISR(true); - return len; -} - -/*virtual*/ int USBSerialStream::waitSpace(uint32_t timeout/*=-1*/) //Wait for space to be available -{ - int ret; - if(space()) //Is still space already left? - { - while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available - return OK; - } - - DBG("Waiting for data space %d ms (-1 is infinite)", timeout); - ret = m_spaceSphre.wait(timeout); //Wait for space to be made or for abort - if(ret <= 0) - { - DBG("Timeout"); - return NET_TIMEOUT; - } - if(!space()) //Even if abort has been called, return that space is available - { - DBG("Aborted"); - return NET_INTERRUPTED; - } - while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available - return OK; -} - -/*virtual*/ int USBSerialStream::abortWrite() //Abort current writing (or waiting) operation -{ - if( !space() ) //If there is space left, no need to abort - { - m_spaceSphre.release(); //Force exiting the waiting state - } - return OK; -} - -void USBSerialStream::setupWriteableISR(bool en) -{ - m_serial.setupIrq(en, IUSBHostSerial::TxIrq); -} - -void USBSerialStream::writeable() //Callback from m_serial when new space is available -{ - if(m_outBuf.isEmpty()) - { - m_serialTxFifoEmpty = true; - } - else - { - m_serialTxFifoEmpty = false; - while(m_serial.writeable() && !m_outBuf.isEmpty()) - { - uint8_t c; - m_outBuf.dequeue(&c); - m_serial.putc((char)c); - } - m_serial.writePacket(); //Start packet write - } - if(!m_outBuf.isFull()) - { - m_spaceSphre.release(); //Force exiting the waiting state - } -}
--- a/USBHost3GModule/USBSerialStream.h Wed Oct 16 14:15:18 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* USBSerialStream.h */ -/* Copyright (C) 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 USBSERIALSTREAM_H_ -#define USBSERIALSTREAM_H_ - - -#include "core/fwk.h" - -#include "USBHost3GModule/IUSBHostSerial.h" -#include "USBHost3GModule/IUSBHostSerialListener.h" - -#include "rtos.h" -#include "core/MtxCircBuffer.h" - -/* Input Serial Stream for USB virtual serial ports interfaces -This class is not thread-safe, except for the *Abort() methods that can be called by any thread/ISR -*/ -#define CIRCBUF_SIZE 127 -class USBSerialStream : public IOStream, IUSBHostSerialListener -{ -public: - USBSerialStream(IUSBHostSerial& serial); - /*virtual*/ ~USBSerialStream(); - - //0 for non-blocking (returns immediately), osWaitForever for infinite blocking - virtual int read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout=osWaitForever); - virtual size_t available(); - virtual int waitAvailable(uint32_t timeout=osWaitForever); //Wait for data to be available - virtual int abortRead(); //Abort current reading (or waiting) operation - - - //0 for non-blocking (returns immediately), osWaitForever for infinite blocking - virtual int write(uint8_t* buf, size_t length, uint32_t timeout=osWaitForever); - virtual size_t space(); - virtual int waitSpace(uint32_t timeout=osWaitForever); //Wait for space to be available - virtual int abortWrite(); //Abort current writing (or waiting) operation - -private: - IUSBHostSerial& m_serial; - volatile bool m_serialTxFifoEmpty; - - void setupReadableISR(bool en); - virtual void readable(); //Callback from m_serial when new data is available - - Semaphore m_availableSphre; //Used for signalling - - void setupWriteableISR(bool en); - virtual void writeable(); //Callback from m_serial when new space is available - - Semaphore m_spaceSphre; //Used for signalling - - MtxCircBuffer<uint8_t, CIRCBUF_SIZE + 1> m_inBuf; - MtxCircBuffer<uint8_t, CIRCBUF_SIZE + 1> m_outBuf; -}; - -#endif /* USBSERIALSTREAM_H_ */
--- a/USBHost3GModule/WANDongle.cpp Wed Oct 16 14:15:18 2013 +0100 +++ b/USBHost3GModule/WANDongle.cpp Thu Oct 17 10:15:19 2013 +0100 @@ -25,8 +25,8 @@ #define __MODULE__ "WANDongle.cpp" #endif -#include "core/dbg.h" -#include <cstdint> +#include "dbg.h" +#include <stdint.h> #include "rtos.h" #include "WANDongle.h" @@ -47,7 +47,7 @@ { //FIXME should run on USB thread - DBG("Trying to connect device"); + USB_DBG("Trying to connect device"); if (dev_connected) { return true; @@ -61,23 +61,23 @@ { m_pInitializer = NULL; //Will be set in setVidPid callback - DBG("Enumerate"); + USB_DBG("Enumerate"); int ret = host->enumerate(dev, this); if(ret) { return false; } - DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid()); + USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid()); if(m_pInitializer) //If an initializer has been found { - DBG("m_pInitializer=%p", m_pInitializer); - DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid()); - DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid()); + 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())) { - DBG("The dongle is in virtual serial mode"); + 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 ) @@ -86,13 +86,13 @@ } for(int j = 0; j < m_serialCount; j++) { - DBG("Connecting serial port #%d", j+1); - DBG("Ep %p", m_pInitializer->getEp(dev, j, false)); - DBG("Ep %p", m_pInitializer->getEp(dev, j, true)); + 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) ); } - DBG("Device connected"); + USB_DBG("Device connected"); dev_connected = true; @@ -101,16 +101,16 @@ } else if ((dev->getVid() == m_pInitializer->getMSDVid()) && (dev->getPid() == m_pInitializer->getMSDPid())) { - DBG("Vodafone K3370 dongle detected in MSD mode"); + USB_DBG("Vodafone K3370 dongle detected in MSD mode"); //Try to switch if( m_pInitializer->switchMode(dev) ) { - DBG("Switched OK"); + USB_DBG("Switched OK"); return false; //Will be connected on a next iteration } else { - ERR("Could not switch mode"); + USB_ERR("Could not switch mode"); return false; } } @@ -168,21 +168,21 @@ { WANDongleInitializer* initializer; - for(unsigned i = 0; i < m_totalInitializers; i++) + for(int i = 0; i < m_totalInitializers; i++) { initializer = m_Initializers[i]; - DBG("initializer=%p", initializer); - DBG("initializer->getSerialVid()=%04x", initializer->getSerialVid()); - DBG("initializer->getSerialPid()=%04x", initializer->getSerialPid()); + 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())) { - DBG("The dongle is in virtual serial mode"); + USB_DBG("The dongle is in virtual serial mode"); m_pInitializer = initializer; break; } else if ((dev->getVid() == initializer->getMSDVid()) && (dev->getPid() == initializer->getMSDPid())) { - DBG("Dongle detected in MSD mode"); + USB_DBG("Dongle detected in MSD mode"); m_pInitializer = initializer; break; } @@ -229,7 +229,7 @@ WANDongle::~WANDongle() { - for(unsigned i = 0; i < m_totalInitializers; i++) + for(int i = 0; i < m_totalInitializers; i++) delete m_Initializers[i]; }
--- a/USBHost3GModule/WANDongleInitializer.h Wed Oct 16 14:15:18 2013 +0100 +++ b/USBHost3GModule/WANDongleInitializer.h Thu Oct 17 10:15:19 2013 +0100 @@ -23,9 +23,7 @@ #ifdef USBHOST_3GMODULE -#include <cstdint> -using std::uint16_t; -using std::uint32_t; +#include <stdint.h> #include "USBHost.h" #include "IUSBEnumerator.h" @@ -44,6 +42,7 @@ uint8_t m_serialIntfMap[WANDONGLE_MAX_SERIAL_PORTS]; public: + virtual ~WANDongleInitializer() {} virtual uint16_t getMSDVid() = 0; virtual uint16_t getMSDPid() = 0;
--- a/USBHost3GModule/WANDongleSerialPort.cpp Wed Oct 16 14:15:18 2013 +0100 +++ b/USBHost3GModule/WANDongleSerialPort.cpp Thu Oct 17 10:15:19 2013 +0100 @@ -25,8 +25,8 @@ #define __MODULE__ "WANDongleSerialPort.cpp" #endif -#include "core/dbg.h" -#include <cstdint> +#include "dbg.h" +#include <stdint.h> #include "rtos.h" #include "WANDongleSerialPort.h" @@ -65,31 +65,31 @@ int WANDongleSerialPort::readPacket() { - DBG("Read packet on %p", this); + USB_DBG("Read packet on %p", this); rx_mtx.lock(); if(lock_rx) { - ERR("Fail"); + USB_ERR("Fail"); rx_mtx.unlock(); return -1; } if( bulk_in == NULL ) { - WARN("Port is disconnected"); + USB_WARN("Port is disconnected"); rx_mtx.unlock(); return -1; } lock_rx = true; //Receiving rx_mtx.unlock(); -// DBG("readPacket"); +// 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(); - ERR("host->bulkRead() returned %d", res); + USB_ERR("host->bulkRead() returned %d", res); Thread::wait(100); return -1; } @@ -101,28 +101,28 @@ tx_mtx.lock(); if(lock_tx) { - ERR("Fail"); + USB_ERR("Fail"); tx_mtx.unlock(); return -1; } if( bulk_out == NULL ) { - WARN("Port is disconnected"); + USB_WARN("Port is disconnected"); tx_mtx.unlock(); return -1; } lock_tx = true; //Transmitting tx_mtx.unlock(); -// DBG("writePacket"); +// 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(); - ERR("host->bulkWrite() returned %d", res); + USB_ERR("host->bulkWrite() returned %d", res); Thread::wait(100); return -1; } @@ -142,7 +142,7 @@ } else { - ERR("CAN'T WRITE!"); + USB_ERR("CAN'T WRITE!"); } tx_mtx.unlock(); return c; @@ -162,7 +162,7 @@ } else { - ERR("CAN'T READ!"); + USB_ERR("CAN'T READ!"); } rx_mtx.unlock(); return c; @@ -305,7 +305,7 @@ else //Error, try reading again { //lock_rx.unlock(); - DBG("Trying again"); + USB_DBG("Trying again"); readPacket(); } }