EthernetNetIf Compatibility.
Dependents: XBeeWiFi_SPI_example
Fork of NetServicesSource by
Diff: drv/serial/usb/UsbSerial.cpp
- Revision:
- 0:632c9925f013
- Child:
- 4:fd826cad83c0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drv/serial/usb/UsbSerial.cpp Fri Jun 11 16:05:15 2010 +0000 @@ -0,0 +1,184 @@ + +/* +Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) + +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 "UsbSerial.h" +#include "usbserialif.h" +#include "rpc.h" + +#include "netCfg.h" +#if NET_USB_SERIAL + +namespace mbed { + +#define BUF_LEN 64 +#define FLUSH_TMOUT 10000 //US + +UsbSerial::UsbSerial(int usbDev, int usbIf, const char *name /*= NULL*/) : Stream(name), m_txTimeout() { + m_inBufEven = new char[BUF_LEN]; + m_inBufOdd = new char[BUF_LEN]; + m_pInBufPos = m_inBufUsr = m_inBufEven; + m_inBufTrmt = m_inBufOdd; + + m_outBufEven = new char[BUF_LEN]; + m_outBufOdd = new char[BUF_LEN]; + m_pOutBufPos = m_outBufUsr = m_outBufEven; + m_outBufTrmt = m_outBufOdd; + + m_inBufLen = m_outBufLen = 0; + +// startRx(); +} + +UsbSerial::~UsbSerial() +{ + delete[] m_inBufEven; + delete[] m_inBufOdd; + delete[] m_outBufEven; + delete[] m_outBufOdd; +} + +void UsbSerial::baud(int baudrate) { + // +} + +void UsbSerial::format(int bits, int parity, int stop) { + // +} + +int UsbSerial::_getc() { + char c; + c = *m_pInBufPos; + m_pInBufPos++; + 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 + { + startTx(); + } + else + { + m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + } + return c; +} + +int UsbSerial::readable() { + if( (m_pInBufPos - m_inBufUsr) < m_inBufLen ) + { + // printf("\r\nREADABLE\r\n"); + return true; + } + else + { + // printf("\r\nNOT READABLE\r\n"); + startRx(); //Try to swap packets & start another transmission + return ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false; + } +} + +int UsbSerial::writeable() { + // printf("\r\nWRITEABLE???\r\n"); + return (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN); +} + + +void UsbSerial::startTx() +{ + if( SerialTransmitted() < 0 ) + { + //Wait & retry + m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT); + return; + } + + m_outBufLen = m_pOutBufPos - m_outBufUsr; + + //Swap buffers + volatile char* swapBuf = m_outBufUsr; + m_outBufUsr = m_outBufTrmt; + m_outBufTrmt = swapBuf; + + SerialTx((volatile USB_INT08U*)m_outBufTrmt, m_outBufLen); + + m_pOutBufPos = m_outBufUsr; + +} + +void UsbSerial::startRx() +{ + if( (m_pInBufPos - m_inBufUsr) < m_inBufLen ) + { + //User buf is not empty, cannot swap now... + return; + } + int len = SerialReceived(); + if( len < 0 ) + { + //Previous transmission not completed + return; + } + + m_inBufLen = len; + + //Swap buffers + 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; + +} + + + +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) + }; + return methods; +} + +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*> > }, + RPC_METHOD_END + }; + static rpc_class c = { "UsbSerial", funcs, NULL }; + return &c; +} + +} // namespace mbed + +#endif +