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

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     outb(UDR, txData);
00121     // set ready state to FALSE
00122     uartReadyTx = FALSE;
00123 }
00124 
00125 // gets a single byte from the uart receive buffer (getchar-style)
00126 int uartGetByte(void)
00127 {
00128     u08 c;
00129     if(uartReceiveByte(&c))
00130         return c;
00131     else
00132         return -1;
00133 }
00134 
00135 // gets a byte (if available) from the uart receive buffer
00136 u08 uartReceiveByte(u08* rxData)
00137 {
00138     // make sure we have a receive buffer
00139     if(uartRxBuffer.size)
00140     {
00141         // make sure we have data
00142         if(uartRxBuffer.datalength)
00143         {
00144             // get byte from beginning of buffer
00145             *rxData = bufferGetFromFront(&uartRxBuffer);
00146             return TRUE;
00147         }
00148         else
00149         {
00150             // no data
00151             return FALSE;
00152         }
00153     }
00154     else
00155     {
00156         // no buffer
00157         return FALSE;
00158     }
00159 }
00160 
00161 // flush all data out of the receive buffer
00162 void uartFlushReceiveBuffer(void)
00163 {
00164     // flush all data from receive buffer
00165     //bufferFlush(&uartRxBuffer);
00166     // same effect as above
00167     uartRxBuffer.datalength = 0;
00168 }
00169 
00170 // return true if uart receive buffer is empty
00171 u08 uartReceiveBufferIsEmpty(void)
00172 {
00173     if(uartRxBuffer.datalength == 0)
00174     {
00175         return TRUE;
00176     }
00177     else
00178     {
00179         return FALSE;
00180     }
00181 }
00182 
00183 // add byte to end of uart Tx buffer
00184 u08 uartAddToTxBuffer(u08 data)
00185 {
00186     // add data byte to the end of the tx buffer
00187     return bufferAddToEnd(&uartTxBuffer, data);
00188 }
00189 
00190 // start transmission of the current uart Tx buffer contents
00191 void uartSendTxBuffer(void)
00192 {
00193     // turn on buffered transmit
00194     uartBufferedTx = TRUE;
00195     // send the first byte to get things going by interrupts
00196     uartSendByte(bufferGetFromFront(&uartTxBuffer));
00197 }
00198 /*
00199 // transmit nBytes from buffer out the uart
00200 u08 uartSendBuffer(char *buffer, u16 nBytes)
00201 {
00202     register u08 first;
00203     register u16 i;
00204 
00205     // check if there's space (and that we have any bytes to send at all)
00206     if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
00207     {
00208         // grab first character
00209         first = *buffer++;
00210         // copy user buffer to uart transmit buffer
00211         for(i = 0; i < nBytes-1; i++)
00212         {
00213             // put data bytes at end of buffer
00214             bufferAddToEnd(&uartTxBuffer, *buffer++);
00215         }
00216 
00217         // send the first byte to get things going by interrupts
00218         uartBufferedTx = TRUE;
00219         uartSendByte(first);
00220         // return success
00221         return TRUE;
00222     }
00223     else
00224     {
00225         // return failure
00226         return FALSE;
00227     }
00228 }
00229 */
00230 // UART Transmit Complete Interrupt Handler
00231 UART_INTERRUPT_HANDLER(SIG_UART_TRANS)
00232 {
00233     // check if buffered tx is enabled
00234     if(uartBufferedTx)
00235     {
00236         // check if there's data left in the buffer
00237         if(uartTxBuffer.datalength)
00238         {
00239             // send byte from top of buffer
00240             outb(UDR, bufferGetFromFront(&uartTxBuffer));
00241         }
00242         else
00243         {
00244             // no data left
00245             uartBufferedTx = FALSE;
00246             // return to ready state
00247             uartReadyTx = TRUE;
00248         }
00249     }
00250     else
00251     {
00252         // we're using single-byte tx mode
00253         // indicate transmit complete, back to ready
00254         uartReadyTx = TRUE;
00255     }
00256 }
00257 
00258 // UART Receive Complete Interrupt Handler
00259 UART_INTERRUPT_HANDLER(SIG_UART_RECV)
00260 {
00261     u08 c;
00262     
00263     // get received char
00264     c = inb(UDR);
00265 
00266     // if there's a user function to handle this receive event
00267     if(UartRxFunc)
00268     {
00269         // call it and pass the received data
00270         UartRxFunc(c);
00271     }
00272     else
00273     {
00274         // otherwise do default processing
00275         // put received char in buffer
00276         // check if there's space
00277         if( !bufferAddToEnd(&uartRxBuffer, c) )
00278         {
00279             // no space in buffer
00280             // count overflow
00281             uartRxOverflow++;
00282         }
00283     }
00284 }

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