Main Page   Compound List   File List   Compound Members   File Members  

uart.c

Go to the documentation of this file.
00001 
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              : 11/01/2001
00009 // Version              : 1.3
00010 // Target MCU   : ATMEL AVR Series
00011 // Editor Tabs  : 3
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 <io.h>
00019 #include <interrupt.h>
00020 #include <sig-avr.h>
00021 
00022 #include "buffer.h"
00023 #include "uart.h"
00024 
00025 // UART global variables
00026 // flag variables
00027 volatile u08   uartReadyTx;
00028 volatile u08   uartBufferedTx;
00029 // receive and transmit buffers
00030 cBuffer uartRxBuffer;
00031 cBuffer uartTxBuffer;
00032 
00033 // UART Transmit Complete Interrupt Function
00034 SIGNAL(SIG_UART_TRANS)      
00035 {
00036         // check if buffered tx is enabled
00037         if(uartBufferedTx)
00038         {
00039                 // check if there's data left in the buffer
00040                 if(uartTxBuffer.datalength)
00041                 {
00042                         // send byte from top of buffer
00043                         outp( bufferGetFromFront(&uartTxBuffer), UDR );
00044                 }
00045                 else
00046                 {
00047                         // no data left
00048                         uartBufferedTx = FALSE;
00049                         // return to ready state
00050                         uartReadyTx = TRUE;
00051                 }
00052         }
00053         else
00054         {
00055                 // we're using single-byte tx mode
00056                 // indicate transmit complete, back to ready
00057                 uartReadyTx = TRUE;
00058         }
00059 }
00060 
00061 // UART Receive Complete Interrupt Function
00062 SIGNAL(SIG_UART_RECV)      
00063 {
00064         // put received char in buffer
00065         // check if there's space
00066         if( !bufferAddToEnd(&uartRxBuffer, inp(UDR)) )
00067         {
00068                 // no space - do something to signal an overflow
00069                 //printfProgStrM("UART RX OVFL");
00070         }
00071 }
00072 
00073 void uartInitBuffers(void)
00074 {
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 }
00080 
00081 void uartSetBaudRate(u16 baudrate)
00082 {
00083         // calculate division factor for requested baud rate, and set it
00084         outp( (u08)((F_CPU+(baudrate*8L))/(baudrate*16L)-1), UBRR);
00085 }
00086 
00087 void uartInit(void)
00088 {
00089         // initialize the buffers
00090         uartInitBuffers();
00091 
00092         // enable RxD/TxD and interrupts
00093         // this line for AT90S8515,8535,ATmega103,etc
00094         //outp(BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN),UCR);
00095         // this line for the Mega163
00096         outp(BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN),UCSRB);
00097 
00098         // set default baud rate
00099         uartSetBaudRate(UART_BAUD_RATE);  
00100         // enable interrupts
00101         sei();
00102         // initialize states
00103         uartReadyTx = TRUE;
00104 }
00105 
00106 cBuffer* uartGetRxBuffer(void)
00107 {
00108         // return rx buffer pointer
00109         return &uartRxBuffer;
00110 }
00111 
00112 cBuffer* uartGetTxBuffer(void)
00113 {
00114         // return tx buffer pointer
00115         return &uartTxBuffer;
00116 }
00117 
00118 void uartSendByte(u08 txData)
00119 {
00120         // wait for the transmitter to be ready
00121         while(!uartReadyTx);
00122         // send byte
00123         outp( txData, UDR );
00124         // set ready state to FALSE
00125         uartReadyTx = FALSE;
00126 }
00127 
00128 u08 uartReceiveByte(u08* rxData)
00129 {
00130         // make sure we have a receive buffer
00131         if(uartRxBuffer.size)
00132         {
00133                 // make sure we have data
00134                 if(uartRxBuffer.datalength)
00135                 {
00136                         // get byte from beginning of buffer
00137                         *rxData = bufferGetFromFront(&uartRxBuffer);
00138                         return TRUE;
00139                 }
00140                 else
00141                 {
00142                         // no data
00143                         return FALSE;
00144                 }
00145         }
00146         else
00147         {
00148                 // no buffer
00149                 return FALSE;
00150         }
00151 }
00152 
00153 void uartFlushReceiveBuffer(void)
00154 {
00155         // flush all data from receive buffer
00156         bufferFlush(&uartRxBuffer);
00157         // same effect as above
00158         // uartRxBuffer.datalength = 0;
00159 }
00160 
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 void uartSendTxBuffer(void)
00174 {
00175         // turn on buffered transmit
00176         uartBufferedTx = TRUE;
00177         // send the first byte to get things going by interrupts
00178         uartSendByte(bufferGetFromFront(&uartTxBuffer));
00179 }
00180 
00181 u08 uartSendBuffer(char *buffer, u16 nBytes)
00182 {
00183         register u08 first;
00184         register u16 i;
00185 
00186         // check if there's space (and that we have any bytes to send at all)
00187         if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
00188         {
00189                 // grab first character
00190                 first = *buffer++;
00191                 // copy user buffer to uart transmit buffer
00192                 for(i = 0; i < nBytes-1; i++)
00193                 {
00194                         // put data bytes at end of buffer
00195                         uartTxBuffer.dataptr[(uartTxBuffer.dataindex + uartTxBuffer.datalength) % uartTxBuffer.size] = *buffer++;
00196                         // increment the length
00197                         uartTxBuffer.datalength++;
00198                 }
00199 
00200                 // send the first byte to get things going by interrupts
00201                 uartBufferedTx = TRUE;
00202                 uartSendByte(first);
00203                 // return success
00204                 return TRUE;
00205         }
00206         else
00207         {
00208                 // return failure
00209                 return FALSE;
00210         }
00211 }

Generated at Fri Oct 25 15:36:38 2002 for avrlib by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001