NetServices Stack source

Dependents:   HelloWorld ServoInterfaceBoardExample1 4180_Lab4

Revision:
4:fd826cad83c0
Parent:
0:632c9925f013
Child:
9:c79fa4034f5b
--- a/drv/serial/buf/SerialBuf.cpp	Fri Jun 18 10:38:57 2010 +0000
+++ b/drv/serial/buf/SerialBuf.cpp	Fri Jul 09 14:46:47 2010 +0000
@@ -36,255 +36,200 @@
 #define m_pStream( a ) (m_pSerial->a)
 #endif
 
-SerialBuf::SerialBuf(int len) : m_trmt(false), m_pSerial(NULL), m_intCanReadData(true), m_readMode(false) //Buffer length
+//Circular buf
+
+SerialCircularBuf::SerialCircularBuf(int len) : m_readMode(false)
+{
+  m_buf = new char[len];
+  m_len = len;
+  m_pReadStart = m_pRead = m_buf;
+  m_pWrite = m_buf;
+} 
+
+SerialCircularBuf::~SerialCircularBuf()
+{
+  if(m_buf)
+    delete[] m_buf;
+}
+
+int SerialCircularBuf::room() //Return room available in buf
+{
+  //return m_len - len() - 1; //-1 is to avoid loop
+  if ( m_pReadStart > m_pWrite )
+    return ( m_pReadStart - m_pWrite - 1 );
+  else
+    return m_len - ( m_pWrite - m_pReadStart ) - 1;
+}
+
+int SerialCircularBuf::len() //Return chars length in buf
+{
+  if ( m_pWrite >= m_pRead )
+    return ( m_pWrite - m_pRead );
+  else
+    return m_len - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_len) - m_pRead ) + ( m_pWrite - m_buf )
+}
+
+void SerialCircularBuf::write(char c)
+{
+#if 0
+  if(!room())
+    return;
+#endif
+  //WARN: Must call room() before
+  *m_pWrite = c;
+  m_pWrite++;
+  if(m_pWrite>=m_buf+m_len)
+    m_pWrite=m_buf;
+}
+char SerialCircularBuf::read()
+{
+#if 0
+  if(!len())
+    return 0;
+#endif
+  //WARN: Must call len() before
+  char c = *m_pRead;
+  m_pRead++;
+  
+  if(m_pRead>=m_buf+m_len)
+    m_pRead=m_buf;
+    
+  if(!m_readMode) //If readmode=false, trash this char
+    m_pReadStart=m_pRead;
+    
+  return c;
+}
+
+void SerialCircularBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
+{
+  if(m_readMode == true && readMode == false)
+  {
+    //Trash bytes that have been read
+    flushRead();
+  }
+  m_readMode = readMode;
+}
+
+void SerialCircularBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true)
+{
+  m_pReadStart = m_pRead;
+}
+
+void SerialCircularBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true)
+{
+  m_pRead = m_pReadStart;
+}
+
+//SerialBuf
+
+SerialBuf::SerialBuf(int len) : m_rxBuf(len), m_txBuf(len), m_pSerial(NULL) //Buffer length
 #if NET_USB_SERIAL
 , m_pUsbSerial(NULL) 
 #endif
 {
-  m_buf = new char[len];
-  m_bufLen=len;
-  m_pRead=m_buf;
-  m_pReadStart=m_buf;
-  m_pReadByInt=m_buf;
-  m_pWrite=m_buf;
+  DBG("New Serial buf@%p\n", this);
 }
 
 SerialBuf::~SerialBuf()
 {
-  delete[] m_buf;
+
 }
 
 void SerialBuf::attach(Serial* pSerial)
 {
+  DBG("Serial buf@%p in attach\n", this);
   m_pSerial = pSerial;
-  m_pSerial->attach<SerialBuf>(this, &SerialBuf::onSerialInterrupt);
-//  onSerialInterrupt(); //Flush hw buffer into current buf
+  m_pSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, Serial::RxIrq);
+  m_pSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, Serial::TxIrq);
+  onRxInterrupt(); //Read data
+}
+
+void SerialBuf::detach()
+{
+  if(m_pSerial)
+  {
+    m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::RxIrq);
+    m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::TxIrq);
+    m_pSerial = NULL;
+  }
+  #if NET_USB_SERIAL
+  else if(m_pUsbSerial)
+  {
+    m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::RxIrq);
+    m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::TxIrq);
+    m_pUsbSerial = NULL;
+  }
+  #endif
 }
 
 #if NET_USB_SERIAL
 void SerialBuf::attach(UsbSerial* pUsbSerial)
 {
   m_pUsbSerial = pUsbSerial;
-  //m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onSerialInterrupt);
-  m_usbTick.attach_us<SerialBuf>(this, &SerialBuf::onSerialInterrupt, 10000); 
+  m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, UsbSerial::RxIrq);
+  m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, UsbSerial::TxIrq);
+  onRxInterrupt(); //Read data
 }
 #endif
 
