Serial Port
Arduino/libraries/SerialPort/SerialPort.h
Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Defines