Keil™, An ARM® Company

Discussion Forum

UART transmitting interrupt handler

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Author
Ankit Thakkar
Posted
4-Oct-2008 05:54
Toolset
ARM
New! UART transmitting interrupt handler

Hello

I am facing a problem in the following code.

code :-

#include "LPC318x.h"
void IRQ_HANDLER(void) __irq
{ PIO_OUTP_SET = 0x7EFFFFFF; PIO_OUTP_SET = 0x7EFFFFFF;
}

int main (void)
{ unsigned int i=0; SYSCLK_CTRL = 0x00000140; HCLKPLL_CTRL = 0x00014024; UARTCLK_CTRL = 0x0F; MIC_ER = 0x000007C0; U5LCR = 0x03; U5CLK = 0x0000020E; UART_CLKMODE = 0x00000550; U5FCR = 0x00; U5IER = 0x07; U3DLL = 27;

while(1) {

U5THR = 0x55; U5THR = 0xAA; }

}

When i enable UART5 interrupt by using MIC_ER interrupt is generated as it should be. But after transmitting the data it jumps to an unusual location
0x000002d4.
But it doesnt go to IRQ handler.
If i don't enable the interrupt using MIC_ER then it executes only while(1) loop.
The main aim of the program is to blink the LED after send data through UART5 as mentioned in the IRQ interrupt handler.

Thank You,

Ankit Thakkar.

Author
Ankit Thakkar
Posted
5-Oct-2008 04:01
Toolset
ARM
New! RE: UART transmitting interrupt handler

hello

I checked again. It was my fault.
It enters into interrupt mode as the interrupt is generated but it doesn't find any interrupt handler at the location. I checked in the map file that IRQ_Handler is assigned an address in the memory map.
As it doesnt find any IRQ handler it goes into ABORT mode.
I need to add IRQ handler at the location assigned to IRQ_Handler in the map file.
But i dont know how to add that IRQ handler.
Let me know if any body familiar with this kind of problem.

Regards,

Ankit thakkar.

Author
Per Westermark
Posted
5-Oct-2008 04:20
Toolset
ARM
New! RE: UART transmitting interrupt handler

I haven't worked with any LPC31xx chips, but the LPC21xx and 23xx chips has special VIC control registers where you assign the pointer to the interrupt handler.

If you just look at example code for your processor, you should find a number of examples where an interrupt handler is defined, and where the interrupt controller is configured to know where the interrupt handler is located. The command "grep" is your friend. If you can't installed a "grep" application on your machine, to quickly google for a Win32 version and install. It helps when you want to quickly scan example code or header files for specific details.

Author
Ankit Thakkar
Posted
6-Oct-2008 03:10
Toolset
ARM
New! RE: UART transmitting interrupt handler

Hello

That is the problem that LPC3180 doesnt have vectored interrupt controller. It has one main interrupt controller and two sub interrupt controllers.
So i have to write down an interrupt handler for IRQ and then in that interrupt handler i have to find that which peripheral has generated interrupt.
And LPC3180 is a new device so there is not much support or sample codes available.
I made following changes in the PHYTEC_LPC3000.s.

IMPORT IRQ_Handler
instead of
IRQ_Handler B IRQ_Handler

And then i defined IRQ_Handler in my application code.
But still it doesnt work.

Regards,

Ankit Thakkar.

Author
Per Westermark
Posted
6-Oct-2008 03:44
Toolset
ARM
New! RE: UART transmitting interrupt handler

A vectored interrupt controller may be cool, but not needed. Your processor still have an interrupt vector table, where you hard-code pointers to interrupt handlers.

You should have something like:

Vectors         LDR     PC,Reset_Addr
                LDR     PC,Undef_Addr
                LDR     PC,SWI_Addr
                LDR     PC,PAbt_Addr
                LDR     PC,DAbt_Addr
                DCD     ||Image$$ER_ROM$$RO$$Length||+\ 
                        ||Image$$RW_RAM1$$RW$$Length||
                LDR     PC,IRQ_Addr
                LDR     PC,FIQ_Addr

