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
store_char(unsigned char c,ring_buffer * rx_buffer)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)
SIGNAL(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)
SIGNAL(SIG_USART0_RECV)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)
SIGNAL(SIG_UART0_RECV)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)
SIGNAL(USART0_RX_vect)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
SIGNAL(SIG_UART_RECV)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)
SIGNAL(USART1_RX_vect)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)
SIGNAL(USART2_RX_vect)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)
SIGNAL(USART3_RX_vect)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
HardwareSerial(ring_buffer * rx_buffer,volatile uint8_t * ubrrh,volatile uint8_t * ubrrl,volatile uint8_t * ucsra,volatile uint8_t * ucsrb,volatile uint8_t * udr,uint8_t rxen,uint8_t txen,uint8_t rxcie,uint8_t udre,uint8_t u2x)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
begin(long baud)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
end()225 void HardwareSerial::end()
226 {
227 cbi(*_ucsrb, _rxen);
228 cbi(*_ucsrb, _txen);
229 cbi(*_ucsrb, _rxcie);
230 }
231
available(void)232 int HardwareSerial::available(void)
233 {
234 return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
235 }
236
peek(void)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
read(void)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
flush()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
write(uint8_t c)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