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

Generated on Sun Oct 29 03:41:08 2006 for Procyon AVRlib by  doxygen 1.4.2