Reset_Addr      DCD     Reset_Handler
Undef_Addr      DCD     Undef_Handler
SWI_Addr        DCD     SWI_Handler
PAbt_Addr       DCD     PAbt_Handler
DAbt_Addr       DCD     DAbt_Handler
                DCD     0               ; Reserved Address
IRQ_Addr        DCD     IRQ_Handler
FIQ_Addr        DCD     FIQ_Handler

Undef_Handler   B       Undef_Handler
SWI_Handler     B       SWI_Handler
PAbt_Handler    B       PAbt_Handler
DAbt_Handler    B       DAbt_Handler
IRQ_Handler     B       IRQ_Handler
FIQ_Handler     B       FIQ_Handler

in your startup file.

When you replaced the IRQ_Handler dummy-loop with an import - did you also write an assembler function IRQ_Handler or did you go for a C function with the __irq keyword?

You can set a breakpoint directly in the vector table, to allow you to follow the interrupt all the way from the start.

Author
Ankit Thakkar
Posted
6-Oct-2008 04:12
Toolset
ARM
New! RE: UART transmitting interrupt handler

Yes i wrote IRQ_Handler named function in the code.

I am posting my code and interrupt vector table code in the header file.

Header file code :-

Vectors LDR PC,Reset_Addr LDR PC,Undef_Addr LDR PC,SWI_Addr LDR PC,PAbt_Addr LDR PC,DAbt_Addr ;DCD ||Image$$ER_IROM1$$RO$$Length||+||Image$$RW_IRAM1$$RW$$Length|| DCD 0x4000 ;PHYTEC comment: This hard codes the size ;that the secondary bootloader uses to copy ;binary software to SDRAM.

LDR PC,IRQ_Addr LDR PC,FIQ_Addr

Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler

Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
FIQ_Handler B FIQ_Handler IMPORT IRQ_Handler

My application code :-

void IRQ_Handler(void)
{ MIC_ER &= 0xFFFFFFFC; led_blink(); MIC_ER = 0x00000003;
}

I have defined this kind of IRQ_Handler in my application code.

Now when IRQ is generated it should execute IRQ_Handler function.
But it goes in to ABORT mode.
When i check SPSR in ABORT mode it shows that it had been into IRQ mode before entering into ABORT.

Author
Per Westermark
Posted
6-Oct-2008 06:09
Toolset
ARM
New! RE: UART transmitting interrupt handler

1) Your code does not look like mine. Might you have missed the posting instructions for source code? Visible just above the text box when you write a message.

2) You don't specify that your "interrupt handler" really is an interrupt handler. How will the compiler know to produce the suitable prologue/epiloge code? That was why I mentioned the __irq keyword in my previous post.

Author
Ankit Thakkar
Posted
6-Oct-2008 23:11
Toolset
ARM
New! RE: UART transmitting interrupt handler

Yes.. You are right.. i mentioned __irq keyword now.
But it doesn't jump at the location of handler shown in the map file.
But I am not clear with prologue/epilogue code.
Can you please tell me what is that?
I presume it to be something like that by using it the processor decides where to jump when the interrupt is generated.

Author
Per Westermark
Posted
6-Oct-2008 23:22
Toolset
ARM
New! RE: UART transmitting interrupt handler

Google is your friend:

http://en.wikipedia.org/wiki/Function_prologue

And have you seen if you can single-step all the way from the interrupt vector table?

Author
Ankit Thakkar
Posted
6-Oct-2008 23:35
Toolset
ARM
New! RE: UART transmitting interrupt handler

yeah.. i got abt prologue and epilogue.
i checked in a single step execution.
Eventhough after the generation of interrupt it doesn't jump anywhere in the program and just executes the instructions in the normal sequence.
So i can not jump to any interrupt handler while executing instructions in single step mode.
When i run the code by pressing f5 it handles the interrupt and the processor goes into IRQ mode.
The location it jumps is 0x000001BC. the location mentioned for IRQ routine is 0x800001A0 which is the address of OFFCHIP SRAM.
As i believe the IRQ routine is placed from OFFCHIP SRAM to onchip SRAM for faster execution.
I dont have any clue where IRQ is stored in onchip SRAM.

