Bonjour/Zerconf library

Dependencies:   mbed

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 SerialBuf::SerialBuf(int len) : m_trmt(false), m_pSerial(NULL), m_intCanReadData(true), m_readMode(false) //Buffer length
00040 #if NET_USB_SERIAL
00041 , m_pUsbSerial(NULL) 
00042 #endif
00043 {
00044   m_buf = new char[len];
00045   m_bufLen=len;
00046   m_pRead=m_buf;
00047   m_pReadStart=m_buf;
00048   m_pReadByInt=m_buf;
00049   m_pWrite=m_buf;
00050 }
00051 
00052 SerialBuf::~SerialBuf()
00053 {
00054   delete[] m_buf;
00055 }
00056 
00057 void SerialBuf::attach(Serial* pSerial)
00058 {
00059   m_pSerial = pSerial;
00060   m_pSerial->attach<SerialBuf>(this, &SerialBuf::onSerialInterrupt);
00061 //  onSerialInterrupt(); //Flush hw buffer into current buf
00062 }
00063 
00064 #if NET_USB_SERIAL
00065 void SerialBuf::attach(UsbSerial* pUsbSerial)
00066 {
00067   m_pUsbSerial = pUsbSerial;
00068   //m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onSerialInterrupt);
00069   m_usbTick.attach_us<SerialBuf>(this, &SerialBuf::onSerialInterrupt, 10000); 
00070 }
00071 #endif
00072 
00073 void SerialBuf::detach()
00074 {
00075   if(m_pSerial)
00076   {
00077     m_pSerial->attach(0);
00078     m_pSerial = NULL;
00079   }
00080   #if NET_USB_SERIAL
00081   else if(m_pUsbSerial)
00082   {
00083     m_usbTick.detach();
00084     m_pUsbSerial = NULL;
00085   }
00086   #endif
00087 }
00088 
00089 
00090 void SerialBuf::onSerialInterrupt() //Callback from m_pSerial
00091 {
00092   //DBG("\r\n[INT]");
00093  // Timer tmr;
00094  // tmr.start();
00095 //  static volatile bool incompleteData = true;
00096 //  static volatile char* pLastIntReadPos = m_buf;
00097   if(!(m_pStream(readable())))
00098   {
00099     return;
00100   }
00101   int len=0;
00102   do
00103   {
00104     if(room()>0)
00105     {
00106       len++;
00107 #ifdef __DEBUGVERBOSE
00108       char c = m_pStream(getc());
00109       DBG("\r\n[%c]",c);
00110       put(c);
00111 #else
00112       put(m_pStream(getc()));
00113 #endif
00114     }
00115     else
00116     {
00117       DBG("\r\nWARN: SerialBuf Overrun");
00118       m_pStream(getc());
00119     }
00120   } while(m_pStream(readable()));
00121   //  DBG("\r\n[/INT]=*%d*\r\n w len=*%d*",tmr.read_us(),len);
00122 
00123   if( m_intCanReadData )
00124   {
00125     volatile bool u_readMode = m_readMode; //Save User context on interrupt
00126     volatile bool handled = onRead();
00127     if(handled)
00128     {
00129       m_pReadByInt = m_pRead;
00130       if(m_pRead==m_pReadStart)
00131       {
00132         //Data has been processed
00133       }
00134       else
00135       {
00136         m_pRead = m_pReadStart;
00137         m_intCanReadData = false; 
00138         //Data has to be processed in user space
00139       }
00140     }
00141     setReadMode( u_readMode );
00142   }
00143 
00144 
00145 #if 0  
00146   if( incompleteData  || ( pLastIntReadPos != m_pRead ) )
00147   {
00148     bool u_readMode = m_readMode; //Save User context on interrupt
00149     incompleteData = onRead();
00150     if(!incompleteData)
00151       m_pRead = m_pReadStart;
00152     pLastIntReadPos = m_pRead;
00153     
00154   }
00155 #endif
00156   
00157 }
00158 
00159 char SerialBuf::getc()
00160 {
00161 //  DBG("\r\n\[GETC]");
00162 #if 0
00163   if(m_trmt) //Was transmitting
00164   {
00165     DBG("\r\n<\r\n");
00166     m_trmt=false;
00167   }
00168 #endif
00169   char c;
00170   c = get();
00171   DBG("%c", c);
00172 //  DBG("\r\n[/GETC]");
00173   return c;
00174 }
00175 
00176 void SerialBuf::putc(char c)
00177 {
00178 #if 0
00179   if(!m_trmt) //Was receiving
00180   {
00181     DBG("\r\n>\r\n");
00182     m_trmt=true;
00183   }
00184 #endif
00185 //  m_pSerial->writeable();
00186 //  while(!m_pSerial->writeable() /*|| m_pSerial->readable()*/)
00187 //  {
00188 //    wait_us(100);
00189 //    DBG("\r\nWait...\r\n");
00190 //  }
00191 /*
00192   NVIC_DisableIRQ(UART1_IRQn);
00193   NVIC_DisableIRQ(UART2_IRQn);
00194   NVIC_DisableIRQ(UART3_IRQn);
00195   */
00196 //  onSerialInterrupt();
00197   m_pStream(putc(c));
00198 /*  NVIC_EnableIRQ(UART1_IRQn);
00199   NVIC_EnableIRQ(UART2_IRQn);
00200   NVIC_EnableIRQ(UART3_IRQn);
00201   */
00202   DBG("%c", c);
00203 }
00204 
00205 /* Buffer Stuff */
00206 
00207 bool SerialBuf::readable()
00208 {
00209 //  onSerialInterrupt(); //Flush hw buffer into current buf
00210  // DBG("\r\nLen=%d",len());
00211   return (len()>0);
00212 }
00213 
00214 bool SerialBuf::writeable()
00215 {
00216   return m_pStream(writeable());
00217 }
00218 
00219 void SerialBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
00220 {
00221   if(m_readMode == true && readMode == false)
00222   {
00223     //Trash bytes that have been read
00224     flushRead();
00225   }
00226   m_readMode=readMode;
00227 }
00228 
00229 void SerialBuf::flushRead() //Delete chars that have been read (only useful with readMode = true)
00230 {
00231   m_pReadStart = m_pRead;
00232 }
00233 
00234 void SerialBuf::resetRead() //Go back to initial read position (only useful with readMode = true)
00235 {
00236   m_pRead = m_pReadStart;
00237 }
00238 
00239 bool SerialBuf::onRead()
00240 {
00241   return false;
00242   //Nothing here
00243 }
00244 
00245 char SerialBuf::get() //Get a char from buf
00246 {
00247   //WARN: Must call len() before
00248   char c = *m_pRead;
00249   m_pRead++;
00250   
00251   if(m_pRead>=m_buf+m_bufLen)
00252     m_pRead=m_buf;
00253     
00254   if(!m_readMode) //If readmode=false, trash this char
00255     m_pReadStart=m_pRead;
00256     
00257   if(m_pRead==m_pReadByInt) //Next message can be processed by interrupt
00258     m_intCanReadData = true;
00259 /*  else if(m_intCanReadData) //Increment this address
00260     m_pReadByInt=m_pRead;*/
00261   return c;
00262 }
00263 
00264 void SerialBuf::put(char c) //Put a char in buf
00265 {
00266   //WARN: Must call room() before
00267   *m_pWrite = c;
00268   m_pWrite++;
00269   if(m_pWrite>=m_buf+m_bufLen)
00270     m_pWrite=m_buf;
00271 }
00272 
00273 int SerialBuf::room() //Return room available in buf
00274 {
00275   //return m_bufLen - len() - 1; //-1 is to avoid loop
00276   if ( m_pReadStart > m_pWrite )
00277     return ( m_pReadStart - m_pWrite - 1 );
00278   else
00279     return m_bufLen - ( m_pWrite - m_pReadStart ) - 1;
00280 }
00281 
00282 int SerialBuf::len() //Return chars length in buf
00283 {
00284   if ( m_pWrite >= m_pRead )
00285     return ( m_pWrite - m_pRead );
00286   else
00287     return m_bufLen - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_bufLen) - m_pRead ) + ( m_pWrite - m_buf )
00288 }
00289 
00290 #endif