1 | /*************************************************************************
|
2 | Title: Interrupt UART library with receive/transmit circular buffers
|
3 | Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
|
4 | File: $Id: uart.c,v 1.6.2.2 2009/11/29 08:56:12 Peter Exp $
|
5 | Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
|
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) 2006 Peter Fleury
|
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 "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 | #if defined(__AVR_AT90S2313__) \
|
61 | || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
|
62 | || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
|
63 | || defined(__AVR_ATmega103__)
|
64 | /* old AVR classic or ATmega103 with one UART */
|
65 | #define AT90_UART
|
66 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
67 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
68 | #define UART0_STATUS USR
|
69 | #define UART0_CONTROL UCR
|
70 | #define UART0_DATA UDR
|
71 | #define UART0_UDRIE UDRIE
|
72 | #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
|
73 | /* old AVR classic with one UART */
|
74 | #define AT90_UART
|
75 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
76 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
77 | #define UART0_STATUS UCSRA
|
78 | #define UART0_CONTROL UCSRB
|
79 | #define UART0_DATA UDR
|
80 | #define UART0_UDRIE UDRIE
|
81 | #elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
|
82 | || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
|
83 | || defined(__AVR_ATmega323__)
|
84 | /* ATmega with one USART */
|
85 | #define ATMEGA_USART
|
86 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
87 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
88 | #define UART0_STATUS UCSRA
|
89 | #define UART0_CONTROL UCSRB
|
90 | #define UART0_DATA UDR
|
91 | #define UART0_UDRIE UDRIE
|
92 | #elif defined(__AVR_ATmega163__)
|
93 | /* ATmega163 with one UART */
|
94 | #define ATMEGA_UART
|
95 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
96 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
97 | #define UART0_STATUS UCSRA
|
98 | #define UART0_CONTROL UCSRB
|
99 | #define UART0_DATA UDR
|
100 | #define UART0_UDRIE UDRIE
|
101 | #elif defined(__AVR_ATmega162__)
|
102 | /* ATmega with two USART */
|
103 | #define ATMEGA_USART0
|
104 | #define ATMEGA_USART1
|
105 | #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV
|
106 | #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
|
107 | #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA
|
108 | #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
|
109 | #define UART0_STATUS UCSR0A
|
110 | #define UART0_CONTROL UCSR0B
|
111 | #define UART0_DATA UDR0
|
112 | #define UART0_UDRIE UDRIE0
|
113 | #define UART1_STATUS UCSR1A
|
114 | #define UART1_CONTROL UCSR1B
|
115 | #define UART1_DATA UDR1
|
116 | #define UART1_UDRIE UDRIE1
|
117 | #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
|
118 | /* ATmega with two USART */
|
119 | #define ATMEGA_USART0
|
120 | #define ATMEGA_USART1
|
121 | #define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV
|
122 | #define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV
|
123 | #define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA
|
124 | #define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA
|
125 | #define UART0_STATUS UCSR0A
|
126 | #define UART0_CONTROL UCSR0B
|
127 | #define UART0_DATA UDR0
|
128 | #define UART0_UDRIE UDRIE0
|
129 | #define UART1_STATUS UCSR1A
|
130 | #define UART1_CONTROL UCSR1B
|
131 | #define UART1_DATA UDR1
|
132 | #define UART1_UDRIE UDRIE1
|
133 | #elif defined(__AVR_ATmega161__)
|
134 | /* ATmega with UART */
|
135 | #error "AVR ATmega161 currently not supported by this libaray !"
|
136 | #elif defined(__AVR_ATmega169__)
|
137 | /* ATmega with one USART */
|
138 | #define ATMEGA_USART
|
139 | #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
|
140 | #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
|
141 | #define UART0_STATUS UCSRA
|
142 | #define UART0_CONTROL UCSRB
|
143 | #define UART0_DATA UDR
|
144 | #define UART0_UDRIE UDRIE
|
145 | #elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
|
146 | /* ATmega with one USART */
|
147 | #define ATMEGA_USART0
|
148 | #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
|
149 | #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
|
150 | #define UART0_STATUS UCSR0A
|
151 | #define UART0_CONTROL UCSR0B
|
152 | #define UART0_DATA UDR0
|
153 | #define UART0_UDRIE UDRIE0
|
154 | #elif defined(__AVR_ATtiny2313__)
|
155 | #define ATMEGA_USART
|
156 | #define UART0_RECEIVE_INTERRUPT SIG_USART0_RX
|
157 | #define UART0_TRANSMIT_INTERRUPT SIG_USART0_UDRE
|
158 | #define UART0_STATUS UCSRA
|
159 | #define UART0_CONTROL UCSRB
|
160 | #define UART0_DATA UDR
|
161 | #define UART0_UDRIE UDRIE
|
162 | #elif defined(__AVR_ATmega329__) ||defined(__AVR_ATmega3290__) ||\
|
163 | defined(__AVR_ATmega649__) ||defined(__AVR_ATmega6490__) ||\
|
164 | defined(__AVR_ATmega325__) ||defined(__AVR_ATmega3250__) ||\
|
165 | defined(__AVR_ATmega645__) ||defined(__AVR_ATmega6450__)
|
166 | /* ATmega with one USART */
|
167 | #define ATMEGA_USART0
|
168 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV
|
169 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA
|
170 | #define UART0_STATUS UCSR0A
|
171 | #define UART0_CONTROL UCSR0B
|
172 | #define UART0_DATA UDR0
|
173 | #define UART0_UDRIE UDRIE0
|
174 | #elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega640__)
|
175 | /* ATmega with two USART */
|
176 | #define ATMEGA_USART0
|
177 | #define ATMEGA_USART1
|
178 | #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV
|
179 | #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
|
180 | #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA
|
181 | #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
|
182 | #define UART0_STATUS UCSR0A
|
183 | #define UART0_CONTROL UCSR0B
|
184 | #define UART0_DATA UDR0
|
185 | #define UART0_UDRIE UDRIE0
|
186 | #define UART1_STATUS UCSR1A
|
187 | #define UART1_CONTROL UCSR1B
|
188 | #define UART1_DATA UDR1
|
189 | #define UART1_UDRIE UDRIE1
|
190 | #elif defined(__AVR_ATmega644__)
|
191 | /* ATmega with one USART */
|
192 | #define ATMEGA_USART0
|
193 | #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
|
194 | #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
|
195 | #define UART0_STATUS UCSR0A
|
196 | #define UART0_CONTROL UCSR0B
|
197 | #define UART0_DATA UDR0
|
198 | #define UART0_UDRIE UDRIE0
|
199 | #elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
|
200 | /* ATmega with two USART */
|
201 | #define ATMEGA_USART0
|
202 | #define ATMEGA_USART1
|
203 | #define UART0_RECEIVE_INTERRUPT SIG_USART_RECV
|
204 | #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV
|
205 | #define UART0_TRANSMIT_INTERRUPT SIG_USART_DATA
|
206 | #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA
|
207 | #define UART0_STATUS UCSR0A
|
208 | #define UART0_CONTROL UCSR0B
|
209 | #define UART0_DATA UDR0
|
210 | #define UART0_UDRIE UDRIE0
|
211 | #define UART1_STATUS UCSR1A
|
212 | #define UART1_CONTROL UCSR1B
|
213 | #define UART1_DATA UDR1
|
214 | #define UART1_UDRIE UDRIE1
|
215 | #else
|
216 | #error "no UART definition for MCU available"
|
217 | #endif
|
218 |
|
219 |
|
220 | /*
|
221 | * module global variables
|
222 | */
|
223 | static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
|
224 | static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
|
225 | static volatile unsigned char UART_TxHead;
|
226 | static volatile unsigned char UART_TxTail;
|
227 | static volatile unsigned char UART_RxHead;
|
228 | static volatile unsigned char UART_RxTail;
|
229 | static volatile unsigned char UART_LastRxError;
|
230 |
|
231 | #if defined( ATMEGA_USART1 )
|
232 | static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
|
233 | static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
|
234 | static volatile unsigned char UART1_TxHead;
|
235 | static volatile unsigned char UART1_TxTail;
|
236 | static volatile unsigned char UART1_RxHead;
|
237 | static volatile unsigned char UART1_RxTail;
|
238 | static volatile unsigned char UART1_LastRxError;
|
239 | #endif
|
240 |
|
241 |
|
242 |
|
243 | SIGNAL(UART0_RECEIVE_INTERRUPT)
|
244 | /*************************************************************************
|
245 | Function: UART Receive Complete interrupt
|
246 | Purpose: called when the UART has received a character
|
247 | **************************************************************************/
|
248 | {
|
249 | unsigned char tmphead;
|
250 | unsigned char data;
|
251 | unsigned char usr;
|
252 | unsigned char lastRxError;
|
253 |
|
254 |
|
255 | /* read UART status register and UART data register */
|
256 | usr = UART0_STATUS;
|
257 | data = UART0_DATA;
|
258 |
|
259 | /* */
|
260 | #if defined( AT90_UART )
|
261 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
|
262 | #elif defined( ATMEGA_USART )
|
263 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
|
264 | #elif defined( ATMEGA_USART0 )
|
265 | lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
|
266 | #elif defined ( ATMEGA_UART )
|
267 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
|
268 | #endif
|
269 |
|
270 | /* calculate buffer index */
|
271 | tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
|
272 |
|
273 | if ( tmphead == UART_RxTail ) {
|
274 | /* error: receive buffer overflow */
|
275 | lastRxError = UART_BUFFER_OVERFLOW >> 8;
|
276 | }else{
|
277 | /* store new index */
|
278 | UART_RxHead = tmphead;
|
279 | /* store received data in buffer */
|
280 | UART_RxBuf[tmphead] = data;
|
281 | }
|
282 | UART_LastRxError = lastRxError;
|
283 | }
|
284 |
|
285 |
|
286 | SIGNAL(UART0_TRANSMIT_INTERRUPT)
|
287 | /*************************************************************************
|
288 | Function: UART Data Register Empty interrupt
|
289 | Purpose: called when the UART is ready to transmit the next byte
|
290 | **************************************************************************/
|
291 | {
|
292 | unsigned char tmptail;
|
293 |
|
294 |
|
295 | if ( UART_TxHead != UART_TxTail) {
|
296 | /* calculate and store new buffer index */
|
297 | tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
|
298 | UART_TxTail = tmptail;
|
299 | /* get one byte from buffer and write it to UART */
|
300 | UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */
|
301 | }else{
|
302 | /* tx buffer empty, disable UDRE interrupt */
|
303 | UART0_CONTROL &= ~_BV(UART0_UDRIE);
|
304 | }
|
305 | }
|
306 |
|
307 |
|
308 | /*************************************************************************
|
309 | Function: uart_init()
|
310 | Purpose: initialize UART and set baudrate
|
311 | Input: baudrate using macro UART_BAUD_SELECT()
|
312 | Returns: none
|
313 | **************************************************************************/
|
314 | void uart_init(unsigned int baudrate)
|
315 | {
|
316 | UART_TxHead = 0;
|
317 | UART_TxTail = 0;
|
318 | UART_RxHead = 0;
|
319 | UART_RxTail = 0;
|
320 |
|
321 | #if defined( AT90_UART )
|
322 | /* set baud rate */
|
323 | UBRR = (unsigned char)baudrate;
|
324 |
|
325 | /* enable UART receiver and transmmitter and receive complete interrupt */
|
326 | UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
|
327 |
|
328 | #elif defined (ATMEGA_USART)
|
329 | /* Set baud rate */
|
330 | if ( baudrate & 0x8000 )
|
331 | {
|
332 | UART0_STATUS = (1<<U2X); //Enable 2x speed
|
333 | baudrate &= ~0x8000;
|
334 | }
|
335 | UBRRH = (unsigned char)(baudrate>>8);
|
336 | UBRRL = (unsigned char) baudrate;
|
337 |
|
338 | /* Enable USART receiver and transmitter and receive complete interrupt */
|
339 | UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
|
340 |
|
341 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
342 | #ifdef URSEL
|
343 | UCSRC = (1<<URSEL)|(3<<UCSZ0);
|
344 | #else
|
345 | UCSRC = (3<<UCSZ0);
|
346 | #endif
|
347 |
|
348 | #elif defined (ATMEGA_USART0 )
|
349 | /* Set baud rate */
|
350 | if ( baudrate & 0x8000 )
|
351 | {
|
352 | UART0_STATUS = (1<<U2X0); //Enable 2x speed
|
353 | baudrate &= ~0x8000;
|
354 | }
|
355 | UBRR0H = (unsigned char)(baudrate>>8);
|
356 | UBRR0L = (unsigned char) baudrate;
|
357 |
|
358 | /* Enable USART receiver and transmitter and receive complete interrupt */
|
359 | UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
|
360 |
|
361 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
362 | #ifdef URSEL0
|
363 | UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
|
364 | #else
|
365 | UCSR0C = (3<<UCSZ00);
|
366 | #endif
|
367 |
|
368 | #elif defined ( ATMEGA_UART )
|
369 | /* set baud rate */
|
370 | if ( baudrate & 0x8000 )
|
371 | {
|
372 | UART0_STATUS = (1<<U2X); //Enable 2x speed
|
373 | baudrate &= ~0x8000;
|
374 | }
|
375 | UBRRHI = (unsigned char)(baudrate>>8);
|
376 | UBRR = (unsigned char) baudrate;
|
377 |
|
378 | /* Enable UART receiver and transmitter and receive complete interrupt */
|
379 | UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
|
380 |
|
381 | #endif
|
382 |
|
383 | }/* uart_init */
|
384 |
|
385 |
|
386 | /*************************************************************************
|
387 | Function: uart_getc()
|
388 | Purpose: return byte from ringbuffer
|
389 | Returns: lower byte: received byte from ringbuffer
|
390 | higher byte: last receive error
|
391 | **************************************************************************/
|
392 | unsigned int uart_getc(void)
|
393 | {
|
394 | unsigned char tmptail;
|
395 | unsigned char data;
|
396 |
|
397 |
|
398 | if ( UART_RxHead == UART_RxTail ) {
|
399 | return UART_NO_DATA; /* no data available */
|
400 | }
|
401 |
|
402 | /* calculate /store buffer index */
|
403 | tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
|
404 | UART_RxTail = tmptail;
|
405 |
|
406 | /* get data from receive buffer */
|
407 | data = UART_RxBuf[tmptail];
|
408 |
|
409 | return (UART_LastRxError << 8) + data;
|
410 |
|
411 | }/* uart_getc */
|
412 |
|
413 |
|
414 | /*************************************************************************
|
415 | Function: uart_putc()
|
416 | Purpose: write byte to ringbuffer for transmitting via UART
|
417 | Input: byte to be transmitted
|
418 | Returns: none
|
419 | **************************************************************************/
|
420 | void uart_putc(unsigned char data)
|
421 | {
|
422 | unsigned char tmphead;
|
423 |
|
424 |
|
425 | tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
|
426 |
|
427 | while ( tmphead == UART_TxTail ){
|
428 | ;/* wait for free space in buffer */
|
429 | }
|
430 |
|
431 | UART_TxBuf[tmphead] = data;
|
432 | UART_TxHead = tmphead;
|
433 |
|
434 | /* enable UDRE interrupt */
|
435 | UART0_CONTROL |= _BV(UART0_UDRIE);
|
436 |
|
437 | }/* uart_putc */
|
438 |
|
439 |
|
440 | /*************************************************************************
|
441 | Function: uart_puts()
|
442 | Purpose: transmit string to UART
|
443 | Input: string to be transmitted
|
444 | Returns: none
|
445 | **************************************************************************/
|
446 | void uart_puts(const char *s )
|
447 | {
|
448 | while (*s)
|
449 | uart_putc(*s++);
|
450 |
|
451 | }/* uart_puts */
|
452 |
|
453 |
|
454 | /*************************************************************************
|
455 | Function: uart_puts_p()
|
456 | Purpose: transmit string from program memory to UART
|
457 | Input: program memory string to be transmitted
|
458 | Returns: none
|
459 | **************************************************************************/
|
460 | void uart_puts_p(const char *progmem_s )
|
461 | {
|
462 | register char c;
|
463 |
|
464 | while ( (c = pgm_read_byte(progmem_s++)) )
|
465 | uart_putc(c);
|
466 |
|
467 | }/* uart_puts_p */
|
468 |
|
469 |
|
470 | /*
|
471 | * these functions are only for ATmegas with two USART
|
472 | */
|
473 | #if defined( ATMEGA_USART1 )
|
474 |
|
475 | SIGNAL(UART1_RECEIVE_INTERRUPT)
|
476 | /*************************************************************************
|
477 | Function: UART1 Receive Complete interrupt
|
478 | Purpose: called when the UART1 has received a character
|
479 | **************************************************************************/
|
480 | {
|
481 | unsigned char tmphead;
|
482 | unsigned char data;
|
483 | unsigned char usr;
|
484 | unsigned char lastRxError;
|
485 |
|
486 |
|
487 | /* read UART status register and UART data register */
|
488 | usr = UART1_STATUS;
|
489 | data = UART1_DATA;
|
490 |
|
491 | /* */
|
492 | lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
|
493 |
|
494 | /* calculate buffer index */
|
495 | tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
|
496 |
|
497 | if ( tmphead == UART1_RxTail ) {
|
498 | /* error: receive buffer overflow */
|
499 | lastRxError = UART_BUFFER_OVERFLOW >> 8;
|
500 | }else{
|
501 | /* store new index */
|
502 | UART1_RxHead = tmphead;
|
503 | /* store received data in buffer */
|
504 | UART1_RxBuf[tmphead] = data;
|
505 | }
|
506 | UART1_LastRxError = lastRxError;
|
507 | }
|
508 |
|
509 |
|
510 | SIGNAL(UART1_TRANSMIT_INTERRUPT)
|
511 | /*************************************************************************
|
512 | Function: UART1 Data Register Empty interrupt
|
513 | Purpose: called when the UART1 is ready to transmit the next byte
|
514 | **************************************************************************/
|
515 | {
|
516 | unsigned char tmptail;
|
517 |
|
518 |
|
519 | if ( UART1_TxHead != UART1_TxTail) {
|
520 | /* calculate and store new buffer index */
|
521 | tmptail = (UART1_TxTail + 1) & UART_TX_BUFFER_MASK;
|
522 | UART1_TxTail = tmptail;
|
523 | /* get one byte from buffer and write it to UART */
|
524 | UART1_DATA = UART1_TxBuf[tmptail]; /* start transmission */
|
525 | }else{
|
526 | /* tx buffer empty, disable UDRE interrupt */
|
527 | UART1_CONTROL &= ~_BV(UART1_UDRIE);
|
528 | }
|
529 | }
|
530 |
|
531 |
|
532 | /*************************************************************************
|
533 | Function: uart1_init()
|
534 | Purpose: initialize UART1 and set baudrate
|
535 | Input: baudrate using macro UART_BAUD_SELECT()
|
536 | Returns: none
|
537 | **************************************************************************/
|
538 | void uart1_init(unsigned int baudrate)
|
539 | {
|
540 | UART1_TxHead = 0;
|
541 | UART1_TxTail = 0;
|
542 | UART1_RxHead = 0;
|
543 | UART1_RxTail = 0;
|
544 |
|
545 |
|
546 | /* Set baud rate */
|
547 | if ( baudrate & 0x8000 )
|
548 | {
|
549 | UART1_STATUS = (1<<U2X1); //Enable 2x speed
|
550 | baudrate &= ~0x8000;
|
551 | }
|
552 | UBRR1H = (unsigned char)(baudrate>>8);
|
553 | UBRR1L = (unsigned char) baudrate;
|
554 |
|
555 | /* Enable USART receiver and transmitter and receive complete interrupt */
|
556 | UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
|
557 |
|
558 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
|
559 | #ifdef URSEL1
|
560 | UCSR1C = (1<<URSEL1)|(3<<UCSZ10);
|
561 | #else
|
562 | UCSR1C = (3<<UCSZ10);
|
563 | #endif
|
564 | }/* uart_init */
|
565 |
|
566 |
|
567 | /*************************************************************************
|
568 | Function: uart1_getc()
|
569 | Purpose: return byte from ringbuffer
|
570 | Returns: lower byte: received byte from ringbuffer
|
571 | higher byte: last receive error
|
572 | **************************************************************************/
|
573 | unsigned int uart1_getc(void)
|
574 | {
|
575 | unsigned char tmptail;
|
576 | unsigned char data;
|
577 |
|
578 |
|
579 | if ( UART1_RxHead == UART1_RxTail ) {
|
580 | return UART_NO_DATA; /* no data available */
|
581 | }
|
582 |
|
583 | /* calculate /store buffer index */
|
584 | tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
|
585 | UART1_RxTail = tmptail;
|
586 |
|
587 | /* get data from receive buffer */
|
588 | data = UART1_RxBuf[tmptail];
|
589 |
|
590 | return (UART1_LastRxError << 8) + data;
|
591 |
|
592 | }/* uart1_getc */
|
593 |
|
594 |
|
595 | /*************************************************************************
|
596 | Function: uart1_putc()
|
597 | Purpose: write byte to ringbuffer for transmitting via UART
|
598 | Input: byte to be transmitted
|
599 | Returns: none
|
600 | **************************************************************************/
|
601 | void uart1_putc(unsigned char data)
|
602 | {
|
603 | unsigned char tmphead;
|
604 |
|
605 |
|
606 | tmphead = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
|
607 |
|
608 | while ( tmphead == UART1_TxTail ){
|
609 | ;/* wait for free space in buffer */
|
610 | }
|
611 |
|
612 | UART1_TxBuf[tmphead] = data;
|
613 | UART1_TxHead = tmphead;
|
614 |
|
615 | /* enable UDRE interrupt */
|
616 | UART1_CONTROL |= _BV(UART1_UDRIE);
|
617 |
|
618 | }/* uart1_putc */
|
619 |
|
620 |
|
621 | /*************************************************************************
|
622 | Function: uart1_puts()
|
623 | Purpose: transmit string to UART1
|
624 | Input: string to be transmitted
|
625 | Returns: none
|
626 | **************************************************************************/
|
627 | void uart1_puts(const char *s )
|
628 | {
|
629 | while (*s)
|
630 | uart1_putc(*s++);
|
631 |
|
632 | }/* uart1_puts */
|
633 |
|
634 |
|
635 | /*************************************************************************
|
636 | Function: uart1_puts_p()
|
637 | Purpose: transmit string from program memory to UART1
|
638 | Input: program memory string to be transmitted
|
639 | Returns: none
|
640 | **************************************************************************/
|
641 | void uart1_puts_p(const char *progmem_s )
|
642 | {
|
643 | register char c;
|
644 |
|
645 | while ( (c = pgm_read_byte(progmem_s++)) )
|
646 | uart1_putc(c);
|
647 |
|
648 | }/* uart1_puts_p */
|
649 |
|
650 |
|
651 | #endif
|