Main Page   Modules   Data Structures   File List   Data Fields   Globals  

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-2003
00007 // Created      : 11/20/2000
00008 // Revised      : 06/09/2003
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 the buffers
00051     uartInitBuffers();
00052     // initialize user receive handlers
00053     UartRxFunc[0] = 0;
00054     UartRxFunc[1] = 0;
00055 
00056     // enable RxD/TxD and interrupts
00057     #ifdef UCR
00058         // this line for AT90S8515,8535,ATmega103,etc
00059         outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00060     #endif
00061     #ifdef UCSRB
00062         // this line for the Mega163
00063         outb(UCSRB, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00064     #endif
00065     #ifdef UCSR0B
00066         // this line for the Mega161/128
00067         outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00068         outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00069     #endif
00070 
00071     // set default baud rate
00072     uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE); 
00073     uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE);
00074     // initialize states
00075     uartReadyTx[0] = TRUE;
00076     uartReadyTx[1] = TRUE;
00077     uartBufferedTx[0] = FALSE;
00078     uartBufferedTx[1] = FALSE;
00079     // clear overflow count
00080     uartRxOverflow[0] = 0;
00081     uartRxOverflow[1] = 0;
00082     // enable interrupts
00083     sei();
00084 }
00085 
00086 void uartInitBuffers(void)
00087 {
00088     #ifndef UART_BUFFERS_EXTERNAL_RAM
00089         // initialize the UART0 buffers
00090         bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
00091         bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
00092         // initialize the UART1 buffers
00093         bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
00094         bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
00095     #else
00096         // initialize the UART0 buffers
00097         bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE);
00098         bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE);
00099         // initialize the UART1 buffers
00100         bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE);
00101         bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE);
00102     #endif
00103 }
00104 
00105 void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c))
00106 {
00107     // make sure the uart number is within bounds
00108     if(nUart < 2)
00109     {
00110         // set the receive interrupt to run the supplied user function
00111         UartRxFunc[nUart] = rx_func;
00112     }
00113 }
00114 
00115 void uartSetBaudRate(u08 nUart, u32 baudrate)
00116 {
00117     // calculate division factor for requested baud rate, and set it
00118     u08 baudrateDiv;
00119     baudrateDiv = (u08)((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
00120     if(nUart)
00121         outb(UBRR1L, baudrateDiv);
00122     else
00123         outb(UBRR0L, baudrateDiv);
00124 }
00125 
00126 cBuffer* uartGetRxBuffer(u08 nUart)
00127 {
00128     // return rx buffer pointer
00129     return &uartRxBuffer[nUart];
00130 }
00131 
00132 cBuffer* uartGetTxBuffer(u08 nUart)
00133 {
00134     // return tx buffer pointer
00135     return &uartTxBuffer[nUart];
00136 }
00137 
00138 void uartSendByte(u08 nUart, u08 txData)
00139 {
00140     // wait for the transmitter to be ready
00141     while(!uartReadyTx[nUart]);
00142     // send byte
00143     if(nUart)
00144         outb(UDR1, txData);
00145     else
00146         outb(UDR0, txData);
00147     // set ready state to FALSE
00148     uartReadyTx[nUart] = FALSE;
00149 }
00150 
00151 void uart0SendByte(u08 data)
00152 {
00153     // send byte on UART0
00154     uartSendByte(0, data);
00155 }
00156 
00157 void uart1SendByte(u08 data)
00158 {
00159     // send byte on UART1
00160     uartSendByte(1, data);
00161 }
00162 
00163 u08 uartReceiveByte(u08 nUart, u08* rxData)
00164 {
00165     // make sure we have a receive buffer
00166     if(uartRxBuffer[nUart].size)
00167     {
00168         // make sure we have data
00169         if(uartRxBuffer[nUart].datalength)
00170         {
00171             // get byte from beginning of buffer
00172             *rxData = bufferGetFromFront(&uartRxBuffer[nUart]);
00173             return TRUE;
00174         }
00175         else
00176             return FALSE;           // no data
00177     }
00178     else
00179         return FALSE;               // no buffer
00180 }
00181 
00182 void uartFlushReceiveBuffer(u08 nUart)
00183 {
00184     // flush all data from receive buffer
00185     bufferFlush(&uartRxBuffer[nUart]);
00186 }
00187 
00188 u08 uartReceiveBufferIsEmpty(u08 nUart)
00189 {
00190     return (uartRxBuffer[nUart].datalength == 0);
00191 }
00192 
00193 void uartAddToTxBuffer(u08 nUart, u08 data)
00194 {
00195     // add data byte to the end of the tx buffer
00196     bufferAddToEnd(&uartTxBuffer[nUart], data);
00197 }
00198 
00199 void uart0AddToTxBuffer(u08 data)
00200 {
00201     uartAddToTxBuffer(0,data);
00202 }
00203 
00204 void uart1AddToTxBuffer(u08 data)
00205 {
00206     uartAddToTxBuffer(1,data);
00207 }
00208 
00209 void uartSendTxBuffer(u08 nUart)
00210 {
00211     // turn on buffered transmit
00212     uartBufferedTx[nUart] = TRUE;
00213     // send the first byte to get things going by interrupts
00214     uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart]));
00215 }
00216 
00217 u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes)
00218 {
00219     register u08 first;
00220     register u16 i;
00221 
00222     // check if there's space (and that we have any bytes to send at all)
00223     if((uartTxBuffer[nUart].datalength + nBytes < uartTxBuffer[nUart].size) && nBytes)
00224     {
00225         // grab first character
00226         first = *buffer++;
00227         // copy user buffer to uart transmit buffer
00228         for(i = 0; i < nBytes-1; i++)
00229         {
00230             // put data bytes at end of buffer
00231             bufferAddToEnd(&uartTxBuffer[nUart], *buffer++);
00232         }
00233 
00234         // send the first byte to get things going by interrupts
00235         uartBufferedTx[nUart] = TRUE;
00236         uartSendByte(nUart, first);
00237         // return success
00238         return TRUE;
00239     }
00240     else
00241     {
00242         // return failure
00243         return FALSE;
00244     }
00245 }
00246 
00247 // UART Transmit Complete Interrupt Function
00248 void uartTransmitService(u08 nUart)
00249 {
00250     // check if buffered tx is enabled
00251     if(uartBufferedTx[nUart])
00252     {
00253         // check if there's data left in the buffer
00254         if(uartTxBuffer[nUart].datalength)
00255         {
00256             // send byte from top of buffer
00257             if(nUart)
00258                 outb(UDR1,  bufferGetFromFront(&uartTxBuffer[1]) );
00259             else
00260                 outb(UDR0,  bufferGetFromFront(&uartTxBuffer[0]) );
00261         }
00262         else
00263         {
00264             // no data left
00265             uartBufferedTx[nUart] = FALSE;
00266             // return to ready state
00267             uartReadyTx[nUart] = TRUE;
00268         }
00269     }
00270     else
00271     {
00272         // we're using single-byte tx mode
00273         // indicate transmit complete, back to ready
00274         uartReadyTx[nUart] = TRUE;
00275     }
00276 }
00277 
00278 // UART Receive Complete Interrupt Function
00279 void uartReceiveService(u08 nUart)
00280 {
00281     u08 c;
00282     // get received char
00283     if(nUart)
00284         c = inb(UDR1);
00285     else
00286         c = inb(UDR0);
00287 
00288     // if there's a user function to handle this receive event
00289     if(UartRxFunc[nUart])
00290     {
00291         // call it and pass the received data
00292         UartRxFunc[nUart](c);
00293     }
00294     else
00295     {
00296         // otherwise do default processing
00297         // put received char in buffer
00298         // check if there's space
00299         if( !bufferAddToEnd(&uartRxBuffer[nUart], c) )
00300         {
00301             // no space in buffer
00302             // count overflow
00303             uartRxOverflow[nUart]++;
00304         }
00305     }
00306 }
00307 
00308 UART_INTERRUPT_HANDLER(SIG_UART0_TRANS)      
00309 {
00310     // service UART0 transmit interrupt
00311     uartTransmitService(0);
00312 }
00313 
00314 UART_INTERRUPT_HANDLER(SIG_UART1_TRANS)      
00315 {
00316     // service UART1 transmit interrupt
00317     uartTransmitService(1);
00318 }
00319 
00320 UART_INTERRUPT_HANDLER(SIG_UART0_RECV)      
00321 {
00322     // service UART0 receive interrupt
00323     uartReceiveService(0);
00324 }
00325 
00326 UART_INTERRUPT_HANDLER(SIG_UART1_RECV)      
00327 {
00328     // service UART1 receive interrupt
00329     uartReceiveService(1);
00330 }

Generated on Sun Feb 22 19:12:31 2004 for Procyon AVRlib by doxygen1.3-rc2