Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

uart2.c

Go to the documentation of this file.
00001 /*! \file uart2.c \brief Dual UART driver with buffer support. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'uart2.c'
00005 // Title        : Dual UART driver with buffer support
00006 // Author       : Pascal Stang - Copyright (C) 2000-2004
00007 // Created      : 11/20/2000
00008 // Revised      : 07/04/2004
00009 // Version      : 1.0
00010 // Target MCU   : ATMEL AVR Series
00011 // Editor Tabs  : 4
00012 //
00013 // Description  : This is a UART driver for AVR-series processors with two
00014 //      hardware UARTs such as the mega161 and mega128 
00015 //
00016 // This code is distributed under the GNU Public License
00017 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00018 //
00019 //*****************************************************************************
00020 
00021 #include <avr/io.h>
00022 #include <avr/interrupt.h>
00023 #include <avr/signal.h>
00024 
00025 #include "buffer.h"
00026 #include "uart2.h"
00027 
00028 // UART global variables
00029 // flag variables
00030 volatile u08   uartReadyTx[2];
00031 volatile u08   uartBufferedTx[2];
00032 // receive and transmit buffers
00033 cBuffer uartRxBuffer[2];
00034 cBuffer uartTxBuffer[2];
00035 unsigned short uartRxOverflow[2];
00036 #ifndef UART_BUFFERS_EXTERNAL_RAM
00037     // using internal ram,
00038     // automatically allocate space in ram for each buffer
00039     static char uart0RxData[UART0_RX_BUFFER_SIZE];
00040     static char uart0TxData[UART0_TX_BUFFER_SIZE];
00041     static char uart1RxData[UART1_RX_BUFFER_SIZE];
00042     static char uart1TxData[UART1_TX_BUFFER_SIZE];
00043 #endif
00044 
00045 typedef void (*voidFuncPtru08)(unsigned char);
00046 volatile static voidFuncPtru08 UartRxFunc[2];
00047 
00048 void uartInit(void)
00049 {
00050     // initialize both uarts
00051     uart0Init();
00052     uart1Init();
00053 }
00054 
00055 void uart0Init(void)
00056 {
00057     // initialize the buffers
00058     uart0InitBuffers();
00059     // initialize user receive handlers
00060     UartRxFunc[0] = 0;
00061     // enable RxD/TxD and interrupts
00062     outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00063     // set default baud rate
00064     uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE); 
00065     // initialize states
00066     uartReadyTx[0] = TRUE;
00067     uartBufferedTx[0] = FALSE;
00068     // clear overflow count
00069     uartRxOverflow[0] = 0;
00070     // enable interrupts
00071     sei();
00072 }
00073 
00074 void uart1Init(void)
00075 {
00076     // initialize the buffers
00077     uart1InitBuffers();
00078     // initialize user receive handlers
00079     UartRxFunc[1] = 0;
00080     // enable RxD/TxD and interrupts
00081     outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00082     // set default baud rate
00083     uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE);
00084     // initialize states
00085     uartReadyTx[1] = TRUE;
00086     uartBufferedTx[1] = FALSE;
00087     // clear overflow count
00088     uartRxOverflow[1] = 0;
00089     // enable interrupts
00090     sei();
00091 }
00092 
00093 void uart0InitBuffers(void)
00094 {
00095     #ifndef UART_BUFFERS_EXTERNAL_RAM
00096         // initialize the UART0 buffers
00097         bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
00098         bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
00099     #else
00100         // initialize the UART0 buffers
00101         bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE);
00102         bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE);
00103     #endif
00104 }
00105 
00106 void uart1InitBuffers(void)
00107 {
00108     #ifndef UART_BUFFERS_EXTERNAL_RAM
00109         // initialize the UART1 buffers
00110         bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
00111         bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
00112     #else
00113         // initialize the UART1 buffers
00114         bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE);
00115         bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE);
00116     #endif
00117 }
00118 
00119 void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c))
00120 {
00121     // make sure the uart number is within bounds
00122     if(nUart < 2)
00123     {
00124         // set the receive interrupt to run the supplied user function
00125         UartRxFunc[nUart] = rx_func;
00126     }
00127 }
00128 
00129 void uartSetBaudRate(u08 nUart, u32 baudrate)
00130 {
00131     // calculate division factor for requested baud rate, and set it
00132     u08 baudrateDiv;
00133     baudrateDiv = (u08)((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
00134     if(nUart)
00135         outb(UBRR1L, baudrateDiv);
00136     else
00137         outb(UBRR0L, baudrateDiv);
00138 }
00139 
00140 cBuffer* uartGetRxBuffer(u08 nUart)
00141 {
00142     // return rx buffer pointer
00143     return &uartRxBuffer[nUart];
00144 }
00145 
00146 cBuffer* uartGetTxBuffer(u08 nUart)
00147 {
00148     // return tx buffer pointer
00149     return &uartTxBuffer[nUart];
00150 }
00151 
00152 void uartSendByte(u08 nUart, u08 txData)
00153 {
00154     // wait for the transmitter to be ready
00155 //  while(!uartReadyTx[nUart]);
00156     // send byte
00157     if(nUart)
00158     {
00159         while(!(UCSR1A & (1<<UDRE)));
00160         outb(UDR1, txData);
00161     }
00162     else
00163     {
00164         while(!(UCSR0A & (1<<UDRE)));
00165         outb(UDR0, txData);
00166     }
00167     // set ready state to FALSE
00168     uartReadyTx[nUart] = FALSE;
00169 }
00170 
00171 void uart0SendByte(u08 data)
00172 {
00173     // send byte on UART0
00174     uartSendByte(0, data);
00175 }
00176 
00177 void uart1SendByte(u08 data)
00178 {
00179     // send byte on UART1
00180     uartSendByte(1, data);
00181 }
00182 
00183 int uart0GetByte(void)
00184 {
00185     // get single byte from receive buffer (if available)
00186     u08 c;
00187     if(uartReceiveByte(0,&c))
00188         return c;
00189     else
00190         return -1;
00191 }
00192 
00193 int uart1GetByte(void)
00194 {
00195     // get single byte from receive buffer (if available)
00196     u08 c;
00197     if(uartReceiveByte(1,&c))
00198         return c;
00199     else
00200         return -1;
00201 }
00202 
00203 
00204 u08 uartReceiveByte(u08 nUart, u08* rxData)
00205 {
00206     // make sure we have a receive buffer
00207     if(uartRxBuffer[nUart].size)
00208     {
00209         // make sure we have data
00210         if(uartRxBuffer[nUart].datalength)
00211         {
00212             // get byte from beginning of buffer
00213             *rxData = bufferGetFromFront(&uartRxBuffer[nUart]);
00214             return TRUE;
00215         }
00216         else
00217             return FALSE;           // no data
00218     }
00219     else
00220         return FALSE;               // no buffer
00221 }
00222 
00223 void uartFlushReceiveBuffer(u08 nUart)
00224 {
00225     // flush all data from receive buffer
00226     bufferFlush(&uartRxBuffer[nUart]);
00227 }
00228 
00229 u08 uartReceiveBufferIsEmpty(u08 nUart)
00230 {
00231     return (uartRxBuffer[nUart].datalength == 0);
00232 }
00233 
00234 void uartAddToTxBuffer(u08 nUart, u08 data)
00235 {
00236     // add data byte to the end of the tx buffer
00237     bufferAddToEnd(&uartTxBuffer[nUart], data);
00238 }
00239 
00240 void uart0AddToTxBuffer(u08 data)
00241 {
00242     uartAddToTxBuffer(0,data);
00243 }
00244 
00245 void uart1AddToTxBuffer(u08 data)
00246 {
00247     uartAddToTxBuffer(1,data);
00248 }
00249 
00250 void uartSendTxBuffer(u08 nUart)
00251 {
00252     // turn on buffered transmit
00253     uartBufferedTx[nUart] = TRUE;
00254     // send the first byte to get things going by interrupts
00255     uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart]));
00256 }
00257 
00258 u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes)
00259 {
00260     register u08 first;
00261     register u16 i;
00262 
00263     // check if there's space (and that we have any bytes to send at all)
00264     if((uartTxBuffer[nUart].datalength + nBytes < uartTxBuffer[nUart].size) && nBytes)
00265     {
00266         // grab first character
00267         first = *buffer++;
00268         // copy user buffer to uart transmit buffer
00269         for(i = 0; i < nBytes-1; i++)
00270         {
00271             // put data bytes at end of buffer
00272             bufferAddToEnd(&uartTxBuffer[nUart], *buffer++);
00273         }
00274 
00275         // send the first byte to get things going by interrupts
00276         uartBufferedTx[nUart] = TRUE;
00277         uartSendByte(nUart, first);
00278         // return success
00279         return TRUE;
00280     }
00281     else
00282     {
00283         // return failure
00284         return FALSE;
00285     }
00286 }
00287 
00288 // UART Transmit Complete Interrupt Function
00289 void uartTransmitService(u08 nUart)
00290 {
00291     // check if buffered tx is enabled
00292     if(uartBufferedTx[nUart])
00293     {
00294         // check if there's data left in the buffer
00295         if(uartTxBuffer[nUart].datalength)
00296         {
00297             // send byte from top of buffer
00298             if(nUart)
00299                 outb(UDR1,  bufferGetFromFront(&uartTxBuffer[1]) );
00300             else
00301                 outb(UDR0,  bufferGetFromFront(&uartTxBuffer[0]) );
00302         }
00303         else
00304         {
00305             // no data left
00306             uartBufferedTx[nUart] = FALSE;
00307             // return to ready state
00308             uartReadyTx[nUart] = TRUE;
00309         }
00310     }
00311     else
00312     {
00313         // we're using single-byte tx mode
00314         // indicate transmit complete, back to ready
00315         uartReadyTx[nUart] = TRUE;
00316     }
00317 }
00318 
00319 // UART Receive Complete Interrupt Function
00320 void uartReceiveService(u08 nUart)
00321 {
00322     u08 c;
00323     // get received char
00324     if(nUart)
00325         c = inb(UDR1);
00326     else
00327         c = inb(UDR0);
00328 
00329     // if there's a user function to handle this receive event
00330     if(UartRxFunc[nUart])
00331     {
00332         // call it and pass the received data
00333         UartRxFunc[nUart](c);
00334     }
00335     else
00336     {
00337         // otherwise do default processing
00338         // put received char in buffer
00339         // check if there's space
00340         if( !bufferAddToEnd(&uartRxBuffer[nUart], c) )
00341         {
00342             // no space in buffer
00343             // count overflow
00344             uartRxOverflow[nUart]++;
00345         }
00346     }
00347 }
00348 
00349 UART_INTERRUPT_HANDLER(SIG_UART0_TRANS)      
00350 {
00351     // service UART0 transmit interrupt
00352     uartTransmitService(0);
00353 }
00354 
00355 UART_INTERRUPT_HANDLER(SIG_UART1_TRANS)      
00356 {
00357     // service UART1 transmit interrupt
00358     uartTransmitService(1);
00359 }
00360 
00361 UART_INTERRUPT_HANDLER(SIG_UART0_RECV)      
00362 {
00363     // service UART0 receive interrupt
00364     uartReceiveService(0);
00365 }
00366 
00367 UART_INTERRUPT_HANDLER(SIG_UART1_RECV)      
00368 {
00369     // service UART1 receive interrupt
00370     uartReceiveService(1);
00371 }

Generated on Tue Sep 20 03:11:43 2005 for Procyon AVRlib by  doxygen 1.4.2