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