Dependents:   TimeZoneDemo EthernetJackTestCode MMEx_Challenge ntp_mem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SerialBuf.cpp Source File

SerialBuf.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 "SerialBuf.h"
00025 #include "mbed.h"
00026 
00027 //#define __DEBUG
00028 #include "dbg/dbg.h"
00029 
00030 #include "netCfg.h"
00031 #if NET_GPRS
00032 
00033 #if NET_USB_SERIAL
00034 #define m_pStream( a ) (m_pSerial?m_pSerial->a:m_pUsbSerial->a)
00035 #else
00036 #define m_pStream( a ) (m_pSerial->a)
00037 #endif
00038 
00039 //Circular buf
00040 
00041 SerialCircularBuf::SerialCircularBuf(int len) : m_readMode(false)
00042 {
00043   m_buf = new char[len];
00044   m_len = len;
00045   m_pReadStart = m_pRead = m_buf;
00046   m_pWrite = m_buf;
00047 } 
00048 
00049 SerialCircularBuf::~SerialCircularBuf()
00050 {
00051   if(m_buf)
00052     delete[] m_buf;
00053 }
00054 
00055 int SerialCircularBuf::room() //Return room available in buf
00056 {
00057   //return m_len - len() - 1; //-1 is to avoid loop
00058   if ( m_pReadStart > m_pWrite )
00059     return ( m_pReadStart - m_pWrite - 1 );
00060   else
00061     return m_len - ( m_pWrite - m_pReadStart ) - 1;
00062 }
00063 
00064 int SerialCircularBuf::len() //Return chars length in buf
00065 {
00066   if ( m_pWrite >= m_pRead )
00067     return ( m_pWrite - m_pRead );
00068   else
00069     return m_len - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_len) - m_pRead ) + ( m_pWrite - m_buf )
00070 }
00071 
00072 void SerialCircularBuf::write(char c)
00073 {
00074 #if 0
00075   if(!room())
00076     return;
00077 #endif
00078   //WARN: Must call room() before
00079   *m_pWrite = c;
00080   m_pWrite++;
00081   if(m_pWrite>=m_buf+m_len)
00082     m_pWrite=m_buf;
00083 }
00084 char SerialCircularBuf::read()
00085 {
00086 #if 0
00087   if(!len())
00088     return 0;
00089 #endif
00090   //WARN: Must call len() before
00091   char c = *m_pRead;
00092   m_pRead++;
00093   
00094   if(m_pRead>=m_buf+m_len)
00095     m_pRead=m_buf;
00096     
00097   if(!m_readMode) //If readmode=false, trash this char
00098     m_pReadStart=m_pRead;
00099     
00100   return c;
00101 }
00102 
00103 void SerialCircularBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
00104 {
00105   if(m_readMode == true && readMode == false)
00106   {
00107     //Trash bytes that have been read
00108     flushRead();
00109   }
00110   m_readMode = readMode;
00111 }
00112 
00113 void SerialCircularBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true)
00114 {
00115   m_pReadStart = m_pRead;
00116 }
00117 
00118 void SerialCircularBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true)
00119 {
00120   m_pRead = m_pReadStart;
00121 }
00122 
00123 //SerialBuf
00124 
00125 SerialBuf::SerialBuf(int len) : m_rxBuf(len), m_txBuf(len), m_pSerial(NULL) //Buffer length
00126 #if NET_USB_SERIAL
00127 , m_pUsbSerial(NULL) 
00128 #endif
00129 {
00130   DBG("New Serial buf@%p\n", this);
00131 }
00132 
00133 SerialBuf::~SerialBuf()
00134 {
00135 
00136 }
00137 
00138 void SerialBuf::attach(Serial* pSerial)
00139 {
00140   DBG("Serial buf@%p in attach\n", this);
00141   m_pSerial = pSerial;
00142   m_pSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, Serial::RxIrq);
00143   m_pSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, Serial::TxIrq);
00144   onRxInterrupt(); //Read data
00145 }
00146 
00147 void SerialBuf::detach()
00148 {
00149   if(m_pSerial)
00150   {
00151     m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::RxIrq);
00152     m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::TxIrq);
00153     m_pSerial = NULL;
00154   }
00155   #if NET_USB_SERIAL
00156   else if(m_pUsbSerial)
00157   {
00158     m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::RxIrq);
00159     m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::TxIrq);
00160     m_pUsbSerial = NULL;
00161   }
00162   #endif
00163 }
00164 
00165 #if NET_USB_SERIAL
00166 void SerialBuf::attach(UsbSerial* pUsbSerial)
00167 {
00168   m_pUsbSerial = pUsbSerial;
00169   m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, UsbSerial::RxIrq);
00170   m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, UsbSerial::TxIrq);
00171   onRxInterrupt(); //Read data
00172 }
00173 #endif
00174 
00175 char SerialBuf::getc()
00176 {
00177   while(!readable());
00178   char c = m_rxBuf.read();
00179   return c;
00180 }
00181 
00182 void SerialBuf::putc(char c)
00183 {
00184   while(!writeable());
00185   m_txBuf.write(c);
00186   onTxInterrupt();
00187 }
00188 
00189 bool SerialBuf::readable()
00190 {
00191   if( !m_rxBuf.len() ) //Fill buf if possible
00192     onRxInterrupt();
00193   return (m_rxBuf.len() > 0);
00194 }
00195 
00196 bool SerialBuf::writeable()
00197 {
00198   if( !m_txBuf.room() ) //Free buf is possible
00199     onTxInterrupt();
00200   return (m_txBuf.room() > 0);
00201 }
00202 
00203 void SerialBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
00204 {
00205   m_rxBuf.setReadMode(readMode);
00206 }
00207 
00208 void SerialBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true)
00209 {
00210   m_rxBuf.flushRead();
00211 }
00212 
00213 void SerialBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true)
00214 {
00215   m_rxBuf.resetRead();
00216 }
00217 
00218 void SerialBuf::onRxInterrupt() //Callback from m_pSerial
00219 {
00220   while( m_rxBuf.room() && m_pStream(readable()) )
00221   {
00222     m_rxBuf.write(m_pStream(getc()));
00223   }
00224 }
00225 
00226 void SerialBuf::onTxInterrupt() //Callback from m_pSerial
00227 {
00228   while( m_txBuf.len() && m_pStream(writeable()) )
00229   {
00230     m_pStream(putc(m_txBuf.read()));
00231   }
00232 }
00233 
00234 
00235 #endif