Author
Per Westermark
Posted
6-Oct-2008 23:49
Toolset
ARM
New! More than single-step

Did you test what happens if you set a breakpoint in the startup file?

Author
Ankit Thakkar
Posted
7-Oct-2008 00:23
Toolset
ARM
New! RE: More than single-step

yeah i placed break points on the vector table points as shown below.

Vectors LDR PC,Reset_Addr LDR PC,Undef_Addr LDR PC,SWI_Addr LDR PC,PAbt_Addr LDR PC,DAbt_Addr ;DCD ||Image$$ER_IROM1$$RO$$Length||+||Image$$RW_IRAM1$$RW$$Length|| DCD 0x4000 ;PHYTEC comment: This hard codes the size ;that the secondary bootloader uses to copy ;binary software to SDRAM.

LDR PC,IRQ_Addr LDR PC,FIQ_Addr

Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler

Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IRQ_Handler B IRQ_Handler
FIQ_Handler B FIQ_Handler

When IRQ is generated and i press F5 it should go to interrupt vector table but PROGRAM counter doesn't go there.

Author
Per Westermark
Posted
7-Oct-2008 00:51
Toolset
ARM
New! RE: More than single-step

You still haven't read the instructions for posting code, which makes any code you post look completely garbled...

Note that the vector table in itself is an array of addresses which may make it impossible to take an interrupt there. You are probably limited to putting breakpoints on the first instruction pointed at by the vector table entries.

Author
Ankit Thakkar
Posted
7-Oct-2008 01:30
Toolset
ARM
New! RE: More than single-step

sorry for bad code posting.
you are right that interrupt vector itself is an array of addresses but when it enters into IRQ mode it loads program counter by the starting address of IRQ routine.
which is LDR instruction.
I have placed breakpoints on that instructions.
So when it enters into IRQ mode it should load PC by IRQ routine starting address.
But it doesn't execute the instruction.
again i m posting the code where i placed the breakpoints in startup file


Vectors         LDR     PC,Reset_Addr
                LDR     PC,Undef_Addr
                LDR     PC,SWI_Addr
                LDR     PC,PAbt_Addr
                LDR     PC,DAbt_Addr
                ;DCD     ||Image$$ER_IROM1$$RO$$Length||+||Image$$RW_IRAM1$$RW$$Length||
                                DCD             0x4000 ;PHYTEC comment: This hard codes the size
                                                           ;that the secondary bootloader uses to copy
                                                           ;binary software to SDRAM.

                LDR     PC,IRQ_Addr
                LDR     PC,FIQ_Addr

And i placed breakpoints when CPSR is changed when it enters into IRQ mode and loads SP.


  Enter IRQ Mode and set its Stack Pointer
                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
                MOV     SP, R0
                SUB     R0, R0, #IRQ_Stack_Size

i have placed breakpoints on all the points as shown in the code. but PC doesn't even enter in that code.

Author
Per Westermark
Posted
7-Oct-2008 02:01
Toolset
ARM
New! RE: More than single-step

Does the address after LDR match the address of your IRQ handler as seen from the map file?

Have you tried to add breakpoints for all the other vectors?

Author
Ankit Thakkar
Posted
7-Oct-2008 02:18
Toolset
ARM
New! RE: More than single-step

HEY
when i place more than two break points in the program and try to run it. it executes code upto first break point but then the execution stops there. it doesnt go ahead by pressing F5. Even it doesnt go ahead if i press F10 or F11. Thats strange.
When i debug step by step using F11 it doesnt execute using F5.
I am doing onchip debugging and ETB module of LPC3180 supports upto two breakpoints at a time only.
So i dont reach on the exact address location where IRQ starting address is located.

Author
Per Westermark
Posted
7-Oct-2008 03:34
Toolset
ARM
New! RE: More than single-step

Much can be done with only two breakpoints.

You may have to run the application multiple times, trying different locations for your breakpoints.

