diff options
Diffstat (limited to 'keyboards/bioi/usart.c')
-rw-r--r-- | keyboards/bioi/usart.c | 1522 |
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 | |||
27 | LICENSE: | ||
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 | /************************************************************************ | ||
44 | uart_available, uart_flush, uart1_available, and uart1_flush functions | ||
45 | were adapted from the Arduino HardwareSerial.h library by Tim Sharpe on | ||
46 | 11 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 | /************************************************************************ | ||
69 | Changelog for modifications made by Tim Sharpe, starting with the current | ||
70 | library version on his Web site as of 05/01/2009. | ||
71 | |||
72 | Date Description | ||
73 | ========================================================================= | ||
74 | 05/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. | ||
82 | 05/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! | ||
89 | 05/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 | |||
443 | ISR(UART0_RECEIVE_INTERRUPT) | ||
444 | /************************************************************************* | ||
445 | Function: UART Receive Complete interrupt | ||
446 | Purpose: 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 | |||
485 | ISR(UART0_TRANSMIT_INTERRUPT) | ||
486 | /************************************************************************* | ||
487 | Function: UART Data Register Empty interrupt | ||
488 | Purpose: 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 | /************************************************************************* | ||
507 | Function: uart0_init() | ||
508 | Purpose: initialize UART and set baudrate | ||
509 | Input: baudrate using macro UART_BAUD_SELECT() | ||
510 | Returns: none | ||
511 | **************************************************************************/ | ||
512 | void 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 | /************************************************************************* | ||
584 | Function: uart0_getc() | ||
585 | Purpose: return byte from ringbuffer | ||
586 | Returns: lower byte: received byte from ringbuffer | ||
587 | higher byte: last receive error | ||
588 | **************************************************************************/ | ||
589 | uint16_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 | /************************************************************************* | ||
613 | Function: uart0_peek() | ||
614 | Purpose: 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() | ||
618 | Returns: lower byte: next byte in ring buffer | ||
619 | higher byte: last receive error | ||
620 | **************************************************************************/ | ||
621 | uint16_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 | /************************************************************************* | ||
642 | Function: uart0_putc() | ||
643 | Purpose: write byte to ringbuffer for transmitting via UART | ||
644 | Input: byte to be transmitted | ||
645 | Returns: none | ||
646 | **************************************************************************/ | ||
647 | void 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 | /************************************************************************* | ||
679 | Function: uart0_puts() | ||
680 | Purpose: transmit string to UART | ||
681 | Input: string to be transmitted | ||
682 | Returns: none | ||
683 | **************************************************************************/ | ||
684 | void uart0_puts(const char *s) | ||
685 | { | ||
686 | while (*s) { | ||
687 | uart0_putc(*s++); | ||
688 | } | ||
689 | |||
690 | } /* uart0_puts */ | ||
691 | |||
692 | |||
693 | /************************************************************************* | ||
694 | Function: uart0_puts_p() | ||
695 | Purpose: transmit string from program memory to UART | ||
696 | Input: program memory string to be transmitted | ||
697 | Returns: none | ||
698 | **************************************************************************/ | ||
699 | void 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 | /************************************************************************* | ||
712 | Function: uart0_available() | ||
713 | Purpose: Determine the number of bytes waiting in the receive buffer | ||
714 | Input: None | ||
715 | Returns: Integer number of bytes in the receive buffer | ||
716 | **************************************************************************/ | ||
717 | uint16_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 | /************************************************************************* | ||
728 | Function: uart0_flush() | ||
729 | Purpose: Flush bytes waiting the receive buffer. Actually ignores them. | ||
730 | Input: None | ||
731 | Returns: None | ||
732 | **************************************************************************/ | ||
733 | void 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 | |||
751 | ISR(UART1_RECEIVE_INTERRUPT) | ||
752 | /************************************************************************* | ||
753 | Function: UART1 Receive Complete interrupt | ||
754 | Purpose: 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 | |||
785 | ISR(UART1_TRANSMIT_INTERRUPT) | ||
786 | /************************************************************************* | ||
787 | Function: UART1 Data Register Empty interrupt | ||
788 | Purpose: 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 | /************************************************************************* | ||
807 | Function: uart1_init() | ||
808 | Purpose: initialize UART1 and set baudrate | ||
809 | Input: baudrate using macro UART_BAUD_SELECT() | ||
810 | Returns: none | ||
811 | **************************************************************************/ | ||
812 | void 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 | /************************************************************************* | ||
842 | Function: uart1_getc() | ||
843 | Purpose: return byte from ringbuffer | ||
844 | Returns: lower byte: received byte from ringbuffer | ||
845 | higher byte: last receive error | ||
846 | **************************************************************************/ | ||
847 | uint16_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 | /************************************************************************* | ||
870 | Function: uart1_peek() | ||
871 | Purpose: 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() | ||
875 | Returns: lower byte: next byte in ring buffer | ||
876 | higher byte: last receive error | ||
877 | **************************************************************************/ | ||
878 | uint16_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 | /************************************************************************* | ||
899 | Function: uart1_putc() | ||
900 | Purpose: write byte to ringbuffer for transmitting via UART | ||
901 | Input: byte to be transmitted | ||
902 | Returns: none | ||
903 | **************************************************************************/ | ||
904 | void 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 | /************************************************************************* | ||
936 | Function: uart1_puts() | ||
937 | Purpose: transmit string to UART1 | ||
938 | Input: string to be transmitted | ||
939 | Returns: none | ||
940 | **************************************************************************/ | ||
941 | void uart1_puts(const char *s) | ||
942 | { | ||
943 | while (*s) { | ||
944 | uart1_putc(*s++); | ||
945 | } | ||
946 | |||
947 | } /* uart1_puts */ | ||
948 | |||
949 | |||
950 | /************************************************************************* | ||
951 | Function: uart1_puts_p() | ||
952 | Purpose: transmit string from program memory to UART1 | ||
953 | Input: program memory string to be transmitted | ||
954 | Returns: none | ||
955 | **************************************************************************/ | ||
956 | void 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 | /************************************************************************* | ||
969 | Function: uart1_available() | ||
970 | Purpose: Determine the number of bytes waiting in the receive buffer | ||
971 | Input: None | ||
972 | Returns: Integer number of bytes in the receive buffer | ||
973 | **************************************************************************/ | ||
974 | uint16_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 | /************************************************************************* | ||
987 | Function: uart1_flush() | ||
988 | Purpose: Flush bytes waiting the receive buffer. Actually ignores them. | ||
989 | Input: None | ||
990 | Returns: None | ||
991 | **************************************************************************/ | ||
992 | void 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 | |||
1010 | ISR(UART2_RECEIVE_INTERRUPT) | ||
1011 | /************************************************************************* | ||
1012 | Function: UART2 Receive Complete interrupt | ||
1013 | Purpose: 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 | |||
1045 | ISR(UART2_TRANSMIT_INTERRUPT) | ||
1046 | /************************************************************************* | ||
1047 | Function: UART2 Data Register Empty interrupt | ||
1048 | Purpose: 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 | /************************************************************************* | ||
1068 | Function: uart2_init() | ||
1069 | Purpose: initialize UART2 and set baudrate | ||
1070 | Input: baudrate using macro UART_BAUD_SELECT() | ||
1071 | Returns: none | ||
1072 | **************************************************************************/ | ||
1073 | void 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 | /************************************************************************* | ||
1103 | Function: uart2_getc() | ||
1104 | Purpose: return byte from ringbuffer | ||
1105 | Returns: lower byte: received byte from ringbuffer | ||
1106 | higher byte: last receive error | ||
1107 | **************************************************************************/ | ||
1108 | uint16_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 | /************************************************************************* | ||
1132 | Function: uart2_peek() | ||
1133 | Purpose: 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() | ||
1137 | Returns: lower byte: next byte in ring buffer | ||
1138 | higher byte: last receive error | ||
1139 | **************************************************************************/ | ||
1140 | uint16_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 | /************************************************************************* | ||
1161 | Function: uart2_putc() | ||
1162 | Purpose: write byte to ringbuffer for transmitting via UART | ||
1163 | Input: byte to be transmitted | ||
1164 | Returns: none | ||
1165 | **************************************************************************/ | ||
1166 | void 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 | /************************************************************************* | ||
1198 | Function: uart2_puts() | ||
1199 | Purpose: transmit string to UART2 | ||
1200 | Input: string to be transmitted | ||
1201 | Returns: none | ||
1202 | **************************************************************************/ | ||
1203 | void uart2_puts(const char *s) | ||
1204 | { | ||
1205 | while (*s) | ||
1206 | uart2_putc(*s++); | ||
1207 | |||
1208 | } /* uart2_puts */ | ||
1209 | |||
1210 | |||
1211 | /************************************************************************* | ||
1212 | Function: uart2_puts_p() | ||
1213 | Purpose: transmit string from program memory to UART2 | ||
1214 | Input: program memory string to be transmitted | ||
1215 | Returns: none | ||
1216 | **************************************************************************/ | ||
1217 | void 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 | /************************************************************************* | ||
1230 | Function: uart2_available() | ||
1231 | Purpose: Determine the number of bytes waiting in the receive buffer | ||
1232 | Input: None | ||
1233 | Returns: Integer number of bytes in the receive buffer | ||
1234 | **************************************************************************/ | ||
1235 | uint16_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 | /************************************************************************* | ||
1248 | Function: uart2_flush() | ||
1249 | Purpose: Flush bytes waiting the receive buffer. Actually ignores them. | ||
1250 | Input: None | ||
1251 | Returns: None | ||
1252 | **************************************************************************/ | ||
1253 | void 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 | |||
1271 | ISR(UART3_RECEIVE_INTERRUPT) | ||
1272 | /************************************************************************* | ||
1273 | Function: UART3 Receive Complete interrupt | ||
1274 | Purpose: 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 | |||
1305 | ISR(UART3_TRANSMIT_INTERRUPT) | ||
1306 | /************************************************************************* | ||
1307 | Function: UART3 Data Register Empty interrupt | ||
1308 | Purpose: 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 | /************************************************************************* | ||
1328 | Function: uart3_init() | ||
1329 | Purpose: initialize UART3 and set baudrate | ||
1330 | Input: baudrate using macro UART_BAUD_SELECT() | ||
1331 | Returns: none | ||
1332 | **************************************************************************/ | ||
1333 | void 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 | /************************************************************************* | ||
1363 | Function: uart3_getc() | ||
1364 | Purpose: return byte from ringbuffer | ||
1365 | Returns: lower byte: received byte from ringbuffer | ||
1366 | higher byte: last receive error | ||
1367 | **************************************************************************/ | ||
1368 | uint16_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 | /************************************************************************* | ||
1391 | Function: uart3_peek() | ||
1392 | Purpose: 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() | ||
1396 | Returns: lower byte: next byte in ring buffer | ||
1397 | higher byte: last receive error | ||
1398 | **************************************************************************/ | ||
1399 | uint16_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 | /************************************************************************* | ||
1420 | Function: uart3_putc() | ||
1421 | Purpose: write byte to ringbuffer for transmitting via UART | ||
1422 | Input: byte to be transmitted | ||
1423 | Returns: none | ||
1424 | **************************************************************************/ | ||
1425 | void 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 | /************************************************************************* | ||
1457 | Function: uart3_puts() | ||
1458 | Purpose: transmit string to UART3 | ||
1459 | Input: string to be transmitted | ||
1460 | Returns: none | ||
1461 | **************************************************************************/ | ||
1462 | void uart3_puts(const char *s) | ||
1463 | { | ||
1464 | while (*s) { | ||
1465 | uart3_putc(*s++); | ||
1466 | } | ||
1467 | |||
1468 | } /* uart3_puts */ | ||
1469 | |||
1470 | |||
1471 | /************************************************************************* | ||
1472 | Function: uart3_puts_p() | ||
1473 | Purpose: transmit string from program memory to UART3 | ||
1474 | Input: program memory string to be transmitted | ||
1475 | Returns: none | ||
1476 | **************************************************************************/ | ||
1477 | void 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 | /************************************************************************* | ||
1490 | Function: uart3_available() | ||
1491 | Purpose: Determine the number of bytes waiting in the receive buffer | ||
1492 | Input: None | ||
1493 | Returns: Integer number of bytes in the receive buffer | ||
1494 | **************************************************************************/ | ||
1495 | uint16_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 | /************************************************************************* | ||
1508 | Function: uart3_flush() | ||
1509 | Purpose: Flush bytes waiting the receive buffer. Actually ignores them. | ||
1510 | Input: None | ||
1511 | Returns: None | ||
1512 | **************************************************************************/ | ||
1513 | void 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) */ | ||