Home | History | Annotate | Download | only in arduino
      1 /*
      2   HardwareSerial.cpp - Hardware serial library for Wiring
      3   Copyright (c) 2006 Nicholas Zambetti.  All right reserved.
      4 
      5   This library is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU Lesser General Public
      7   License as published by the Free Software Foundation; either
      8   version 2.1 of the License, or (at your option) any later version.
      9 
     10   This library is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13   Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General Public
     16   License along with this library; if not, write to the Free Software
     17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     18 
     19   Modified 23 November 2006 by David A. Mellis
     20   Modified 28 September 2010 by Mark Sproul
     21 */
     22 
     23 #include <stdlib.h>
     24 #include <stdio.h>
     25 #include <string.h>
     26 #include <inttypes.h>
     27 #include "wiring.h"
     28 #include "wiring_private.h"
     29 
     30 // this next line disables the entire HardwareSerial.cpp,
     31 // this is so I can support Attiny series and any other chip without a uart
     32 #if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
     33 
     34 #include "HardwareSerial.h"
     35 
     36 // Define constants and variables for buffering incoming serial data.  We're
     37 // using a ring buffer (I think), in which rx_buffer_head is the index of the
     38 // location to which to write the next incoming character and rx_buffer_tail
     39 // is the index of the location from which to read.
     40 #if (RAMEND < 1000)
     41   #define RX_BUFFER_SIZE 32
     42 #else
     43   #define RX_BUFFER_SIZE 128
     44 #endif
     45 
     46 struct ring_buffer
     47 {
     48   unsigned char buffer[RX_BUFFER_SIZE];
     49   int head;
     50   int tail;
     51 };
     52 
     53 #if defined(UBRRH) || defined(UBRR0H)
     54   ring_buffer rx_buffer  =  { { 0 }, 0, 0 };
     55 #endif
     56 #if defined(UBRR1H)
     57   ring_buffer rx_buffer1  =  { { 0 }, 0, 0 };
     58 #endif
     59 #if defined(UBRR2H)
     60   ring_buffer rx_buffer2  =  { { 0 }, 0, 0 };
     61 #endif
     62 #if defined(UBRR3H)
     63   ring_buffer rx_buffer3  =  { { 0 }, 0, 0 };
     64 #endif
     65 
     66 inline void store_char(unsigned char c, ring_buffer *rx_buffer)
     67 {
     68   int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE;
     69 
     70   // if we should be storing the received character into the location
     71   // just before the tail (meaning that the head would advance to the
     72   // current location of the tail), we're about to overflow the buffer
     73   // and so we don't write the character or advance the head.
     74   if (i != rx_buffer->tail) {
     75     rx_buffer->buffer[rx_buffer->head] = c;
     76     rx_buffer->head = i;
     77   }
     78 }
     79 
     80 #if defined(USART_RX_vect)
     81   SIGNAL(USART_RX_vect)
     82   {
     83   #if defined(UDR0)
     84     unsigned char c  =  UDR0;
     85   #elif defined(UDR)
     86     unsigned char c  =  UDR;  //  atmega8535
     87   #else
     88     #error UDR not defined
     89   #endif
     90     store_char(c, &rx_buffer);
     91   }
     92 #elif defined(SIG_USART0_RECV) && defined(UDR0)
     93   SIGNAL(SIG_USART0_RECV)
     94   {
     95     unsigned char c  =  UDR0;
     96     store_char(c, &rx_buffer);
     97   }
     98 #elif defined(SIG_UART0_RECV) && defined(UDR0)
     99   SIGNAL(SIG_UART0_RECV)
    100   {
    101     unsigned char c  =  UDR0;
    102     store_char(c, &rx_buffer);
    103   }
    104 //#elif defined(SIG_USART_RECV)
    105 #elif defined(USART0_RX_vect)
    106   // fixed by Mark Sproul this is on the 644/644p
    107   //SIGNAL(SIG_USART_RECV)
    108   SIGNAL(USART0_RX_vect)
    109   {
    110   #if defined(UDR0)
    111     unsigned char c  =  UDR0;
    112   #elif defined(UDR)
    113     unsigned char c  =  UDR;  //  atmega8, atmega32
    114   #else
    115     #error UDR not defined
    116   #endif
    117     store_char(c, &rx_buffer);
    118   }
    119 #elif defined(SIG_UART_RECV)
    120   // this is for atmega8
    121   SIGNAL(SIG_UART_RECV)
    122   {
    123   #if defined(UDR0)
    124     unsigned char c  =  UDR0;  //  atmega645
    125   #elif defined(UDR)
    126     unsigned char c  =  UDR;  //  atmega8
    127   #endif
    128     store_char(c, &rx_buffer);
    129   }
    130 #elif defined(USBCON)
    131   #warning No interrupt handler for usart 0
    132   #warning Serial(0) is on USB interface
    133 #else
    134   #error No interrupt handler for usart 0
    135 #endif
    136 
    137 //#if defined(SIG_USART1_RECV)
    138 #if defined(USART1_RX_vect)
    139   //SIGNAL(SIG_USART1_RECV)
    140   SIGNAL(USART1_RX_vect)
    141   {
    142     unsigned char c = UDR1;
    143     store_char(c, &rx_buffer1);
    144   }
    145 #elif defined(SIG_USART1_RECV)
    146   #error SIG_USART1_RECV
    147 #endif
    148 
    149 #if defined(USART2_RX_vect) && defined(UDR2)
    150   SIGNAL(USART2_RX_vect)
    151   {
    152     unsigned char c = UDR2;
    153     store_char(c, &rx_buffer2);
    154   }
    155 #elif defined(SIG_USART2_RECV)
    156   #error SIG_USART2_RECV
    157 #endif
    158 
    159 #if defined(USART3_RX_vect) && defined(UDR3)
    160   SIGNAL(USART3_RX_vect)
    161   {
    162     unsigned char c = UDR3;
    163     store_char(c, &rx_buffer3);
    164   }
    165 #elif defined(SIG_USART3_RECV)
    166   #error SIG_USART3_RECV
    167 #endif
    168 
    169 
    170 
    171 // Constructors ////////////////////////////////////////////////////////////////
    172 
    173 HardwareSerial::HardwareSerial(ring_buffer *rx_buffer,
    174   volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
    175   volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
    176   volatile uint8_t *udr,
    177   uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre, uint8_t u2x)
    178 {
    179   _rx_buffer = rx_buffer;
    180   _ubrrh = ubrrh;
    181   _ubrrl = ubrrl;
    182   _ucsra = ucsra;
    183   _ucsrb = ucsrb;
    184   _udr = udr;
    185   _rxen = rxen;
    186   _txen = txen;
    187   _rxcie = rxcie;
    188   _udre = udre;
    189   _u2x = u2x;
    190 }
    191 
    192 // Public Methods //////////////////////////////////////////////////////////////
    193 
    194 void HardwareSerial::begin(long baud)
    195 {
    196   uint16_t baud_setting;
    197   bool use_u2x = true;
    198 
    199 #if F_CPU == 16000000UL
    200   // hardcoded exception for compatibility with the bootloader shipped
    201   // with the Duemilanove and previous boards and the firmware on the 8U2
    202   // on the Uno and Mega 2560.
    203   if (baud == 57600) {
    204     use_u2x = false;
    205   }
    206 #endif
    207 
    208   if (use_u2x) {
    209     *_ucsra = 1 << _u2x;
    210     baud_setting = (F_CPU / 4 / baud - 1) / 2;
    211   } else {
    212     *_ucsra = 0;
    213     baud_setting = (F_CPU / 8 / baud - 1) / 2;
    214   }
    215 
    216   // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
    217   *_ubrrh = baud_setting >> 8;
    218   *_ubrrl = baud_setting;
    219 
    220   sbi(*_ucsrb, _rxen);
    221   sbi(*_ucsrb, _txen);
    222   sbi(*_ucsrb, _rxcie);
    223 }
    224 
    225 void HardwareSerial::end()
    226 {
    227   cbi(*_ucsrb, _rxen);
    228   cbi(*_ucsrb, _txen);
    229   cbi(*_ucsrb, _rxcie);
    230 }
    231 
    232 int HardwareSerial::available(void)
    233 {
    234   return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
    235 }
    236 
    237 int HardwareSerial::peek(void)
    238 {
    239   if (_rx_buffer->head == _rx_buffer->tail) {
    240     return -1;
    241   } else {
    242     return _rx_buffer->buffer[_rx_buffer->tail];
    243   }
    244 }
    245 
    246 int HardwareSerial::read(void)
    247 {
    248   // if the head isn't ahead of the tail, we don't have any characters
    249   if (_rx_buffer->head == _rx_buffer->tail) {
    250     return -1;
    251   } else {
    252     unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    253     _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
    254     return c;
    255   }
    256 }
    257 
    258 void HardwareSerial::flush()
    259 {
    260   // don't reverse this or there may be problems if the RX interrupt
    261   // occurs after reading the value of rx_buffer_head but before writing
    262   // the value to rx_buffer_tail; the previous value of rx_buffer_head
    263   // may be written to rx_buffer_tail, making it appear as if the buffer
    264   // don't reverse this or there may be problems if the RX interrupt
    265   // occurs after reading the value of rx_buffer_head but before writing
    266   // the value to rx_buffer_tail; the previous value of rx_buffer_head
    267   // may be written to rx_buffer_tail, making it appear as if the buffer
    268   // were full, not empty.
    269   _rx_buffer->head = _rx_buffer->tail;
    270 }
    271 
    272 void HardwareSerial::write(uint8_t c)
    273 {
    274   while (!((*_ucsra) & (1 << _udre)))
    275     ;
    276 
    277   *_udr = c;
    278 }
    279 
    280 // Preinstantiate Objects //////////////////////////////////////////////////////
    281 
    282 #if defined(UBRRH) && defined(UBRRL)
    283   HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X);
    284 #elif defined(UBRR0H) && defined(UBRR0L)
    285   HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0);
    286 #elif defined(USBCON)
    287   #warning no serial port defined  (port 0)
    288 #else
    289   #error no serial port defined  (port 0)
    290 #endif
    291 
    292 #if defined(UBRR1H)
    293   HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1);
    294 #endif
    295 #if defined(UBRR2H)
    296   HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2);
    297 #endif
    298 #if defined(UBRR3H)
    299   HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3);
    300 #endif
    301 
    302 #endif // whole file
    303 
    304