We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I'm using the LPC2129 and Keil Tools. The purpose of the code is to interrupt on the receipt of a single byte of data and assign "data" to its value. The interrupt seems to work however "data" isn't the right value. Please help, Thanks.
#include <stdio.h> /* prototype declarations for I/O functions */ #include <lpc21xx.h> /* LPC21xx definitions */ void U1ISR(void) __irq; //Declare UART1 IRQ ISR int data; int main (void) { PINSEL0 = 0x0005800A; // Enable UART1 U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ U1DLL = 8; /* 115200 Baud Rate @ 15MHz VPB Clock */ U1LCR = 0x03; /* DLAB = 0 */ U1IER = 0x1; //Enable the RDA interrupt VICVectAddr0 = (unsigned long)U1ISR; //Set UART1 ISR Vector Address VICVectCntl0 = 0x20 | 7; //Enable Slot, Set Channel 7 VICIntEnable = 0x80; //Enable Int UART1 blah ... blah ... blah while (1) { yada ... yada ... yada } } void U1ISR(void) __irq { U1IIR |= 0x01; /* Clear Interrupt */ data = U1RBR; VICVectAddr = 0x0; /* return from interrupt */ }
The internal ARM uart is a 16550 right? Reading the 16550 data sheet is says that RBR holds the FIFO result of a 16 byte buffer. I think you need to clear the buffer and zero the counter somewhere. This is done by setting bit1 of FIFO (FCR) Got this from:- www.greenleafsoft.com/.../TI 16550C.pdf page25
Let me know what the eventual fix is I am interested..
I think you are correct about the FCR register. I added the following code, however nothing changed.
U1FCR = 0x07; //Enables and Resets FIFO, 1 byte
I commented out the following line because the register is Read only and the interrupt should be claer by reading the Rx register:
// U1IIR |= 0x01; /* Clear Interrupt */
I'm watching the values in the debugger window. "data" should vary from 0x0 to 0xFF, instead there is sporadic change from 0x30 to 0x37.
Hi, I cut/copied your code and have run it on Keil in the simulator mode. used serial#2 window and looked at Uart1, whatever character I type appears in the U1RBR/THR window correctly. ie. 1 = 0x31, Q=0x51 etc
I have not tried on a target because I have to switch to uart0. I can do it but see if you can get the same simulation to work.
Then I have a request to you. Would you mind looking at my post of today. Download the example and explain to me whats going on. I kept going back to it on and off all day. But I am too inexperienced with C to know what to do. Thanks!
Further, I have just played with your code, it compiles fine in Thumb mode, but throws a link error in ARM mode. Is there something that I have to do in the C code other than just switch the target options between Thumb/Arm ?
Greatly appreciate some help.
#include <stdio.h> /* prototype declarations for I/O functions */ #include <lpc21xx.h> /* LPC21xx definitions */
void U1ISR(void) __irq; //Declare UART1 IRQ ISR
int data;
void main (void)
{ PINSEL0 = 0x0005800A; // Enable UART1 U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ U1DLL = 8; /* 115200 Baud Rate @ 15MHz VPB Clock */ U1LCR = 0x03; /* DLAB = 0 */ U1IER = 0x1; //Enable the RDA interrupt
VICVectAddr0 = (unsigned long)U1ISR; //Set UART1 ISR Vector Address VICVectCntl0 = 0x20 | 7; //Enable Slot, Set Channel 7 VICIntEnable = 0x80; //Enable Int UART1 U1FCR = 0x07; //Enables and Resets FIFO, 1 byte
while (1) { } }
void U1ISR(void) __irq { U1IIR |= 0x01; /* Clear Interrupt */ data = U1RBR; VICVectAddr = 0x0; /* return from interrupt */ }
Thanks. After reading you post and running the code in the simulator, I realized that the test source is sending a string of characters to represent an integer ...
I'm compiling the code in ARM mode and I'm not receiving any errors. I don't think you need any special statements other than the selection you mentioned. However, I recently downloaded an updated version of uVision on another computer and some of the same problems you mentioned in the other post happened. The issue was the projects were using an older startup.s file ...
Thanks, so you confirm that your small code piece can be switched between ARM and Thumb mode using the Flash-Configure, Flash Tools-C tab,-Use Thumb Mode toggle and it compiles in both modes without problems. Is so, I will try a clean install.
I was wondering about your code, initially at (*1*)VicVectAddr0 gets U1ISR, which makes sense. Then at the end of the interupt (*2*) it gets put back to 0x0. and back to U1ISR addr at (*1*) again. Is this the right thing to do I wonder. I would have thought that the ISR vector can be left alone and something else done to reset the interupt for next time. Am I completely wrong or just not understanding what is happening?
(*1*) VICVectAddr0 = (unsigned long)U1ISR; //Set UART1 ISR Vector Address VICVectCntl0 = 0x20 | 7; //Enable Slot, Set Channel 7 VICIntEnable = 0x80; //Enable Int UART1
void U1ISR(void) __irq { U1IIR |= 0x01; /* Clear Interrupt */ data = U1RBR; (*2*) VICVectAddr = 0x0; /* return from interrupt */