1 | /*************************************************************************
|
2 | Title: Interrupt UART library with receive/transmit circular buffers
|
3 | Author: Peter Fleury <pfleury@gmx.ch> http://tinyurl.com/peterfleury
|
4 | File: $Id: uart.c,v 1.15.2.4 2015/09/05 18:33:32 peter Exp $
|
5 | Software: AVR-GCC 4.x
|
6 | Hardware: any AVR with built-in UART,
|
7 | License: GNU General Public License
|
8 |
|
9 | DESCRIPTION:
|
10 | An interrupt is generated when the UART has finished transmitting or
|
11 | receiving a byte. The interrupt handling routines use circular buffers
|
12 | for buffering received and transmitted data.
|
13 |
|
14 | The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
|
15 | the buffer size in bytes. Note that these variables must be a
|
16 | power of 2.
|
17 |
|
18 | USAGE:
|
19 | Refere to the header file uart.h for a description of the routines.
|
20 | See also example test_uart.c.
|
21 |
|
22 | NOTES:
|
23 | Based on Atmel Application Note AVR306
|
24 |
|
25 | LICENSE:
|
26 | Copyright (C) 2015 Peter Fleury, GNU General Public License Version 3
|
27 |
|
28 | This program is free software; you can redistribute it and/or modify
|
29 | it under the terms of the GNU General Public License as published by
|
30 | the Free Software Foundation; either version 2 of the License, or
|
31 | any later version.
|
32 |
|
33 | This program is distributed in the hope that it will be useful,
|
34 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
35 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
36 | GNU General Public License for more details.
|
37 |
|
38 | *************************************************************************/
|
39 | #include <avr/io.h>
|
40 | #include <avr/interrupt.h>
|
41 | #include <avr/pgmspace.h>
|
42 | #include "C:\Users\...\uart.h"
|
43 |
|
44 |
|
45 | /*
|
46 | * constants and macros
|
47 | */
|
48 |
|
49 | /* size of RX/TX buffers */
|
50 | #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
|
51 | #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
|
52 |
|
53 | #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
|
54 | #error RX buffer size is not a power of 2
|
55 | #endif
|
56 | #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
|
57 | #error TX buffer size is not a power of 2
|
58 | #endif
|
59 |
|
60 |
|
61 | #if defined(__AVR_AT90S2313__) || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S8515__) || \
|
62 | defined(__AVR_AT90S4434__) || defined(__AVR_AT90S8535__) || \
|
63 | defined(__AVR_ATmega103__)
|
64 | /* old AVR classic or ATmega103 with one UART */
|
65 | #define UART0_RECEIVE_INTERRUPT UART_RX_vect
|
66 | #define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
|
67 | #define UART0_STATUS USR
|
68 | #define UART0_CONTROL UCR
|
69 | #define UART0_DATA UDR
|
70 | #define UART0_UDRIE UDRIE
|
71 | #define UART0_UBRRL UBRR
|
72 | #define UART0_BIT_U2X U2X
|
73 | #define UART0_BIT_RXCIE RXCIE
|
74 | #define UART0_BIT_RXEN RXEN
|
75 | #define UART0_BIT_TXEN TXEN
|
76 | #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
|
77 | /* old AVR classic with one UART */
|
78 | #define UART0_RECEIVE_INTERRUPT UART_RX_vect
|
79 | #define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
|
80 | #define UART0_STATUS UCSRA
|
81 | #define UART0_CONTROL UCSRB
|
82 | #define UART0_DATA UDR
|
83 | #define UART0_UDRIE UDRIE
|
84 | #define UART0_UBRRL UBRR
|
85 | #define UART0_BIT_U2X U2X
|
86 | #define UART0_BIT_RXCIE RXCIE
|
87 | #define UART0_BIT_RXEN RXEN
|
88 | #define UART0_BIT_TXEN TXEN
|
89 | #elif defined(__AVR_AT90PWM216__) || defined(__AVR_AT90PWM316__)
|
90 | /* AT90PWN216/316 with one USART */
|
91 | #define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
92 | #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
93 | #define UART0_STATUS UCSRA
|
94 | #define UART0_CONTROL UCSRB
|
95 | #define UART0_CONTROLC UCSRC
|
96 | #define UART0_DATA UDR
|
97 | #define UART0_UDRIE UDRIE
|
98 | #define UART0_UBRRL UBRRL
|
99 | #define UART0_UBRRH UBRRH
|
100 | #define UART0_BIT_U2X U2X
|
101 | #define UART0_BIT_RXCIE RXCIE
|
102 | #define UART0_BIT_RXEN RXEN
|
103 | #define UART0_BIT_TXEN TXEN
|
104 | #define UART0_BIT_UCSZ0 UCSZ0
|
105 | #define UART0_BIT_UCSZ1 UCSZ1
|
106 | #elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega8A__) || \
|
107 | defined(__AVR_ATmega16__) || defined(__AVR_ATmega16A__) || \
|
108 | defined(__AVR_ATmega32__) || defined(__AVR_ATmega32A__) || \
|
109 | defined(__AVR_ATmega323__)
|
110 | /* ATmega with one USART */
|
111 | #define UART0_RECEIVE_INTERRUPT USART_RXC_vect
|
112 | #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
113 | #define UART0_STATUS UCSRA
|
114 | #define UART0_CONTROL UCSRB
|
115 | #define UART0_CONTROLC UCSRC
|
116 | #define UART0_DATA UDR
|
117 | #define UART0_UDRIE UDRIE
|
118 | #define UART0_UBRRL UBRRL
|
119 | #define UART0_UBRRH UBRRH
|
120 | #define UART0_BIT_U2X U2X
|
121 | #define UART0_BIT_RXCIE RXCIE
|
122 | #define UART0_BIT_RXEN RXEN
|
123 | #define UART0_BIT_TXEN TXEN
|
124 | #define UART0_BIT_UCSZ0 UCSZ0
|
125 | #define UART0_BIT_UCSZ1 UCSZ1
|
126 | #define UART0_BIT_URSEL URSEL
|
127 | #elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__)
|
128 | #define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
129 | #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
130 | #define UART0_STATUS UCSRA
|
131 | #define UART0_CONTROL UCSRB
|
132 | #define UART0_CONTROLC UCSRC
|
133 | #define UART0_DATA UDR
|
134 | #define UART0_UDRIE UDRIE
|
135 | #define UART0_UBRRL UBRRL
|
136 | #define UART0_UBRRH UBRRH
|
137 | #define UART0_BIT_U2X U2X
|
138 | #define UART0_BIT_RXCIE RXCIE
|
139 | #define UART0_BIT_RXEN RXEN
|
140 | #define UART0_BIT_TXEN TXEN
|
141 | #define UART0_BIT_UCSZ0 UCSZ0
|
142 | #define UART0_BIT_UCSZ1 UCSZ1
|
143 | #define UART0_BIT_URSEL URSEL
|
144 | #elif defined(__AVR_ATmega163__)
|
145 | /* ATmega163 with one UART */
|
146 | #define UART0_RECEIVE_INTERRUPT UART_RX_vect
|
147 | #define UART0_TRANSMIT_INTERRUPT UART_UDRE_vect
|
148 | #define UART0_STATUS UCSRA
|
149 | #define UART0_CONTROL UCSRB
|
150 | #define UART0_DATA UDR
|
151 | #define UART0_UDRIE UDRIE
|
152 | #define UART0_UBRRL UBRR
|
153 | #define UART0_UBRRH UBRRHI
|
154 | #define UART0_BIT_U2X U2X
|
155 | #define UART0_BIT_RXCIE RXCIE
|
156 | #define UART0_BIT_RXEN RXEN
|
157 | #define UART0_BIT_TXEN TXEN
|
158 | #elif defined(__AVR_ATmega162__)
|
159 | /* ATmega with two USART */
|
160 | #define ATMEGA_USART1
|
161 | #define UART0_RECEIVE_INTERRUPT USART0_RXC_vect
|
162 | #define UART1_RECEIVE_INTERRUPT USART1_RXC_vect
|
163 | #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
164 | #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
165 | #define UART0_STATUS UCSR0A
|
166 | #define UART0_CONTROL UCSR0B
|
167 | #define UART0_CONTROLC UCSR0C
|
168 | #define UART0_DATA UDR0
|
169 | #define UART0_UDRIE UDRIE0
|
170 | #define UART0_UBRRL UBRR0L
|
171 | #define UART0_UBRRH UBRR0H
|
172 | #define UART0_BIT_URSEL URSEL0
|
173 | #define UART0_BIT_U2X U2X0
|
174 | #define UART0_BIT_RXCIE RXCIE0
|
175 | #define UART0_BIT_RXEN RXEN0
|
176 | #define UART0_BIT_TXEN TXEN0
|
177 | #define UART0_BIT_UCSZ0 UCSZ00
|
178 | #define UART0_BIT_UCSZ1 UCSZ01
|
179 | #define UART1_STATUS UCSR1A
|
180 | #define UART1_CONTROL UCSR1B
|
181 | #define UART1_CONTROLC UCSR1C
|
182 | #define UART1_DATA UDR1
|
183 | #define UART1_UDRIE UDRIE1
|
184 | #define UART1_UBRRL UBRR1L
|
185 | #define UART1_UBRRH UBRR1H
|
186 | #define UART1_BIT_URSEL URSEL1
|
187 | #define UART1_BIT_U2X U2X1
|
188 | #define UART1_BIT_RXCIE RXCIE1
|
189 | #define UART1_BIT_RXEN RXEN1
|
190 | #define UART1_BIT_TXEN TXEN1
|
191 | #define UART1_BIT_UCSZ0 UCSZ10
|
192 | #define UART1_BIT_UCSZ1 UCSZ11
|
193 | #elif defined(__AVR_ATmega161__)
|
194 | /* ATmega with UART */
|
195 | #error "AVR ATmega161 currently not supported by this libaray !"
|
196 | #elif defined(__AVR_ATmega169__)
|
197 | /* ATmega with one USART */
|
198 | #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
199 | #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
200 | #define UART0_STATUS UCSRA
|
201 | #define UART0_CONTROL UCSRB
|
202 | #define UART0_CONTROLC UCSRC
|
203 | #define UART0_DATA UDR
|
204 | #define UART0_UDRIE UDRIE
|
205 | #define UART0_UBRRL UBRRL
|
206 | #define UART0_UBRRH UBRRH
|
207 | #define UART0_BIT_U2X U2X
|
208 | #define UART0_BIT_RXCIE RXCIE
|
209 | #define UART0_BIT_RXEN RXEN
|
210 | #define UART0_BIT_TXEN TXEN
|
211 | #define UART0_BIT_UCSZ0 UCSZ0
|
212 | #define UART0_BIT_UCSZ1 UCSZ1
|
213 | #elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48PB__) || \
|
214 | defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88PB__) || \
|
215 | defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__)|| defined(__AVR_ATmega168P__)|| defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || \
|
216 | defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || \
|
217 | defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__)
|
218 | /* ATmega with one USART */
|
219 | #define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
220 | #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
221 | #define UART0_STATUS UCSR0A
|
222 | #define UART0_CONTROL UCSR0B
|
223 | #define UART0_CONTROLC UCSR0C
|
224 | #define UART0_DATA UDR0
|
225 | #define UART0_UDRIE UDRIE0
|
226 | #define UART0_UBRRL UBRR0L
|
227 | #define UART0_UBRRH UBRR0H
|
228 | #define UART0_BIT_U2X U2X0
|
229 | #define UART0_BIT_RXCIE RXCIE0
|
230 | #define UART0_BIT_RXEN RXEN0
|
231 | #define UART0_BIT_TXEN TXEN0
|
232 | #define UART0_BIT_UCSZ0 UCSZ00
|
233 | #define UART0_BIT_UCSZ1 UCSZ01
|
234 | #elif defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny2313A__) || defined(__AVR_ATtiny4313__)
|
235 | /* ATtiny with one USART */
|
236 | #define UART0_RECEIVE_INTERRUPT USART_RX_vect
|
237 | #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
|
238 | #define UART0_STATUS UCSRA
|
239 | #define UART0_CONTROL UCSRB
|
240 | #define UART0_CONTROLC UCSRC
|
241 | #define UART0_DATA UDR
|
242 | #define UART0_UDRIE UDRIE
|
243 | #define UART0_UBRRL UBRRL
|
244 | #define UART0_UBRRH UBRRH
|
245 | #define UART0_BIT_U2X U2X
|
246 | #define UART0_BIT_RXCIE RXCIE
|
247 | #define UART0_BIT_RXEN RXEN
|
248 | #define UART0_BIT_TXEN TXEN
|
249 | #define UART0_BIT_UCSZ0 UCSZ0
|
250 | #define UART0_BIT_UCSZ1 UCSZ1
|
251 | #elif defined(__AVR_ATmega329__) || defined(__AVR_ATmega649__) || defined(__AVR_ATmega3290__) || defined(__AVR_ATmega6490__) ||\
|
252 | defined(__AVR_ATmega169A__) || defined(__AVR_ATmega169PA__) || \
|
253 | defined(__AVR_ATmega329A__) || defined(__AVR_ATmega329PA__) || defined(__AVR_ATmega3290A__) || defined(__AVR_ATmega3290PA__) || \
|
254 | defined(__AVR_ATmega649A__) || defined(__AVR_ATmega649P__) || defined(__AVR_ATmega6490A__) || defined(__AVR_ATmega6490P__) || \
|
255 | defined(__AVR_ATmega165__) || defined(__AVR_ATmega325__) || defined(__AVR_ATmega645__) || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega6450__) || \
|
256 | defined(__AVR_ATmega165A__) || defined(__AVR_ATmega165PA__) || \
|
257 | defined(__AVR_ATmega325A__) || defined(__AVR_ATmega325PA__) || defined(__AVR_ATmega3250A__) || defined(__AVR_ATmega3250PA__) ||\
|
258 | defined(__AVR_ATmega645A__) || defined(__AVR_ATmega645PA__) || defined(__AVR_ATmega6450A__) || defined(__AVR_ATmega6450PA__) || \
|
259 | defined(__AVR_ATmega644__)
|
260 | /* ATmega with one USART */
|
261 | #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
262 | #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
263 | #define UART0_STATUS UCSR0A
|
264 | #define UART0_CONTROL UCSR0B
|
265 | #define UART0_CONTROLC UCSR0C
|
266 | #define UART0_DATA UDR0
|
267 | #define UART0_UDRIE UDRIE0
|
268 | #define UART0_UBRRL UBRR0L
|
269 | #define UART0_UBRRH UBRR0H
|
270 | #define UART0_BIT_U2X U2X0
|
271 | #define UART0_BIT_RXCIE RXCIE0
|
272 | #define UART0_BIT_RXEN RXEN0
|
273 | #define UART0_BIT_TXEN TXEN0
|
274 | #define UART0_BIT_UCSZ0 UCSZ00
|
275 | #define UART0_BIT_UCSZ1 UCSZ01
|
276 | #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega128A__) ||\
|
277 | defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || \
|
278 | defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__) || \
|
279 | defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164PA__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__) || \
|
280 | defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) ||\
|
281 | defined(__AVR_ATtiny1634__)
|
282 | /* ATmega with two USART */
|
283 | #define ATMEGA_USART1
|
284 | #define UART0_RECEIVE_INTERRUPT USART0_RX_vect
|
285 | #define UART1_RECEIVE_INTERRUPT USART1_RX_vect
|
286 | #define UART0_TRANSMIT_INTERRUPT USART0_UDRE_vect
|
287 | #define UART1_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
288 | #define UART0_STATUS UCSR0A
|
289 | #define UART0_CONTROL UCSR0B
|
290 | #define UART0_CONTROLC UCSR0C
|
291 | #define UART0_DATA UDR0
|
292 | #define UART0_UDRIE UDRIE0
|
293 | #define UART0_UBRRL UBRR0L
|
294 | #define UART0_UBRRH UBRR0H
|
295 | #define UART0_BIT_U2X U2X0
|
296 | #define UART0_BIT_RXCIE RXCIE0
|
297 | #define UART0_BIT_RXEN RXEN0
|
298 | #define UART0_BIT_TXEN TXEN0
|
299 | #define UART0_BIT_UCSZ0 UCSZ00
|
300 | #define UART0_BIT_UCSZ1 UCSZ01
|
301 | #define UART1_STATUS UCSR1A
|
302 | #define UART1_CONTROL UCSR1B
|
303 | #define UART1_CONTROLC UCSR1C
|
304 | #define UART1_DATA UDR1
|
305 | #define UART1_UDRIE UDRIE1
|
306 | #define UART1_UBRRL UBRR1L
|
307 | #define UART1_UBRRH UBRR1H
|
308 | #define UART1_BIT_U2X U2X1
|
309 | #define UART1_BIT_RXCIE RXCIE1
|
310 | #define UART1_BIT_RXEN RXEN1
|
311 | #define UART1_BIT_TXEN TXEN1
|
312 | #define UART1_BIT_UCSZ0 UCSZ10
|
313 | #define UART1_BIT_UCSZ1 UCSZ11
|
314 | #elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || \
|
315 | defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \
|
316 | defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \
|
317 | defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)
|
318 | #define UART0_RECEIVE_INTERRUPT USART1_RX_vect
|
319 | #define UART0_TRANSMIT_INTERRUPT USART1_UDRE_vect
|
320 | #define UART0_STATUS UCSR1A
|
321 | #define UART0_CONTROL UCSR1B
|
322 | #define UART0_CONTROLC UCSR1C
|
323 | #define UART0_DATA UDR1
|
324 | #define UART0_UDRIE UDRIE1
|
325 | #define UART0_UBRRL UBRR1L
|
326 | #define UART0_UBRRH UBRR1H
|
327 | #define UART0_BIT_U2X U2X1
|
328 | #define UART0_BIT_RXCIE RXCIE1
|
329 | #define UART0_BIT_RXEN RXEN1
|
330 | #define UART0_BIT_TXEN TXEN1
|
331 | #define UART0_BIT_UCSZ0 UCSZ10
|
332 | #define UART0_BIT_UCSZ1 UCSZ11
|
333 | #else
|
334 | #error "no UART definition for MCU available"
|
335 | #endif
|
336 |
|
337 |
|
338 |
|
339 | /*
|
340 | * module global variables
|
341 | */
|
342 | static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
|
343 | static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
|
344 | static volatile unsigned char UART_TxHead;
|
345 | static volatile unsigned char UART_TxTail;
|
346 | static volatile unsigned char UART_RxHead;
|
347 | static volatile unsigned char UART_RxTail;
|
348 | static volatile unsigned char UART_LastRxError;
|
349 |
|
350 | #if defined( ATMEGA_USART1 )
|
351 | static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
|
352 | static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
|
353 | static volatile unsigned char UART1_TxHead;
|
354 | static volatile unsigned char UART1_TxTail;
|
355 | static volatile unsigned char UART1_RxHead;
|
356 | static volatile unsigned char UART1_RxTail;
|
357 | static volatile unsigned char UART1_LastRxError;
|
358 | #endif
|
359 |
|
360 |
|
361 |
|
362 | ISR (UART0_RECEIVE_INTERRUPT)
|
363 | /*************************************************************************
|
364 | Function: UART Receive Complete interrupt
|
365 | Purpose: called when the UART has received a character
|
366 | **************************************************************************/
|
367 | {
|
368 | unsigned char tmphead;
|
369 | unsigned char data;
|
370 | unsigned char usr;
|
371 | unsigned char lastRxError;
|
372 |
|
373 |
|
374 | /* read UART status register and UART data register */
|
375 | usr = UART0_STATUS;
|
376 | data = UART0_DATA;
|
377 |
|
378 | /* get FEn (Frame Error) DORn (Data OverRun) UPEn (USART Parity Error) bits */
|
379 | #if defined(FE) && defined(DOR) && defined(UPE)
|
380 | lastRxError = usr & (_BV(FE)|_BV(DOR)|_BV(UPE) );
|
381 | #elif defined(FE0) && defined(DOR0) && defined(UPE0)
|
382 | lastRxError = usr & (_BV(FE0)|_BV(DOR0)|_BV(UPE0) );
|
383 | #elif defined(FE1) && defined(DOR1) && defined(UPE1)
|
384 | lastRxError = usr & (_BV(FE1)|_BV(DOR1)|_BV(UPE1) );
|
385 | #elif defined(FE) && defined(DOR)
|
386 | lastRxError = usr & (_BV(FE)|_BV(DOR) );
|
387 | #endif
|
388 |
|
389 | /* calculate buffer index */
|
390 | tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
|
391 |
|
392 | if ( tmphead == UART_RxTail ) {
|
393 | /* error: receive buffer overflow */
|
394 | lastRxError = UART_BUFFER_OVERFLOW >> 8;
|
395 | }else{
|
396 | /* store new index */
|
397 | UART_RxHead = tmphead;
|
398 | /* store received data in buffer */
|
399 | UART_RxBuf[tmphead] = data;
|
400 | }
|
401 | UART_LastRxError |= lastRxError;
|
402 | }
|
403 |
|
404 |
|
405 | ISR (UART0_TRANSMIT_INTERRUPT)
|
406 | /*************************************************************************
|
407 | Function: UART Data Register Empty interrupt
|
408 | Purpose: called when the UART is ready to transmit the next byte
|
409 | **************************************************************************/
|
410 | {
|
411 | unsigned char tmptail;
|
412 |
|
413 |
|
414 | if ( UART_TxHead != UART_TxTail) {
|
415 | /* calculate and store new buffer index */
|
416 | tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
|
417 | UART_TxTail = tmptail;
|
418 | /* get one byte from buffer and write it to UART */
|
419 | UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */
|
420 | }else{
|
421 | /* tx buffer empty, disable UDRE interrupt */
|
422 | UART0_CONTROL &= ~_BV(UART0_UDRIE);
|
423 | }
|
424 | }
|
425 |
|
426 |
|
427 | /*************************************************************************
|
428 | Function: uart_init()
|
429 | Purpose: initialize UART and set baudrate
|
430 | Input: baudrate using macro UART_BAUD_SELECT()
|
431 | Returns: none
|
432 | **************************************************************************/
|
433 | void uart_init(unsigned int baudrate)
|
434 | {
|
435 | UART_TxHead = 0;
|
436 | UART_TxTail = 0;
|
437 | UART_RxHead = 0;
|
438 | UART_RxTail = 0;
|
439 |
|
440 | #ifdef UART_TEST
|
441 | #ifndef UART0_BIT_U2X
|
442 | #warning "UART0_BIT_U2X not defined"
|
443 | #endif
|
444 | #ifndef UART0_UBRRH
|
445 | #warning "UART0_UBRRH not defined"
|
446 | #endif
|
447 | #ifndef UART0_CONTROLC
|
448 | #warning "UART0_CONTROLC not defined"
|
449 | #endif
|
450 | #if defined(URSEL) || defined(URSEL0)
|
451 | #ifndef UART0_BIT_URSEL
|
452 | #warning "UART0_BIT_URSEL not defined"
|
453 | #endif
|
454 | #endif
|
455 | #endif
|
456 |
|
457 | /* Set baud rate */
|
458 | if ( baudrate & 0x8000 )
|
459 | {
|
460 | #if UART0_BIT_U2X
|
461 | UART0_STATUS = (1<<UART0_BIT_U2X); //Enable 2x speed
|
462 | #endif
|
463 | }
|
464 | #if defined(UART0_UBRRH)
|
465 | UART0_UBRRH = (unsigned char)((baudrate>>8)&0x80) ;
|
466 | #endif
|
467 | UART0_UBRRL = (unsigned char) (baudrate&0x00FF);
|
468 |
|
469 | /* Enable USART receiver and transmitter and receive complete interrupt */
|
470 | UART0_CONTROL = _BV(UART0_BIT_RXCIE)|(1<<UART0_BIT_RXEN)|(1<<UART0_BIT_TXEN);
|
471 |
|
472 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
473 | #ifdef UART0_CONTROLC
|
474 | #ifdef UART0_BIT_URSEL
|
475 | UART0_CONTROLC = (1<<UART0_BIT_URSEL)|(1<<UART0_BIT_UCSZ1)|(1<<UART0_BIT_UCSZ0);
|
476 | #else
|
477 | UART0_CONTROLC = (1<<UART0_BIT_UCSZ1)|(1<<UART0_BIT_UCSZ0);
|
478 | #endif
|
479 | #endif
|
480 |
|
481 | }/* uart_init */
|
482 |
|
483 |
|
484 | /*************************************************************************
|
485 | Function: uart_getc()
|
486 | Purpose: return byte from ringbuffer
|
487 | Returns: lower byte: received byte from ringbuffer
|
488 | higher byte: last receive error
|
489 | **************************************************************************/
|
490 | unsigned int uart_getc(void)
|
491 | {
|
492 | unsigned char tmptail;
|
493 | unsigned char data;
|
494 | unsigned char lastRxError;
|
495 |
|
496 |
|
497 | if ( UART_RxHead == UART_RxTail ) {
|
498 | return UART_NO_DATA; /* no data available */
|
499 | }
|
500 |
|
501 | /* calculate buffer index */
|
502 | tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
|
503 |
|
504 | /* get data from receive buffer */
|
505 | data = UART_RxBuf[tmptail];
|
506 | lastRxError = UART_LastRxError;
|
507 |
|
508 | /* store buffer index */
|
509 | UART_RxTail = tmptail;
|
510 |
|
511 | UART_LastRxError = 0;
|
512 | return (lastRxError << 8) + data;
|
513 |
|
514 | }/* uart_getc */
|
515 |
|
516 |
|
517 | /*************************************************************************
|
518 | Function: uart_putc()
|
519 | Purpose: write byte to ringbuffer for transmitting via UART
|
520 | Input: byte to be transmitted
|
521 | Returns: none
|
522 | **************************************************************************/
|
523 | void uart_putc(unsigned char data)
|
524 | {
|
525 | unsigned char tmphead;
|
526 |
|
527 |
|
528 | tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
|
529 |
|
530 | while ( tmphead == UART_TxTail ){
|
531 | ;/* wait for free space in buffer */
|
532 | }
|
533 |
|
534 | UART_TxBuf[tmphead] = data;
|
535 | UART_TxHead = tmphead;
|
536 |
|
537 | /* enable UDRE interrupt */
|
538 | UART0_CONTROL |= _BV(UART0_UDRIE);
|
539 |
|
540 | }/* uart_putc */
|
541 |
|
542 |
|
543 | /*************************************************************************
|
544 | Function: uart_puts()
|
545 | Purpose: transmit string to UART
|
546 | Input: string to be transmitted
|
547 | Returns: none
|
548 | **************************************************************************/
|
549 | void uart_puts(const char *s )
|
550 | {
|
551 | while (*s)
|
552 | uart_putc(*s++);
|
553 |
|
554 | }/* uart_puts */
|
555 |
|
556 |
|
557 | /*************************************************************************
|
558 | Function: uart_puts_p()
|
559 | Purpose: transmit string from program memory to UART
|
560 | Input: program memory string to be transmitted
|
561 | Returns: none
|
562 | **************************************************************************/
|
563 | void uart_puts_p(const char *progmem_s )
|
564 | {
|
565 | register char c;
|
566 |
|
567 | while ( (c = pgm_read_byte(progmem_s++)) )
|
568 | uart_putc(c);
|
569 |
|
570 | }/* uart_puts_p */
|
571 |
|
572 |
|
573 | /*
|
574 | * these functions are only for ATmegas with two USART
|
575 | */
|
576 | #if defined( ATMEGA_USART1 )
|
577 |
|
578 | ISR(UART1_RECEIVE_INTERRUPT)
|
579 | /*************************************************************************
|
580 | Function: UART1 Receive Complete interrupt
|
581 | Purpose: called when the UART1 has received a character
|
582 | **************************************************************************/
|
583 | {
|
584 | unsigned char tmphead;
|
585 | unsigned char data;
|
586 | unsigned char usr;
|
587 | unsigned char lastRxError;
|
588 |
|
589 |
|
590 | /* read UART status register and UART data register */
|
591 | usr = UART1_STATUS;
|
592 | data = UART1_DATA;
|
593 |
|
594 | /* get FEn (Frame Error) DORn (Data OverRun) UPEn (USART Parity Error) bits */
|
595 | lastRxError = usr & (_BV(FE1)|_BV(DOR1)|_BV(UPE1) );
|
596 |
|
597 | /* calculate buffer index */
|
598 | tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
|
599 |
|
600 | if ( tmphead == UART1_RxTail ) {
|
601 | /* error: receive buffer overflow */
|
602 | lastRxError = UART_BUFFER_OVERFLOW >> 8;
|
603 | }else{
|
604 | /* store new index */
|
605 | UART1_RxHead = tmphead;
|
606 | /* store received data in buffer */
|
607 | UART1_RxBuf[tmphead] = data;
|
608 | }
|
609 | UART1_LastRxError |= lastRxError;
|
610 | }
|
611 |
|
612 |
|
613 | ISR(UART1_TRANSMIT_INTERRUPT)
|
614 | /*************************************************************************
|
615 | Function: UART1 Data Register Empty interrupt
|
616 | Purpose: called when the UART1 is ready to transmit the next byte
|
617 | **************************************************************************/
|
618 | {
|
619 | unsigned char tmptail;
|
620 |
|
621 |
|
622 | if ( UART1_TxHead != UART1_TxTail) {
|
623 | /* calculate and store new buffer index */
|
624 | tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
|
625 | UART1_TxTail = tmptail;
|
626 | /* get one byte from buffer and write it to UART */
|
627 | UART1_DATA = UART1_TxBuf[tmptail]; /* start transmission */
|
628 | }else{
|
629 | /* tx buffer empty, disable UDRE interrupt */
|
630 | UART1_CONTROL &= ~_BV(UART1_UDRIE);
|
631 | }
|
632 | }
|
633 |
|
634 |
|
635 | /*************************************************************************
|
636 | Function: uart1_init()
|
637 | Purpose: initialize UART1 and set baudrate
|
638 | Input: baudrate using macro UART_BAUD_SELECT()
|
639 | Returns: none
|
640 | **************************************************************************/
|
641 | void uart1_init(unsigned int baudrate)
|
642 | {
|
643 | UART1_TxHead = 0;
|
644 | UART1_TxTail = 0;
|
645 | UART1_RxHead = 0;
|
646 | UART1_RxTail = 0;
|
647 |
|
648 | #ifdef UART_TEST
|
649 | #ifndef UART1_BIT_U2X
|
650 | #warning "UART1_BIT_U2X not defined"
|
651 | #endif
|
652 | #ifndef UART1_UBRRH
|
653 | #warning "UART1_UBRRH not defined"
|
654 | #endif
|
655 | #ifndef UART1_CONTROLC
|
656 | #warning "UART1_CONTROLC not defined"
|
657 | #endif
|
658 | #if defined(URSEL) || defined(URSEL1)
|
659 | #ifndef UART1_BIT_URSEL
|
660 | #warning "UART1_BIT_URSEL not defined"
|
661 | #endif
|
662 | #endif
|
663 | #endif
|
664 |
|
665 | /* Set baud rate */
|
666 | if ( baudrate & 0x8000 )
|
667 | {
|
668 | #if UART1_BIT_U2X
|
669 | UART1_STATUS = (1<<UART1_BIT_U2X); //Enable 2x speed
|
670 | #endif
|
671 | }
|
672 | UART1_UBRRH = (unsigned char)((baudrate>>8)&0x80) ;
|
673 | UART1_UBRRL = (unsigned char) baudrate;
|
674 |
|
675 | /* Enable USART receiver and transmitter and receive complete interrupt */
|
676 | UART1_CONTROL = _BV(UART1_BIT_RXCIE)|(1<<UART1_BIT_RXEN)|(1<<UART1_BIT_TXEN);
|
677 |
|
678 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
679 | #ifdef UART1_BIT_URSEL
|
680 | UART1_CONTROLC = (1<<UART1_BIT_URSEL)|(1<<UART1_BIT_UCSZ1)|(1<<UART1_BIT_UCSZ0);
|
681 | #else
|
682 | UART1_CONTROLC = (1<<UART1_BIT_UCSZ1)|(1<<UART1_BIT_UCSZ0);
|
683 | #endif
|
684 |
|
685 | }/* uart_init */
|
686 |
|
687 |
|
688 | /*************************************************************************
|
689 | Function: uart1_getc()
|
690 | Purpose: return byte from ringbuffer
|
691 | Returns: lower byte: received byte from ringbuffer
|
692 | higher byte: last receive error
|
693 | **************************************************************************/
|
694 | unsigned int uart1_getc(void)
|
695 | {
|
696 | unsigned char tmptail;
|
697 | unsigned int data;
|
698 | unsigned char lastRxError;
|
699 |
|
700 |
|
701 | if ( UART1_RxHead == UART1_RxTail ) {
|
702 | return UART_NO_DATA; /* no data available */
|
703 | }
|
704 |
|
705 | /* calculate buffer index */
|
706 | tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
|
707 |
|
708 | /* get data from receive buffer */
|
709 | data = UART1_RxBuf[tmptail];
|
710 | lastRxError = UART1_LastRxError;
|
711 |
|
712 | /* store buffer index */
|
713 | UART1_RxTail = tmptail;
|
714 |
|
715 | UART1_LastRxError = 0;
|
716 | return (lastRxError << 8) + data;
|
717 |
|
718 | }/* uart1_getc */
|
719 |
|
720 |
|
721 | /*************************************************************************
|
722 | Function: uart1_putc()
|
723 | Purpose: write byte to ringbuffer for transmitting via UART
|
724 | Input: byte to be transmitted
|
725 | Returns: none
|
726 | **************************************************************************/
|
727 | void uart1_putc(unsigned char data)
|
728 | {
|
729 | unsigned char tmphead;
|
730 |
|
731 |
|
732 | tmphead = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
|
733 |
|
734 | while ( tmphead == UART1_TxTail ){
|
735 | ;/* wait for free space in buffer */
|
736 | }
|
737 |
|
738 | UART1_TxBuf[tmphead] = data;
|
739 | UART1_TxHead = tmphead;
|
740 |
|
741 | /* enable UDRE interrupt */
|
742 | UART1_CONTROL |= _BV(UART1_UDRIE);
|
743 |
|
744 | }/* uart1_putc */
|
745 |
|
746 |
|
747 | /*************************************************************************
|
748 | Function: uart1_puts()
|
749 | Purpose: transmit string to UART1
|
750 | Input: string to be transmitted
|
751 | Returns: none
|
752 | **************************************************************************/
|
753 | void uart1_puts(const char *s )
|
754 | {
|
755 | while (*s)
|
756 | uart1_putc(*s++);
|
757 |
|
758 | }/* uart1_puts */
|
759 |
|
760 |
|
761 | /*************************************************************************
|
762 | Function: uart1_puts_p()
|
763 | Purpose: transmit string from program memory to UART1
|
764 | Input: program memory string to be transmitted
|
765 | Returns: none
|
766 | **************************************************************************/
|
767 | void uart1_puts_p(const char *progmem_s )
|
768 | {
|
769 | register char c;
|
770 |
|
771 | while ( (c = pgm_read_byte(progmem_s++)) )
|
772 | uart1_putc(c);
|
773 |
|
774 | }/* uart1_puts_p */
|
775 |
|
776 |
|
777 | #endif
|