Author
Ankit Thakkar
Posted
7-Oct-2008 04:54
Toolset
ARM
New! RE: More than single-step

hey
i checked that whether my interrupt is routine is called from interrupt handler or not.
Its working. Interrupt handler defined in start up file calls function which i have defined in the source code.
I checked it by manually executing instruction at interrupt handler in startup file.
Now problem remains that when IRQ is generated does Program counter goes to interrupt handler defined in the start up file or not.
I am trying for this.

Author
Ankit Thakkar
Posted
7-Oct-2008 23:28
Toolset
ARM
New! RE: More than single-step

Hello

I run code from external SDRAM.
when IRQ is generated program counter jumps to some location in IRAM. i dont know how data is moved from external SDRAM to IRAM. So i cant come to know where my interrupt vector table is stored in IRAM.

Author
Tamir Michael
Posted
8-Oct-2008 01:23
Toolset
ARM
New! RE: More than single-step

it is exceedingly difficult to understand what's wrong without a clear understanding of HOW your system is organized. how does it boot? what is the logic behind the bootcode? memory available? without minimal topology details - I doubt whether anybody would be in a position to help. give more details in concise, technical language.

Author
Ankit Thakkar
Posted
8-Oct-2008 01:32
Toolset
ARM
New! RE: More than single-step

yeah sure.

My code is in external SDRAM which starts from 0x80000000.
In the starting of my code interrupt vector table is located then all functions are stored.
In my code i defined an IRQ handler function. Which should be called when IRQ is generated.
But When IRQ is generated it goes into onchip IRAM (0x00000000 to 0x00004000) instead of going into IRQ handler function.
I have verified that if program counter goes into interrupt vector table it calls the desired function.
So the problem is that when IRQ is generated why program counter doesnt enter into interrupt vector table.

Author
Tamir Michael
Posted
8-Oct-2008 01:41
Toolset
ARM
New! RE: More than single-step

in case of an IRQ, the processor is supposed to go to 0x18 - which must contain the instruction to just to your function. is that the case?

Author
Tamir Michael
Posted
8-Oct-2008 01:42
Toolset
ARM
New! RE: More than single-step

in meant, of course , "jump to your function"

Author
Ankit Thakkar
Posted
8-Oct-2008 01:46
Toolset
ARM
New! RE: More than single-step

no.
I have stored the whole code in SRAM. And the map file shows the location of IRQ handler function is 0x800001a4.
But it doesnt jump to the location 0x800001a4 when IRQ is generated. LPC3180 doesnt have vectored interrupt controller. It contains one main interrupt controller and two sub interrupt controller.

Author
Jim Hampak
Posted
8-Oct-2008 03:35
Toolset
ARM
New! RE: More than single-step

What happens when you single step past the code? do you get the registers bold in the window?

Author
Ankit Thakkar
Posted
8-Oct-2008 03:52
Toolset
ARM
New! RE: More than single-step

In simple step past memory is updated as it should be.
Even in single step everything goes well but when IRQ is generated program counter doesn't jump on IRQ routine while executing in single step.
keil doesnt offer simulation capabilities for lpc3180 so its a pain to check memory values everytime.

Author
Ankit Thakkar
Posted
11-Oct-2008 22:49
Toolset
ARM
New! RE: More than single-step

Hello

I managed to enter into the interrupt vector table when IRQ is generated.
I mapped IRAM to 0x00000000.
At startup interrupt vectors are located. But It doesn't jump to the desired location.
Instead of that if i execute LDR PC,[PC,#0x0018]
from external SRAM it jumps to the desired location but if i execute this instruction at the remapped location
0x00000018. It doesnt jump to the specific location.
Does anybody have any idea?

Author
Ankit Thakkar
Posted
12-Oct-2008 01:36
Toolset
ARM
New! RE: More than single-step

THANKS GUYS...
I MADE IT WORKING FINALLY..

Author
Tamir Michael
Posted
12-Oct-2008 08:28
Toolset
ARM
New! RE: More than single-step

please, tell us what the problem was?

Next Thread | Thread List | Previous Thread Start a Thread | Settings