Rev 1145 Rev 1858
1 /*! \file uart.c \brief UART driver with buffer support. */ 1 /*! \file uart.c \brief UART driver with buffer support. */
2 // ***************************************************************************** 2 // *****************************************************************************
3 // 3 //
4 // File Name : 'uart.c' 4 // File Name : 'uart.c'
5 // Title : UART driver with buffer support 5 // Title : UART driver with buffer support
6 // Author : Pascal Stang - Copyright (C) 2000-2002 6 // Author : Pascal Stang - Copyright (C) 2000-2002
7 // Created : 11/22/2000 7 // Created : 11/22/2000
8 // Revised : 06/09/2003 8 // Revised : 06/09/2003
9 // Version : 1.3 9 // Version : 1.3
10 // Target MCU : ATMEL AVR Series 10 // Target MCU : ATMEL AVR Series
11 // Editor Tabs : 4 11 // Editor Tabs : 4
12 // 12 //
13 // This code is distributed under the GNU Public License 13 // This code is distributed under the GNU Public License
14 // which can be found at http://www.gnu.org/licenses/gpl.txt 14 // which can be found at http://www.gnu.org/licenses/gpl.txt
15 // 15 //
16 // ***************************************************************************** 16 // *****************************************************************************
17   17  
18 #include <avr/io.h> 18 #include <avr/io.h>
19 #include <avr/interrupt.h> 19 #include <avr/interrupt.h>
20   20  
21 #include "buffer.h" 21 #include "buffer.h"
22 #include "uart.h" 22 #include "uart.h"
23   23  
24 // UART global variables 24 // UART global variables
25 // flag variables 25 // flag variables
26 volatile u08 uartReadyTx; ///< uartReadyTx flag 26 volatile u08 uartReadyTx; ///< uartReadyTx flag
27 volatile u08 uartBufferedTx; ///< uartBufferedTx flag 27 volatile u08 uartBufferedTx; ///< uartBufferedTx flag
28 // receive and transmit buffers 28 // receive and transmit buffers
29 cBuffer uartRxBuffer; ///< uart receive buffer 29 cBuffer uartRxBuffer; ///< uart receive buffer
30 cBuffer uartTxBuffer; ///< uart transmit buffer 30 cBuffer uartTxBuffer; ///< uart transmit buffer
31 unsigned short uartRxOverflow; ///< receive overflow counter 31 unsigned short uartRxOverflow; ///< receive overflow counter
32   32  
33 #ifndef UART_BUFFERS_EXTERNAL_RAM 33 #ifndef UART_BUFFERS_EXTERNAL_RAM
34 // using internal ram, 34 // using internal ram,
35 // automatically allocate space in ram for each buffer 35 // automatically allocate space in ram for each buffer
36 static char uartRxData[UART_RX_BUFFER_SIZE]; 36 static char uartRxData[UART_RX_BUFFER_SIZE];
37 static char uartTxData[UART_TX_BUFFER_SIZE]; 37 static char uartTxData[UART_TX_BUFFER_SIZE];
38 #endif 38 #endif
39   39  
40 typedef void (*voidFuncPtru08)(unsigned char); 40 typedef void (*voidFuncPtru08)(unsigned char);
41 volatile static voidFuncPtru08 UartRxFunc; 41 volatile static voidFuncPtru08 UartRxFunc;
42   42  
43 // enable and initialize the uart 43 // enable and initialize the uart
44 void uartInit(void) 44 void uartInit(void)
45 { 45 {
46 // initialize the buffers 46 // initialize the buffers
47 uartInitBuffers(); 47 uartInitBuffers();
48 // initialize user receive handler 48 // initialize user receive handler
49 UartRxFunc = 0; 49 UartRxFunc = 0;
50   50  
51 // enable RxD/TxD and interrupts 51 // enable RxD/TxD and interrupts
52 outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN)); 52 outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
53   53  
54 // set default baud rate 54 // set default baud rate
55 uartSetBaudRate(UART_DEFAULT_BAUD_RATE); 55 uartSetBaudRate(UART_DEFAULT_BAUD_RATE);
56 // initialize states 56 // initialize states
57 uartReadyTx = TRUE; 57 uartReadyTx = TRUE;
58 uartBufferedTx = FALSE; 58 uartBufferedTx = FALSE;
59 // clear overflow count 59 // clear overflow count
60 uartRxOverflow = 0; 60 uartRxOverflow = 0;
61 // enable interrupts 61 // enable interrupts
62 sei(); 62 sei();
63 } 63 }
64   64  
65 // create and initialize the uart transmit and receive buffers 65 // create and initialize the uart transmit and receive buffers
66 void uartInitBuffers(void) 66 void uartInitBuffers(void)
67 { 67 {
68 #ifndef UART_BUFFERS_EXTERNAL_RAM 68 #ifndef UART_BUFFERS_EXTERNAL_RAM
69 // initialize the UART receive buffer 69 // initialize the UART receive buffer
70 bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE); 70 bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE);
71 // initialize the UART transmit buffer 71 // initialize the UART transmit buffer
72 bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE); 72 bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE);
73 #else 73 #else
74 // initialize the UART receive buffer 74 // initialize the UART receive buffer
75 bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE); 75 bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE);
76 // initialize the UART transmit buffer 76 // initialize the UART transmit buffer
77 bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE); 77 bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE);
78 #endif 78 #endif
79 } 79 }
80   80  
81 // redirects received data to a user function 81 // redirects received data to a user function
82 void uartSetRxHandler(void (*rx_func)(unsigned char c)) 82 void uartSetRxHandler(void (*rx_func)(unsigned char c))
83 { 83 {
84 // set the receive interrupt to run the supplied user function 84 // set the receive interrupt to run the supplied user function
85 UartRxFunc = rx_func; 85 UartRxFunc = rx_func;
86 } 86 }
87   87  
88 // set the uart baud rate 88 // set the uart baud rate
89 void uartSetBaudRate(u32 baudrate) 89 void uartSetBaudRate(u32 baudrate)
90 { 90 {
91 // calculate division factor for requested baud rate, and set it 91 // calculate division factor for requested baud rate, and set it
92 u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1); 92 u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
93 outb(UBRRL, bauddiv); 93 outb(UBRRL, bauddiv);
94 #ifdef UBRRH 94 #ifdef UBRRH
95 outb(UBRRH, bauddiv>>8); 95 outb(UBRRH, bauddiv>>8);
96 #endif 96 #endif
97 } 97 }
98   98  
99 // returns the receive buffer structure 99 // returns the receive buffer structure
100 cBuffer* uartGetRxBuffer(void) 100 cBuffer* uartGetRxBuffer(void)
101 { 101 {
102 // return rx buffer pointer 102 // return rx buffer pointer
103 return &uartRxBuffer; 103 return &uartRxBuffer;
104 } 104 }
105   105  
106 // returns the transmit buffer structure 106 // returns the transmit buffer structure
107 cBuffer* uartGetTxBuffer(void) 107 cBuffer* uartGetTxBuffer(void)
108 { 108 {
109 // return tx buffer pointer 109 // return tx buffer pointer
110 return &uartTxBuffer; 110 return &uartTxBuffer;
111 } 111 }
112   112  
113 // transmits a byte over the uart 113 // transmits a byte over the uart
114 void uartSendByte(u08 txData) 114 void uartSendByte(u08 txData)
115 { 115 {
116 // wait for the transmitter to be ready 116 // wait for the transmitter to be ready
117 while(!uartReadyTx); 117 while(!uartReadyTx);
118 // send byte 118 // send byte
119 outb(UDR, txData); 119 outb(UDR, txData);
120 // set ready state to FALSE 120 // set ready state to FALSE
121 uartReadyTx = FALSE; 121 uartReadyTx = FALSE;
122 } 122 }
123   123  
124 // gets a single byte from the uart receive buffer (getchar-style) 124 // gets a single byte from the uart receive buffer (getchar-style)
125 int uartGetByte(void) 125 int uartGetByte(void)
126 { 126 {
127 u08 c; 127 u08 c;
128 if(uartReceiveByte(&c)) 128 if(uartReceiveByte(&c))
129 return c; 129 return c;
130 else 130 else
131 return -1; 131 return -1;
132 } 132 }
133   133  
134 // gets a byte (if available) from the uart receive buffer 134 // gets a byte (if available) from the uart receive buffer
135 u08 uartReceiveByte(u08* rxData) 135 u08 uartReceiveByte(u08* rxData)
136 { 136 {
137 // make sure we have a receive buffer 137 // make sure we have a receive buffer
138 if(uartRxBuffer.size) 138 if(uartRxBuffer.size)
139 { 139 {
140 // make sure we have data 140 // make sure we have data
141 if(uartRxBuffer.datalength) 141 if(uartRxBuffer.datalength)
142 { 142 {
143 // get byte from beginning of buffer 143 // get byte from beginning of buffer
144 *rxData = bufferGetFromFront(&uartRxBuffer); 144 *rxData = bufferGetFromFront(&uartRxBuffer);
145 return TRUE; 145 return TRUE;
146 } 146 }
147 else 147 else
148 { 148 {
149 // no data 149 // no data
150 return FALSE; 150 return FALSE;
151 } 151 }
152 } 152 }
153 else 153 else
154 { 154 {
155 // no buffer 155 // no buffer
156 return FALSE; 156 return FALSE;
157 } 157 }
158 } 158 }
159   159  
160 // flush all data out of the receive buffer 160 // flush all data out of the receive buffer
161 void uartFlushReceiveBuffer(void) 161 void uartFlushReceiveBuffer(void)
162 { 162 {
163 // flush all data from receive buffer 163 // flush all data from receive buffer
164 //bufferFlush(&uartRxBuffer); 164 //bufferFlush(&uartRxBuffer);
165 // same effect as above 165 // same effect as above
166 uartRxBuffer.datalength = 0; 166 uartRxBuffer.datalength = 0;
167 } 167 }
168   168  
169 // return true if uart receive buffer is empty 169 // return true if uart receive buffer is empty
170 u08 uartReceiveBufferIsEmpty(void) 170 u08 uartReceiveBufferIsEmpty(void)
171 { 171 {
172 if(uartRxBuffer.datalength == 0) 172 if(uartRxBuffer.datalength == 0)
173 { 173 {
174 return TRUE; 174 return TRUE;
175 } 175 }
176 else 176 else
177 { 177 {
178 return FALSE; 178 return FALSE;
179 } 179 }
180 } 180 }
181   181  
182 // add byte to end of uart Tx buffer 182 // add byte to end of uart Tx buffer
183 u08 uartAddToTxBuffer(u08 data) 183 u08 uartAddToTxBuffer(u08 data)
184 { 184 {
185 // add data byte to the end of the tx buffer 185 // add data byte to the end of the tx buffer
186 return bufferAddToEnd(&uartTxBuffer, data); 186 return bufferAddToEnd(&uartTxBuffer, data);
187 } 187 }
188   188  
189 // start transmission of the current uart Tx buffer contents 189 // start transmission of the current uart Tx buffer contents
190 void uartSendTxBuffer(void) 190 void uartSendTxBuffer(void)
191 { 191 {
192 // turn on buffered transmit 192 // turn on buffered transmit
193 uartBufferedTx = TRUE; 193 uartBufferedTx = TRUE;
194 // send the first byte to get things going by interrupts 194 // send the first byte to get things going by interrupts
195 uartSendByte(bufferGetFromFront(&uartTxBuffer)); 195 uartSendByte(bufferGetFromFront(&uartTxBuffer));
196 } 196 }
197 /* 197 /*
198 // transmit nBytes from buffer out the uart 198 // transmit nBytes from buffer out the uart
199 u08 uartSendBuffer(char *buffer, u16 nBytes) 199 u08 uartSendBuffer(char *buffer, u16 nBytes)
200 { 200 {
201 register u08 first; 201 register u08 first;
202 register u16 i; 202 register u16 i;
203   203  
204 // check if there's space (and that we have any bytes to send at all) 204 // check if there's space (and that we have any bytes to send at all)
205 if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes) 205 if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
206 { 206 {
207 // grab first character 207 // grab first character
208 first = *buffer++; 208 first = *buffer++;
209 // copy user buffer to uart transmit buffer 209 // copy user buffer to uart transmit buffer
210 for(i = 0; i < nBytes-1; i++) 210 for(i = 0; i < nBytes-1; i++)
211 { 211 {
212 // put data bytes at end of buffer 212 // put data bytes at end of buffer
213 bufferAddToEnd(&uartTxBuffer, *buffer++); 213 bufferAddToEnd(&uartTxBuffer, *buffer++);
214 } 214 }
215   215  
216 // send the first byte to get things going by interrupts 216 // send the first byte to get things going by interrupts
217 uartBufferedTx = TRUE; 217 uartBufferedTx = TRUE;
218 uartSendByte(first); 218 uartSendByte(first);
219 // return success 219 // return success
220 return TRUE; 220 return TRUE;
221 } 221 }
222 else 222 else
223 { 223 {
224 // return failure 224 // return failure
225 return FALSE; 225 return FALSE;
226 } 226 }
227 } 227 }
228 */ 228 */
229 // UART Transmit Complete Interrupt Handler 229 // UART Transmit Complete Interrupt Handler
230 UART_INTERRUPT_HANDLER(SIG_UART_TRANS) 230 UART_INTERRUPT_HANDLER(SIG_UART_TRANS)
231 { 231 {
232 // check if buffered tx is enabled 232 // check if buffered tx is enabled
233 if(uartBufferedTx) 233 if(uartBufferedTx)
234 { 234 {
235 // check if there's data left in the buffer 235 // check if there's data left in the buffer
236 if(uartTxBuffer.datalength) 236 if(uartTxBuffer.datalength)
237 { 237 {
238 // send byte from top of buffer 238 // send byte from top of buffer
239 outb(UDR, bufferGetFromFront(&uartTxBuffer)); 239 outb(UDR, bufferGetFromFront(&uartTxBuffer));
240 } 240 }
241 else 241 else
242 { 242 {
243 // no data left 243 // no data left
244 uartBufferedTx = FALSE; 244 uartBufferedTx = FALSE;
245 // return to ready state 245 // return to ready state
246 uartReadyTx = TRUE; 246 uartReadyTx = TRUE;
247 } 247 }
248 } 248 }
249 else 249 else
250 { 250 {
251 // we're using single-byte tx mode 251 // we're using single-byte tx mode
252 // indicate transmit complete, back to ready 252 // indicate transmit complete, back to ready
253 uartReadyTx = TRUE; 253 uartReadyTx = TRUE;
254 } 254 }
255 } 255 }
256   256  
257 // UART Receive Complete Interrupt Handler 257 // UART Receive Complete Interrupt Handler
258 UART_INTERRUPT_HANDLER(SIG_UART_RECV) 258 UART_INTERRUPT_HANDLER(SIG_UART_RECV)
259 { 259 {
260 u08 c; 260 u08 c;
261 261
262 // get received char 262 // get received char
263 c = inb(UDR); 263 c = inb(UDR);
264   264  
265 // if there's a user function to handle this receive event 265 // if there's a user function to handle this receive event
266 if(UartRxFunc) 266 if(UartRxFunc)
267 { 267 {
268 // call it and pass the received data 268 // call it and pass the received data
269 UartRxFunc(c); 269 UartRxFunc(c);
270 } 270 }
271 else 271 else
272 { 272 {
273 // otherwise do default processing 273 // otherwise do default processing
274 // put received char in buffer 274 // put received char in buffer
275 // check if there's space 275 // check if there's space
276 if( !bufferAddToEnd(&uartRxBuffer, c) ) 276 if( !bufferAddToEnd(&uartRxBuffer, c) )
277 { 277 {
278 // no space in buffer 278 // no space in buffer
279 // count overflow 279 // count overflow
280 uartRxOverflow++; 280 uartRxOverflow++;
281 } 281 }
282 } 282 }
283 } 283 }