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
46struct 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
66inline 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
173HardwareSerial::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
194void 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
225void HardwareSerial::end()
226{
227  cbi(*_ucsrb, _rxen);
228  cbi(*_ucsrb, _txen);
229  cbi(*_ucsrb, _rxcie);
230}
231
232int HardwareSerial::available(void)
233{
234  return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
235}
236
237int 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
246int 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
258void 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
272void 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