Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 16:37:49 by 1.7.2