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 }

Generated on Mon Nov 6 23:36:58 2006 for Procyon ARMlib by  doxygen 1.4.2