Serial Port
|
00001 /* Arduino SerialPort Library 00002 * Copyright (C) 2012 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 #ifndef SerialPort_h 00025 #define SerialPort_h 00026 //------------------------------------------------------------------------------ 00028 #define SERIAL_PORT_VERSION 20130222 00029 //------------------------------------------------------------------------------ 00036 #define ALLOW_LARGE_BUFFERS 1 00037 //------------------------------------------------------------------------------ 00044 #define USE_WRITE_OVERRIDES 1 00045 //------------------------------------------------------------------------------ 00052 #define BUFFERED_RX 1 00053 //------------------------------------------------------------------------------ 00060 #define BUFFERED_TX 1 00061 //------------------------------------------------------------------------------ 00065 #define ENABLE_RX_ERROR_CHECKING 1 00066 //------------------------------------------------------------------------------ 00067 // Define symbols to allocate 64 byte ring buffers with capacity for 63 bytes. 00069 #define USE_NEW_SERIAL SerialPort<0, 63, 63> NewSerial 00070 00071 #define USE_NEW_SERIAL1 SerialPort<1, 63, 63> NewSerial1 00072 00073 #define USE_NEW_SERIAL2 SerialPort<2, 63, 63> NewSerial2 00074 00075 #define USE_NEW_SERIAL3 SerialPort<3, 63, 63> NewSerial3 00076 //------------------------------------------------------------------------------ 00077 #include <avr/io.h> 00078 #include <avr/pgmspace.h> 00079 #include <Arduino.h> 00080 //------------------------------------------------------------------------------ 00081 #if defined(UCSR3A) 00082 static const uint8_t SERIAL_PORT_COUNT = 4; 00083 #elif defined(UCSR2A) 00084 static const uint8_t SERIAL_PORT_COUNT = 3; 00085 #elif defined(UCSR1A) 00086 static const uint8_t SERIAL_PORT_COUNT = 2; 00087 #elif defined(UCSR0A) || defined(UCSRA) 00088 static const uint8_t SERIAL_PORT_COUNT = 1; 00089 #else 00090 #error no serial ports. 00091 #endif 00092 //------------------------------------------------------------------------------ 00093 #ifdef UCSR0A 00094 // Bits in UCSRA. 00095 static const uint8_t M_RXC = 1 << RXC0; 00096 static const uint8_t M_TXC = 1 << TXC0; 00097 static const uint8_t M_UDRE = 1 << UDRE0; 00098 static const uint8_t M_FE = 1 << FE0; 00099 static const uint8_t M_DOR = 1 << DOR0; 00100 static const uint8_t M_UPE = 1 << UPE0; 00101 static const uint8_t M_U2X = 1 << U2X0; 00102 // Bits in UCSRB. 00103 static const uint8_t M_RXCIE = 1 << RXCIE0; 00104 static const uint8_t M_TXCIE = 1 << TXCIE0; 00105 static const uint8_t M_UDRIE = 1 << UDRIE0; 00106 static const uint8_t M_RXEN = 1 << RXEN0; 00107 static const uint8_t M_TXEN = 1 << TXEN0; 00108 // Bits in UCSRC. 00109 static const uint8_t M_UPM0 = 1 << UPM00; 00110 static const uint8_t M_UPM1 = 1 << UPM01; 00111 static const uint8_t M_USBS = 1 << USBS0; 00112 static const uint8_t M_UCSZ0 = 1 << UCSZ00; 00113 static const uint8_t M_UCSZ1 = 1 << UCSZ01; 00114 #elif defined(UCSRA) // UCSR0A 00115 // Bits in UCSRA. 00116 static const uint8_t M_RXC = 1 << RXC; 00117 static const uint8_t M_TXC = 1 << TXC; 00118 static const uint8_t M_UDRE = 1 << UDRE; 00119 static const uint8_t M_FE = 1 << FE; 00120 static const uint8_t M_DOR = 1 << DOR; 00121 static const uint8_t M_UPE = 1 << PE; 00122 static const uint8_t M_U2X = 1 << U2X; 00123 // Bits in UCSRB. 00124 static const uint8_t M_RXCIE = 1 << RXCIE; 00125 static const uint8_t M_TXCIE = 1 << TXCIE; 00126 static const uint8_t M_UDRIE = 1 << UDRIE; 00127 static const uint8_t M_RXEN = 1 << RXEN; 00128 static const uint8_t M_TXEN = 1 << TXEN; 00129 // Bits in UCSRC. 00130 static const uint8_t M_UPM0 = 1 << UPM0; 00131 static const uint8_t M_UPM1 = 1 << UPM1; 00132 static const uint8_t M_USBS = 1 << USBS; 00133 static const uint8_t M_UCSZ0 = 1 << UCSZ0; 00134 static const uint8_t M_UCSZ1 = 1 << UCSZ1; 00135 #elif defined(UCSR1A) // UCSR0A 00136 // Bits in UCSRA. 00137 static const uint8_t M_RXC = 1 << RXC1; 00138 static const uint8_t M_TXC = 1 << TXC1; 00139 static const uint8_t M_UDRE = 1 << UDRE1; 00140 static const uint8_t M_FE = 1 << FE1; 00141 static const uint8_t M_DOR = 1 << DOR1; 00142 static const uint8_t M_UPE = 1 << UPE1; 00143 static const uint8_t M_U2X = 1 << U2X1; 00144 // Bits in UCSRB. 00145 static const uint8_t M_RXCIE = 1 << RXCIE1; 00146 static const uint8_t M_TXCIE = 1 << TXCIE1; 00147 static const uint8_t M_UDRIE = 1 << UDRIE1; 00148 static const uint8_t M_RXEN = 1 << RXEN1; 00149 static const uint8_t M_TXEN = 1 << TXEN1; 00150 // Bits in UCSRC. 00151 static const uint8_t M_UPM0 = 1 << UPM10; 00152 static const uint8_t M_UPM1 = 1 << UPM11; 00153 static const uint8_t M_USBS = 1 << USBS1; 00154 static const uint8_t M_UCSZ0 = 1 << UCSZ10; 00155 static const uint8_t M_UCSZ1 = 1 << UCSZ11; 00156 #else // UCSR0A 00157 #error no serial ports 00158 #endif // UCSR0A 00159 //------------------------------------------------------------------------------ 00161 static const uint8_t SP_1_STOP_BIT = 0; 00163 static const uint8_t SP_2_STOP_BIT = M_USBS; 00164 00166 static const uint8_t SP_NO_PARITY = 0; 00168 static const uint8_t SP_EVEN_PARITY = M_UPM1; 00170 static const uint8_t SP_ODD_PARITY = M_UPM0 | M_UPM1; 00171 00173 static const uint8_t SP_5_BIT_CHAR = 0; 00175 static const uint8_t SP_6_BIT_CHAR = M_UCSZ0; 00177 static const uint8_t SP_7_BIT_CHAR = M_UCSZ1; 00179 static const uint8_t SP_8_BIT_CHAR = M_UCSZ0 | M_UCSZ1; 00181 static const uint8_t SP_OPT_MASK = M_USBS | M_UPM0 | M_UPM1 |M_UCSZ0 | M_UCSZ1; 00182 00184 static const uint8_t SP_FRAMING_ERROR = M_FE; 00186 static const uint8_t SP_RX_DATA_OVERRUN = M_DOR; 00188 static const uint8_t SP_PARITY_ERROR = M_UPE; 00190 static const uint8_t SP_UCSRA_ERROR_MASK = M_FE | M_DOR | M_UPE; 00192 static const uint8_t SP_RX_BUF_OVERRUN = 1; 00193 #if 1 & ((1 << FE0) | (1 << DOR0) |(1 << UPE0)) 00194 #error Invalid SP_RX_BUF_OVERRUN bit 00195 #endif // SP_RX_BUF_OVERRUN 00196 //------------------------------------------------------------------------------ 00201 struct UsartRegister { 00202 volatile uint8_t* ucsra; 00203 volatile uint8_t* ucsrb; 00204 volatile uint8_t* ucsrc; 00205 volatile uint8_t* ubrrl; 00206 volatile uint8_t* ubrrh; 00207 volatile uint8_t* udr; 00208 }; 00209 //------------------------------------------------------------------------------ 00214 static const UsartRegister usart[] = { 00215 #ifdef UCSR0A 00216 {&UCSR0A, &UCSR0B, &UCSR0C, &UBRR0L, &UBRR0H, &UDR0}, 00217 #elif defined(UCSRA) 00218 {&UCSRA, &UCSRB, &UCSRC, &UBRRL, &UBRRH, &UDR}, 00219 #else // UCSR0A 00220 {0, 0, 0, 0, 0, 0}, 00221 #endif // UCSR0A 00222 00223 #ifdef UCSR1A 00224 {&UCSR1A, &UCSR1B, &UCSR1C, &UBRR1L, &UBRR1H, &UDR1}, 00225 #else // UCSR1A 00226 {0, 0, 0, 0, 0, 0}, 00227 #endif // UCSR1A 00228 00229 #ifdef UCSR2A 00230 {&UCSR2A, &UCSR2B, &UCSR2C, &UBRR2L, &UBRR2H, &UDR2}, 00231 #else // UCSR2A 00232 {0, 0, 0, 0, 0, 0}, 00233 #endif // UCSR2A 00234 00235 #ifdef UCSR3A 00236 {&UCSR3A, &UCSR3B, &UCSR3C, &UBRR3L, &UBRR3H, &UDR3} 00237 #else // UCSR3A 00238 {0, 0, 0, 0, 0, 0} 00239 #endif // UCSR3A 00240 }; 00241 //------------------------------------------------------------------------------ 00246 class SerialRingBuffer { 00247 public: 00249 #if ALLOW_LARGE_BUFFERS 00250 typedef uint16_t buf_size_t; 00251 #else // ALLOW_LARGE_BUFFERS 00252 typedef uint8_t buf_size_t; 00253 #endif // ALLOW_LARGE_BUFFERS 00254 int available(); 00256 bool empty() {return head_ == tail_;} 00257 void flush(); 00258 bool get(uint8_t* b); 00259 buf_size_t get(uint8_t* b, buf_size_t n); 00260 void init(uint8_t* b, buf_size_t s); 00261 int peek(); 00262 bool put(uint8_t b); 00263 buf_size_t put(const uint8_t* b, buf_size_t n); 00264 buf_size_t put_P(PGM_P b, buf_size_t n); 00265 private: 00266 uint8_t* buf_; 00267 volatile buf_size_t head_; 00268 volatile buf_size_t tail_; 00269 buf_size_t size_; 00270 }; 00271 //------------------------------------------------------------------------------ 00273 extern SerialRingBuffer rxRingBuf[]; 00275 extern SerialRingBuffer txRingBuf[]; 00277 extern uint8_t rxErrorBits[]; 00278 //------------------------------------------------------------------------------ 00282 uint8_t badPortNumber(void) 00283 __attribute__((error("Bad port number"))); 00287 uint8_t badRxBufSize(void) 00288 __attribute__((error("RX buffer size too large"))); 00292 uint8_t badTxBufSize(void) 00293 __attribute__((error("TX buffer size too large"))); 00294 //------------------------------------------------------------------------------ 00299 template<uint8_t PortNumber, size_t RxBufSize, size_t TxBufSize> 00300 class SerialPort : public Stream { 00301 public: 00302 //---------------------------------------------------------------------------- 00304 SerialPort() { 00305 if (PortNumber >= SERIAL_PORT_COUNT || !usart[PortNumber].ucsra) { 00306 badPortNumber(); 00307 } 00308 if (sizeof(SerialRingBuffer::buf_size_t) == 1) { 00309 if (RxBufSize > 254) badRxBufSize(); 00310 if (TxBufSize > 254) badTxBufSize(); 00311 } 00312 if (RxBufSize) rxRingBuf[PortNumber].init(rxBuffer_, sizeof(rxBuffer_)); 00313 if (TxBufSize) txRingBuf[PortNumber].init(txBuffer_, sizeof(txBuffer_)); 00314 } 00315 //---------------------------------------------------------------------------- 00320 int available(void) { 00321 if (!RxBufSize) { 00322 return *usart[PortNumber].ucsra & M_RXC ? 1 : 0; 00323 } else { 00324 return rxRingBuf[PortNumber].available(); 00325 } 00326 } 00327 //---------------------------------------------------------------------------- 00349 void begin(uint32_t baud, uint8_t options = SP_8_BIT_CHAR) { 00350 uint16_t baud_setting; 00351 00352 // disable USART interrupts. Set UCSRB to reset values. 00353 *usart[PortNumber].ucsrb = 0; 00354 00355 // set option bits 00356 *usart[PortNumber].ucsrc = options & SP_OPT_MASK; 00357 00358 if (F_CPU == 16000000UL && baud == 57600) { 00359 // hardcoded exception for compatibility with the bootloader shipped 00360 // with the Duemilanove and previous boards and the firmware on the 8U2 00361 // on the Uno and Mega 2560. 00362 *usart[PortNumber].ucsra = 0; 00363 baud_setting = (F_CPU / 8 / baud - 1) / 2; 00364 } else { 00365 *usart[PortNumber].ucsra = M_U2X; 00366 baud_setting = (F_CPU / 4 / baud - 1) / 2; 00367 } 00368 // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) 00369 *usart[PortNumber].ubrrh = baud_setting >> 8; 00370 *usart[PortNumber].ubrrl = baud_setting; 00371 00372 // enable RX and TX 00373 uint8_t bits = M_TXEN | M_RXEN; 00374 00375 // enable receive interrupt if buffered 00376 if (RxBufSize) bits |= M_RXCIE; 00377 *usart[PortNumber].ucsrb = bits; 00378 } 00379 //---------------------------------------------------------------------------- 00380 #if ENABLE_RX_ERROR_CHECKING 00381 00382 void clearRxError() {rxErrorBits[PortNumber] = 0;} 00390 uint8_t getRxError() {return rxErrorBits[PortNumber];} 00391 #endif // ENABLE_RX_ERROR_CHECKING 00392 //---------------------------------------------------------------------------- 00398 void end() { 00399 // wait for transmission of outgoing data 00400 flushTx(); 00401 // disable USART 00402 cli(); 00403 *usart[PortNumber].ucsrb &= ~(M_RXEN | M_TXEN | M_RXCIE | M_UDRIE); 00404 sei(); 00405 // clear any received data 00406 flushRx(); 00407 } 00408 //---------------------------------------------------------------------------- 00412 void flush() {flushTx();} 00413 //---------------------------------------------------------------------------- 00417 void flushRx() { 00418 if (RxBufSize) { 00419 rxRingBuf[PortNumber].flush(); 00420 } else { 00421 uint8_t b; 00422 while (*usart[PortNumber].ucsra & M_RXC) b = *usart[PortNumber].udr; 00423 } 00424 } 00425 //---------------------------------------------------------------------------- 00429 void flushTx() { 00430 if (TxBufSize) { 00431 while (!txRingBuf[PortNumber].empty()) {} 00432 } 00433 } 00434 //---------------------------------------------------------------------------- 00439 int peek(void) { 00440 return RxBufSize ? rxRingBuf[PortNumber].peek() : -1; 00441 } 00442 //---------------------------------------------------------------------------- 00449 __attribute__((noinline)) 00450 int read() { 00451 if (!RxBufSize) { 00452 uint8_t s = *usart[PortNumber].ucsra; 00453 #if ENABLE_RX_ERROR_CHECKING 00454 rxErrorBits[PortNumber] |= s & SP_UCSRA_ERROR_MASK; 00455 #endif // ENABLE_RX_ERROR_CHECKING 00456 return s & M_RXC ? *usart[PortNumber].udr : -1; 00457 } else { 00458 uint8_t b; 00459 return rxRingBuf[PortNumber].get(&b) ? b : -1; 00460 } 00461 } 00462 //---------------------------------------------------------------------------- 00471 __attribute__((noinline)) 00472 size_t read(uint8_t* b, size_t n) { 00473 uint8_t* limit = b + n; 00474 uint8_t* p = b; 00475 if (RxBufSize) { 00476 while (p < limit && !rxRingBuf[PortNumber].empty()) { 00477 size_t nr = limit - p; 00478 if (sizeof(SerialRingBuffer::buf_size_t) == 1 && nr > 255) nr = 255; 00479 p += rxRingBuf[PortNumber].get(p, nr); 00480 } 00481 } else { 00482 while (p < limit) { 00483 int rb = read(); 00484 if (rb < 0) break; 00485 *p++ = rb; 00486 } 00487 } 00488 return p - b; 00489 } 00490 //---------------------------------------------------------------------------- 00497 __attribute__((noinline)) 00498 size_t write(uint8_t b) { 00499 if (!TxBufSize) { 00500 while (!(*usart[PortNumber].ucsra & M_UDRE)) {} 00501 *usart[PortNumber].udr = b; 00502 } else { 00503 // Wait for TX ISR if buffer is full. 00504 while (!txRingBuf[PortNumber].put(b)) {} 00505 00506 // Enable interrupts. 00507 *usart[PortNumber].ucsrb |= M_UDRIE; 00508 } 00509 return 1; 00510 } 00511 //---------------------------------------------------------------------------- 00515 __attribute__((noinline)) 00516 size_t writeln() { 00517 write('\r'); 00518 write('\n'); 00519 return 2; 00520 } 00521 //---------------------------------------------------------------------------- 00528 __attribute__((noinline)) 00529 size_t writeln(const char* s) { 00530 return write(s) + writeln(); 00531 } 00532 00533 //---------------------------------------------------------------------------- 00541 __attribute__((noinline)) 00542 size_t write_P(PGM_P b, size_t n) { 00543 if (!TxBufSize) { 00544 for (size_t i = 0; i < n; i++) write(pgm_read_byte(b + i)); 00545 } else { 00546 size_t w = n; 00547 while (w) { 00548 size_t nw = w; 00549 if (sizeof(SerialRingBuffer::buf_size_t) == 1 && nw > 255) nw = 255; 00550 size_t m = txRingBuf[PortNumber].put_P(b, nw); 00551 00552 // enable interrupts 00553 *usart[PortNumber].ucsrb |= M_UDRIE; 00554 w -= m; 00555 b += m; 00556 } 00557 } 00558 return n; 00559 } 00560 //---------------------------------------------------------------------------- 00567 __attribute__((noinline)) 00568 size_t write(const __FlashStringHelper* s) { 00569 const char PROGMEM* p = (const char PROGMEM*)s; 00570 size_t n = strlen_P(p); 00571 return write_P(p, n); 00572 } 00573 //---------------------------------------------------------------------------- 00580 __attribute__((noinline)) 00581 size_t writeln(const __FlashStringHelper* s) { 00582 return write(s) + writeln(); 00583 } 00584 #if USE_WRITE_OVERRIDES 00585 //---------------------------------------------------------------------------- 00593 __attribute__((noinline)) 00594 size_t write(const uint8_t* b, size_t n) { 00595 if (!TxBufSize) { 00596 for (size_t i = 0; i < n; i++) write(b[i]); 00597 } else { 00598 size_t w = n; 00599 while (w) { 00600 size_t nw = w; 00601 if (sizeof(SerialRingBuffer::buf_size_t) == 1 && nw > 255) nw = 255; 00602 size_t m = txRingBuf[PortNumber].put(b, nw); 00603 00604 // Enable interrupts. 00605 *usart[PortNumber].ucsrb |= M_UDRIE; 00606 w -= m; 00607 b += m; 00608 } 00609 } 00610 return n; 00611 } 00612 //---------------------------------------------------------------------------- 00619 __attribute__((noinline)) 00620 size_t write(const char* s) { 00621 size_t n = strlen(s); 00622 return write(reinterpret_cast<const uint8_t*>(s), n); 00623 } 00624 #else // USE_WRITE_OVERRIDES 00625 using Print::write; // use write(str) and write(buf, size) from Print 00626 #endif // USE_WRITE_OVERRIDES 00627 //---------------------------------------------------------------------------- 00628 private: 00629 // RX buffer with a capacity of RxBufSize. 00630 uint8_t rxBuffer_[RxBufSize + 1]; 00631 // TX buffer with a capacity of TxBufSize. 00632 uint8_t txBuffer_[TxBufSize + 1]; 00633 }; 00634 //------------------------------------------------------------------------------ 00635 #endif // SerialPort_h