Rev Author Line No. Line
1269 kakl 1 /*! \file uart2.c \brief Dual UART driver with buffer support. */
2 //*****************************************************************************
3 //
4 // File Name : 'uart2.c'
5 // Title : Dual UART driver with buffer support
6 // Author : Pascal Stang - Copyright (C) 2000-2004
7 // Created : 11/20/2000
8 // Revised : 07/04/2004
9 // Version : 1.0
10 // Target MCU : ATMEL AVR Series
11 // Editor Tabs : 4
12 //
13 // Description : This is a UART driver for AVR-series processors with two
14 // hardware UARTs such as the mega161 and mega128
15 //
16 // This code is distributed under the GNU Public License
17 // which can be found at http://www.gnu.org/licenses/gpl.txt
18 //
19 //*****************************************************************************
20  
21 #include <avr/io.h>
22 #include <avr/interrupt.h>
23  
24 #include "buffer.h"
25 #include "uart2.h"
26  
27 // UART global variables
28 // flag variables
29 volatile u08 uartReadyTx[2];
30 volatile u08 uartBufferedTx[2];
31 // receive and transmit buffers
32 cBuffer uartRxBuffer[2];
33 cBuffer uartTxBuffer[2];
34 unsigned short uartRxOverflow[2];
35 #ifndef UART_BUFFER_EXTERNAL_RAM
36 // using internal ram,
37 // automatically allocate space in ram for each buffer
38 static char uart0RxData[UART0_RX_BUFFER_SIZE];
39 static char uart0TxData[UART0_TX_BUFFER_SIZE];
40 static char uart1RxData[UART1_RX_BUFFER_SIZE];
41 static char uart1TxData[UART1_TX_BUFFER_SIZE];
42 #endif
43  
44 typedef void (*voidFuncPtru08)(unsigned char);
45 volatile static voidFuncPtru08 UartRxFunc[2];
46  
47 void uartInit(void)
48 {
49 // initialize both uarts
50 uart0Init();
51 uart1Init();
52 }
53  
54 void uart0Init(void)
55 {
56 // initialize the buffers
57 uart0InitBuffers();
58 // initialize user receive handlers
59 UartRxFunc[0] = 0;
60 // enable RxD/TxD and interrupts
61 outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
62 // set default baud rate
63 uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE);
64 // initialize states
65 uartReadyTx[0] = TRUE;
66 uartBufferedTx[0] = FALSE;
67 // clear overflow count
68 uartRxOverflow[0] = 0;
69 // enable interrupts
70 sei();
71 }
72  
73 void uart1Init(void)
74 {
75 // initialize the buffers
76 uart1InitBuffers();
77 // initialize user receive handlers
78 UartRxFunc[1] = 0;
79 // enable RxD/TxD and interrupts
80 outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
81 // set default baud rate
82 uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE);
83 // initialize states
84 uartReadyTx[1] = TRUE;
85 uartBufferedTx[1] = FALSE;
86 // clear overflow count
87 uartRxOverflow[1] = 0;
88 // enable interrupts
89 sei();
90 }
91  
92 void uart0InitBuffers(void)
93 {
94 #ifndef UART_BUFFER_EXTERNAL_RAM
95 // initialize the UART0 buffers
96 bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
97 bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
98 #else
99 // initialize the UART0 buffers
100 bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE);
101 bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE);
102 #endif
103 }
104  
105 void uart1InitBuffers(void)
106 {
107 #ifndef UART_BUFFER_EXTERNAL_RAM
108 // initialize the UART1 buffers
109 bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
110 bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
111 #else
112 // initialize the UART1 buffers
113 bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE);
114 bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE);
115 #endif
116 }
117  
118 void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c))
119 {
120 // make sure the uart number is within bounds
121 if(nUart < 2)
122 {
123 // set the receive interrupt to run the supplied user function
124 UartRxFunc[nUart] = rx_func;
125 }
126 }
127  
128 void uartSetBaudRate(u08 nUart, u32 baudrate)
129 {
130 // calculate division factor for requested baud rate, and set it
131 u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
132 if(nUart)
133 {
134 outb(UBRR1L, bauddiv);
135 #ifdef UBRR1H
136 outb(UBRR1H, bauddiv>>8);
137 #endif
138 }
139 else
140 {
141 outb(UBRR0L, bauddiv);
142 #ifdef UBRR0H
143 outb(UBRR0H, bauddiv>>8);
144 #endif
145 }
146 }
147  
148 cBuffer* uartGetRxBuffer(u08 nUart)
149 {
150 // return rx buffer pointer
151 return &uartRxBuffer[nUart];
152 }
153  
154 cBuffer* uartGetTxBuffer(u08 nUart)
155 {
156 // return tx buffer pointer
157 return &uartTxBuffer[nUart];
158 }
159  
160 void uartSendByte(u08 nUart, u08 txData)
161 {
162 // wait for the transmitter to be ready
163 // while(!uartReadyTx[nUart]);
164 // send byte
165 if(nUart)
166 {
167 while(!(UCSR1A & (1<<UDRE)));
168 outb(UDR1, txData);
169 }
170 else
171 {
172 while(!(UCSR0A & (1<<UDRE)));
173 outb(UDR0, txData);
174 }
175 // set ready state to FALSE
176 uartReadyTx[nUart] = FALSE;
177 }
178  
179 void uart0SendByte(u08 data)
180 {
181 // send byte on UART0
182 uartSendByte(0, data);
183 }
184  
185 void uart1SendByte(u08 data)
186 {
187 // send byte on UART1
188 uartSendByte(1, data);
189 }
190  
191 int uart0GetByte(void)
192 {
193 // get single byte from receive buffer (if available)
194 u08 c;
195 if(uartReceiveByte(0,&c))
196 return c;
197 else
198 return -1;
199 }
200  
201 int uart1GetByte(void)
202 {
203 // get single byte from receive buffer (if available)
204 u08 c;
205 if(uartReceiveByte(1,&c))
206 return c;
207 else
208 return -1;
209 }
210  
211  
212 u08 uartReceiveByte(u08 nUart, u08* rxData)
213 {
214 // make sure we have a receive buffer
215 if(uartRxBuffer[nUart].size)
216 {
217 // make sure we have data
218 if(uartRxBuffer[nUart].datalength)
219 {
220 // get byte from beginning of buffer
221 *rxData = bufferGetFromFront(&uartRxBuffer[nUart]);
222 return TRUE;
223 }
224 else
225 return FALSE; // no data
226 }
227 else
228 return FALSE; // no buffer
229 }
230  
231 void uartFlushReceiveBuffer(u08 nUart)
232 {
233 // flush all data from receive buffer
234 bufferFlush(&uartRxBuffer[nUart]);
235 }
236  
237 u08 uartReceiveBufferIsEmpty(u08 nUart)
238 {
239 return (uartRxBuffer[nUart].datalength == 0);
240 }
241  
242 void uartAddToTxBuffer(u08 nUart, u08 data)
243 {
244 // add data byte to the end of the tx buffer
245 bufferAddToEnd(&uartTxBuffer[nUart], data);
246 }
247  
248 void uart0AddToTxBuffer(u08 data)
249 {
250 uartAddToTxBuffer(0,data);
251 }
252  
253 void uart1AddToTxBuffer(u08 data)
254 {
255 uartAddToTxBuffer(1,data);
256 }
257  
258 void uartSendTxBuffer(u08 nUart)
259 {
260 // turn on buffered transmit
261 uartBufferedTx[nUart] = TRUE;
262 // send the first byte to get things going by interrupts
263 uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart]));
264 }
265  
266 u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes)
267 {
268 register u08 first;
269 register u16 i;
270  
271 // check if there's space (and that we have any bytes to send at all)
272 if((uartTxBuffer[nUart].datalength + nBytes < uartTxBuffer[nUart].size) && nBytes)
273 {
274 // grab first character
275 first = *buffer++;
276 // copy user buffer to uart transmit buffer
277 for(i = 0; i < nBytes-1; i++)
278 {
279 // put data bytes at end of buffer
280 bufferAddToEnd(&uartTxBuffer[nUart], *buffer++);
281 }
282  
283 // send the first byte to get things going by interrupts
284 uartBufferedTx[nUart] = TRUE;
285 uartSendByte(nUart, first);
286 // return success
287 return TRUE;
288 }
289 else
290 {
291 // return failure
292 return FALSE;
293 }
294 }
295  
296 // UART Transmit Complete Interrupt Function
297 void uartTransmitService(u08 nUart)
298 {
299 // check if buffered tx is enabled
300 if(uartBufferedTx[nUart])
301 {
302 // check if there's data left in the buffer
303 if(uartTxBuffer[nUart].datalength)
304 {
305 // send byte from top of buffer
306 if(nUart)
307 outb(UDR1, bufferGetFromFront(&uartTxBuffer[1]) );
308 else
309 outb(UDR0, bufferGetFromFront(&uartTxBuffer[0]) );
310 }
311 else
312 {
313 // no data left
314 uartBufferedTx[nUart] = FALSE;
315 // return to ready state
316 uartReadyTx[nUart] = TRUE;
317 }
318 }
319 else
320 {
321 // we're using single-byte tx mode
322 // indicate transmit complete, back to ready
323 uartReadyTx[nUart] = TRUE;
324 }
325 }
326  
327 // UART Receive Complete Interrupt Function
328 void uartReceiveService(u08 nUart)
329 {
330 u08 c;
331 // get received char
332 if(nUart)
333 c = inb(UDR1);
334 else
335 c = inb(UDR0);
336  
337 // if there's a user function to handle this receive event
338 if(UartRxFunc[nUart])
339 {
340 // call it and pass the received data
341 UartRxFunc[nUart](c);
342 }
343 else
344 {
345 // otherwise do default processing
346 // put received char in buffer
347 // check if there's space
348 if( !bufferAddToEnd(&uartRxBuffer[nUart], c) )
349 {
350 // no space in buffer
351 // count overflow
352 uartRxOverflow[nUart]++;
353 }
354 }
355 }
356  
357 UART_INTERRUPT_HANDLER(SIG_UART0_TRANS)
358 {
359 // service UART0 transmit interrupt
360 uartTransmitService(0);
361 }
362  
363 UART_INTERRUPT_HANDLER(SIG_UART1_TRANS)
364 {
365 // service UART1 transmit interrupt
366 uartTransmitService(1);
367 }
368  
369 UART_INTERRUPT_HANDLER(SIG_UART0_RECV)
370 {
371 // service UART0 receive interrupt
372 uartReceiveService(0);
373 }
374  
375 UART_INTERRUPT_HANDLER(SIG_UART1_RECV)
376 {
377 // service UART1 receive interrupt
378 uartReceiveService(1);
379 }