• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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