NetServices Stack source

Dependents:   HelloWorld ServoInterfaceBoardExample1 4180_Lab4

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