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

uart2.c

Go to the documentation of this file.
00001 /*! \file uart2.c \brief Dual UART driver with buffer support. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'uart2.c'
00005 // Title        : Dual UART driver with buffer support
00006 // Author       : Pascal Stang - Copyright (C) 2000-2004
00007 // Created      : 11/20/2000
00008 // Revised      : 07/04/2004
00009 // Version      : 1.0
00010 // Target MCU   : ATMEL AVR Series
00011 // Editor Tabs  : 4
00012 //
00013 // Description  : This is a UART driver for AVR-series processors with two
00014 //      hardware UARTs such as the mega161 and mega128 
00015 //
00016 // This code is distributed under the GNU Public License
00017 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00018 //
00019 //*****************************************************************************
00020 
00021 #include <avr/io.h>
00022 #include <avr/interrupt.h>
00023 
00024 #include "buffer.h"
00025 #include "uart2.h"
00026 
00027 // UART global variables
00028 // flag variables
00029 volatile u08   uartReadyTx[2];
00030 volatile u08   uartBufferedTx[2];
00031 // receive and transmit buffers
00032 cBuffer uartRxBuffer[2];
00033 cBuffer uartTxBuffer[2];
00034 unsigned short uartRxOverflow[2];
00035 #ifndef UART_BUFFER_EXTERNAL_RAM
00036     // using internal ram,
00037     // automatically allocate space in ram for each buffer
00038     static char uart0RxData[UART0_RX_BUFFER_SIZE];
00039     static char uart0TxData[UART0_TX_BUFFER_SIZE];
00040     static char uart1RxData[UART1_RX_BUFFER_SIZE];
00041     static char uart1TxData[UART1_TX_BUFFER_SIZE];
00042 #endif
00043 
00044 typedef void (*voidFuncPtru08)(unsigned char);
00045 volatile static voidFuncPtru08 UartRxFunc[2];
00046 
00047 void uartInit(void)
00048 {
00049     // initialize both uarts
00050     uart0Init();
00051     uart1Init();
00052 }
00053 
00054 void uart0Init(void)
00055 {
00056     // initialize the buffers
00057     uart0InitBuffers();
00058     // initialize user receive handlers
00059     UartRxFunc[0] = 0;
00060     // enable RxD/TxD and interrupts
00061     outb(UCSR0B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00062     // set default baud rate
00063     uartSetBaudRate(0, UART0_DEFAULT_BAUD_RATE); 
00064     // initialize states
00065     uartReadyTx[0] = TRUE;
00066     uartBufferedTx[0] = FALSE;
00067     // clear overflow count
00068     uartRxOverflow[0] = 0;
00069     // enable interrupts
00070     sei();
00071 }
00072 
00073 void uart1Init(void)
00074 {
00075     // initialize the buffers
00076     uart1InitBuffers();
00077     // initialize user receive handlers
00078     UartRxFunc[1] = 0;
00079     // enable RxD/TxD and interrupts
00080     outb(UCSR1B, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00081     // set default baud rate
00082     uartSetBaudRate(1, UART1_DEFAULT_BAUD_RATE);
00083     // initialize states
00084     uartReadyTx[1] = TRUE;
00085     uartBufferedTx[1] = FALSE;
00086     // clear overflow count
00087     uartRxOverflow[1] = 0;
00088     // enable interrupts
00089     sei();
00090 }
00091 
00092 void uart0InitBuffers(void)
00093 {
00094     #ifndef UART_BUFFER_EXTERNAL_RAM
00095         // initialize the UART0 buffers
00096         bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
00097         bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
00098     #else
00099         // initialize the UART0 buffers
00100         bufferInit(&uartRxBuffer[0], (u08*) UART0_RX_BUFFER_ADDR, UART0_RX_BUFFER_SIZE);
00101         bufferInit(&uartTxBuffer[0], (u08*) UART0_TX_BUFFER_ADDR, UART0_TX_BUFFER_SIZE);
00102     #endif
00103 }
00104 
00105 void uart1InitBuffers(void)
00106 {
00107     #ifndef UART_BUFFER_EXTERNAL_RAM
00108         // initialize the UART1 buffers
00109         bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
00110         bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
00111     #else
00112         // initialize the UART1 buffers
00113         bufferInit(&uartRxBuffer[1], (u08*) UART1_RX_BUFFER_ADDR, UART1_RX_BUFFER_SIZE);
00114         bufferInit(&uartTxBuffer[1], (u08*) UART1_TX_BUFFER_ADDR, UART1_TX_BUFFER_SIZE);
00115     #endif
00116 }
00117 
00118 void uartSetRxHandler(u08 nUart, void (*rx_func)(unsigned char c))
00119 {
00120     // make sure the uart number is within bounds
00121     if(nUart < 2)
00122     {
00123         // set the receive interrupt to run the supplied user function
00124         UartRxFunc[nUart] = rx_func;
00125     }
00126 }
00127 
00128 void uartSetBaudRate(u08 nUart, u32 baudrate)
00129 {
00130     // calculate division factor for requested baud rate, and set it
00131     u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
00132     if(nUart)
00133     {
00134         outb(UBRR1L, bauddiv);
00135         #ifdef UBRR1H
00136         outb(UBRR1H, bauddiv>>8);
00137         #endif
00138     }
00139     else
00140     {
00141         outb(UBRR0L, bauddiv);
00142         #ifdef UBRR0H
00143         outb(UBRR0H, bauddiv>>8);
00144         #endif
00145     }
00146 }
00147 
00148 cBuffer* uartGetRxBuffer(u08 nUart)
00149 {
00150     // return rx buffer pointer
00151     return &uartRxBuffer[nUart];
00152 }
00153 
00154 cBuffer* uartGetTxBuffer(u08 nUart)
00155 {
00156     // return tx buffer pointer
00157     return &uartTxBuffer[nUart];
00158 }
00159 
00160 void uartSendByte(u08 nUart, u08 txData)
00161 {
00162     // wait for the transmitter to be ready
00163 //  while(!uartReadyTx[nUart]);
00164     // send byte
00165     if(nUart)
00166     {
00167         while(!(UCSR1A & (1<<UDRE)));
00168         outb(UDR1, txData);
00169     }
00170     else
00171     {
00172         while(!(UCSR0A & (1<<UDRE)));
00173         outb(UDR0, txData);
00174     }
00175     // set ready state to FALSE
00176     uartReadyTx[nUart] = FALSE;
00177 }
00178 
00179 void uart0SendByte(u08 data)
00180 {
00181     // send byte on UART0
00182     uartSendByte(0, data);
00183 }
00184 
00185 void uart1SendByte(u08 data)
00186 {
00187     // send byte on UART1
00188     uartSendByte(1, data);
00189 }
00190 
00191 int uart0GetByte(void)
00192 {
00193     // get single byte from receive buffer (if available)
00194     u08 c;
00195     if(uartReceiveByte(0,&c))
00196         return c;
00197     else
00198         return -1;
00199 }
00200 
00201 int uart1GetByte(void)
00202 {
00203     // get single byte from receive buffer (if available)
00204     u08 c;
00205     if(uartReceiveByte(1,&c))
00206         return c;
00207     else
00208         return -1;
00209 }
00210 
00211 
00212 u08 uartReceiveByte(u08 nUart, u08* rxData)
00213 {
00214     // make sure we have a receive buffer
00215     if(uartRxBuffer[nUart].size)
00216     {
00217         // make sure we have data
00218         if(uartRxBuffer[nUart].datalength)
00219         {
00220             // get byte from beginning of buffer
00221             *rxData = bufferGetFromFront(&uartRxBuffer[nUart]);
00222             return TRUE;
00223         }
00224         else
00225             return FALSE;           // no data
00226     }
00227     else
00228         return FALSE;               // no buffer
00229 }
00230 
00231 void uartFlushReceiveBuffer(u08 nUart)
00232 {
00233     // flush all data from receive buffer
00234     bufferFlush(&uartRxBuffer[nUart]);
00235 }
00236 
00237 u08 uartReceiveBufferIsEmpty(u08 nUart)
00238 {
00239     return (uartRxBuffer[nUart].datalength == 0);
00240 }
00241 
00242 void uartAddToTxBuffer(u08 nUart, u08 data)
00243 {
00244     // add data byte to the end of the tx buffer
00245     bufferAddToEnd(&uartTxBuffer[nUart], data);
00246 }
00247 
00248 void uart0AddToTxBuffer(u08 data)
00249 {
00250     uartAddToTxBuffer(0,data);
00251 }
00252 
00253 void uart1AddToTxBuffer(u08 data)
00254 {
00255     uartAddToTxBuffer(1,data);
00256 }
00257 
00258 void uartSendTxBuffer(u08 nUart)
00259 {
00260     // turn on buffered transmit
00261     uartBufferedTx[nUart] = TRUE;
00262     // send the first byte to get things going by interrupts
00263     uartSendByte(nUart, bufferGetFromFront(&uartTxBuffer[nUart]));
00264 }
00265 
00266 u08 uartSendBuffer(u08 nUart, char *buffer, u16 nBytes)
00267 {
00268     register u08 first;
00269     register u16 i;
00270 
00271     // check if there's space (and that we have any bytes to send at all)
00272     if((uartTxBuffer[nUart].datalength + nBytes < uartTxBuffer[nUart].size) && nBytes)
00273     {
00274         // grab first character
00275         first = *buffer++;
00276         // copy user buffer to uart transmit buffer
00277         for(i = 0; i < nBytes-1; i++)
00278         {
00279             // put data bytes at end of buffer
00280             bufferAddToEnd(&uartTxBuffer[nUart], *buffer++);
00281         }
00282 
00283         // send the first byte to get things going by interrupts
00284         uartBufferedTx[nUart] = TRUE;
00285         uartSendByte(nUart, first);
00286         // return success
00287         return TRUE;
00288     }
00289     else
00290     {
00291         // return failure
00292         return FALSE;
00293     }
00294 }
00295 
00296 // UART Transmit Complete Interrupt Function
00297 void uartTransmitService(u08 nUart)
00298 {
00299     // check if buffered tx is enabled
00300     if(uartBufferedTx[nUart])
00301     {
00302         // check if there's data left in the buffer
00303         if(uartTxBuffer[nUart].datalength)
00304         {
00305             // send byte from top of buffer
00306             if(nUart)
00307                 outb(UDR1,  bufferGetFromFront(&uartTxBuffer[1]) );
00308             else
00309                 outb(UDR0,  bufferGetFromFront(&uartTxBuffer[0]) );
00310         }
00311         else
00312         {
00313             // no data left
00314             uartBufferedTx[nUart] = FALSE;
00315             // return to ready state
00316             uartReadyTx[nUart] = TRUE;
00317         }
00318     }
00319     else
00320     {
00321         // we're using single-byte tx mode
00322         // indicate transmit complete, back to ready
00323         uartReadyTx[nUart] = TRUE;
00324     }
00325 }
00326 
00327 // UART Receive Complete Interrupt Function
00328 void uartReceiveService(u08 nUart)
00329 {
00330     u08 c;
00331     // get received char
00332     if(nUart)
00333         c = inb(UDR1);
00334     else
00335         c = inb(UDR0);
00336 
00337     // if there's a user function to handle this receive event
00338     if(UartRxFunc[nUart])
00339     {
00340         // call it and pass the received data
00341         UartRxFunc[nUart](c);
00342     }
00343     else
00344     {
00345         // otherwise do default processing
00346         // put received char in buffer
00347         // check if there's space
00348         if( !bufferAddToEnd(&uartRxBuffer[nUart], c) )
00349         {
00350             // no space in buffer
00351             // count overflow
00352             uartRxOverflow[nUart]++;
00353         }
00354     }
00355 }
00356 
00357 UART_INTERRUPT_HANDLER(SIG_UART0_TRANS)      
00358 {
00359     // service UART0 transmit interrupt
00360     uartTransmitService(0);
00361 }
00362 
00363 UART_INTERRUPT_HANDLER(SIG_UART1_TRANS)      
00364 {
00365     // service UART1 transmit interrupt
00366     uartTransmitService(1);
00367 }
00368 
00369 UART_INTERRUPT_HANDLER(SIG_UART0_RECV)      
00370 {
00371     // service UART0 receive interrupt
00372     uartReceiveService(0);
00373 }
00374 
00375 UART_INTERRUPT_HANDLER(SIG_UART1_RECV)      
00376 {
00377     // service UART1 receive interrupt
00378     uartReceiveService(1);
00379 }

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