EthernetNetIf Compatibility.
Dependents: XBeeWiFi_SPI_example
Fork of NetServicesSource by
Diff: drv/serial/buf/SerialBuf.cpp
- Revision:
- 4:fd826cad83c0
- Parent:
- 0:632c9925f013
- Child:
- 9:c79fa4034f5b
diff -r 95e0bc00a1bb -r fd826cad83c0 drv/serial/buf/SerialBuf.cpp --- 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