-void SerialBuf::detach()
-{
-  if(m_pSerial)
-  {
-    m_pSerial->attach(0);
-    m_pSerial = NULL;
-  }
-  #if NET_USB_SERIAL
-  else if(m_pUsbSerial)
-  {
-    m_usbTick.detach();
-    m_pUsbSerial = NULL;
-  }
-  #endif
-}
-
-
-void SerialBuf::onSerialInterrupt() //Callback from m_pSerial
-{
-  //DBG("\r\n[INT]");
- // Timer tmr;
- // tmr.start();
-//  static volatile bool incompleteData = true;
-//  static volatile char* pLastIntReadPos = m_buf;
-  if(!(m_pStream(readable())))
-  {
-    return;
-  }
-  int len=0;
-  do
-  {
-    if(room()>0)
-    {
-      len++;
-#ifdef __DEBUGVERBOSE
-      char c = m_pStream(getc());
-      DBG("\r\n[%c]",c);
-      put(c);
-#else
-      put(m_pStream(getc()));
-#endif
-    }
-    else
-    {
-      DBG("\r\nWARN: SerialBuf Overrun");
-      m_pStream(getc());
-    }
-  } while(m_pStream(readable()));
-  //  DBG("\r\n[/INT]=*%d*\r\n w len=*%d*",tmr.read_us(),len);
-
-  if( m_intCanReadData )
-  {
-    volatile bool u_readMode = m_readMode; //Save User context on interrupt
-    volatile bool handled = onRead();
-    if(handled)
-    {
-      m_pReadByInt = m_pRead;
-      if(m_pRead==m_pReadStart)
-      {
-        //Data has been processed
-      }
-      else
-      {
-        m_pRead = m_pReadStart;
-        m_intCanReadData = false; 
-        //Data has to be processed in user space
-      }
-    }
-    setReadMode( u_readMode );
-  }
-
-
-#if 0  
-  if( incompleteData  || ( pLastIntReadPos != m_pRead ) )
-  {
-    bool u_readMode = m_readMode; //Save User context on interrupt
-    incompleteData = onRead();
-    if(!incompleteData)
-      m_pRead = m_pReadStart;
-    pLastIntReadPos = m_pRead;
-    
-  }
-#endif
-  
-}
-
 char SerialBuf::getc()
 {
-//  DBG("\r\n\[GETC]");
-#if 0
-  if(m_trmt) //Was transmitting
-  {
-    DBG("\r\n<\r\n");
-    m_trmt=false;
-  }
-#endif
-  char c;
-  c = get();
-  DBG("%c", c);
-//  DBG("\r\n[/GETC]");
+  while(!readable());
+  char c = m_rxBuf.read();
   return c;
 }
 
 void SerialBuf::putc(char c)
 {
-#if 0
-  if(!m_trmt) //Was receiving
-  {
-    DBG("\r\n>\r\n");
-    m_trmt=true;
-  }
-#endif
-//  m_pSerial->writeable();
-//  while(!m_pSerial->writeable() /*|| m_pSerial->readable()*/)
-//  {
-//    wait_us(100);
-//    DBG("\r\nWait...\r\n");
-//  }
-/*
-  NVIC_DisableIRQ(UART1_IRQn);
-  NVIC_DisableIRQ(UART2_IRQn);
-  NVIC_DisableIRQ(UART3_IRQn);
-  */
-//  onSerialInterrupt();
-  m_pStream(putc(c));
-/*  NVIC_EnableIRQ(UART1_IRQn);
-  NVIC_EnableIRQ(UART2_IRQn);
-  NVIC_EnableIRQ(UART3_IRQn);
-  */
-  DBG("%c", c);
+  while(!writeable());
+  m_txBuf.write(c);
+  onTxInterrupt();
 }
 
