Hello,
I'm using LPC 3250 Developer's Kit. I want to study the UART 5 with the TX interrupt enabled. Here is the piece of c code compiled using RVDS and debugged using DSTREAM.
The program is transmitting the characters to hyper terminal but I was expecting the character 'I' to be transmitted when it enters the IRQ ISR. But it didn't.
Need your assistance to generate interrupt in IRQ mode for UART 5 Transmission.
Thank You S GR
#include "lpc32xx_uart.h" #include "lpc32xx_timer.h" #include "lpc32xx_chip.h" /**************************************************************************************** *Function :send_data *Inputs :string *Output :none *Purpose :To print the string on serial port ****************************************************************************************/ void send_data(unsigned char ch) { UartReg.dll_fifo=ch; while(!(UartReg.lsr & 0x20)); } /**************************************************************************************** *Function :send_data *Inputs :string *Output :none *Purpose :To print the string on serial port ****************************************************************************************/ void send_string(volatile unsigned char *str) { while(*str != '\0') { send_data(*str); str++; } } /**************************************************************************************** *Function :receive_data *Inputs :string *Output :none *Purpose :To print the string on serial port ****************************************************************************************/ unsigned char receive_data(void) { unsigned char ch; while(!(UartReg.lsr & 0x01)); ch=UartReg.dll_fifo; return(ch); } /**************************************************************************************** *Function :uart5_MICInit *Inputs : *Output : *Purpose : ****************************************************************************************/ void uart5_MICInit(void) { UartReg.dlm_ier = UART_IER_THRE; // Enable UART Tx Interrupt MIC_APR |= (1<<9); // Activation Polarity (Active High for UART 5) MIC_ATR &= ~(1<<9); // Activation Type (Level 0) MIC_ITR &= ~(1<<9); // Interrupt Type (IRQ = 0) MIC_ER |= (1<<9); // Enable register for UART 5 } int main(void) { uart5_MICInit(); send_string((unsigned char *)"UART5 LPC3250 \n\r"); while(1) { ch = receive_data(); send_data(ch); } return 1; } __irq void IRQ_Handler(void) { send_data('I'); // for uart5 return; }
you're not setting the communication speed.
and you seem to be attempting to send data both in the main loop and the interrupt.
try to think about what you want the processor to do, then write code to achieve it.
Drew Kneel
I understand that LPC 3250's UART5 is already set to 115200bps @ 13 MHz by the Stage 1 loader (S1L). So I didn't set it once again.
I'm able to see the message UART5 LPC3250 in the Hyper terminal when running the program via DSTREAM.
Thx
S GR
In the function uart5_MICInit() I'm trying to enable the UART's Tx interrupt and MIC registers for UART5. I'm expecting the character I to be transmitted to hyper terminal when Interrupt occurs.
Thx S GR
And what else do you think the S1L sets up in the UART? Just as importantly, what is NOT set up by the S1L that needs to be for your use?
It would be sensible to re-initialise the complete UART in your code, then you are guaranteed to have settings as you expect.
The way you're transmitting/receiving data is not optimal for an interrupt (i.e., it loops) and you are trying to call the transmit routine both from the interrupt and the main loop.
I made a few changes.
1. Changed My main() and IRQ ISR as below.
int main(void) { char i; volatile unsigned int *destAddr = (volatile unsigned int *)0x0; volatile unsigned int *srcAddr = (volatile unsigned int *)0x80000000; for(i=0;i<=20;i++) { *destAddr = *srcAddr; destAddr++;srcAddr++; } uart5_MICInit(); send_data('A'); while(1); return 1; } void IRQ_Handler(void)__irq { char ch; ch = UartReg.iir_fcr; send_data('I'); // for uart5 return; }
All other functions remaining the same.
2. My code was loaded at 0x80000000 in the scatter file. So whenever the IRQ occurs PC will be loaded with 0x18 which doesn't had any jumping instruction to branch to IRQ ISR.
3. So I did some stuff in a strange way. i.e, I copied the vector address defines from 0x8000000 - 0x80000050 was copied to 0x0 - 0x50.
_PC_start: 80000000 E59FF018 LDR pc,0x80000020 <VECTORS_S+0x20> 80000004 E59FF018 LDR pc,0x80000024 <VECTORS_S+0x24> 80000008 E59FF018 LDR pc,0x80000028 <VECTORS_S+0x28> 8000000C E59FF018 LDR pc,0x8000002c <VECTORS_S+0x2C> 80000010 E59FF018 LDR pc,0x80000030 <VECTORS_S+0x30> 80000014 E1A00000 MOV r0,r0 80000018 E59FF014 LDR pc,0x80000034 <VECTORS_S+0x34> 8000001C E59FF014 LDR pc,0x80000038 <VECTORS_S+0x38> 80000020 80000304 <Data> 0x04 0x03 0x00 0x80 80000024 8000003C <Data> '<' 0x00 0x00 0x80 80000028 80000040 <Data> '@' 0x00 0x00 0x80 8000002C 80000044 <Data> 'D' 0x00 0x00 0x80 80000030 80000048 <Data> 'H' 0x00 0x00 0x80 80000034 8000004C <Data> 'L' 0x00 0x00 0x80 80000038 80000050 <Data> 'P' 0x00 0x00 0x80 Undefined_Handler: 8000003C EAFFFFFE B Undefined_Handler <0x8000003c> SWI_Handler: 80000040 EAFFFFFE B SWI_Handler <0x80000040> Prefetch_Handler: 80000044 EAFFFFFE B Prefetch_Handler <0x80000044> Abort_Handler: 80000048 EAFFFFFE B Abort_Handler <0x80000048> IRQ_Intrpt_Handler: 8000004C EA00007B B IRQ_Handler <0x80000240> FIQ_Handler: 80000050 EAFFFFFE B FIQ_Handler <0x80000050>
4. So now after copying to 0x0-0x50 when the IRQ occurs the PC is loaded with 0x18, which contains jumping instruction to the IRQ ISR address defined @ 0x8000004c.
5. Now the control is transferred to ISR and the character I is printed continuously to Hyper terminal.
As you can see the UART IIR register is read out to clear the interrupt, I was expecting the character I to be printed only once. But tons of I is being printed. Do you have any explanation for that ?
NB: UART was not re-Initialised !
Thx S GR H
You say that like it's a good thing. It really isn't!
But tons of I is being printed. Do you have any explanation for that ?
Yes, the interrupt is being executed, it clears the cause of the interrupt, but once the loaded 'I' is issued another interrupt will be generated.
Your copy of the vector should not be required. Examine the LPC32x0.S file (specifically RAM_INTVEC).
It's good to see that you're making progress, but I recommend that you stop and think. Then your progress might be more dramatic.
Thanks for the support and the explanations.