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

# uartintr.c

    00001 /*! \file uartintr.c \brief UART driver for ARM LPC2000 16550 with interrupts. */
    00002 //*****************************************************************************
    00003 //
    00004 // File Name    : 'uartintr.c'
    00005 // Title        : UART driver for ARM LPC2000 16550 with interrupts
    00006 // Author       : Pascal Stang - Copyright (C) 2004-2006
    00007 // Created      : 4/3/2004
    00008 // Revised      : 4/11/2006
    00009 // Version      : 0.1
    00010 // Target MCU   : Philips ARM LPC2000 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 <limits.h>
    00019 #include "LPC2000.h"
    00020
    00021 #include "global.h"
    00022 #include "processor.h"
    00023 #include "buffer.h"
    00024 #include "uartintr.h"
    00025
    00026 // receive and transmit buffers
    00027 cBuffer uartRxBuffer[2];            ///< uart receive buffer
    00028 cBuffer uartTxBuffer[2];            ///< uart transmit buffer
    00029 static unsigned char uart0RxData[UART0_RX_BUFFER_SIZE];
    00030 static unsigned char uart1RxData[UART1_RX_BUFFER_SIZE];
    00031
    00032 //! enable and initialize the uart
    00033 void uart0Init(uint16_t baud, uint8_t mode, uint8_t fifomode)
    00034 {
    00035     // set pin-select register to connect to UART0
    00036     PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
    00037     // reset and initialize the UART
    00038     U0IER = 0;      // disable all interrupt sources
    00039     U0IIR;          // clear any pending interrupts
    00040     U0FCR = (UFCR_TX_FIFO_RESET|UFCR_RX_FIFO_RESET);    // reset the Tx/Rx FIFOs
    00041     // set the baudrate divisor
    00042     U0LCR = ULCR_DLAB_ENABLE;   // set divisor access bit (permits modification of divisors)
    00043     U0DLL = (baud);             // set the baud division
    00044     U0DLM = (baud>>8);
    00045     U0LCR = 0;                  // reset DLAB (normal operation)
    00046     // set line parameters and fifo mode
    00047     U0LCR = mode;
    00048     U0FCR = fifomode;
    00049     // with uart configured, clear line status and receive registers
    00050     U0RBR; U0LSR;
    00051     // initialize buffers
    00052     uart0InitBuffers();
    00053     // attach interrupt handler
    00054     processorVicAttach(VIC_UART0, 0, uart0Service);
    00055     // enable receive interrupt
    00056     U0IER |= UIER_ERBFI;
    00057 }
    00058
    00059 void uart1Init(uint16_t baud, uint8_t mode, uint8_t fifomode)
    00060 {
    00061     // set pin-select register to connect to UART1
    00062     PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
    00063     // reset and initialize the UART
    00064     U1IER = 0;      // disable all interrupt sources
    00065     U1IIR;          // clear any pending interrupts
    00066     U1FCR = (UFCR_TX_FIFO_RESET|UFCR_RX_FIFO_RESET);    // reset the Tx/Rx FIFOs
    00067     // set the baudrate divisor
    00068     U1LCR = ULCR_DLAB_ENABLE;   // set divisor access bit (permits modification of divisors)
    00069     U1DLL = (baud);             // set the baud division
    00070     U1DLM = (baud>>8);
    00071     U1LCR = 0;                  // reset DLAB (normal operation)
    00072     // set line parameters and fifo mode
    00073     U1LCR = mode;
    00074     U1FCR = fifomode;
    00075     // with uart configured, clear line status and receive registers
    00076     U1RBR; U1LSR;
    00077     // initialize buffers
    00078     uart1InitBuffers();
    00079     // attach interrupt handler
    00080     processorVicAttach(VIC_UART1, 0, uart1Service);
    00081     // enable receive interrupt
    00082     U1IER |= UIER_ERBFI;
    00083 }
    00084
    00085 void uart0InitBuffers(void)
    00086 {
    00087     // initialize the UART0 buffers
    00088     bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
    00089     //bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
    00090 }
    00091
    00092 void uart1InitBuffers(void)
    00093 {
    00094     // initialize the UART1 buffers
    00095     bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
    00096     //bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
    00097 }
    00098
    00099 cBuffer* uart0GetRxBuffer(void)
    00100 {
    00101     // return rx buffer pointer
    00102     return &uartRxBuffer[0];
    00103 }
    00104
    00105 cBuffer* uart1GetRxBuffer(void)
    00106 {
    00107     // return rx buffer pointer
    00108     return &uartRxBuffer[1];
    00109 }
    00110
    00111 int uart0SendByte(int data)
    00112 {
    00113     // wait for tx buffer ready
    00114     while( !(U0LSR & ULSR_THRE) );
    00115     // send the character
    00116     return (U0THR = data);
    00117 }
    00118
    00119 int uart1SendByte(int data)
    00120 {
    00121     // wait for tx buffer ready
    00122     while( !(U1LSR & ULSR_THRE) );
    00123     // send the character
    00124     return (U1THR = data);
    00125 }
    00126
    00127 int uart0GetByte(void)
    00128 {
    00129     // if character is available, return it
    00130     if(uartRxBuffer[0].datalength)
    00131         return bufferGetFromFront(&uartRxBuffer[0]);
    00132     // otherwise, return failure
    00133     return -1;
    00134 }
    00135
    00136 int uart1GetByte(void)
    00137 {
    00138     // if character is available, return it
    00139     if(uartRxBuffer[1].datalength)      // check if character is available
    00140         return bufferGetFromFront(&uartRxBuffer[1]);    // return character
    00141     // otherwise, return failure
    00142     return -1;
    00143 }
    00144
    00145 void uart0Service(void)
    00146 {
    00147     uint8_t intr_flags;
    00148
    00149 //  ISR_ENTRY();
    00150
    00151     // service pending interrupts until the interrupt status register is clear
    00152     while( !((intr_flags=U0IIR) & UIIR_NO_INT) )
    00153     {
    00154         // check the interrupt source
    00155         switch(intr_flags & UIIR_ID_MASK)
    00156         {
    00157         case UIIR_RLS_INT:  // receive line status interrupt
    00158             U0LSR;                  // clear interrupt by reading status
    00159             break;
    00160         case UIIR_CTI_INT:  // character timeout interrupt
    00161         case UIIR_RDA_INT:  // receive data available interrupt
    00162             do { bufferAddToEnd(&uartRxBuffer[1], U0RBR); } while(U0LSR & ULSR_RDR);
    00163             break;
    00164         case UIIR_THRE_INT: // transmit holding register empty
    00165             break;
    00166         default:            // unknown/unhandled interrupt
    00167             U0LSR;                  // read registers to clear
    00168             U0RBR;
    00169             break;
    00170         }
    00171     }
    00172
    00173     VICSoftIntClear = (1<<VIC_UART0);   // clear software interrupt
    00174     VICVectAddr = 0x00000000;           // clear the VIC
    00175 //  ISR_EXIT();
    00176 }
    00177
    00178 void uart1Service(void)
    00179 {
    00180     uint8_t intr_flags;
    00181
    00182 //  ISR_ENTRY();
    00183
    00184     // service pending interrupts until the interrupt status register is clear
    00185     while( !((intr_flags=U1IIR) & UIIR_NO_INT) )
    00186     {
    00187         // check the interrupt source
    00188         switch(intr_flags & UIIR_ID_MASK)
    00189         {
    00190         case UIIR_RLS_INT:  // receive line status interrupt
    00191             U1LSR;                  // clear interrupt by reading status
    00192             break;
    00193         case UIIR_CTI_INT:  // character timeout interrupt
    00194         case UIIR_RDA_INT:  // receive data available interrupt
    00195             do { bufferAddToEnd(&uartRxBuffer[1], U1RBR); } while(U1LSR & ULSR_RDR);
    00196             break;
    00197         case UIIR_THRE_INT: // transmit holding register empty
    00198             break;
    00199         case UIIR_MS_INT:   // MODEM Status
    00200             U1MSR;                  // read MSR to clear
    00201             break;
    00202         default:            // unknown/unhandled interrupt
    00203             U1LSR;                  // read registers to clear
    00204             U1RBR;
    00205             U1MSR;
    00206             break;
    00207         }
    00208     }
    00209
    00210     VICSoftIntClear = (1<<VIC_UART1);   // clear software interrupt
    00211     VICVectAddr = 0x00000000;           // clear the VIC
    00212 //  ISR_EXIT();
    00213 }