Rev 60 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 60 | Rev 69 | ||
|---|---|---|---|
| 1 | /************************************************************************* |
1 | /************************************************************************* |
| 2 | Title: Interrupt UART library with receive/transmit circular buffers |
2 | Title: Interrupt UART library with receive/transmit circular buffers |
| 3 | Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury |
3 | Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury |
| 4 | File: $Id: uart.c,v 1.5.2.2 2004/02/27 22:00:28 peter Exp $ |
4 | File: $Id: uart.c,v 1.5.2.2 2004/02/27 22:00:28 peter Exp $ |
| 5 | Software: AVR-GCC 3.3 |
5 | Software: AVR-GCC 3.3 |
| 6 | Hardware: any AVR with built-in UART, |
6 | Hardware: any AVR with built-in UART, |
| 7 | tested on AT90S8515 at 4 Mhz and ATmega at 1Mhz |
7 | tested on AT90S8515 at 4 Mhz and ATmega at 1Mhz |
| 8 | Extensions:- uart_puti by M. Thomas 9/2004 |
8 | Extensions:- uart_puti by M. Thomas 9/2004 |
| 9 | - uart_puthex_nibble and _byte by M.T. 9/2004 |
9 | - uart_puthex_nibble and _byte by M.T. 9/2004 |
| 10 | - uart_putbin_byte by M.T. 1/2005 |
10 | - uart_putbin_byte by M.T. 1/2005 |
| 11 | 11 | ||
| 12 | DESCRIPTION: |
12 | DESCRIPTION: |
| 13 | An interrupt is generated when the UART has finished transmitting or |
13 | An interrupt is generated when the UART has finished transmitting or |
| 14 | receiving a byte. The interrupt handling routines use circular buffers |
14 | receiving a byte. The interrupt handling routines use circular buffers |
| 15 | for buffering received and transmitted data. |
15 | for buffering received and transmitted data. |
| 16 | |
16 | |
| 17 | The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define |
17 | The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define |
| 18 | the buffer size in bytes. Note that these variables must be a |
18 | the buffer size in bytes. Note that these variables must be a |
| 19 | power of 2. |
19 | power of 2. |
| 20 | |
20 | |
| 21 | USAGE: |
21 | USAGE: |
| 22 | Refere to the header file uart.h for a description of the routines. |
22 | Refere to the header file uart.h for a description of the routines. |
| 23 | See also example test_uart.c. |
23 | See also example test_uart.c. |
| 24 | 24 | ||
| 25 | NOTES: |
25 | NOTES: |
| 26 | Based on Atmel Application Note AVR306 |
26 | Based on Atmel Application Note AVR306 |
| 27 | |
27 | |
| 28 | *************************************************************************/ |
28 | *************************************************************************/ |
| 29 | #include <stdlib.h> |
29 | #include <stdlib.h> |
| 30 | #include <stdio.h> |
30 | #include <stdio.h> |
| 31 | 31 | ||
| 32 | #include <avr/io.h> |
32 | #include <avr/io.h> |
| 33 | #include <avr/interrupt.h> |
33 | #include <avr/interrupt.h> |
| 34 | #include <avr/pgmspace.h> |
34 | #include <avr/pgmspace.h> |
| 35 | 35 | ||
| 36 | #include <uart.h> |
36 | #include <uart.h> |
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | static int uart_putchar(char c, FILE *stream); |
39 | static int uart_putchar(char c, FILE *stream); |
| 40 | 40 | ||
| 41 | static FILE myStdOut = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE); |
41 | static FILE myStdOut = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE); |
| 42 | 42 | ||
| 43 | static int uart_putchar(char c, FILE *stream) { |
43 | static int uart_putchar(char c, FILE *stream) { |
| 44 | if (c == '\n') uart_putchar('\r', stream); |
44 | if (c == '\n') uart_putchar('\r', stream); |
| 45 | uart_putc(c); |
45 | uart_putc(c); |
| 46 | return 0; |
46 | return 0; |
| 47 | } |
47 | } |
| 48 | 48 | ||
| 49 | 49 | ||
| 50 | /* |
50 | /* |
| 51 | * constants and macros |
51 | * constants and macros |
| 52 | */ |
52 | */ |
| 53 | 53 | ||
| 54 | /* size of RX/TX buffers */ |
54 | /* size of RX/TX buffers */ |
| 55 | #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1) |
55 | #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1) |
| 56 | #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1) |
56 | #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1) |
| 57 | 57 | ||
| 58 | #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) |
58 | #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK ) |
| 59 | #error RX buffer size is not a power of 2 |
59 | #error RX buffer size is not a power of 2 |
| 60 | #endif |
60 | #endif |
| 61 | #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK ) |
61 | #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK ) |
| 62 | #error TX buffer size is not a power of 2 |
62 | #error TX buffer size is not a power of 2 |
| 63 | #endif |
63 | #endif |
| 64 | 64 | ||
| 65 | #if defined(__AVR_AT90S2313__) \ |
65 | #if defined(__AVR_AT90S2313__) \ |
| 66 | || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \ |
66 | || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \ |
| 67 | || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) |
67 | || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) |
| 68 | /* old AVR classic with one UART */ |
68 | /* old AVR classic with one UART */ |
| 69 | #define AT90_UART |
69 | #define AT90_UART |
| 70 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
70 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
| 71 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
71 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
| 72 | #define UART0_STATUS USR |
72 | #define UART0_STATUS USR |
| 73 | #define UART0_CONTROL UCR |
73 | #define UART0_CONTROL UCR |
| 74 | #define UART0_DATA UDR |
74 | #define UART0_DATA UDR |
| 75 | #define UART0_UDRIE UDRIE |
75 | #define UART0_UDRIE UDRIE |
| 76 | #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) |
76 | #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) |
| 77 | /* old AVR classic with one UART */ |
77 | /* old AVR classic with one UART */ |
| 78 | #define AT90_UART |
78 | #define AT90_UART |
| 79 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
79 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
| 80 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
80 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
| 81 | #define UART0_STATUS UCSRA |
81 | #define UART0_STATUS UCSRA |
| 82 | #define UART0_CONTROL UCSRB |
82 | #define UART0_CONTROL UCSRB |
| 83 | #define UART0_DATA UDR |
83 | #define UART0_DATA UDR |
| 84 | #define UART0_UDRIE UDRIE |
84 | #define UART0_UDRIE UDRIE |
| 85 | #elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ |
85 | #elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ |
| 86 | || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \ |
86 | || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \ |
| 87 | || defined(__AVR_ATmega323__) |
87 | || defined(__AVR_ATmega323__) |
| 88 | /* ATMega with one USART */ |
88 | /* ATMega with one USART */ |
| 89 | #define ATMEGA_USART |
89 | #define ATMEGA_USART |
| 90 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
90 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
| 91 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
91 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
| 92 | #define UART0_STATUS UCSRA |
92 | #define UART0_STATUS UCSRA |
| 93 | #define UART0_CONTROL UCSRB |
93 | #define UART0_CONTROL UCSRB |
| 94 | #define UART0_DATA UDR |
94 | #define UART0_DATA UDR |
| 95 | #define UART0_UDRIE UDRIE |
95 | #define UART0_UDRIE UDRIE |
| 96 | #elif defined(__AVR_ATmega163__) |
96 | #elif defined(__AVR_ATmega163__) |
| 97 | /* ATMega163 with one UART */ |
97 | /* ATMega163 with one UART */ |
| 98 | #define ATMEGA_UART |
98 | #define ATMEGA_UART |
| 99 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
99 | #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV |
| 100 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
100 | #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA |
| 101 | #define UART0_STATUS UCSRA |
101 | #define UART0_STATUS UCSRA |
| 102 | #define UART0_CONTROL UCSRB |
102 | #define UART0_CONTROL UCSRB |
| 103 | #define UART0_DATA UDR |
103 | #define UART0_DATA UDR |
| 104 | #define UART0_UDRIE UDRIE |
104 | #define UART0_UDRIE UDRIE |
| 105 | #elif defined(__AVR_ATmega162__) |
105 | #elif defined(__AVR_ATmega162__) |
| 106 | /* ATMega with two USART */ |
106 | /* ATMega with two USART */ |
| 107 | #define ATMEGA_USART0 |
107 | #define ATMEGA_USART0 |
| 108 | #define ATMEGA_USART1 |
108 | #define ATMEGA_USART1 |
| 109 | #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV |
109 | #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV |
| 110 | #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV |
110 | #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV |
| 111 | #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA |
111 | #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA |
| 112 | #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA |
112 | #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA |
| 113 | #define UART0_STATUS UCSR0A |
113 | #define UART0_STATUS UCSR0A |
| 114 | #define UART0_CONTROL UCSR0B |
114 | #define UART0_CONTROL UCSR0B |
| 115 | #define UART0_DATA UDR0 |
115 | #define UART0_DATA UDR0 |
| 116 | #define UART0_UDRIE UDRIE0 |
116 | #define UART0_UDRIE UDRIE0 |
| 117 | #define UART1_STATUS UCSR1A |
117 | #define UART1_STATUS UCSR1A |
| 118 | #define UART1_CONTROL UCSR1B |
118 | #define UART1_CONTROL UCSR1B |
| 119 | #define UART1_DATA UDR1 |
119 | #define UART1_DATA UDR1 |
| 120 | #define UART1_UDRIE UDRIE1 |
120 | #define UART1_UDRIE UDRIE1 |
| 121 | #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) |
121 | #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) |
| 122 | /* ATMega with two USART */ |
122 | /* ATMega with two USART */ |
| 123 | #define ATMEGA_USART0 |
123 | #define ATMEGA_USART0 |
| 124 | #define ATMEGA_USART1 |
124 | #define ATMEGA_USART1 |
| 125 | #define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV |
125 | #define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV |
| 126 | #define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV |
126 | #define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV |
| 127 | #define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA |
127 | #define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA |
| 128 | #define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA |
128 | #define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA |
| 129 | #define UART0_STATUS UCSR0A |
129 | #define UART0_STATUS UCSR0A |
| 130 | #define UART0_CONTROL UCSR0B |
130 | #define UART0_CONTROL UCSR0B |
| 131 | #define UART0_DATA UDR0 |
131 | #define UART0_DATA UDR0 |
| 132 | #define UART0_UDRIE UDRIE0 |
132 | #define UART0_UDRIE UDRIE0 |
| 133 | #define UART1_STATUS UCSR1A |
133 | #define UART1_STATUS UCSR1A |
| 134 | #define UART1_CONTROL UCSR1B |
134 | #define UART1_CONTROL UCSR1B |
| 135 | #define UART1_DATA UDR1 |
135 | #define UART1_DATA UDR1 |
| 136 | #define UART1_UDRIE UDRIE1 |
136 | #define UART1_UDRIE UDRIE1 |
| 137 | #elif defined(__AVR_ATmega103__) |
137 | #elif defined(__AVR_ATmega103__) |
| 138 | /* ATMega with one UART */ |
138 | /* ATMega with one UART */ |
| 139 | #error "AVR ATmega103 currently not supported by this libaray !" |
139 | #error "AVR ATmega103 currently not supported by this libaray !" |
| 140 | #elif defined(__AVR_ATmega161__) |
140 | #elif defined(__AVR_ATmega161__) |
| 141 | /* ATmega with UART */ |
141 | /* ATmega with UART */ |
| 142 | #error "AVR ATmega161 currently not supported by this libaray !" |
142 | #error "AVR ATmega161 currently not supported by this libaray !" |
| 143 | #elif defined(__AVR_ATmega169__) |
143 | #elif defined(__AVR_ATmega169__) |
| 144 | #error "AVR ATmega169 currently not supported by this libaray !" |
144 | #error "AVR ATmega169 currently not supported by this libaray !" |
| 145 | #endif |
145 | #endif |
| 146 | 146 | ||
| 147 | 147 | ||
| 148 | /* |
148 | /* |
| 149 | * module global variables |
149 | * module global variables |
| 150 | */ |
150 | */ |
| 151 | static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE]; |
151 | static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE]; |
| 152 | static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE]; |
152 | static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE]; |
| 153 | static volatile unsigned char UART_TxHead; |
153 | static volatile unsigned char UART_TxHead; |
| 154 | static volatile unsigned char UART_TxTail; |
154 | static volatile unsigned char UART_TxTail; |
| 155 | static volatile unsigned char UART_RxHead; |
155 | static volatile unsigned char UART_RxHead; |
| 156 | static volatile unsigned char UART_RxTail; |
156 | static volatile unsigned char UART_RxTail; |
| 157 | static volatile unsigned char UART_LastRxError; |
157 | static volatile unsigned char UART_LastRxError; |
| 158 | 158 | ||
| 159 | 159 | ||
| 160 | 160 | ||
| 161 | ISR(UART0_RECEIVE_INTERRUPT) |
161 | ISR(UART0_RECEIVE_INTERRUPT) |
| 162 | /************************************************************************* |
162 | /************************************************************************* |
| 163 | Function: UART Receive Complete interrupt |
163 | Function: UART Receive Complete interrupt |
| 164 | Purpose: called when the UART has received a character |
164 | Purpose: called when the UART has received a character |
| 165 | **************************************************************************/ |
165 | **************************************************************************/ |
| 166 | { |
166 | { |
| 167 | unsigned char tmphead; |
167 | unsigned char tmphead; |
| 168 | unsigned char data; |
168 | unsigned char data; |
| 169 | unsigned char usr; |
169 | unsigned char usr; |
| 170 | unsigned char lastRxError; |
170 | unsigned char lastRxError; |
| 171 | 171 | ||
| 172 | 172 | ||
| 173 | /* read UART status register and UART data register */ |
173 | /* read UART status register and UART data register */ |
| 174 | usr = UART0_STATUS; |
174 | usr = UART0_STATUS; |
| 175 | data = UART0_DATA; |
175 | data = UART0_DATA; |
| 176 | 176 | ||
| 177 | /* */ |
177 | /* */ |
| 178 | #if defined( AT90_UART ) |
178 | #if defined( AT90_UART ) |
| 179 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); |
179 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); |
| 180 | #elif defined( ATMEGA_USART ) |
180 | #elif defined( ATMEGA_USART ) |
| 181 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); |
181 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); |
| 182 | #elif defined( ATMEGA_USART0 ) |
182 | #elif defined( ATMEGA_USART0 ) |
| 183 | lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) ); |
183 | lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) ); |
| 184 | #elif defined ( ATMEGA_UART ) |
184 | #elif defined ( ATMEGA_UART ) |
| 185 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); |
185 | lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); |
| 186 | #endif |
186 | #endif |
| 187 | 187 | ||
| 188 | /* calculate buffer index */ |
188 | /* calculate buffer index */ |
| 189 | tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK; |
189 | tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK; |
| 190 | 190 | ||
| 191 | if ( tmphead == UART_RxTail ) { |
191 | if ( tmphead == UART_RxTail ) { |
| 192 | /* error: receive buffer overflow */ |
192 | /* error: receive buffer overflow */ |
| 193 | lastRxError = UART_BUFFER_OVERFLOW >> 8; |
193 | lastRxError = UART_BUFFER_OVERFLOW >> 8; |
| 194 | }else{ |
194 | }else{ |
| 195 | /* store new index */ |
195 | /* store new index */ |
| 196 | UART_RxHead = tmphead; |
196 | UART_RxHead = tmphead; |
| 197 | /* store received data in buffer */ |
197 | /* store received data in buffer */ |
| 198 | UART_RxBuf[tmphead] = data; |
198 | UART_RxBuf[tmphead] = data; |
| 199 | } |
199 | } |
| 200 | UART_LastRxError = lastRxError; |
200 | UART_LastRxError = lastRxError; |
| 201 | } |
201 | } |
| 202 | 202 | ||
| 203 | 203 | ||
| 204 | ISR(UART0_TRANSMIT_INTERRUPT) |
204 | ISR(UART0_TRANSMIT_INTERRUPT) |
| 205 | /************************************************************************* |
205 | /************************************************************************* |
| 206 | Function: UART Data Register Empty interrupt |
206 | Function: UART Data Register Empty interrupt |
| 207 | Purpose: called when the UART is ready to transmit the next byte |
207 | Purpose: called when the UART is ready to transmit the next byte |
| 208 | **************************************************************************/ |
208 | **************************************************************************/ |
| 209 | { |
209 | { |
| 210 | unsigned char tmptail; |
210 | unsigned char tmptail; |
| 211 | 211 | ||
| 212 | 212 | ||
| 213 | if ( UART_TxHead != UART_TxTail) { |
213 | if ( UART_TxHead != UART_TxTail) { |
| 214 | /* calculate and store new buffer index */ |
214 | /* calculate and store new buffer index */ |
| 215 | tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK; |
215 | tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK; |
| 216 | UART_TxTail = tmptail; |
216 | UART_TxTail = tmptail; |
| 217 | /* get one byte from buffer and write it to UART */ |
217 | /* get one byte from buffer and write it to UART */ |
| 218 | UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */ |
218 | UART0_DATA = UART_TxBuf[tmptail]; /* start transmission */ |
| 219 | }else{ |
219 | }else{ |
| 220 | /* tx buffer empty, disable UDRE interrupt */ |
220 | /* tx buffer empty, disable UDRE interrupt */ |
| 221 | UART0_CONTROL &= ~_BV(UART0_UDRIE); |
221 | UART0_CONTROL &= ~_BV(UART0_UDRIE); |
| 222 | } |
222 | } |
| 223 | } |
223 | } |
| 224 | 224 | ||
| 225 | 225 | ||
| 226 | 226 | ||
| 227 | /** |
227 | /** |
| 228 | * Wrapper function for uart_init. |
228 | * Wrapper function for uart_init. |
| 229 | */ |
229 | */ |
| 230 | void UartInit() { |
230 | void UartInit() { |
| 231 | uart_init((UART_BAUD_SELECT((BAUD),F_OSC))); |
231 | uart_init((UART_BAUD_SELECT((BAUD),F_OSC))); |
| 232 | stdout = &myStdOut; |
232 | stdout = &myStdOut; |
| 233 | } |
233 | } |
| 234 | 234 | ||
| 235 | 235 | ||
| 236 | /************************************************************************* |
236 | /************************************************************************* |
| 237 | Function: uart_init() |
237 | Function: uart_init() |
| 238 | Purpose: initialize UART and set baudrate |
238 | Purpose: initialize UART and set baudrate |
| 239 | Input: baudrate using macro UART_BAUD_SELECT() |
239 | Input: baudrate using macro UART_BAUD_SELECT() |
| 240 | Returns: none |
240 | Returns: none |
| 241 | **************************************************************************/ |
241 | **************************************************************************/ |
| 242 | void uart_init(unsigned int baudrate) |
242 | void uart_init(unsigned int baudrate) |
| 243 | { |
243 | { |
| 244 | UART_TxHead = 0; |
244 | UART_TxHead = 0; |
| 245 | UART_TxTail = 0; |
245 | UART_TxTail = 0; |
| 246 | UART_RxHead = 0; |
246 | UART_RxHead = 0; |
| 247 | UART_RxTail = 0; |
247 | UART_RxTail = 0; |
| 248 | 248 | ||
| 249 | #if defined( AT90_UART ) |
249 | #if defined( AT90_UART ) |
| 250 | /* set baud rate */ |
250 | /* set baud rate */ |
| 251 | UBRR = (unsigned char)baudrate; |
251 | UBRR = (unsigned char)baudrate; |
| 252 | 252 | ||
| 253 | /* enable UART receiver and transmmitter and receive complete interrupt */ |
253 | /* enable UART receiver and transmmitter and receive complete interrupt */ |
| 254 | UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|BV(TXEN); |
254 | UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|BV(TXEN); |
| 255 | 255 | ||
| 256 | #elif defined (ATMEGA_USART) |
256 | #elif defined (ATMEGA_USART) |
| 257 | /* Set baud rate */ |
257 | /* Set baud rate */ |
| 258 | UBRRH = (unsigned char)(baudrate>>8); |
258 | UBRRH = (unsigned char)(baudrate>>8); |
| 259 | UBRRL = (unsigned char) baudrate; |
259 | UBRRL = (unsigned char) baudrate; |
| 260 | 260 | ||
| 261 | /* Enable USART receiver and transmitter and receive complete interrupt */ |
261 | /* Enable USART receiver and transmitter and receive complete interrupt */ |
| 262 | UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); |
262 | UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); |
| 263 | 263 | ||
| 264 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ |
264 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ |
| 265 | #ifdef URSEL |
265 | #ifdef URSEL |
| 266 | UCSRC = (1<<URSEL)|(3<<UCSZ0); |
266 | UCSRC = (1<<URSEL)|(3<<UCSZ0); |
| 267 | #else |
267 | #else |
| 268 | UCSRC = (3<<UCSZ0); |
268 | UCSRC = (3<<UCSZ0); |
| 269 | #endif |
269 | #endif |
| 270 | 270 | ||
| 271 | #elif defined (ATMEGA_USART0 ) |
271 | #elif defined (ATMEGA_USART0 ) |
| 272 | /* Set baud rate */ |
272 | /* Set baud rate */ |
| 273 | UBRR0H = (unsigned char)(baudrate>>8); |
273 | UBRR0H = (unsigned char)(baudrate>>8); |
| 274 | UBRR0L = (unsigned char) baudrate; |
274 | UBRR0L = (unsigned char) baudrate; |
| 275 | 275 | ||
| 276 | /* Enable USART receiver and transmitter and receive complete interrupt */ |
276 | /* Enable USART receiver and transmitter and receive complete interrupt */ |
| 277 | UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0); |
277 | UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0); |
| 278 | 278 | ||
| 279 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ |
279 | /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ |
| 280 | #ifdef URSEL0 |
280 | #ifdef URSEL0 |
| 281 | UCSR0C = (1<<URSEL0)|(3<<UCSZ00); |
281 | UCSR0C = (1<<URSEL0)|(3<<UCSZ00); |
| 282 | #else |
282 | #else |
| 283 | UCSR0C = (3<<UCSZ00); |
283 | UCSR0C = (3<<UCSZ00); |
| 284 | #endif |
284 | #endif |
| 285 | 285 | ||
| 286 | #elif defined ( ATMEGA_UART ) |
286 | #elif defined ( ATMEGA_UART ) |
| 287 | /* set baud rate */ |
287 | /* set baud rate */ |
| 288 | UBRRHI = (unsigned char)(baudrate>>8); |
288 | UBRRHI = (unsigned char)(baudrate>>8); |
| 289 | UBRR = (unsigned char) baudrate; |
289 | UBRR = (unsigned char) baudrate; |
| 290 | 290 | ||
| 291 | /* Enable UART receiver and transmitter and receive complete interrupt */ |
291 | /* Enable UART receiver and transmitter and receive complete interrupt */ |
| 292 | UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); |
292 | UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); |
| 293 | 293 | ||
| 294 | #endif |
294 | #endif |
| 295 | 295 | ||
| 296 | }/* uart_init */ |
296 | }/* uart_init */ |
| 297 | 297 | ||
| 298 | 298 | ||
| 299 | /************************************************************************* |
299 | /************************************************************************* |
| 300 | Function: uart_getc() |
300 | Function: uart_getc() |
| 301 | Purpose: return byte from ringbuffer |
301 | Purpose: return byte from ringbuffer |
| 302 | Returns: lower byte: received byte from ringbuffer |
302 | Returns: lower byte: received byte from ringbuffer |
| 303 | higher byte: last receive error |
303 | higher byte: last receive error |
| 304 | **************************************************************************/ |
304 | **************************************************************************/ |
| 305 | unsigned int uart_getc(void) |
305 | unsigned int uart_getc(void) |
| 306 | { |
306 | { |
| 307 | unsigned char tmptail; |
307 | unsigned char tmptail; |
| 308 | unsigned char data; |
308 | unsigned char data; |
| 309 | 309 | ||
| 310 | 310 | ||
| 311 | if ( UART_RxHead == UART_RxTail ) { |
311 | if ( UART_RxHead == UART_RxTail ) { |
| 312 | return UART_NO_DATA; /* no data available */ |
312 | return UART_NO_DATA; /* no data available */ |
| 313 | } |
313 | } |
| 314 | 314 | ||
| 315 | /* calculate /store buffer index */ |
315 | /* calculate /store buffer index */ |
| 316 | tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK; |
316 | tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK; |
| 317 | UART_RxTail = tmptail; |
317 | UART_RxTail = tmptail; |
| 318 | 318 | ||
| 319 | /* get data from receive buffer */ |
319 | /* get data from receive buffer */ |
| 320 | data = UART_RxBuf[tmptail]; |
320 | data = UART_RxBuf[tmptail]; |
| 321 | 321 | ||
| 322 | return (UART_LastRxError << 8) + data; |
322 | return (UART_LastRxError << 8) + data; |
| 323 | 323 | ||
| 324 | }/* uart_getc */ |
324 | }/* uart_getc */ |
| 325 | 325 | ||
| 326 | 326 | ||
| 327 | /************************************************************************* |
327 | /************************************************************************* |
| 328 | Function: uart_putc() |
328 | Function: uart_putc() |
| 329 | Purpose: write byte to ringbuffer for transmitting via UART |
329 | Purpose: write byte to ringbuffer for transmitting via UART |
| 330 | Input: byte to be transmitted |
330 | Input: byte to be transmitted |
| 331 | Returns: none |
331 | Returns: none |
| 332 | **************************************************************************/ |
332 | **************************************************************************/ |
| 333 | void uart_putc(unsigned char data) |
333 | void uart_putc(unsigned char data) |
| 334 | { |
334 | { |
| 335 | unsigned char tmphead; |
335 | unsigned char tmphead; |
| 336 | 336 | ||
| 337 | 337 | ||
| 338 | tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK; |
338 | tmphead = (UART_TxHead + 1) & UART_TX_BUFFER_MASK; |
| 339 | 339 | ||
| 340 | while ( tmphead == UART_TxTail ){ |
340 | while ( tmphead == UART_TxTail ){ |
| 341 | ;/* wait for free space in buffer */ |
341 | ;/* wait for free space in buffer */ |
| 342 | } |
342 | } |
| 343 | 343 | ||
| 344 | UART_TxBuf[tmphead] = data; |
344 | UART_TxBuf[tmphead] = data; |
| 345 | UART_TxHead = tmphead; |
345 | UART_TxHead = tmphead; |
| 346 | 346 | ||
| 347 | /* enable UDRE interrupt */ |
347 | /* enable UDRE interrupt */ |
| 348 | UART0_CONTROL |= _BV(UART0_UDRIE); |
348 | UART0_CONTROL |= _BV(UART0_UDRIE); |
| 349 | 349 | ||
| 350 | }/* uart_putc */ |
350 | }/* uart_putc */ |
| 351 | 351 | ||
| 352 | 352 | ||
| 353 | /************************************************************************* |
353 | /************************************************************************* |
| 354 | Function: uart_puts() |
354 | Function: uart_puts() |
| 355 | Purpose: transmit string to UART |
355 | Purpose: transmit string to UART |
| 356 | Input: string to be transmitted |
356 | Input: string to be transmitted |
| 357 | Returns: none |
357 | Returns: none |
| 358 | **************************************************************************/ |
358 | **************************************************************************/ |
| 359 | void uart_puts(const char *s ) |
359 | void uart_puts(const char *s ) |
| 360 | { |
360 | { |
| 361 | while (*s) |
361 | while (*s) |
| 362 | uart_putc(*s++); |
362 | uart_putc(*s++); |
| 363 | 363 | ||
| 364 | }/* uart_puts */ |
364 | }/* uart_puts */ |
| 365 | 365 | ||
| 366 | 366 | ||
| 367 | /************************************************************************* |
367 | /************************************************************************* |
| 368 | Function: uart_puts_p() |
368 | Function: uart_puts_p() |
| 369 | Purpose: transmit string from program memory to UART |
369 | Purpose: transmit string from program memory to UART |
| 370 | Input: program memory string to be transmitted |
370 | Input: program memory string to be transmitted |
| 371 | Returns: none |
371 | Returns: none |
| 372 | **************************************************************************/ |
372 | **************************************************************************/ |
| 373 | void uart_puts_p(const char *progmem_s ) |
373 | void uart_puts_p(const char *progmem_s ) |
| 374 | { |
374 | { |
| 375 | register char c; |
375 | register char c; |
| 376 | 376 | ||
| 377 | while ( (c = pgm_read_byte(progmem_s++)) ) |
377 | while ( (c = pgm_read_byte(progmem_s++)) ) |
| 378 | uart_putc(c); |
378 | uart_putc(c); |
| 379 | 379 | ||
| 380 | }/* uart_puts_p */ |
380 | }/* uart_puts_p */ |
| 381 | 381 | ||
| 382 | /************************************************************************* |
382 | /************************************************************************* |
| 383 | Function: uart_puti() |
383 | Function: uart_puti() |
| 384 | Purpose: transmit integer as ASCII to UART |
384 | Purpose: transmit integer as ASCII to UART |
| 385 | Input: integer value |
385 | Input: integer value |
| 386 | Returns: none |
386 | Returns: none |
| 387 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
387 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
| 388 | Don't blame P. Fleury if it doesn't work ;-) |
388 | Don't blame P. Fleury if it doesn't work ;-) |
| 389 | **************************************************************************/ |
389 | **************************************************************************/ |
| 390 | void uart_puti( const int val ) |
390 | void uart_puti( const int val ) |
| 391 | { |
391 | { |
| 392 | char buffer[sizeof(int)*8+1]; |
392 | char buffer[sizeof(int)*8+1]; |
| 393 | 393 | ||
| 394 | uart_puts( itoa(val, buffer, 10) ); |
394 | uart_puts( itoa(val, buffer, 10) ); |
| 395 | 395 | ||
| 396 | }/* uart_puti */ |
396 | }/* uart_puti */ |
| 397 | 397 | ||
| 398 | /************************************************************************* |
398 | /************************************************************************* |
| 399 | Function: uart_puthex_nibble() |
399 | Function: uart_puthex_nibble() |
| 400 | Purpose: transmit lower nibble as ASCII-hex to UART |
400 | Purpose: transmit lower nibble as ASCII-hex to UART |
| 401 | Input: byte value |
401 | Input: byte value |
| 402 | Returns: none |
402 | Returns: none |
| 403 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
403 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
| 404 | Don't blame P. Fleury if it doesn't work ;-) |
404 | Don't blame P. Fleury if it doesn't work ;-) |
| 405 | **************************************************************************/ |
405 | **************************************************************************/ |
| 406 | void uart_puthex_nibble(const unsigned char b) |
406 | void uart_puthex_nibble(const unsigned char b) |
| 407 | { |
407 | { |
| 408 | unsigned char c = b & 0x0f; |
408 | unsigned char c = b & 0x0f; |
| 409 | if (c>9) c += 'A'-10; |
409 | if (c>9) c += 'A'-10; |
| 410 | else c += '0'; |
410 | else c += '0'; |
| 411 | uart_putc(c); |
411 | uart_putc(c); |
| 412 | } /* uart_puthex_nibble */ |
412 | } /* uart_puthex_nibble */ |
| 413 | 413 | ||
| 414 | /************************************************************************* |
414 | /************************************************************************* |
| 415 | Function: uart_puthex_byte() |
415 | Function: uart_puthex_byte() |
| 416 | Purpose: transmit upper and lower nibble as ASCII-hex to UART |
416 | Purpose: transmit upper and lower nibble as ASCII-hex to UART |
| 417 | Input: byte value |
417 | Input: byte value |
| 418 | Returns: none |
418 | Returns: none |
| 419 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
419 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
| 420 | Don't blame P. Fleury if it doesn't work ;-) |
420 | Don't blame P. Fleury if it doesn't work ;-) |
| 421 | **************************************************************************/ |
421 | **************************************************************************/ |
| 422 | void uart_puthex_byte(const unsigned char b) |
422 | void uart_puthex_byte(const unsigned char b) |
| 423 | { |
423 | { |
| 424 | uart_puthex_nibble(b>>4); |
424 | uart_puthex_nibble(b>>4); |
| 425 | uart_puthex_nibble(b); |
425 | uart_puthex_nibble(b); |
| 426 | } /* uart_puthex_byte */ |
426 | } /* uart_puthex_byte */ |
| 427 | 427 | ||
| 428 | /************************************************************************* |
428 | /************************************************************************* |
| 429 | Function: uart_putbin_byte() |
429 | Function: uart_putbin_byte() |
| 430 | Purpose: transmit byte as ASCII-bin to UART |
430 | Purpose: transmit byte as ASCII-bin to UART |
| 431 | Input: byte value |
431 | Input: byte value |
| 432 | Returns: none |
432 | Returns: none |
| 433 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
433 | This functions has been added by Martin Thomas <eversmith@heizung-thomas.de> |
| 434 | Don't blame P. Fleury if it doesn't work ;-) |
434 | Don't blame P. Fleury if it doesn't work ;-) |
| 435 | **************************************************************************/ |
435 | **************************************************************************/ |
| 436 | void uart_putbin_byte(const unsigned char b) |
436 | void uart_putbin_byte(const unsigned char b) |
| 437 | { |
437 | { |
| 438 | #if 0 |
438 | #if 0 |
| 439 | char buffer[sizeof(int)*8+1]; |
439 | char buffer[sizeof(int)*8+1]; |
| 440 | 440 | ||
| 441 | uart_puts( itoa(b, buffer, 2) ); |
441 | uart_puts( itoa(b, buffer, 2) ); |
| 442 | #else |
442 | #else |
| 443 | signed char i; |
443 | signed char i; |
| 444 | for (i=7;i>=0;i--) { |
444 | for (i=7;i>=0;i--) { |
| 445 | if (b & (1<<i)) { |
445 | if (b & (1<<i)) { |
| 446 | uart_putc('1'); |
446 | uart_putc('1'); |
| 447 | } |
447 | } |
| 448 | else { |
448 | else { |
| 449 | uart_putc('0'); |
449 | uart_putc('0'); |
| 450 | } |
450 | } |
| 451 | } |
451 | } |
| 452 | #endif |
452 | #endif |
| 453 | } /* uart_putbin_byte */ |
453 | } /* uart_putbin_byte */ |
| 454 | 454 | ||