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 }