aboutsummaryrefslogtreecommitdiff
path: root/keyboards/bioi/usart.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/bioi/usart.c')
-rw-r--r--keyboards/bioi/usart.c1522
1 files changed, 1522 insertions, 0 deletions
diff --git a/keyboards/bioi/usart.c b/keyboards/bioi/usart.c
new file mode 100644
index 000000000..f37845e5c
--- /dev/null
+++ b/keyboards/bioi/usart.c
@@ -0,0 +1,1522 @@
1/*************************************************************************
2
3 Title: Interrupt UART library with receive/transmit circular buffers
4 Author: Andy Gock
5 Software: AVR-GCC 4.1, AVR Libc 1.4
6 Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz
7 License: GNU General Public License
8 Usage: see README.md and Doxygen manual
9
10 Based on original library by Peter Fluery, Tim Sharpe, Nicholas Zambetti.
11
12 https://github.com/andygock/avr-uart
13
14 Updated UART library (this one) by Andy Gock
15 https://github.com/andygock/avr-uart
16
17 Based on updated UART library (this one) by Tim Sharpe
18 http://beaststwo.org/avr-uart/index.shtml
19
20 Based on original library by Peter Fluery
21 http://homepage.hispeed.ch/peterfleury/avr-software.html
22
23*************************************************************************/
24
25/*************************************************************************
26
27LICENSE:
28 Copyright (C) 2012 Andy Gock
29 Copyright (C) 2006 Peter Fleury
30
31 This program is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version 2 of the License, or
34 any later version.
35
36 This program is distributed in the hope that it will be useful,
37 but WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 GNU General Public License for more details.
40
41*************************************************************************/
42
43/************************************************************************
44uart_available, uart_flush, uart1_available, and uart1_flush functions
45were adapted from the Arduino HardwareSerial.h library by Tim Sharpe on
4611 Jan 2009. The license info for HardwareSerial.h is as follows:
47
48 HardwareSerial.cpp - Hardware serial library for Wiring
49 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
50
51 This library is free software; you can redistribute it and/or
52 modify it under the terms of the GNU Lesser General Public
53 License as published by the Free Software Foundation; either
54 version 2.1 of the License, or (at your option) any later version.
55
56 This library is distributed in the hope that it will be useful,
57 but WITHOUT ANY WARRANTY; without even the implied warranty of
58 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
59 Lesser General Public License for more details.
60
61 You should have received a copy of the GNU Lesser General Public
62 License along with this library; if not, write to the Free Software
63 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
64
65 Modified 23 November 2006 by David A. Mellis
66************************************************************************/
67
68/************************************************************************
69Changelog for modifications made by Tim Sharpe, starting with the current
70 library version on his Web site as of 05/01/2009.
71
72Date Description
73=========================================================================
7405/11/2009 Changed all existing UARTx_RECEIVE_INTERRUPT and UARTx_TRANSMIT_INTERRUPT
75 macros to use the "_vect" format introduced in AVR-Libc
76 v1.4.0. Had to split the 3290 and 6490 out of their existing
77 macro due to an inconsistency in the UART0_RECEIVE_INTERRUPT
78 vector name (seems like a typo: USART_RX_vect for the 3290/6490
79 vice USART0_RX_vect for the others in the macro).
80 Verified all existing macro register names against the device
81 header files in AVR-Libc v1.6.6 to catch any inconsistencies.
8205/12/2009 Added support for 48P, 88P, 168P, and 328P by adding them to the
83 existing 48/88/168 macro.
84 Added Arduino-style available() and flush() functions for both
85 supported UARTs. Really wanted to keep them out of the library, so
86 that it would be as close as possible to Peter Fleury's original
87 library, but has scoping issues accessing internal variables from
88 another program. Go C!
8905/13/2009 Changed Interrupt Service Routine label from the old "SIGNAL" to
90 the "ISR" format introduced in AVR-Libc v1.4.0.
91
92************************************************************************/
93
94#include <avr/io.h>
95#include <avr/interrupt.h>
96#include <avr/pgmspace.h>
97#include <util/atomic.h>
98#include "usart.h"
99
100/*
101 * constants and macros
102 */
103
104/* size of RX/TX buffers */
105#define UART_RX0_BUFFER_MASK (UART_RX0_BUFFER_SIZE - 1)
106#define UART_RX1_BUFFER_MASK (UART_RX1_BUFFER_SIZE - 1)
107#define UART_RX2_BUFFER_MASK (UART_RX2_BUFFER_SIZE - 1)
108#define UART_RX3_BUFFER_MASK (UART_RX3_BUFFER_SIZE - 1)
109
110#define UART_TX0_BUFFER_MASK (UART_TX0_BUFFER_SIZE - 1)
111#define UART_TX1_BUFFER_MASK (UART_TX1_BUFFER_SIZE - 1)
112#define UART_TX2_BUFFER_MASK (UART_TX2_BUFFER_SIZE - 1)
113#define UART_TX3_BUFFER_MASK (UART_TX3_BUFFER_SIZE - 1)
114
115#if (UART_RX0_BUFFER_SIZE & UART_RX0_BUFFER_MASK)
116 #error RX0 buffer size is not a power of 2
117#endif
118#if (UART_TX0_BUFFER_SIZE & UART_TX0_BUFFER_MASK)
119 #error TX0 buffer size is not a power of 2
120#endif
121
122#if (UART_RX1_BUFFER_SIZE & UART_RX1_BUFFER_MASK)
123 #error RX1 buffer size is not a power of 2
124#endif
125#if (UART_TX1_BUFFER_SIZE & UART_TX1_BUFFER_MASK)
126 #error TX1 buffer size is not a power of 2
127#endif
128
129#if (UART_RX2_BUFFER_SIZE & UART_RX2_BUFFER_MASK)
130 #error RX2 buffer size is not a power of 2
131#endif
132#if (UART_TX2_BUFFER_SIZE & UART_TX2_BUFFER_MASK)
133 #error TX2 buffer size is not a power of 2
134#endif
135
136#if (UART_RX3_BUFFER_SIZE & UART_RX3_BUFFER_MASK)
137 #error RX3 buffer size is not a power of 2
138#endif
139#if (UART_TX3_BUFFER_SIZE & UART_TX3_BUFFER_MASK)
140 #error TX3 buffer size is not a power of 2
141#endif
142
143#if defined(__AVR_AT90S2313__) \
144 || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
145 || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
146 || defined(__AVR_ATmega103__)
147 /* old AVR classic or ATmega103 with one UART */
148 #define AT90_UART
149 #define UART0_RECEIVE_INTERRUPT UART_RX_vect
150 #define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
151 #define UART0_STATUS USR
152 #define UART0_CONTROL UCR
153 #define UART0_DATA UDR
154 #define UART0_UDRIE UDRIE
155#elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
156 /* old AVR classic with one UART */
157 #define AT90_UART
158 #define UART0_RECEIVE_INTERRUPT UART_RX_vect
159 #define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
160 #define UART0_STATUS UCSRA
161 #define UART0_CONTROL UCSRB
162 #define UART0_DATA UDR
163 #define UART0_UDRIE UDRIE
164#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
165 || defined(__AVR_ATmega323__)
166 /* ATmega with one USART */
167 #define ATMEGA_USART
168 #define UART0_RECEIVE_INTERRUPT USART_RXC_vect
169 #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
170 #define UART0_STATUS UCSRA
171 #define UART0_CONTROL UCSRB
172 #define UART0_DATA UDR
173 #define UART0_UDRIE UDRIE
174#elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega16U4__) || \
175 defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U6__)
176 /* ATmega with one USART, but is called USART1 (untested) */
177 #define ATMEGA_USART1
178 #define UART1_RECEIVE_INTERRUPT USART1_RX_vect
179 #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
180 #define UART1_STATUS UCSR1A
181 #define UART1_CONTROL UCSR1B
182 #define UART1_DATA UDR1
183 #define UART1_UDRIE UDRIE1
184#elif defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
185 /* ATmega with one USART */
186 #define ATMEGA_USART
187 #define UART0_RECEIVE_INTERRUPT USART_RX_vect
188 #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
189 #define UART0_STATUS UCSRA
190 #define UART0_CONTROL UCSRB
191 #define UART0_DATA UDR
192 #define UART0_UDRIE UDRIE
193#elif defined(__AVR_ATmega163__)
194 /* ATmega163 with one UART */
195 #define ATMEGA_UART
196 #define UART0_RECEIVE_INTERRUPT UART_RX_vect
197 #define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
198 #define UART0_STATUS UCSRA
199 #define UART0_CONTROL UCSRB
200 #define UART0_DATA UDR
201 #define UART0_UDRIE UDRIE
202#elif defined(__AVR_ATmega162__)
203 /* ATmega with two USART */
204 #define ATMEGA_USART0
205 #define ATMEGA_USART1
206 #define UART0_RECEIVE_INTERRUPT USART0_RXC_vect
207 #define UART1_RECEIVE_INTERRUPT USART1_RXC_vect
208 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
209 #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
210 #define UART0_STATUS UCSR0A
211 #define UART0_CONTROL UCSR0B
212 #define UART0_DATA UDR0
213 #define UART0_UDRIE UDRIE0
214 #define UART1_STATUS UCSR1A
215 #define UART1_CONTROL UCSR1B
216 #define UART1_DATA UDR1
217 #define UART1_UDRIE UDRIE1
218#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
219 /* ATmega with two USART */
220 #define ATMEGA_USART0
221 #define ATMEGA_USART1
222 #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
223 #define UART1_RECEIVE_INTERRUPT USART1_RX_vect
224 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
225 #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
226 #define UART0_STATUS UCSR0A
227 #define UART0_CONTROL UCSR0B
228 #define UART0_DATA UDR0
229 #define UART0_UDRIE UDRIE0
230 #define UART1_STATUS UCSR1A
231 #define UART1_CONTROL UCSR1B
232 #define UART1_DATA UDR1
233 #define UART1_UDRIE UDRIE1
234#elif defined(__AVR_ATmega161__)
235 /* ATmega with UART */
236 #error "AVR ATmega161 currently not supported by this libaray !"
237#elif defined(__AVR_ATmega169__)
238 /* ATmega with one USART */
239 #define ATMEGA_USART
240 #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
241 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
242 #define UART0_STATUS UCSRA
243 #define UART0_CONTROL UCSRB
244 #define UART0_DATA UDR
245 #define UART0_UDRIE UDRIE
246#elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || \
247 defined(__AVR_ATmega48P__) ||defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || \
248 defined(__AVR_ATmega328P__)
249 /* TLS-Added 48P/88P/168P/328P */
250 /* ATmega with one USART */
251 #define ATMEGA_USART0
252 #define UART0_RECEIVE_INTERRUPT USART_RX_vect
253 #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
254 #define UART0_STATUS UCSR0A
255 #define UART0_CONTROL UCSR0B
256 #define UART0_DATA UDR0
257 #define UART0_UDRIE UDRIE0
258#elif defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny2313A__) || defined(__AVR_ATtiny4313__)
259 #define ATMEGA_USART
260 #define UART0_RECEIVE_INTERRUPT USART_RX_vect
261 #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
262 #define UART0_STATUS UCSRA
263 #define UART0_CONTROL UCSRB
264 #define UART0_DATA UDR
265 #define UART0_UDRIE UDRIE
266#elif defined(__AVR_ATmega329__) ||\
267 defined(__AVR_ATmega649__) ||\
268 defined(__AVR_ATmega325__) ||defined(__AVR_ATmega3250__) ||\
269 defined(__AVR_ATmega645__) ||defined(__AVR_ATmega6450__)
270 /* ATmega with one USART */
271 #define ATMEGA_USART0
272 #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
273 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
274 #define UART0_STATUS UCSR0A
275 #define UART0_CONTROL UCSR0B
276 #define UART0_DATA UDR0
277 #define UART0_UDRIE UDRIE0
278#elif defined(__AVR_ATmega3290__) ||\
279 defined(__AVR_ATmega6490__)
280 /* TLS-Separated these two from the previous group because of inconsistency in the USART_RX */
281 /* ATmega with one USART */
282 #define ATMEGA_USART0
283 #define UART0_RECEIVE_INTERRUPT USART_RX_vect
284 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
285 #define UART0_STATUS UCSR0A
286 #define UART0_CONTROL UCSR0B
287 #define UART0_DATA UDR0
288 #define UART0_UDRIE UDRIE0
289#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega640__)
290 /* ATmega with four USART */
291 #define ATMEGA_USART0
292 #define ATMEGA_USART1
293 #define ATMEGA_USART2
294 #define ATMEGA_USART3
295 #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
296 #define UART1_RECEIVE_INTERRUPT USART1_RX_vect
297 #define UART2_RECEIVE_INTERRUPT USART2_RX_vect
298 #define UART3_RECEIVE_INTERRUPT USART3_RX_vect
299 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
300 #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
301 #define UART2_TRANSMIT_INTERRUPT USART2_UDRE_vect
302 #define UART3_TRANSMIT_INTERRUPT USART3_UDRE_vect
303 #define UART0_STATUS UCSR0A
304 #define UART0_CONTROL UCSR0B
305 #define UART0_DATA UDR0
306 #define UART0_UDRIE UDRIE0
307 #define UART1_STATUS UCSR1A
308 #define UART1_CONTROL UCSR1B
309 #define UART1_DATA UDR1
310 #define UART1_UDRIE UDRIE1
311 #define UART2_STATUS UCSR2A
312 #define UART2_CONTROL UCSR2B
313 #define UART2_DATA UDR2
314 #define UART2_UDRIE UDRIE2
315 #define UART3_STATUS UCSR3A
316 #define UART3_CONTROL UCSR3B
317 #define UART3_DATA UDR3
318 #define UART3_UDRIE UDRIE3
319#elif defined(__AVR_ATmega644__)
320 /* ATmega with one USART */
321 #define ATMEGA_USART0
322 #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
323 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
324 #define UART0_STATUS UCSR0A
325 #define UART0_CONTROL UCSR0B
326 #define UART0_DATA UDR0
327 #define UART0_UDRIE UDRIE0
328#elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__) || \
329 defined(__AVR_ATmega1284P__)
330 /* ATmega with two USART */
331 #define ATMEGA_USART0
332 #define ATMEGA_USART1
333 #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
334 #define UART1_RECEIVE_INTERRUPT USART1_RX_vect
335 #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
336 #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
337 #define UART0_STATUS UCSR0A
338 #define UART0_CONTROL UCSR0B
339 #define UART0_DATA UDR0
340 #define UART0_UDRIE UDRIE0
341 #define UART1_STATUS UCSR1A
342 #define UART1_CONTROL UCSR1B
343 #define UART1_DATA UDR1
344 #define UART1_UDRIE UDRIE1
345#else
346 #error "no UART definition for MCU available"
347#endif
348
349/*
350 * Module global variables
351 */
352
353#if defined(USART0_ENABLED)
354 #if defined(ATMEGA_USART) || defined(ATMEGA_USART0)
355 static volatile uint8_t UART_TxBuf[UART_TX0_BUFFER_SIZE];
356 static volatile uint8_t UART_RxBuf[UART_RX0_BUFFER_SIZE];
357
358 #if defined(USART0_LARGE_BUFFER)
359 static volatile uint16_t UART_TxHead;
360 static volatile uint16_t UART_TxTail;
361 static volatile uint16_t UART_RxHead;
362 static volatile uint16_t UART_RxTail;
363 static volatile uint8_t UART_LastRxError;
364 #else
365 static volatile uint8_t UART_TxHead;
366 static volatile uint8_t UART_TxTail;
367 static volatile uint8_t UART_RxHead;
368 static volatile uint8_t UART_RxTail;
369 static volatile uint8_t UART_LastRxError;
370 #endif
371
372 #endif
373#endif
374
375#if defined(USART1_ENABLED)
376 #if defined(ATMEGA_USART1)
377 static volatile uint8_t UART1_TxBuf[UART_TX1_BUFFER_SIZE];
378 static volatile uint8_t UART1_RxBuf[UART_RX1_BUFFER_SIZE];
379
380 #if defined(USART1_LARGE_BUFFER)
381 static volatile uint16_t UART1_TxHead;
382 static volatile uint16_t UART1_TxTail;
383 static volatile uint16_t UART1_RxHead;
384 static volatile uint16_t UART1_RxTail;
385 static volatile uint8_t UART1_LastRxError;
386 #else
387 static volatile uint8_t UART1_TxHead;
388 static volatile uint8_t UART1_TxTail;
389 static volatile uint8_t UART1_RxHead;
390 static volatile uint8_t UART1_RxTail;
391 static volatile uint8_t UART1_LastRxError;
392 #endif
393 #endif
394#endif
395
396#if defined(USART2_ENABLED)
397 #if defined(ATMEGA_USART2)
398 static volatile uint8_t UART2_TxBuf[UART_TX2_BUFFER_SIZE];
399 static volatile uint8_t UART2_RxBuf[UART_RX2_BUFFER_SIZE];
400
401 #if defined(USART2_LARGE_BUFFER)
402 static volatile uint16_t UART2_TxHead;
403 static volatile uint16_t UART2_TxTail;
404 static volatile uint16_t UART2_RxHead;
405 static volatile uint16_t UART2_RxTail;
406 static volatile uint8_t UART2_LastRxError;
407 #else
408 static volatile uint8_t UART2_TxHead;
409 static volatile uint8_t UART2_TxTail;
410 static volatile uint8_t UART2_RxHead;
411 static volatile uint8_t UART2_RxTail;
412 static volatile uint8_t UART2_LastRxError;
413 #endif
414 #endif
415#endif
416
417#if defined(USART3_ENABLED)
418 #if defined(ATMEGA_USART3)
419 static volatile uint8_t UART3_TxBuf[UART_TX3_BUFFER_SIZE];
420 static volatile uint8_t UART3_RxBuf[UART_RX3_BUFFER_SIZE];
421
422 #if defined(USART3_LARGE_BUFFER)
423 static volatile uint16_t UART3_TxHead;
424 static volatile uint16_t UART3_TxTail;
425 static volatile uint16_t UART3_RxHead;
426 static volatile uint16_t UART3_RxTail;
427 static volatile uint8_t UART3_LastRxError;
428 #else
429 static volatile uint8_t UART3_TxHead;
430 static volatile uint8_t UART3_TxTail;
431 static volatile uint8_t UART3_RxHead;
432 static volatile uint8_t UART3_RxTail;
433 static volatile uint8_t UART3_LastRxError;
434 #endif
435
436 #endif
437#endif
438
439#if defined(USART0_ENABLED)
440
441#if defined(AT90_UART) || defined(ATMEGA_USART) || defined(ATMEGA_USART0)
442
443ISR(UART0_RECEIVE_INTERRUPT)
444/*************************************************************************
445Function: UART Receive Complete interrupt
446Purpose: called when the UART has received a character
447**************************************************************************/
448{
449 uint16_t tmphead;
450 uint8_t data;
451 uint8_t usr;
452 uint8_t lastRxError;
453
454 /* read UART status register and UART data register */
455 usr = UART0_STATUS;
456 data = UART0_DATA;
457
458 /* */
459#if defined(AT90_UART)
460 lastRxError = (usr & (_BV(FE)|_BV(DOR)));
461#elif defined(ATMEGA_USART)
462 lastRxError = (usr & (_BV(FE)|_BV(DOR)));
463#elif defined(ATMEGA_USART0)
464 lastRxError = (usr & (_BV(FE0)|_BV(DOR0)));
465#elif defined (ATMEGA_UART)
466 lastRxError = (usr & (_BV(FE)|_BV(DOR)));
467#endif
468
469 /* calculate buffer index */
470 tmphead = (UART_RxHead + 1) & UART_RX0_BUFFER_MASK;
471
472 if (tmphead == UART_RxTail) {
473 /* error: receive buffer overflow */
474 lastRxError = UART_BUFFER_OVERFLOW >> 8;
475 } else {
476 /* store new index */
477 UART_RxHead = tmphead;
478 /* store received data in buffer */
479 UART_RxBuf[tmphead] = data;
480 }
481 UART_LastRxError = lastRxError;
482}
483
484
485ISR(UART0_TRANSMIT_INTERRUPT)
486/*************************************************************************
487Function: UART Data Register Empty interrupt
488Purpose: called when the UART is ready to transmit the next byte
489**************************************************************************/
490{
491 uint16_t tmptail;
492
493 if (UART_TxHead != UART_TxTail) {
494 /* calculate and store new buffer index */
495 tmptail = (UART_TxTail + 1) & UART_TX0_BUFFER_MASK;
496 UART_TxTail = tmptail;
497 /* get one byte from buffer and write it to UART */
498 UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */
499 } else {
500 /* tx buffer empty, disable UDRE interrupt */
501 UART0_CONTROL &= ~_BV(UART0_UDRIE);
502 }
503}
504
505
506/*************************************************************************
507Function: uart0_init()
508Purpose: initialize UART and set baudrate
509Input: baudrate using macro UART_BAUD_SELECT()
510Returns: none
511**************************************************************************/
512void uart0_init(uint16_t baudrate)
513{
514 ATOMIC_BLOCK(ATOMIC_FORCEON) {
515 UART_TxHead = 0;
516 UART_TxTail = 0;
517 UART_RxHead = 0;
518 UART_RxTail = 0;
519 }
520
521#if defined(AT90_UART)
522 /* set baud rate */
523 UBRR = (uint8_t) baudrate;
524
525 /* enable UART receiver and transmitter and receive complete interrupt */
526 UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
527
528#elif defined (ATMEGA_USART)
529 /* Set baud rate */
530 if (baudrate & 0x8000) {
531 UART0_STATUS = (1<<U2X); //Enable 2x speed
532 baudrate &= ~0x8000;
533 }
534 UBRRH = (uint8_t) (baudrate>>8);
535 UBRRL = (uint8_t) baudrate;
536
537 /* Enable USART receiver and transmitter and receive complete interrupt */
538 UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
539
540 /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
541#ifdef URSEL
542 UCSRC = (1<<URSEL)|(3<<UCSZ0);
543#else
544 UCSRC = (3<<UCSZ0);
545#endif
546
547#elif defined (ATMEGA_USART0)
548 /* Set baud rate */
549 if (baudrate & 0x8000) {
550 UART0_STATUS = (1<<U2X0); //Enable 2x speed
551 baudrate &= ~0x8000;
552 }
553 UBRR0H = (uint8_t)(baudrate>>8);
554 UBRR0L = (uint8_t) baudrate;
555
556 /* Enable USART receiver and transmitter and receive complete interrupt */
557 UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
558
559 /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
560#ifdef URSEL0
561 UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
562#else
563 UCSR0C = (3<<UCSZ00);
564#endif
565
566#elif defined (ATMEGA_UART)
567 /* set baud rate */
568 if (baudrate & 0x8000) {
569 UART0_STATUS = (1<<U2X); //Enable 2x speed
570 baudrate &= ~0x8000;
571 }
572 UBRRHI = (uint8_t) (baudrate>>8);
573 UBRR = (uint8_t) baudrate;
574
575 /* Enable UART receiver and transmitter and receive complete interrupt */
576 UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
577
578#endif
579
580} /* uart0_init */
581
582
583/*************************************************************************
584Function: uart0_getc()
585Purpose: return byte from ringbuffer
586Returns: lower byte: received byte from ringbuffer
587 higher byte: last receive error
588**************************************************************************/
589uint16_t uart0_getc(void)
590{
591 uint16_t tmptail;
592 uint8_t data;
593
594 ATOMIC_BLOCK(ATOMIC_FORCEON) {
595 if (UART_RxHead == UART_RxTail) {
596 return UART_NO_DATA; /* no data available */
597 }
598 }
599
600 /* calculate / store buffer index */
601 tmptail = (UART_RxTail + 1) & UART_RX0_BUFFER_MASK;
602
603 UART_RxTail = tmptail;
604
605 /* get data from receive buffer */
606 data = UART_RxBuf[tmptail];
607
608 return (UART_LastRxError << 8) + data;
609
610} /* uart0_getc */
611
612/*************************************************************************
613Function: uart0_peek()
614Purpose: Returns the next byte (character) of incoming UART data without
615 removing it from the ring buffer. That is, successive calls to
616 uartN_peek() will return the same character, as will the next
617 call to uartN_getc()
618Returns: lower byte: next byte in ring buffer
619 higher byte: last receive error
620**************************************************************************/
621uint16_t uart0_peek(void)
622{
623 uint16_t tmptail;
624 uint8_t data;
625
626 ATOMIC_BLOCK(ATOMIC_FORCEON) {
627 if (UART_RxHead == UART_RxTail) {
628 return UART_NO_DATA; /* no data available */
629 }
630 }
631
632 tmptail = (UART_RxTail + 1) & UART_RX0_BUFFER_MASK;
633
634 /* get data from receive buffer */
635 data = UART_RxBuf[tmptail];
636
637 return (UART_LastRxError << 8) + data;
638
639} /* uart0_peek */
640
641/*************************************************************************
642Function: uart0_putc()
643Purpose: write byte to ringbuffer for transmitting via UART
644Input: byte to be transmitted
645Returns: none
646**************************************************************************/
647void uart0_putc(uint8_t data)
648{
649
650#ifdef USART0_LARGE_BUFFER
651 uint16_t tmphead;
652 uint16_t txtail_tmp;
653
654 tmphead = (UART_TxHead + 1) & UART_TX0_BUFFER_MASK;
655
656 do {
657 ATOMIC_BLOCK(ATOMIC_FORCEON) {
658 txtail_tmp = UART_TxTail;
659 }
660 } while (tmphead == txtail_tmp); /* wait for free space in buffer */
661#else
662 uint16_t tmphead;
663
664 tmphead = (UART_TxHead + 1) & UART_TX0_BUFFER_MASK;
665
666 while (tmphead == UART_TxTail); /* wait for free space in buffer */
667#endif
668
669 UART_TxBuf[tmphead] = data;
670 UART_TxHead = tmphead;
671
672 /* enable UDRE interrupt */
673 UART0_CONTROL |= _BV(UART0_UDRIE);
674
675} /* uart0_putc */
676
677
678/*************************************************************************
679Function: uart0_puts()
680Purpose: transmit string to UART
681Input: string to be transmitted
682Returns: none
683**************************************************************************/
684void uart0_puts(const char *s)
685{
686 while (*s) {
687 uart0_putc(*s++);
688 }
689
690} /* uart0_puts */
691
692
693/*************************************************************************
694Function: uart0_puts_p()
695Purpose: transmit string from program memory to UART
696Input: program memory string to be transmitted
697Returns: none
698**************************************************************************/
699void uart0_puts_p(const char *progmem_s)
700{
701 register char c;
702
703 while ((c = pgm_read_byte(progmem_s++))) {
704 uart0_putc(c);
705 }
706
707} /* uart0_puts_p */
708
709
710
711/*************************************************************************
712Function: uart0_available()
713Purpose: Determine the number of bytes waiting in the receive buffer
714Input: None
715Returns: Integer number of bytes in the receive buffer
716**************************************************************************/
717uint16_t uart0_available(void)
718{
719 uint16_t ret;
720
721 ATOMIC_BLOCK(ATOMIC_FORCEON) {
722 ret = (UART_RX0_BUFFER_SIZE + UART_RxHead - UART_RxTail) & UART_RX0_BUFFER_MASK;
723 }
724 return ret;
725} /* uart0_available */
726
727/*************************************************************************
728Function: uart0_flush()
729Purpose: Flush bytes waiting the receive buffer. Actually ignores them.
730Input: None
731Returns: None
732**************************************************************************/
733void uart0_flush(void)
734{
735 ATOMIC_BLOCK(ATOMIC_FORCEON) {
736 UART_RxHead = UART_RxTail;
737 }
738} /* uart0_flush */
739
740#endif
741
742#endif /* defined(USART0_ENABLED) */
743
744#if defined(USART1_ENABLED)
745
746/*
747 * these functions are only for ATmegas with two USART
748 */
749#if defined(ATMEGA_USART1)
750
751ISR(UART1_RECEIVE_INTERRUPT)
752/*************************************************************************
753Function: UART1 Receive Complete interrupt
754Purpose: called when the UART1 has received a character
755**************************************************************************/
756{
757 uint16_t tmphead;
758 uint8_t data;
759 uint8_t usr;
760 uint8_t lastRxError;
761
762 /* read UART status register and UART data register */
763 usr = UART1_STATUS;
764 data = UART1_DATA;
765
766 /* */
767 lastRxError = (usr & (_BV(FE1)|_BV(DOR1)));
768
769 /* calculate buffer index */
770 tmphead = (UART1_RxHead + 1) & UART_RX1_BUFFER_MASK;
771
772 if (tmphead == UART1_RxTail) {
773 /* error: receive buffer overflow */
774 lastRxError = UART_BUFFER_OVERFLOW >> 8;
775 } else {
776 /* store new index */
777 UART1_RxHead = tmphead;
778 /* store received data in buffer */
779 UART1_RxBuf[tmphead] = data;
780 }
781 UART1_LastRxError = lastRxError;
782}
783
784
785ISR(UART1_TRANSMIT_INTERRUPT)
786/*************************************************************************
787Function: UART1 Data Register Empty interrupt
788Purpose: called when the UART1 is ready to transmit the next byte
789**************************************************************************/
790{
791 uint16_t tmptail;
792
793 if (UART1_TxHead != UART1_TxTail) {
794 /* calculate and store new buffer index */
795 tmptail = (UART1_TxTail + 1) & UART_TX1_BUFFER_MASK;
796 UART1_TxTail = tmptail;
797 /* get one byte from buffer and write it to UART */
798 UART1_DATA = UART1_TxBuf[tmptail]; /* start transmission */
799 } else {
800 /* tx buffer empty, disable UDRE interrupt */
801 UART1_CONTROL &= ~_BV(UART1_UDRIE);
802 }
803}
804
805
806/*************************************************************************
807Function: uart1_init()
808Purpose: initialize UART1 and set baudrate
809Input: baudrate using macro UART_BAUD_SELECT()
810Returns: none
811**************************************************************************/
812void uart1_init(uint16_t baudrate)
813{
814 ATOMIC_BLOCK(ATOMIC_FORCEON) {
815 UART1_TxHead = 0;
816 UART1_TxTail = 0;
817 UART1_RxHead = 0;
818 UART1_RxTail = 0;
819 }
820
821 /* Set baud rate */
822 if (baudrate & 0x8000) {
823 UART1_STATUS = (1<<U2X1); //Enable 2x speed
824 baudrate &= ~0x8000;
825 }
826 UBRR1H = (uint8_t) (baudrate>>8);
827 UBRR1L = (uint8_t) baudrate;
828
829 /* Enable USART receiver and transmitter and receive complete interrupt */
830 UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
831
832 /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
833#ifdef URSEL1
834 UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
835#else
836 UCSR1C = (3<<UCSZ10);
837#endif
838} /* uart_init */
839
840
841/*************************************************************************
842Function: uart1_getc()
843Purpose: return byte from ringbuffer
844Returns: lower byte: received byte from ringbuffer
845 higher byte: last receive error
846**************************************************************************/
847uint16_t uart1_getc(void)
848{
849 uint16_t tmptail;
850 uint8_t data;
851
852 ATOMIC_BLOCK(ATOMIC_FORCEON) {
853 if (UART1_RxHead == UART1_RxTail) {
854 return UART_NO_DATA; /* no data available */
855 }
856
857 /* calculate / store buffer index */
858 tmptail = (UART1_RxTail + 1) & UART_RX1_BUFFER_MASK;
859 UART1_RxTail = tmptail;
860 }
861
862 /* get data from receive buffer */
863 data = UART1_RxBuf[tmptail];
864
865 return (UART1_LastRxError << 8) + data;
866
867} /* uart1_getc */
868
869/*************************************************************************
870Function: uart1_peek()
871Purpose: Returns the next byte (character) of incoming UART data without
872 removing it from the ring buffer. That is, successive calls to
873 uartN_peek() will return the same character, as will the next
874 call to uartN_getc()
875Returns: lower byte: next byte in ring buffer
876 higher byte: last receive error
877**************************************************************************/
878uint16_t uart1_peek(void)
879{
880 uint16_t tmptail;
881 uint8_t data;
882
883 ATOMIC_BLOCK(ATOMIC_FORCEON) {
884 if (UART1_RxHead == UART1_RxTail) {
885 return UART_NO_DATA; /* no data available */
886 }
887 }
888
889 tmptail = (UART1_RxTail + 1) & UART_RX1_BUFFER_MASK;
890
891 /* get data from receive buffer */
892 data = UART1_RxBuf[tmptail];
893
894 return (UART1_LastRxError << 8) + data;
895
896} /* uart1_peek */
897
898/*************************************************************************
899Function: uart1_putc()
900Purpose: write byte to ringbuffer for transmitting via UART
901Input: byte to be transmitted
902Returns: none
903**************************************************************************/
904void uart1_putc(uint8_t data)
905{
906
907#ifdef USART1_LARGE_BUFFER
908 uint16_t tmphead;
909 uint16_t txtail_tmp;
910
911 tmphead = (UART1_TxHead + 1) & UART_TX1_BUFFER_MASK;
912
913 do {
914 ATOMIC_BLOCK(ATOMIC_FORCEON) {
915 txtail_tmp = UART1_TxTail;
916 }
917 } while (tmphead == txtail_tmp); /* wait for free space in buffer */
918#else
919 uint16_t tmphead;
920
921 tmphead = (UART1_TxHead + 1) & UART_TX1_BUFFER_MASK;
922
923 while (tmphead == UART1_TxTail); /* wait for free space in buffer */
924#endif
925
926 UART1_TxBuf[tmphead] = data;
927 UART1_TxHead = tmphead;
928
929 /* enable UDRE interrupt */
930 UART1_CONTROL |= _BV(UART1_UDRIE);
931
932} /* uart1_putc */
933
934
935/*************************************************************************
936Function: uart1_puts()
937Purpose: transmit string to UART1
938Input: string to be transmitted
939Returns: none
940**************************************************************************/
941void uart1_puts(const char *s)
942{
943 while (*s) {
944 uart1_putc(*s++);
945 }
946
947} /* uart1_puts */
948
949
950/*************************************************************************
951Function: uart1_puts_p()
952Purpose: transmit string from program memory to UART1
953Input: program memory string to be transmitted
954Returns: none
955**************************************************************************/
956void uart1_puts_p(const char *progmem_s)
957{
958 register char c;
959
960 while ((c = pgm_read_byte(progmem_s++))) {
961 uart1_putc(c);
962 }
963
964} /* uart1_puts_p */
965
966
967
968/*************************************************************************
969Function: uart1_available()
970Purpose: Determine the number of bytes waiting in the receive buffer
971Input: None
972Returns: Integer number of bytes in the receive buffer
973**************************************************************************/
974uint16_t uart1_available(void)
975{
976 uint16_t ret;
977
978 ATOMIC_BLOCK(ATOMIC_FORCEON) {
979 ret = (UART_RX1_BUFFER_SIZE + UART1_RxHead - UART1_RxTail) & UART_RX1_BUFFER_MASK;
980 }
981 return ret;
982} /* uart1_available */
983
984
985
986/*************************************************************************
987Function: uart1_flush()
988Purpose: Flush bytes waiting the receive buffer. Actually ignores them.
989Input: None
990Returns: None
991**************************************************************************/
992void uart1_flush(void)
993{
994 ATOMIC_BLOCK(ATOMIC_FORCEON) {
995 UART1_RxHead = UART1_RxTail;
996 }
997} /* uart1_flush */
998
999#endif
1000
1001#endif /* defined(USART1_ENABLED) */
1002
1003#if defined(USART2_ENABLED)
1004
1005/*
1006 * these functions are only for ATmegas with four USART
1007 */
1008#if defined(ATMEGA_USART2)
1009
1010ISR(UART2_RECEIVE_INTERRUPT)
1011/*************************************************************************
1012Function: UART2 Receive Complete interrupt
1013Purpose: called when the UART2 has received a character
1014**************************************************************************/
1015{
1016 uint16_t tmphead;
1017 uint8_t data;
1018 uint8_t usr;
1019 uint8_t lastRxError;
1020
1021
1022 /* read UART status register and UART data register */
1023 usr = UART2_STATUS;
1024 data = UART2_DATA;
1025
1026 /* */
1027 lastRxError = (usr & (_BV(FE2)|_BV(DOR2)));
1028
1029 /* calculate buffer index */
1030 tmphead = (UART2_RxHead + 1) & UART_RX2_BUFFER_MASK;
1031
1032 if (tmphead == UART2_RxTail) {
1033 /* error: receive buffer overflow */
1034 lastRxError = UART_BUFFER_OVERFLOW >> 8;
1035 } else {
1036 /* store new index */
1037 UART2_RxHead = tmphead;
1038 /* store received data in buffer */
1039 UART2_RxBuf[tmphead] = data;
1040 }
1041 UART2_LastRxError = lastRxError;
1042}
1043
1044
1045ISR(UART2_TRANSMIT_INTERRUPT)
1046/*************************************************************************
1047Function: UART2 Data Register Empty interrupt
1048Purpose: called when the UART2 is ready to transmit the next byte
1049**************************************************************************/
1050{
1051 uint16_t tmptail;
1052
1053
1054 if (UART2_TxHead != UART2_TxTail) {
1055 /* calculate and store new buffer index */
1056 tmptail = (UART2_TxTail + 1) & UART_TX2_BUFFER_MASK;
1057 UART2_TxTail = tmptail;
1058 /* get one byte from buffer and write it to UART */
1059 UART2_DATA = UART2_TxBuf[tmptail]; /* start transmission */
1060 } else {
1061 /* tx buffer empty, disable UDRE interrupt */
1062 UART2_CONTROL &= ~_BV(UART2_UDRIE);
1063 }
1064}
1065
1066
1067/*************************************************************************
1068Function: uart2_init()
1069Purpose: initialize UART2 and set baudrate
1070Input: baudrate using macro UART_BAUD_SELECT()
1071Returns: none
1072**************************************************************************/
1073void uart2_init(uint16_t baudrate)
1074{
1075 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1076 UART2_TxHead = 0;
1077 UART2_TxTail = 0;
1078 UART2_RxHead = 0;
1079 UART2_RxTail = 0;
1080 }
1081
1082 /* Set baud rate */
1083 if (baudrate & 0x8000) {
1084 UART2_STATUS = (1<<U2X2); //Enable 2x speed
1085 baudrate &= ~0x8000;
1086 }
1087 UBRR2H = (uint8_t) (baudrate>>8);
1088 UBRR2L = (uint8_t) baudrate;
1089
1090 /* Enable USART receiver and transmitter and receive complete interrupt */
1091 UART2_CONTROL = _BV(RXCIE2)|(1<<RXEN2)|(1<<TXEN2);
1092
1093 /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
1094#ifdef URSEL2
1095 UCSR2C = (1<<URSEL2)|(3<<UCSZ20);
1096#else
1097 UCSR2C = (3<<UCSZ20);
1098#endif
1099} /* uart_init */
1100
1101
1102/*************************************************************************
1103Function: uart2_getc()
1104Purpose: return byte from ringbuffer
1105Returns: lower byte: received byte from ringbuffer
1106 higher byte: last receive error
1107**************************************************************************/
1108uint16_t uart2_getc(void)
1109{
1110 uint16_t tmptail;
1111 uint8_t data;
1112
1113 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1114 if (UART2_RxHead == UART2_RxTail) {
1115 return UART_NO_DATA; /* no data available */
1116 }
1117 }
1118
1119 /* calculate / store buffer index */
1120
1121 tmptail = (UART2_RxTail + 1) & UART_RX2_BUFFER_MASK;
1122 UART2_RxTail = tmptail;
1123
1124 /* get data from receive buffer */
1125 data = UART2_RxBuf[tmptail];
1126
1127 return (UART2_LastRxError << 8) + data;
1128
1129} /* uart2_getc */
1130
1131/*************************************************************************
1132Function: uart2_peek()
1133Purpose: Returns the next byte (character) of incoming UART data without
1134 removing it from the ring buffer. That is, successive calls to
1135 uartN_peek() will return the same character, as will the next
1136 call to uartN_getc()
1137Returns: lower byte: next byte in ring buffer
1138 higher byte: last receive error
1139**************************************************************************/
1140uint16_t uart2_peek(void)
1141{
1142 uint16_t tmptail;
1143 uint8_t data;
1144
1145 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1146 if (UART2_RxHead == UART2_RxTail) {
1147 return UART_NO_DATA; /* no data available */
1148 }
1149 }
1150
1151 tmptail = (UART2_RxTail + 1) & UART_RX2_BUFFER_MASK;
1152
1153 /* get data from receive buffer */
1154 data = UART2_RxBuf[tmptail];
1155
1156 return (UART2_LastRxError << 8) + data;
1157
1158} /* uart2_peek */
1159
1160/*************************************************************************
1161Function: uart2_putc()
1162Purpose: write byte to ringbuffer for transmitting via UART
1163Input: byte to be transmitted
1164Returns: none
1165**************************************************************************/
1166void uart2_putc(uint8_t data)
1167{
1168
1169#ifdef USART2_LARGE_BUFFER
1170 uint16_t tmphead;
1171 uint16_t txtail_tmp;
1172
1173 tmphead = (UART2_TxHead + 1) & UART_TX2_BUFFER_MASK;
1174
1175 do {
1176 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1177 txtail_tmp = UART2_TxTail;
1178 }
1179 } while (tmphead == txtail_tmp); /* wait for free space in buffer */
1180#else
1181 uint16_t tmphead;
1182
1183 tmphead = (UART2_TxHead + 1) & UART_TX2_BUFFER_MASK;
1184
1185 while (tmphead == UART2_TxTail); /* wait for free space in buffer */
1186#endif
1187
1188 UART2_TxBuf[tmphead] = data;
1189 UART2_TxHead = tmphead;
1190
1191 /* enable UDRE interrupt */
1192 UART2_CONTROL |= _BV(UART2_UDRIE);
1193
1194} /* uart2_putc */
1195
1196
1197/*************************************************************************
1198Function: uart2_puts()
1199Purpose: transmit string to UART2
1200Input: string to be transmitted
1201Returns: none
1202**************************************************************************/
1203void uart2_puts(const char *s)
1204{
1205 while (*s)
1206 uart2_putc(*s++);
1207
1208} /* uart2_puts */
1209
1210
1211/*************************************************************************
1212Function: uart2_puts_p()
1213Purpose: transmit string from program memory to UART2
1214Input: program memory string to be transmitted
1215Returns: none
1216**************************************************************************/
1217void uart2_puts_p(const char *progmem_s)
1218{
1219 register char c;
1220
1221 while ((c = pgm_read_byte(progmem_s++))) {
1222 uart2_putc(c);
1223 }
1224
1225} /* uart2_puts_p */
1226
1227
1228
1229/*************************************************************************
1230Function: uart2_available()
1231Purpose: Determine the number of bytes waiting in the receive buffer
1232Input: None
1233Returns: Integer number of bytes in the receive buffer
1234**************************************************************************/
1235uint16_t uart2_available(void)
1236{
1237 uint16_t ret;
1238
1239 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1240 ret = (UART_RX2_BUFFER_SIZE + UART2_RxHead - UART2_RxTail) & UART_RX2_BUFFER_MASK;
1241 }
1242 return ret;
1243} /* uart2_available */
1244
1245
1246
1247/*************************************************************************
1248Function: uart2_flush()
1249Purpose: Flush bytes waiting the receive buffer. Actually ignores them.
1250Input: None
1251Returns: None
1252**************************************************************************/
1253void uart2_flush(void)
1254{
1255 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1256 UART2_RxHead = UART2_RxTail;
1257 }
1258} /* uart2_flush */
1259
1260#endif
1261
1262#endif /* defined(USART2_ENABLED) */
1263
1264#if defined(USART3_ENABLED)
1265
1266/*
1267 * these functions are only for ATmegas with four USART
1268 */
1269#if defined(ATMEGA_USART3)
1270
1271ISR(UART3_RECEIVE_INTERRUPT)
1272/*************************************************************************
1273Function: UART3 Receive Complete interrupt
1274Purpose: called when the UART3 has received a character
1275**************************************************************************/
1276{
1277 uint16_t tmphead;
1278 uint8_t data;
1279 uint8_t usr;
1280 uint8_t lastRxError;
1281
1282 /* read UART status register and UART data register */
1283 usr = UART3_STATUS;
1284 data = UART3_DATA;
1285
1286 /* */
1287 lastRxError = (usr & (_BV(FE3)|_BV(DOR3)));
1288
1289 /* calculate buffer index */
1290 tmphead = (UART3_RxHead + 1) & UART_RX3_BUFFER_MASK;
1291
1292 if (tmphead == UART3_RxTail) {
1293 /* error: receive buffer overflow */
1294 lastRxError = UART_BUFFER_OVERFLOW >> 8;
1295 } else {
1296 /* store new index */
1297 UART3_RxHead = tmphead;
1298 /* store received data in buffer */
1299 UART3_RxBuf[tmphead] = data;
1300 }
1301 UART3_LastRxError = lastRxError;
1302}
1303
1304
1305ISR(UART3_TRANSMIT_INTERRUPT)
1306/*************************************************************************
1307Function: UART3 Data Register Empty interrupt
1308Purpose: called when the UART3 is ready to transmit the next byte
1309**************************************************************************/
1310{
1311 uint16_t tmptail;
1312
1313
1314 if (UART3_TxHead != UART3_TxTail) {
1315 /* calculate and store new buffer index */
1316 tmptail = (UART3_TxTail + 1) & UART_TX3_BUFFER_MASK;
1317 UART3_TxTail = tmptail;
1318 /* get one byte from buffer and write it to UART */
1319 UART3_DATA = UART3_TxBuf[tmptail]; /* start transmission */
1320 } else {
1321 /* tx buffer empty, disable UDRE interrupt */
1322 UART3_CONTROL &= ~_BV(UART3_UDRIE);
1323 }
1324}
1325
1326
1327/*************************************************************************
1328Function: uart3_init()
1329Purpose: initialize UART3 and set baudrate
1330Input: baudrate using macro UART_BAUD_SELECT()
1331Returns: none
1332**************************************************************************/
1333void uart3_init(uint16_t baudrate)
1334{
1335 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1336 UART3_TxHead = 0;
1337 UART3_TxTail = 0;
1338 UART3_RxHead = 0;
1339 UART3_RxTail = 0;
1340 }
1341
1342 /* Set baud rate */
1343 if (baudrate & 0x8000) {
1344 UART3_STATUS = (1<<U2X3); //Enable 2x speed
1345 baudrate &= ~0x8000;
1346 }
1347 UBRR3H = (uint8_t)(baudrate>>8);
1348 UBRR3L = (uint8_t) baudrate;
1349
1350 /* Enable USART receiver and transmitter and receive complete interrupt */
1351 UART3_CONTROL = _BV(RXCIE3)|(1<<RXEN3)|(1<<TXEN3);
1352
1353 /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
1354#ifdef URSEL3
1355 UCSR3C = (1<<URSEL3)|(3<<UCSZ30);
1356#else
1357 UCSR3C = (3<<UCSZ30);
1358#endif
1359} /* uart_init */
1360
1361
1362/*************************************************************************
1363Function: uart3_getc()
1364Purpose: return byte from ringbuffer
1365Returns: lower byte: received byte from ringbuffer
1366 higher byte: last receive error
1367**************************************************************************/
1368uint16_t uart3_getc(void)
1369{
1370 uint16_t tmptail;
1371 uint8_t data;
1372
1373 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1374 if (UART3_RxHead == UART3_RxTail) {
1375 return UART_NO_DATA; /* no data available */
1376 }
1377 }
1378
1379 /* calculate / store buffer index */
1380 tmptail = (UART3_RxTail + 1) & UART_RX3_BUFFER_MASK;
1381 UART3_RxTail = tmptail;
1382
1383 /* get data from receive buffer */
1384 data = UART3_RxBuf[tmptail];
1385
1386 return (UART3_LastRxError << 8) + data;
1387
1388} /* uart3_getc */
1389
1390/*************************************************************************
1391Function: uart3_peek()
1392Purpose: Returns the next byte (character) of incoming UART data without
1393 removing it from the ring buffer. That is, successive calls to
1394 uartN_peek() will return the same character, as will the next
1395 call to uartN_getc()
1396Returns: lower byte: next byte in ring buffer
1397 higher byte: last receive error
1398**************************************************************************/
1399uint16_t uart3_peek(void)
1400{
1401 uint16_t tmptail;
1402 uint8_t data;
1403
1404 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1405 if (UART3_RxHead == UART3_RxTail) {
1406 return UART_NO_DATA; /* no data available */
1407 }
1408 }
1409
1410 tmptail = (UART3_RxTail + 1) & UART_RX3_BUFFER_MASK;
1411
1412 /* get data from receive buffer */
1413 data = UART3_RxBuf[tmptail];
1414
1415 return (UART3_LastRxError << 8) + data;
1416
1417} /* uart3_peek */
1418
1419/*************************************************************************
1420Function: uart3_putc()
1421Purpose: write byte to ringbuffer for transmitting via UART
1422Input: byte to be transmitted
1423Returns: none
1424**************************************************************************/
1425void uart3_putc(uint8_t data)
1426{
1427
1428#ifdef USART3_LARGE_BUFFER
1429 uint16_t tmphead;
1430 uint16_t txtail_tmp;
1431
1432 tmphead = (UART3_TxHead + 1) & UART_TX3_BUFFER_MASK;
1433
1434 do {
1435 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1436 txtail_tmp = UART3_TxTail;
1437 }
1438 } while (tmphead == txtail_tmp); /* wait for free space in buffer */
1439#else
1440 uint16_t tmphead;
1441
1442 tmphead = (UART3_TxHead + 1) & UART_TX3_BUFFER_MASK;
1443
1444 while (tmphead == UART3_TxTail); /* wait for free space in buffer */
1445#endif
1446
1447 UART3_TxBuf[tmphead] = data;
1448 UART3_TxHead = tmphead;
1449
1450 /* enable UDRE interrupt */
1451 UART3_CONTROL |= _BV(UART3_UDRIE);
1452
1453} /* uart3_putc */
1454
1455
1456/*************************************************************************
1457Function: uart3_puts()
1458Purpose: transmit string to UART3
1459Input: string to be transmitted
1460Returns: none
1461**************************************************************************/
1462void uart3_puts(const char *s)
1463{
1464 while (*s) {
1465 uart3_putc(*s++);
1466 }
1467
1468} /* uart3_puts */
1469
1470
1471/*************************************************************************
1472Function: uart3_puts_p()
1473Purpose: transmit string from program memory to UART3
1474Input: program memory string to be transmitted
1475Returns: none
1476**************************************************************************/
1477void uart3_puts_p(const char *progmem_s)
1478{
1479 register char c;
1480
1481 while ((c = pgm_read_byte(progmem_s++))) {
1482 uart3_putc(c);
1483 }
1484
1485} /* uart3_puts_p */
1486
1487
1488
1489/*************************************************************************
1490Function: uart3_available()
1491Purpose: Determine the number of bytes waiting in the receive buffer
1492Input: None
1493Returns: Integer number of bytes in the receive buffer
1494**************************************************************************/
1495uint16_t uart3_available(void)
1496{
1497 uint16_t ret;
1498
1499 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1500 ret = (UART_RX3_BUFFER_SIZE + UART3_RxHead - UART3_RxTail) & UART_RX3_BUFFER_MASK;
1501 }
1502 return ret;
1503} /* uart3_available */
1504
1505
1506
1507/*************************************************************************
1508Function: uart3_flush()
1509Purpose: Flush bytes waiting the receive buffer. Actually ignores them.
1510Input: None
1511Returns: None
1512**************************************************************************/
1513void uart3_flush(void)
1514{
1515 ATOMIC_BLOCK(ATOMIC_FORCEON) {
1516 UART3_RxHead = UART3_RxTail;
1517 }
1518} /* uart3_flush */
1519
1520#endif
1521
1522#endif /* defined(USART3_ENABLED) */