Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Trouble With PIT ISR
PostPosted: Tue May 10, 2011 12:27 am 
Offline

Joined: Thu Feb 17, 2011 9:23 am
Posts: 13
I am experiencing some trouble when trying to get an interrupt to fire based on the PIT. The timer seems to be counting correctly, but when it reaches its compare value, instead of branching to the ISR (which i believe was set correctly based on stepping through the code), it jumps away to 0x18 where it appears to execute: b 0x18

I can post the code I've taken from an example if that would be helpful, but thought I'd ask first in case I'm doing something obviously incorrect.


Top
 Profile  
 
 Post subject: Re: Trouble With PIT ISR
PostPosted: Tue May 10, 2011 6:09 am 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
Sounds like your start up code does not contain the IRQ/FIQ code to vector through the AIC

LDR PC,[PC,#-0xF20] ; @ 0x18 (IRQ) Vector From AIC_IVR
LDR PC,[PC,#-0xF20] ; @ 0x1C (FIQ) Vector From AIC_FVR


Top
 Profile  
 
 Post subject: Re: Trouble With PIT ISR
PostPosted: Tue May 10, 2011 5:37 pm 
Offline

Joined: Thu Feb 17, 2011 9:23 am
Posts: 13
Ok, after reading the 'AT91 Assembler Code Startup Sequence for C Code Applications Software' for a while and I think I have a slightly better understanding of whats going on in the lowlevelinit and startup files I am using. It looks like the problem may be stemming from the lowlevelinit file in the following code:
*(uint32_t volatile *)(&__ram_start + 0x00) = LDR_PC_PC;
*(uint32_t volatile *)(&__ram_start + 0x04) = LDR_PC_PC;
*(uint32_t volatile *)(&__ram_start + 0x08) = LDR_PC_PC;
*(uint32_t volatile *)(&__ram_start + 0x0C) = LDR_PC_PC;
*(uint32_t volatile *)(&__ram_start + 0x10) = LDR_PC_PC;
*(uint32_t volatile *)(&__ram_start + 0x14) = MAGIC;
*(uint32_t volatile *)(&__ram_start + 0x18) = LDR_PC_PC;
*(uint32_t volatile *)(&__ram_start + 0x1C) = LDR_PC_PC;
where LDR_PC_PC is defined as:
#define LDR_PC_PC 0xE59FF018U

It looks like last 2 lines are incorrect, but I'm not sure how to reference the instruction properly in C (although I may be entirely wrong altogether). If this is the problem, I'm a little confused on how to fix it... I am still very new to the world of ARM, and not much use with asm. I've attached the startup and lowlevelinit files I am using... maybe you could point me in the right direction.

Sorry if there was a better way to format the above lines of code, and thanks again for the help!


Attachments:
startup.zip [5.83 KiB]
Downloaded 9 times
Top
 Profile  
 
 Post subject: Re: Trouble With PIT ISR
PostPosted: Tue May 10, 2011 5:49 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
Some example of indirecting the main vectors, and vector through the AIC

219 00000000 E59FF018 Vectors LDR PC,Reset_Addr
220 00000004 E59FF018 LDR PC,Undef_Addr
221 00000008 E59FF018 LDR PC,SWI_Addr
222 0000000C E59FF018 LDR PC,PAbt_Addr
223 00000010 E59FF018 LDR PC,DAbt_Addr
224 00000014 E1A00000 NOP ; Reserved Vector
225 00000018 ; LDR PC,IRQ_Addr
226 00000018 E51FFF20 LDR PC,[PC,#-0xF20] ; Vector From AIC_IVR
227 0000001C ; LDR PC,FIQ_Addr
228 0000001C E51FFF20 LDR PC,[PC,#-0xF20] ; Vector From AIC_FVR

230 00000020 00000000 Reset_Addr DCD Reset_Handler
231 00000024 00000000 Undef_Addr DCD Undef_Handler
232 00000028 00000000 SWI_Addr DCD SWI_Handler
233 0000002C 00000000 PAbt_Addr DCD PAbt_Handler
234 00000030 00000000 DAbt_Addr DCD DAbt_Handler

So you want 0xE51FFF20U for 0x18/0x1C vectors, it loads the new program counter from the AIC, and off it will go to your interrupt service routine address.


Top
 Profile  
 
 Post subject: Re: Trouble With PIT ISR
PostPosted: Tue May 10, 2011 9:42 pm 
Offline

Joined: Thu Feb 17, 2011 9:23 am
Posts: 13
Thanks so much for the help, that did lead to a fix of the problem. The correct ISR is now executed under the proper condition... if I have no code in the ISR, it returns back to the main program, however if there is any code to execute in the ISR the program causes a data abort exception. Surely I've done something wrong, hehe. I'm not sure whats causing this, as the LR register contains the address of the next instruction it should have executed in the main loop.


Top
 Profile  
 
 Post subject: Re: Trouble With PIT ISR
PostPosted: Tue May 10, 2011 10:07 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
The ARM7/ARM9 have specific register stacking/preservation requirements under interrupt which aren't identical to your regular C/ABI conventions. Under Keil you'd use a __irq directive for the subroutine so it generates the appropriate prologue/epilog code.

__irq void PIT_Handler (void)
{
// ...
*AT91C_AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;
}


Top
 Profile  
 
 Post subject: Re: Trouble With PIT ISR
PostPosted: Sat May 14, 2011 12:12 am 
Offline

Joined: Thu Feb 17, 2011 9:23 am
Posts: 13
The reason I was getting an exception I believe was because I wasn't setting the AIC_EOICR register. In any event... when I use LDR pc,[PC,#-0xF20] in the vector table for the IRQ address, when I come out of the ISR I noticed the ARM is still in IRQ mode and the I flag has been reset again (CPSR = 0x600000d2). Inside the ISR I can put it back into system mode as it was before (whether or not this is necessary, I'm not entirely sure), however I am unable to clear the I flag again (clearing it has no effect).

Is it customary to manually set this flag each time one exits and ISR?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: