Darran Shepherd
/
AutoIpNetStack
Net stack with AutoIP enabled
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 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
Generated on Tue Jul 12 2022 15:37:05 by 1.7.2