-/* Buffer Stuff */
-
 bool SerialBuf::readable()
 {
-//  onSerialInterrupt(); //Flush hw buffer into current buf
- // DBG("\r\nLen=%d",len());
-  return (len()>0);
+  if( !m_rxBuf.len() ) //Fill buf if possible
+    onRxInterrupt();
+  return (bool)m_rxBuf.len();
 }
 
 bool SerialBuf::writeable()
 {
-  return m_pStream(writeable());
+  if( !m_rxBuf.room() ) //Free buf is possible
+    onTxInterrupt();
+  return (bool)m_txBuf.room();
 }
 
 void SerialBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
 {
-  if(m_readMode == true && readMode == false)
-  {
-    //Trash bytes that have been read
-    flushRead();
-  }
-  m_readMode=readMode;
+  m_rxBuf.setReadMode(readMode);
 }
 
-void SerialBuf::flushRead() //Delete chars that have been read (only useful with readMode = true)
+void SerialBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true)
 {
-  m_pReadStart = m_pRead;
+  m_rxBuf.flushRead();
 }
 
-void SerialBuf::resetRead() //Go back to initial read position (only useful with readMode = true)
+void SerialBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true)
 {
-  m_pRead = m_pReadStart;
-}
-
-bool SerialBuf::onRead()
-{
-  return false;
-  //Nothing here
+  m_rxBuf.resetRead();
 }
 
-char SerialBuf::get() //Get a char from buf
+void SerialBuf::onRxInterrupt() //Callback from m_pSerial
 {
-  //WARN: Must call len() before
-  char c = *m_pRead;
-  m_pRead++;
-  
-  if(m_pRead>=m_buf+m_bufLen)
-    m_pRead=m_buf;
-    
-  if(!m_readMode) //If readmode=false, trash this char
-    m_pReadStart=m_pRead;
-    
-  if(m_pRead==m_pReadByInt) //Next message can be processed by interrupt
-    m_intCanReadData = true;
-/*  else if(m_intCanReadData) //Increment this address
-    m_pReadByInt=m_pRead;*/
-  return c;
+  while( m_rxBuf.room() && m_pStream(readable()) )
+  {
+    m_rxBuf.write(m_pStream(getc()));
+  }
 }
 
-void SerialBuf::put(char c) //Put a char in buf
+void SerialBuf::onTxInterrupt() //Callback from m_pSerial
 {
-  //WARN: Must call room() before
-  *m_pWrite = c;
-  m_pWrite++;
-  if(m_pWrite>=m_buf+m_bufLen)
-    m_pWrite=m_buf;
+  while( m_txBuf.len() && m_pStream(writeable()) )
+  {
+    m_pStream(putc(m_txBuf.read()));
+  }
 }
 
-int SerialBuf::room() //Return room available in buf
-{
-  //return m_bufLen - len() - 1; //-1 is to avoid loop
-  if ( m_pReadStart > m_pWrite )
-    return ( m_pReadStart - m_pWrite - 1 );
-  else
-    return m_bufLen - ( m_pWrite - m_pReadStart ) - 1;
-}
-
-int SerialBuf::len() //Return chars length in buf
-{
-  if ( m_pWrite >= m_pRead )
-    return ( m_pWrite - m_pRead );
-  else
-    return m_bufLen - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_bufLen) - m_pRead ) + ( m_pWrite - m_buf )
-}
 
 #endif