Main Page   Modules   Data Structures   File List   Data Fields   Globals  

uart.c

Go to the documentation of this file.
00001 /*! \file uart.c \brief UART driver with buffer support. */
00002 // *****************************************************************************
00003 //
00004 // File Name    : 'uart.c'
00005 // Title        : UART driver with buffer support
00006 // Author       : Pascal Stang - Copyright (C) 2000-2002
00007 // Created      : 11/22/2000
00008 // Revised      : 06/09/2003
00009 // Version      : 1.3
00010 // Target MCU   : ATMEL AVR Series
00011 // Editor Tabs  : 4
00012 //
00013 // This code is distributed under the GNU Public License
00014 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00015 //
00016 // *****************************************************************************
00017 
00018 #include <avr/io.h>
00019 #include <avr/interrupt.h>
00020 #include <avr/signal.h>
00021 
00022 #include "buffer.h"
00023 #include "uart.h"
00024 
00025 // UART global variables
00026 // flag variables
00027 volatile u08   uartReadyTx;         ///< uartReadyTx flag
00028 volatile u08   uartBufferedTx;      ///< uartBufferedTx flag
00029 // receive and transmit buffers
00030 cBuffer uartRxBuffer;               ///< uart receive buffer
00031 cBuffer uartTxBuffer;               ///< uart transmit buffer
00032 unsigned short uartRxOverflow;      ///< receive overflow counter
00033 
00034 #ifndef UART_BUFFERS_EXTERNAL_RAM
00035     // using internal ram,
00036     // automatically allocate space in ram for each buffer
00037     static char uartRxData[UART_RX_BUFFER_SIZE];
00038     static char uartTxData[UART_TX_BUFFER_SIZE];
00039 #endif
00040 
00041 typedef void (*voidFuncPtru08)(unsigned char);
00042 volatile static voidFuncPtru08 UartRxFunc;
00043 
00044 //! enable and initialize the uart
00045 void uartInit(void)
00046 {
00047     // initialize the buffers
00048     uartInitBuffers();
00049     // initialize user receive handler
00050     UartRxFunc = 0;
00051 
00052     // enable RxD/TxD and interrupts
00053     outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00054 
00055     // set default baud rate
00056     uartSetBaudRate(UART_DEFAULT_BAUD_RATE);  
00057     // initialize states
00058     uartReadyTx = TRUE;
00059     uartBufferedTx = FALSE;
00060     // clear overflow count
00061     uartRxOverflow = 0;
00062     // enable interrupts
00063     sei();
00064 }
00065 
00066 //! create and initialize the uart transmit and receive buffers
00067 void uartInitBuffers(void)
00068 {
00069     #ifndef UART_BUFFERS_EXTERNAL_RAM
00070         // initialize the UART receive buffer
00071         bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE);
00072         // initialize the UART transmit buffer
00073         bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE);
00074     #else
00075         // initialize the UART receive buffer
00076         bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE);
00077         // initialize the UART transmit buffer
00078         bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE);
00079     #endif
00080 }
00081 
00082 //! redirects received data to a user function
00083 void uartSetRxHandler(void (*rx_func)(unsigned char c))
00084 {
00085     // set the receive interrupt to run the supplied user function
00086     UartRxFunc = rx_func;
00087 }
00088 
00089 //! set the uart baud rate
00090 void uartSetBaudRate(u32 baudrate)
00091 {
00092     // calculate division factor for requested baud rate, and set it
00093     u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
00094     outb(UBRRL, bauddiv);
00095     #ifdef UBRRH
00096     outb(UBRRH, bauddiv>>8);
00097     #endif
00098 }
00099 
00100 //! returns the receive buffer structure 
00101 cBuffer* uartGetRxBuffer(void)
00102 {
00103     // return rx buffer pointer
00104     return &uartRxBuffer;
00105 }
00106 
00107 //! returns the transmit buffer structure 
00108 cBuffer* uartGetTxBuffer(void)
00109 {
00110     // return tx buffer pointer
00111     return &uartTxBuffer;
00112 }
00113 
00114 //! transmits a byte over the uart
00115 void uartSendByte(u08 txData)
00116 {
00117     // wait for the transmitter to be ready
00118     while(!uartReadyTx);
00119     // send byte
00120     outp( txData, UDR );
00121     // set ready state to FALSE
00122     uartReadyTx = FALSE;
00123 }
00124 
00125 //! gets a byte (if available) from the uart receive buffer
00126 u08 uartReceiveByte(u08* rxData)
00127 {
00128     // make sure we have a receive buffer
00129     if(uartRxBuffer.size)
00130     {
00131         // make sure we have data
00132         if(uartRxBuffer.datalength)
00133         {
00134             // get byte from beginning of buffer
00135             *rxData = bufferGetFromFront(&uartRxBuffer);
00136             return TRUE;
00137         }
00138         else
00139         {
00140             // no data
00141             return FALSE;
00142         }
00143     }
00144     else
00145     {
00146         // no buffer
00147         return FALSE;
00148     }
00149 }
00150 
00151 //! flush all data out of the receive buffer
00152 void uartFlushReceiveBuffer(void)
00153 {
00154     // flush all data from receive buffer
00155     //bufferFlush(&uartRxBuffer);
00156     // same effect as above
00157     uartRxBuffer.datalength = 0;
00158 }
00159 
00160 //! return true if uart receive buffer is empty
00161 u08 uartReceiveBufferIsEmpty(void)
00162 {
00163     if(uartRxBuffer.datalength == 0)
00164     {
00165         return TRUE;
00166     }
00167     else
00168     {
00169         return FALSE;
00170     }
00171 }
00172 
00173 //! add byte to end of uart Tx buffer
00174 void uartAddToTxBuffer(u08 data)
00175 {
00176     // add data byte to the end of the tx buffer
00177     bufferAddToEnd(&uartTxBuffer, data);
00178 }
00179 
00180 //! start transmission of the current uart Tx buffer contents
00181 void uartSendTxBuffer(void)
00182 {
00183     // turn on buffered transmit
00184     uartBufferedTx = TRUE;
00185     // send the first byte to get things going by interrupts
00186     uartSendByte(bufferGetFromFront(&uartTxBuffer));
00187 }
00188 /*
00189 //! transmit nBytes from buffer out the uart
00190 u08 uartSendBuffer(char *buffer, u16 nBytes)
00191 {
00192     register u08 first;
00193     register u16 i;
00194 
00195     // check if there's space (and that we have any bytes to send at all)
00196     if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
00197     {
00198         // grab first character
00199         first = *buffer++;
00200         // copy user buffer to uart transmit buffer
00201         for(i = 0; i < nBytes-1; i++)
00202         {
00203             // put data bytes at end of buffer
00204             bufferAddToEnd(&uartTxBuffer, *buffer++);
00205         }
00206 
00207         // send the first byte to get things going by interrupts
00208         uartBufferedTx = TRUE;
00209         uartSendByte(first);
00210         // return success
00211         return TRUE;
00212     }
00213     else
00214     {
00215         // return failure
00216         return FALSE;
00217     }
00218 }
00219 */
00220 //! UART Transmit Complete Interrupt Handler
00221 UART_INTERRUPT_HANDLER(SIG_UART_TRANS)
00222 {
00223     // check if buffered tx is enabled
00224     if(uartBufferedTx)
00225     {
00226         // check if there's data left in the buffer
00227         if(uartTxBuffer.datalength)
00228         {
00229             // send byte from top of buffer
00230             outp( bufferGetFromFront(&uartTxBuffer), UDR );
00231         }
00232         else
00233         {
00234             // no data left
00235             uartBufferedTx = FALSE;
00236             // return to ready state
00237             uartReadyTx = TRUE;
00238         }
00239     }
00240     else
00241     {
00242         // we're using single-byte tx mode
00243         // indicate transmit complete, back to ready
00244         uartReadyTx = TRUE;
00245     }
00246 }
00247 
00248 //! UART Receive Complete Interrupt Handler
00249 UART_INTERRUPT_HANDLER(SIG_UART_RECV)
00250 {
00251     u08 c;
00252     
00253     // get received char
00254     c = inp(UDR);
00255 
00256     // if there's a user function to handle this receive event
00257     if(UartRxFunc)
00258     {
00259         // call it and pass the received data
00260         UartRxFunc(c);
00261     }
00262     else
00263     {
00264         // otherwise do default processing
00265         // put received char in buffer
00266         // check if there's space
00267         if( !bufferAddToEnd(&uartRxBuffer, c) )
00268         {
00269             // no space in buffer
00270             // count overflow
00271             uartRxOverflow++;
00272         }
00273     }
00274 }

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