MSP device support complete. NOT TESTED YET! Preliminary python host lib
[cerebrum.git] / avr / uart.c
blobc1fc8ab6e8aebbc961e91fecd103fc93892defb1
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
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.
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.
18 USAGE:
19 Refere to the header file uart.h for a description of the routines.
20 See also example test_uart.c.
22 NOTES:
23 Based on Atmel Application Note AVR306
25 LICENSE:
26 Copyright (C) 2006 Peter Fleury
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.
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.
38 *************************************************************************/
39 #include <avr/io.h>
40 #include <avr/interrupt.h>
41 #include <avr/pgmspace.h>
42 #include "uart.h"
46 * constants and macros
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)
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
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 USART_RX_vect
149 #define UART0_TRANSMIT_INTERRUPT USART_UDRE_vect
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
221 * module global variables
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;
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
243 ISR(UART0_RECEIVE_INTERRUPT)
244 /*************************************************************************
245 Function: UART Receive Complete interrupt
246 Purpose: called when the UART has received a character
247 **************************************************************************/
249 unsigned char tmphead;
250 unsigned char data;
251 unsigned char usr;
252 unsigned char lastRxError;
255 /* read UART status register and UART data register */
256 usr = UART0_STATUS;
257 data = UART0_DATA;
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
270 /* calculate buffer index */
271 tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
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;
282 UART_LastRxError = lastRxError;
286 ISR(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 **************************************************************************/
292 unsigned char tmptail;
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);
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)
316 UART_TxHead = 0;
317 UART_TxTail = 0;
318 UART_RxHead = 0;
319 UART_RxTail = 0;
321 #if defined( AT90_UART )
322 /* set baud rate */
323 UBRR = (unsigned char)baudrate;
325 /* enable UART receiver and transmmitter and receive complete interrupt */
326 UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
328 #elif defined (ATMEGA_USART)
329 /* Set baud rate */
330 if ( baudrate & 0x8000 )
332 UART0_STATUS = (1<<U2X); //Enable 2x speed
333 baudrate &= ~0x8000;
335 UBRRH = (unsigned char)(baudrate>>8);
336 UBRRL = (unsigned char) baudrate;
338 /* Enable USART receiver and transmitter and receive complete interrupt */
339 UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
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
348 #elif defined (ATMEGA_USART0 )
349 /* Set baud rate */
350 if ( baudrate & 0x8000 )
352 UART0_STATUS = (1<<U2X0); //Enable 2x speed
353 baudrate &= ~0x8000;
355 UBRR0H = (unsigned char)(baudrate>>8);
356 UBRR0L = (unsigned char) baudrate;
358 /* Enable USART receiver and transmitter and receive complete interrupt */
359 UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
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
368 #elif defined ( ATMEGA_UART )
369 /* set baud rate */
370 if ( baudrate & 0x8000 )
372 UART0_STATUS = (1<<U2X); //Enable 2x speed
373 baudrate &= ~0x8000;
375 UBRRHI = (unsigned char)(baudrate>>8);
376 UBRR = (unsigned char) baudrate;
378 /* Enable UART receiver and transmitter and receive complete interrupt */
379 UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
381 #endif
383 }/* uart_init */
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)
394 unsigned char tmptail;
395 unsigned char data;
398 if ( UART_RxHead == UART_RxTail ) {
399 return UART_NO_DATA; /* no data available */
402 /* calculate /store buffer index */
403 tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
404 UART_RxTail = tmptail;
406 /* get data from receive buffer */
407 data = UART_RxBuf[tmptail];
409 return (UART_LastRxError << 8) + data;
411 }/* uart_getc */
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)
422 unsigned char tmphead;
425 tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
427 while ( tmphead == UART_TxTail ){
428 ;/* wait for free space in buffer */
431 UART_TxBuf[tmphead] = data;
432 UART_TxHead = tmphead;
434 /* enable UDRE interrupt */
435 UART0_CONTROL |= _BV(UART0_UDRIE);
437 }/* uart_putc */
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 )
448 while (*s)
449 uart_putc(*s++);
451 }/* uart_puts */
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 )
462 register char c;
464 while ( (c = pgm_read_byte(progmem_s++)) )
465 uart_putc(c);
467 }/* uart_puts_p */
471 * these functions are only for ATmegas with two USART
473 #if defined( ATMEGA_USART1 )
475 ISR(UART1_RECEIVE_INTERRUPT)
476 /*************************************************************************
477 Function: UART1 Receive Complete interrupt
478 Purpose: called when the UART1 has received a character
479 **************************************************************************/
481 unsigned char tmphead;
482 unsigned char data;
483 unsigned char usr;
484 unsigned char lastRxError;
487 /* read UART status register and UART data register */
488 usr = UART1_STATUS;
489 data = UART1_DATA;
491 /* */
492 lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
494 /* calculate buffer index */
495 tmphead = ( UART1_RxHead + 1) & UART_RX_BUFFER_MASK;
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;
506 UART1_LastRxError = lastRxError;
510 ISR(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 **************************************************************************/
516 unsigned char tmptail;
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);
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)
540 UART1_TxHead = 0;
541 UART1_TxTail = 0;
542 UART1_RxHead = 0;
543 UART1_RxTail = 0;
546 /* Set baud rate */
547 if ( baudrate & 0x8000 )
549 UART1_STATUS = (1<<U2X1); //Enable 2x speed
550 baudrate &= ~0x8000;
552 UBRR1H = (unsigned char)(baudrate>>8);
553 UBRR1L = (unsigned char) baudrate;
555 /* Enable USART receiver and transmitter and receive complete interrupt */
556 UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1);
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 */
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)
575 unsigned char tmptail;
576 unsigned char data;
579 if ( UART1_RxHead == UART1_RxTail ) {
580 return UART_NO_DATA; /* no data available */
583 /* calculate /store buffer index */
584 tmptail = (UART1_RxTail + 1) & UART_RX_BUFFER_MASK;
585 UART1_RxTail = tmptail;
587 /* get data from receive buffer */
588 data = UART1_RxBuf[tmptail];
590 return (UART1_LastRxError << 8) + data;
592 }/* uart1_getc */
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)
603 unsigned char tmphead;
606 tmphead = (UART1_TxHead + 1) & UART_TX_BUFFER_MASK;
608 while ( tmphead == UART1_TxTail ){
609 ;/* wait for free space in buffer */
612 UART1_TxBuf[tmphead] = data;
613 UART1_TxHead = tmphead;
615 /* enable UDRE interrupt */
616 UART1_CONTROL |= _BV(UART1_UDRIE);
618 }/* uart1_putc */
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 )
629 while (*s)
630 uart1_putc(*s++);
632 }/* uart1_puts */
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 )
643 register char c;
645 while ( (c = pgm_read_byte(progmem_s++)) )
646 uart1_putc(c);
648 }/* uart1_puts_p */
651 #endif