Bonjour/Zerconf library

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UsbSerial.cpp Source File

UsbSerial.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "UsbSerial.h"
00025 #include "usbserialif.h"
00026 #include "rpc.h"
00027 
00028 #include "netCfg.h"
00029 #if NET_USB_SERIAL
00030 
00031 namespace mbed {
00032 
00033 #define BUF_LEN 64
00034 #define FLUSH_TMOUT 10000 //US
00035 
00036 UsbSerial::UsbSerial(int usbDev, int usbIf, const char *name /*= NULL*/) : Stream(name), m_txTimeout() { 
00037   m_inBufEven = new char[BUF_LEN];
00038   m_inBufOdd = new char[BUF_LEN];
00039   m_pInBufPos = m_inBufUsr = m_inBufEven;
00040   m_inBufTrmt = m_inBufOdd;
00041   
00042   m_outBufEven = new char[BUF_LEN];
00043   m_outBufOdd = new char[BUF_LEN];
00044   m_pOutBufPos = m_outBufUsr = m_outBufEven;
00045   m_outBufTrmt = m_outBufOdd;
00046   
00047   m_inBufLen = m_outBufLen = 0;
00048   
00049 //  startRx();
00050 }
00051 
00052 UsbSerial::~UsbSerial()
00053 {
00054   delete[] m_inBufEven;
00055   delete[] m_inBufOdd;
00056   delete[] m_outBufEven;
00057   delete[] m_outBufOdd;
00058 }
00059 
00060 void UsbSerial::baud(int baudrate) { 
00061     //
00062 }
00063 
00064 void UsbSerial::format(int bits, int parity, int stop) { 
00065   //
00066 } 
00067 
00068 int UsbSerial::_getc() { 
00069     char c;
00070     c = *m_pInBufPos;
00071     m_pInBufPos++;
00072     return c;
00073 }
00074 
00075 int UsbSerial::_putc(int c) { 
00076     m_txTimeout.detach(); //Do not want to be interrupted, accessing shared data here...
00077     *m_pOutBufPos = (char) c;
00078     m_pOutBufPos++;
00079     if( (m_pOutBufPos - m_outBufUsr) == BUF_LEN) //Must flush
00080     {
00081       startTx();
00082     }
00083     else
00084     {
00085       m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);
00086     }
00087     return c;
00088 }
00089 
00090 int UsbSerial::readable() { 
00091     if( (m_pInBufPos - m_inBufUsr) < m_inBufLen )
00092     {
00093     //  printf("\r\nREADABLE\r\n");
00094       return true;
00095     }
00096     else
00097     {
00098     //  printf("\r\nNOT READABLE\r\n");
00099       startRx(); //Try to swap packets & start another transmission
00100       return ((m_pInBufPos - m_inBufUsr) < m_inBufLen )?true:false;
00101     }
00102 }
00103 
00104 int UsbSerial::writeable() { 
00105   //  printf("\r\nWRITEABLE???\r\n");
00106     return (bool)( (m_pOutBufPos - m_outBufUsr) < BUF_LEN);
00107 }
00108 
00109 
00110 void UsbSerial::startTx()
00111 {
00112   if( SerialTransmitted() < 0 )
00113   {
00114     //Wait & retry
00115     m_txTimeout.attach_us(this, &UsbSerial::startTx, FLUSH_TMOUT);
00116     return;
00117   }
00118   
00119   m_outBufLen = m_pOutBufPos - m_outBufUsr;
00120   
00121   //Swap buffers
00122   volatile char* swapBuf = m_outBufUsr;
00123   m_outBufUsr = m_outBufTrmt;
00124   m_outBufTrmt = swapBuf;
00125   
00126   SerialTx((volatile USB_INT08U*)m_outBufTrmt, m_outBufLen);
00127   
00128   m_pOutBufPos = m_outBufUsr;
00129 
00130 }
00131 
00132 void UsbSerial::startRx()
00133 {
00134   if( (m_pInBufPos - m_inBufUsr) < m_inBufLen )
00135   {
00136     //User buf is not empty, cannot swap now...
00137     return;
00138   }
00139   int len = SerialReceived();
00140   if( len < 0 )
00141   {
00142     //Previous transmission not completed
00143     return;
00144   }
00145   
00146   m_inBufLen = len;
00147   
00148   //Swap buffers
00149   volatile char* swapBuf = m_inBufUsr;
00150   m_inBufUsr =  m_inBufTrmt;
00151   m_inBufTrmt = swapBuf;
00152   
00153   SerialRx((volatile USB_INT08U*)m_inBufTrmt, BUF_LEN); //Start another transmission
00154   
00155   m_pInBufPos = m_inBufUsr;
00156 
00157 }
00158 
00159 
00160 
00161 const struct rpc_method *UsbSerial::get_rpc_methods() { 
00162     static const rpc_method methods[] = {
00163         { "baud", rpc_method_caller<UsbSerial, int, &UsbSerial::baud> },
00164         { "format", rpc_method_caller<UsbSerial, int, int, int, &UsbSerial::format> },
00165         { "readable", rpc_method_caller<int, UsbSerial, &UsbSerial::readable> },
00166         { "writeable", rpc_method_caller<int, UsbSerial, &UsbSerial::writeable> },
00167         RPC_METHOD_SUPER(Stream)
00168     };
00169     return methods;
00170 }
00171 
00172 struct rpc_class *UsbSerial::get_rpc_class() {
00173     static const rpc_function funcs[] = {
00174         { "new", rpc_function_caller<const char*, int, int, const char*, Base::construct<UsbSerial,int,int,const char*> > },
00175         RPC_METHOD_END
00176     };
00177     static rpc_class c = { "UsbSerial", funcs, NULL };
00178     return &c;
00179 }
00180 
00181 } // namespace mbed
00182 
00183 #endif
00184