Serial Port
|
00001 /* Arduino SerialPort Library 00002 * Copyright (C) 2011 by William Greiman 00003 * 00004 * This file is part of the Arduino SerialPort Library 00005 * 00006 * This Library is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This Library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with the Arduino SerialPort Library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00024 #include <SerialPort.h> 00025 //------------------------------------------------------------------------------ 00030 int SerialRingBuffer::available() { 00031 uint8_t s = SREG; 00032 cli(); 00033 int n = head_ - tail_; 00034 SREG = s; 00035 return n < 0 ? size_ + n : n; 00036 } 00037 //------------------------------------------------------------------------------ 00042 void SerialRingBuffer::flush() { 00043 uint8_t s = SREG; 00044 cli(); 00045 head_ = tail_ = 0; 00046 SREG = s; 00047 } 00048 //------------------------------------------------------------------------------ 00054 bool SerialRingBuffer::get(uint8_t* b) { 00055 buf_size_t t = tail_; 00056 if (head_ == t) return false; 00057 *b = buf_[t++]; 00058 tail_ = t < size_ ? t : 0; 00059 return true; 00060 } 00061 //------------------------------------------------------------------------------ 00072 SerialRingBuffer::buf_size_t SerialRingBuffer::get(uint8_t* b, buf_size_t n) { 00073 buf_size_t nr; 00074 cli(); 00075 buf_size_t h = head_; 00076 sei(); 00077 buf_size_t t = tail_; 00078 if (h < t) { 00079 nr = size_ - t; 00080 } else if (t < h) { 00081 nr = h - t; 00082 } else { 00083 return 0; 00084 } 00085 if (nr > n) nr = n; 00086 memcpy(b, &buf_[t], nr); 00087 t += nr; 00088 tail_ = t < size_ ? t : t - size_; 00089 return nr; 00090 } 00091 //------------------------------------------------------------------------------ 00096 void SerialRingBuffer::init(uint8_t* b, buf_size_t s) { 00097 buf_ = b; 00098 size_ = s; 00099 head_ = tail_ = 0; 00100 } 00101 //------------------------------------------------------------------------------ 00105 int SerialRingBuffer::peek() { 00106 return empty() ? -1 : buf_[tail_]; 00107 } 00108 //------------------------------------------------------------------------------ 00115 bool SerialRingBuffer::put(uint8_t b) { 00116 buf_size_t h = head_; 00117 // OK to store here even if ring is full. 00118 buf_[h++] = b; 00119 if (h >= size_) h = 0; 00120 if (h == tail_) return false; 00121 head_ = h; 00122 return true; 00123 } 00124 //------------------------------------------------------------------------------ 00135 SerialRingBuffer::buf_size_t 00136 SerialRingBuffer::put(const uint8_t* b, buf_size_t n) { 00137 cli(); 00138 buf_size_t t = tail_; 00139 sei(); 00140 buf_size_t space; // space in ring buffer 00141 buf_size_t h = head_; 00142 if (h < t) { 00143 space = t - h - 1; 00144 } else { 00145 space = size_ - h; 00146 if (t == 0) space -= 1; 00147 } 00148 if (n > space) n = space; 00149 memcpy(&buf_[h], b, n); 00150 h += n; 00151 head_ = h < size_ ? h : h - size_; 00152 return n; 00153 } 00154 //------------------------------------------------------------------------------ 00165 SerialRingBuffer::buf_size_t SerialRingBuffer::put_P(PGM_P b, buf_size_t n) { 00166 cli(); 00167 buf_size_t t = tail_; 00168 sei(); 00169 buf_size_t space; // space in ring buffer 00170 buf_size_t h = head_; 00171 if (h < t) { 00172 space = t - h - 1; 00173 } else { 00174 space = size_ - h; 00175 if (t == 0) space -= 1; 00176 } 00177 if (n > space) n = space; 00178 memcpy_P(&buf_[h], b, n); 00179 h += n; 00180 head_ = h < size_ ? h : h - size_; 00181 return n; 00182 } 00183 //============================================================================== 00184 // global data and ISRs 00185 #if ENABLE_RX_ERROR_CHECKING 00186 // 00187 uint8_t rxErrorBits[SERIAL_PORT_COUNT]; 00188 #endif // ENABLE_RX_ERROR_CHECKING 00189 //------------------------------------------------------------------------------ 00190 #if BUFFERED_RX 00191 //------------------------------------------------------------------------------ 00192 SerialRingBuffer rxRingBuf[SERIAL_PORT_COUNT]; 00193 //------------------------------------------------------------------------------ 00194 #if ENABLE_RX_ERROR_CHECKING 00195 inline static void rx_isr(uint8_t n) { 00196 uint8_t e = *usart[n].ucsra & SP_UCSRA_ERROR_MASK; 00197 uint8_t b = *usart[n].udr; 00198 if (!rxRingBuf[n].put(b)) e |= SP_RX_BUF_OVERRUN; 00199 rxErrorBits[n] |= e; 00200 } 00201 #else // ENABLE_RX_ERROR_CHECKING 00202 inline static void rx_isr(uint8_t n) { 00203 uint8_t b = *usart[n].udr; 00204 rxRingBuf[n].put(b); 00205 } 00206 #endif // ENABLE_RX_ERROR_CHECKING 00207 //------------------------------------------------------------------------------ 00208 // SerialRingBuffer rxbuf0; 00209 #if defined(USART_RX_vect) 00210 ISR(USART_RX_vect) { 00211 rx_isr(0); 00212 } 00213 #elif defined(SIG_USART0_RECV) 00214 ISR(SIG_USART0_RECV) { 00215 rx_isr(0); 00216 } 00217 #elif defined(SIG_UART0_RECV) 00218 ISR(SIG_UART0_RECV) { 00219 rx_isr(0); 00220 } 00221 #elif defined(USART0_RX_vect) 00222 ISR(USART0_RX_vect) { 00223 rx_isr(0); 00224 } 00225 #elif defined(SIG_UART_RECV) 00226 ISR(SIG_UART_RECV) { 00227 rx_isr(0); 00228 } 00229 #endif // vector USART0 00230 #ifdef USART1_RX_vect 00231 ISR(USART1_RX_vect) { 00232 rx_isr(1); 00233 } 00234 #endif // USART1_RX_vect 00235 00236 #ifdef USART2_RX_vect 00237 ISR(USART2_RX_vect) { 00238 rx_isr(2); 00239 } 00240 #endif // USART2_RX_vect 00241 00242 #ifdef USART3_RX_vect 00243 ISR(USART3_RX_vect) { 00244 rx_isr(3); 00245 } 00246 #endif // USART3_RX_vect 00247 #endif // BUFFERED_RX 00248 //------------------------------------------------------------------------------ 00249 #if BUFFERED_TX 00250 //------------------------------------------------------------------------------ 00251 SerialRingBuffer txRingBuf[SERIAL_PORT_COUNT]; 00252 //------------------------------------------------------------------------------ 00253 inline static void tx_isr(uint8_t n) { 00254 uint8_t b; 00255 if (txRingBuf[n].get(&b)) { 00256 *usart[n].udr = b; 00257 } else { 00258 // no data - disable interrupts 00259 *usart[n].ucsrb &= ~M_UDRIE; 00260 } 00261 } 00262 #if defined(UART0_UDRE_vect) 00263 ISR(UART0_UDRE_vect) { 00264 tx_isr(0); 00265 } 00266 #elif defined(UART_UDRE_vect) 00267 ISR(UART_UDRE_vect) { 00268 tx_isr(0); 00269 } 00270 #elif defined(USART0_UDRE_vect) 00271 ISR(USART0_UDRE_vect) { 00272 tx_isr(0); 00273 } 00274 #elif defined(USART_UDRE_vect) 00275 ISR(USART_UDRE_vect) { 00276 tx_isr(0); 00277 } 00278 #endif // USART0 TX 00279 00280 #ifdef USART1_UDRE_vect 00281 ISR(USART1_UDRE_vect) { 00282 tx_isr(1); 00283 } 00284 #endif // USART1_UDRE_vect 00285 00286 #ifdef USART2_UDRE_vect 00287 ISR(USART2_UDRE_vect) { 00288 tx_isr(2); 00289 } 00290 #endif // USART2_UDRE_vect 00291 00292 #ifdef USART3_UDRE_vect 00293 ISR(USART3_UDRE_vect) { 00294 tx_isr(3); 00295 } 00296 #endif // USART3_UDRE_vect 00297 #endif // BUFFERED_TX