I've spent a lot of time trying to get this UART Interrupt to work. Not enough I suppose. What have I missed? This is written for the OLIMEX 2148 compiles and runs under GCC and uses the Phillips std LPC214x.h I hope this will be useful to others who have tried and failed! Thanks for your help! Flee #include "LPC214x.h" #define OSCILLATOR_CLOCK 60000000 #define OVERRUN_ERROR 0x02 #define RECEIVE_RDY 0x01 #define PLOCK 0x400 #define VIC_VECTCNTL_EN (1 << 5) #define VIC_CHANNEL_UART0 6 #define CPSR_IRQ_EN_MASK 0x00000080 /********************************************************** Function declarations **********************************************************/ void Initialize(void); void feed(void); void set_interrupts(void); void initUART0( unsigned int baud ); unsigned char getchUART0( void ); unsigned char putchUART0( unsigned char txChar ); unsigned char getTimedCharUART0( void ); void IRQ_Routine (void) __attribute__ ((interrupt("IRQ"))); void FIQ_Routine (void) __attribute__ ((interrupt("FIQ"))); void SWI_Routine (void) __attribute__ ((interrupt("SWI"))); void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF"))); void UART0_Handler(void) __attribute__ ((interrupt("IRQ"))); /********************************************************** Global Variables **********************************************************/ unsigned char hostInterface; unsigned long baud0; unsigned long baud1; unsigned char TxByte0; unsigned char RxByte0; volatile char dummy; unsigned long status; /********************************************************** MAIN **********************************************************/ int main (void) { hostInterface = 0xFF; baud0 = 9600; TxByte0 = 0x2e; // TxByte for UART 0 int j; // loop counter (stack variable) // Initialize the system Initialize(); // Initialize the PLL U0IER &= 0x0; // disable all Interrupts U0IER : 0xE000C004 VICVectAddr0 = (unsigned long) UART0_Handler; //the address where uart 0 service routine starts VICVectCntl0 = VIC_VECTCNTL_EN | VIC_CHANNEL_UART0; // (0x20? | 6) uart interrupt VICIntEnable = (1 << VIC_CHANNEL_UART0); // (1 << 6) initUART0(baud0); // Init Serial Port1 dummy = U0IIR; // read IrqID - required to get interrupts started status = VICIRQStatus; U0IER |= 0x1; // enable RBR Interrupts set bit 0 for UART0 RBR Interrupts // set io pins for led P0.7 IODIR0|= 0x00000C00; // pin P0.7 is an output, everything else is input after reset IOSET0= 0x00000C00; // led off // endless loop to toggle the leds while (1) { for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000800; for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000400; for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000000; for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000C00; // write and read UART 0 putchUART0(TxByte0); // lets us know the port is functioning } } /**********************************************************/ void Initialize(void) { PLLCFG=0x24; // 60Mhz Setting Multiplier and Divider values feed(); PLLCON=0x1; // Enabling the PLL feed(); while(!(PLLSTAT & PLOCK)) ; // Wait for the PLL to lock to set frequency PLLCON=0x3; // Connect the PLL as the clock source feed(); // Enabling MAM and setting number of clocks used for Flash memory fetch (4 cclks in this case) MAMCR=0x2; MAMTIM=0x4; VPBDIV=0x1; // Setting peripheral Clock (pclk) to System Clock (cclk) } /**************************************************************************/ void feed(void) { PLLFEED=0xAA; PLLFEED=0x55; } void initUART0( unsigned int baud ) { // Divisor has to be redivided if the VPB changes // Also, MultDiv values to correct for errors are not used unsigned int divisor = OSCILLATOR_CLOCK / (baud * 16); //R.M - COMPILES! - had to explicitly include libgcc.a library in makefile // Sets Baud Rate // U0LCR Register [bit7][bit6] [bit5] [bit4] [bit3] [bit2] [bit1][bit0] // DLAB Set Stick Even Par Stop Word Length // Break Parity Par Sel Enable Bits U0LCR = 0x83; // U0CLR = U0CLR | SET_DLAB | SET_PARITY | WORD_LENGTH; // U0DLL Divisor Latch LSB - 8 bit data U0DLL = divisor & 0xFF; // U0DLM Divisor Latch MSB - 8 bit data // unsigned int divisor = OSCILLATOR_CLOCK / (baud * 16); // = 60000000 / (9600 * 16) U0DLM = (divisor >> 8) & 0xFF; U0LCR &= 0x7F; // Clear DLAB Bit U0FCR |= 0x01; // Set the fractional divide PINSEL0 = (PINSEL0 & ~0xF) | 0x05; } //*************************************************************************** unsigned char putchUART0( unsigned char txChar ) { // When U0LSR THRE bit is set, the U0THR is empty and can be written while ( !(U0LSR & 0x20) ); // DLAB in U0LCR must be clear to access this register, this register U0THR = txChar; } //*************************************************************************** unsigned char getchUART0( void ) { //when U0LSR's DR bit is 1, the UART RBR register has valid data //while (U0LSR_bit.DR == 0); //if(U0LSR & RECEIVE_RDY) return U0RBR; //else // return 0x3A; } /* Stubs for various interrupts (may be replaced later) */ /* ---------------- */ void IRQ_Routine (void) { while (1) ; } void FIQ_Routine (void) { while (1) ; } void SWI_Routine (void) { while (1) ; } void UNDEF_Routine (void) { while (1) ; } void UART0_Handler(void) { // we will need to test what the interrupt is.... if we get it working putchUART0(getchUART0()); /* Acknowledge IRQ */ // now clear the interrupt VICVectAddr = 0; } --------------------------------- Yahoo! Mail Bring photos to life! New PhotoMail makes sharing a breeze.
Still trying UART0 Interrupts - almost there
Started by ●February 28, 2006
Reply by ●March 1, 20062006-03-01
Hi , Can you tell me your requirement. I think in all the examples,they clearly explained every thing.If you tell your requirement then i can help you.Because,i didnt gone through your program in depth. But, if you look your program,you done many thing wrong. If you want to write a UART 0 Interrupt program maximum it will come 25 lnes.Please tell your requirement or otherwise go through the example program very clearly. you will get a idea. I've spent a lot of time trying to get this UART Interrupt to work. Not enough I suppose. What have I missed? This is written for the OLIMEX 2148 compiles and runs under GCC and uses the Phillips std LPC214x.h I hope this will be useful to others who have tried and failed! Thanks for your help! Flee #include "LPC214x.h" #define OSCILLATOR_CLOCK 60000000 #define OVERRUN_ERROR 0x02 #define RECEIVE_RDY 0x01 #define PLOCK 0x400 #define VIC_VECTCNTL_EN (1 << 5) #define VIC_CHANNEL_UART0 6 #define CPSR_IRQ_EN_MASK 0x00000080 /********************************************************** Function declarations **********************************************************/ void Initialize(void); void feed(void); void set_interrupts(void); void initUART0( unsigned int baud ); unsigned char getchUART0( void ); unsigned char putchUART0( unsigned char txChar ); unsigned char getTimedCharUART0( void ); void IRQ_Routine (void) __attribute__ ((interrupt("IRQ"))); void FIQ_Routine (void) __attribute__ ((interrupt("FIQ"))); void SWI_Routine (void) __attribute__ ((interrupt("SWI"))); void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF"))); void UART0_Handler(void) __attribute__ ((interrupt("IRQ"))); /********************************************************** Global Variables **********************************************************/ unsigned char hostInterface; unsigned long baud0; unsigned long baud1; unsigned char TxByte0; unsigned char RxByte0; volatile char dummy; unsigned long status; /********************************************************** MAIN **********************************************************/ int main (void) { hostInterface = 0xFF; baud0 = 9600; TxByte0 = 0x2e; // TxByte for UART 0 int j; // loop counter (stack variable) // Initialize the system Initialize(); // Initialize the PLL U0IER &= 0x0; // disable all Interrupts U0IER : 0xE000C004 VICVectAddr0 = (unsigned long) UART0_Handler; //the address where uart 0 service routine starts VICVectCntl0 = VIC_VECTCNTL_EN | VIC_CHANNEL_UART0; // (0x20? | 6) uart interrupt VICIntEnable = (1 << VIC_CHANNEL_UART0); // (1 << 6) initUART0(baud0); // Init Serial Port1 dummy = U0IIR; // read IrqID - required to get interrupts started status = VICIRQStatus; U0IER |= 0x1; // enable RBR Interrupts set bit 0 for UART0 RBR Interrupts // set io pins for led P0.7 IODIR0|= 0x00000C00; // pin P0.7 is an output, everything else is input after reset IOSET0= 0x00000C00; // led off // endless loop to toggle the leds while (1) { for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000800; for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000400; for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000000; for (j = 0; j < 500000; j++ ); IOPIN0= 0x00000C00; // write and read UART 0 putchUART0(TxByte0); // lets us know the port is functioning } } /**********************************************************/ void Initialize(void) { PLLCFG=0x24; // 60Mhz Setting Multiplier and Divider values feed(); PLLCON=0x1; // Enabling the PLL feed(); while(!(PLLSTAT & PLOCK)) ; // Wait for the PLL to lock to set frequency PLLCON=0x3; // Connect the PLL as the clock source feed(); // Enabling MAM and setting number of clocks used for Flash memory fetch (4 cclks in this case) MAMCR=0x2; MAMTIM=0x4; VPBDIV=0x1; // Setting peripheral Clock (pclk) to System Clock (cclk) } /**************************************************************************/ void feed(void) { PLLFEED=0xAA; PLLFEED=0x55; } void initUART0( unsigned int baud ) { // Divisor has to be redivided if the VPB changes // Also, MultDiv values to correct for errors are not used unsigned int divisor = OSCILLATOR_CLOCK / (baud * 16); //R.M - COMPILES! - had to explicitly include libgcc.a library in makefile // Sets Baud Rate // U0LCR Register [bit7][bit6] [bit5] [bit4] [bit3] [bit2] [bit1][bit0] // DLAB Set Stick Even Par Stop Word Length // Break Parity Par Sel Enable Bits U0LCR = 0x83; // U0CLR = U0CLR | SET_DLAB | SET_PARITY | WORD_LENGTH; // U0DLL Divisor Latch LSB - 8 bit data U0DLL = divisor & 0xFF; // U0DLM Divisor Latch MSB - 8 bit data // unsigned int divisor = OSCILLATOR_CLOCK / (baud * 16); // = 60000000 / (9600 * 16) U0DLM = (divisor >> 8) & 0xFF; U0LCR &= 0x7F; // Clear DLAB Bit U0FCR |= 0x01; // Set the fractional divide PINSEL0 = (PINSEL0 & ~0xF) | 0x05; } //*************************************************************************** unsigned char putchUART0( unsigned char txChar ) { // When U0LSR THRE bit is set, the U0THR is empty and can be written while ( !(U0LSR & 0x20) ); // DLAB in U0LCR must be clear to access this register, this register U0THR = txChar; } //*************************************************************************** unsigned char getchUART0( void ) { //when U0LSR's DR bit is 1, the UART RBR register has valid data //while (U0LSR_bit.DR == 0); //if(U0LSR & RECEIVE_RDY) return U0RBR; //else // return 0x3A; } /* Stubs for various interrupts (may be replaced later) */ /* ---------------- */ void IRQ_Routine (void) { while (1) ; } void FIQ_Routine (void) { while (1) ; } void SWI_Routine (void) { while (1) ; } void UNDEF_Routine (void) { while (1) ; } void UART0_Handler(void) { // we will need to test what the interrupt is.... if we get it working putchUART0(getchUART0()); /* Acknowledge IRQ */ // now clear the interrupt VICVectAddr = 0; } --------------------------------- Yahoo! Mail Bring photos to life! New PhotoMail makes sharing a breeze. Yahoo! Groups Links