EthernetNetIf Compatibility.
Dependents: XBeeWiFi_SPI_example
Fork of NetServicesSource by
Diff: drv/serial/usb/UsbSerial.cpp
- Revision:
- 4:fd826cad83c0
- Parent:
- 0:632c9925f013
--- a/drv/serial/usb/UsbSerial.cpp Fri Jun 18 10:38:57 2010 +0000 +++ b/drv/serial/usb/UsbSerial.cpp Fri Jul 09 14:46:47 2010 +0000 @@ -21,9 +21,12 @@ THE SOFTWARE. */ +#include "rpc.h" + #include "UsbSerial.h" -#include "usbserialif.h" -#include "rpc.h" + +//#define __DEBUG +#include "dbg/dbg.h" #include "netCfg.h" #if NET_USB_SERIAL @@ -31,9 +34,11 @@ namespace mbed { #define BUF_LEN 64 -#define FLUSH_TMOUT 10000 //US +#define FLUSH_TMOUT 100000 //US -UsbSerial::UsbSerial(int usbDev, int usbIf, const char *name /*= NULL*/) : Stream(name), m_txTimeout() { +UsbSerial::UsbSerial(UsbDevice* pDevice, int epIn, int epOut, const char* name /*= NULL*/) : Stream(name), m_epIn(pDevice, epIn, true, USB_BULK, BUF_LEN), m_epOut(pDevice, epOut, false, USB_BULK, BUF_LEN), +m_pInCbItem(NULL), m_pInCbMeth(NULL), m_pOutCbItem(NULL), m_pOutCbMeth(NULL) +{ m_inBufEven = new char[BUF_LEN]; m_inBufOdd = new char[BUF_LEN]; m_pInBufPos = m_inBufUsr = m_inBufEven; @@ -46,7 +51,14 @@ m_inBufLen = m_outBufLen = 0; -// startRx(); + DBG("Starting RX'ing on in ep\n"); + + m_timeout = false; + + m_epIn.setOnCompletion(this, &UsbSerial::onEpInTransfer); + m_epOut.setOnCompletion(this, &UsbSerial::onEpOutTransfer); + + startRx(); } UsbSerial::~UsbSerial() @@ -65,57 +77,157 @@ // } +#if 0 //For doc only +template <class T> +void attach(T* pCbItem, void (T::*pCbMeth)()) +{ + m_pCbItem = (CDummy*) pCbItem; + m_pCbMeth = (void (CDummy::*)()) pCbMeth; +} +#endif + int UsbSerial::_getc() { + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); char c; c = *m_pInBufPos; m_pInBufPos++; + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); return c; } int UsbSerial::_putc(int c) { - m_txTimeout.detach(); //Do not want to be interrupted, accessing shared data here... - *m_pOutBufPos = (char) c; - m_pOutBufPos++; - if( (m_pOutBufPos - m_outBufUsr) == BUF_LEN) //Must flush + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); + if( (m_pOutBufPos - m_outBufUsr) < BUF_LEN ) { + *m_pOutBufPos = (char) c; + m_pOutBufPos++; + } + else + { + DBG("NO WAY!!!\n"); + } + #if 1 + if( (m_pOutBufPos - m_outBufUsr) >= BUF_LEN ) //Must flush + { + if(m_timeout) + m_txTimeout.detach(); startTx(); } else { - m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + /*if(m_timeout) + m_txTimeout.detach(); + m_timeout = true; + m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);*/ + if(!m_timeout) + { + m_timeout = true; + m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + } } + #endif + //startTx(); + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); return c; } int UsbSerial::readable() { + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); + int res; if( (m_pInBufPos - m_inBufUsr) < m_inBufLen ) { - // printf("\r\nREADABLE\r\n"); - return true; + //DBG("\r\nREADABLE\r\n"); + res = true; } else { - // printf("\r\nNOT READABLE\r\n"); + //DBG("\r\nNOT READABLE\r\n"); startRx(); //Try to swap packets & start another transmission - return ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false; + res = ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false; } + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); + return (bool)res; } int UsbSerial::writeable() { - // printf("\r\nWRITEABLE???\r\n"); - return (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN); + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); + NVIC_DisableIRQ(USB_IRQn); + // DBG("\r\nWRITEABLE???\r\n"); + int res = (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN); + NVIC_EnableIRQ(USB_IRQn); + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); + return res; +} + +void UsbSerial::onReadable() +{ + if(m_pInCbItem && m_pInCbMeth) + (m_pInCbItem->*m_pInCbMeth)(); } +void UsbSerial::onWriteable() +{ + if(m_pOutCbItem && m_pOutCbMeth) + (m_pOutCbItem->*m_pOutCbMeth)(); +} + +void UsbSerial::onEpInTransfer() +{ + int len = m_epIn.status(); + DBG("RX transfer completed w len=%d\n",len); + startRx(); + if(len > 0) + onReadable(); +} + +void UsbSerial::onEpOutTransfer() +{ + int len = m_epOut.status(); + DBG("TX transfer completed w len=%d\n",len); + if(m_timeout) + m_txTimeout.detach(); + startTx(); + if(len > 0) + onWriteable(); +} void UsbSerial::startTx() { - if( SerialTransmitted() < 0 ) + + DBG("Transfer>\n"); + + m_timeout = false; + +// m_txTimeout.detach(); + + if(!(m_pOutBufPos - m_outBufUsr)) { - //Wait & retry - m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + DBG("?!?!?\n"); return; } + if( m_epOut.status() == USBERR_PROCESSING ) + { + //Wait & retry + //m_timeout = true; + //m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + DBG("Ep is busy...\n"); + return; + } + + if( m_epOut.status() < 0 ) + { + DBG("Tx trying again...\n"); + m_epOut.transfer((volatile uint8_t*)m_outBufTrmt, m_outBufLen); + return; + } + m_outBufLen = m_pOutBufPos - m_outBufUsr; //Swap buffers @@ -123,7 +235,7 @@ m_outBufUsr = m_outBufTrmt; m_outBufTrmt = swapBuf; - SerialTx((volatile USB_INT08U*)m_outBufTrmt, m_outBufLen); + m_epOut.transfer((volatile uint8_t*)m_outBufTrmt, m_outBufLen); m_pOutBufPos = m_outBufUsr; @@ -136,10 +248,16 @@ //User buf is not empty, cannot swap now... return; } - int len = SerialReceived(); + int len = m_epIn.status(); + if( len == USBERR_PROCESSING ) + { + //Previous transmission not completed + return; + } if( len < 0 ) { - //Previous transmission not completed + DBG("Rx trying again...\n"); + m_epIn.transfer((volatile uint8_t*)m_inBufTrmt, BUF_LEN); //Start another transmission return; } @@ -149,19 +267,16 @@ volatile char* swapBuf = m_inBufUsr; m_inBufUsr = m_inBufTrmt; m_inBufTrmt = swapBuf; - - SerialRx((volatile USB_INT08U*)m_inBufTrmt, BUF_LEN); //Start another transmission + m_pInBufPos = m_inBufUsr; - m_pInBufPos = m_inBufUsr; - + DBG("Starting new transfer\n"); + m_epIn.transfer((volatile uint8_t*)m_inBufTrmt, BUF_LEN); //Start another transmission + } - - +#ifdef MBED_RPC const struct rpc_method *UsbSerial::get_rpc_methods() { static const rpc_method methods[] = { - { "baud", rpc_method_caller<UsbSerial, int, &UsbSerial::baud> }, - { "format", rpc_method_caller<UsbSerial, int, int, int, &UsbSerial::format> }, { "readable", rpc_method_caller<int, UsbSerial, &UsbSerial::readable> }, { "writeable", rpc_method_caller<int, UsbSerial, &UsbSerial::writeable> }, RPC_METHOD_SUPER(Stream) @@ -171,12 +286,13 @@ struct rpc_class *UsbSerial::get_rpc_class() { static const rpc_function funcs[] = { - { "new", rpc_function_caller<const char*, int, int, const char*, Base::construct<UsbSerial,int,int,const char*> > }, + /*{ "new", rpc_function_caller<const char*, UsbDevice*, int, int, const char*, Base::construct<UsbSerial,UsbDevice*,int,int,const char*> > },*/ //RPC is buggy RPC_METHOD_END }; static rpc_class c = { "UsbSerial", funcs, NULL }; return &c; } +#endif } // namespace mbed