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 }