M52223EVB Interrupt Vector Question

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

M52223EVB Interrupt Vector Question

3,409 次查看
BobJohnson
Contributor I
Hello,
 
Sorry if this is an newb question but here goes....
 
I'm using all the standard Code Warrior 6.3 code which came with me M52223 Eval Board. I'm having some trouble getting the interrupt vectors to work. I've enabled interrupts on a few peripherals like the PIT, RTC, and ADC. I can verify that the interrupts are firing, however I added some code to the irq_handler function in Int_handlers.c which never seems to execute. So basically my irq_handler function in Int_handlers.c is never being called.
 
A previous post reccomended I call this function: mcf5xxx_irq_enable (), however that hasn't helped either. I haven't touched the vectors.s file as it seemed all the peripherals I am testing are pointing at irq_handler.
 
Basically I'm wondering if there is some simple step I am missing.
 
Thanks in advance. 
标签 (1)
0 项奖励
回复
3 回复数

1,122 次查看
mccPaul
Contributor I
Hi
 
When an interrupt occurs in the Coldfire architecture, the interrupt controller module works out the vector number that is associated with the interrupt and then it executes the function that the vector points to. It is common practice to point all unused vectors to a default handler that can be used for debugging or other diagnostics.
 
If you want to create a handler for a specific interrupt, you would normally change the vector for that interrupt to point to the handler. ISRs are usually written to be as efficient as possible and as the interrupt module has already determined a vector for you, it is not very good practice to duplicate this effort in software with a big switch statement in a generic handler.
 
If your vector table remains in flash, then you will not be able to change it at run time and you need to set the vector for your interrupt to point at the ISR. This is easily done - just copy the way that the irq_handler does it, you need to add one line and change another in the vectors.s file, assume you are adding my_irq_handler():
 
In vectors.s add:
 
extern _my_irq_handler
 
Change the vector (let's say it is PIT0):
 
vector77:   .long   _my_irq_handler
 
(you need the leading _ because the CodeWarrior compiler decorates all functions with a leading _, but vectors.s is an assembler file.)
 
Now define your function:
 
 
Code:
__interrupt__void timer_handler (void){ MCF_PIT0_PMR |= MCF_PIT_PCSR_PIF;}

 
So now your code will compile, but your ISR will not be called. There are two more steps that you need, one is to configure the peripheral to generate interrupts, and the second is to inform the interrupt module that the interrupt is active and to set a level and priority. I think you are missing out the second step.
 
Here is the source to two functions that I use. The first initialises a PIT and you will see that is calls the second, which enables the interrupt in the interrupt module.
 
Code:
/* FUNCTION: PIT_Timer_Init() * * Initialise and enable a Programmable Interval Timer * * PARAM1: PIT - can be 0, 1, 2 or 3 * * PARAM2: Prescaler value - sets the tick frequency to *     (system clock/2) divided by 2^PCSR * * PARAM3: Modulo counter - sets the mumber of ticks per interrupt * * PARAM4: Interrupt handler * * RETURNS: none */voidPIT_Timer_Init(uint8 timer, uint8 PCSR, uint16 PMR, void (*handler)(void)){ // At 64MHz: // PCSR = 5 gives a tick per uS // PMR = 10000 gives an interrupt every 10ms if (timer < 4) {  uint8 ipl = MCF5282_INTC_ICR_IL(TIMER_NETWORK_LEVEL)     | MCF5282_INTC_ICR_IP(timer);  MCF5282_PIT_PCSR(timer) = 0;  // Set up interrupt handler  mcf5282_interrupt_init(timer + 55, ipl, handler);  // Set modulo count  // (= number of ticks per interrupt)  MCF5282_PIT_PMR(timer) = PMR;  // Tick frequency = (system clock/2) divided by 2^PCSR  MCF5282_PIT_PCSR(timer)  = (uint16)(MCF5282_PIT_PCSR_PRE(PCSR));  // Create and enable 'set and forget' timer  MCF5282_PIT_PCSR(timer) |= MCF5282_PIT_PCSR_OVW         | MCF5282_PIT_PCSR_PIE         | MCF5282_PIT_PCSR_PIF         | MCF5282_PIT_PCSR_RLD         | MCF5282_PIT_PCSR_EN; }}/* FUNCTION: PIT_Timer_Stop() * * Disable timer interrupts for the specified PIT * * PARAM1: PIT - can be 0, 1, 2 or 3 * * RETURNS: none */voidPIT_Timer_Stop(uint8 timer){ if (timer < 4)  MCF5282_PIT_PCSR(timer) &= ~( MCF5282_PIT_PCSR_PIE | MCF5282_PIT_PCSR_EN );}

 
Code:
/* FUNCTION: mcf5282_interrupt_init() * * Initialise an interrupt handler for an interrupt source * for INTC0. If the handler is a NULL pointer, then mask * this interrupt. * * PARAM1: Interrupt source (1..62) * * PARAM2: Interrupt level and priority * * PARAM3: Interrupt handler * * RETURNS: none */voidmcf5282_interrupt_init(uint8 source, uint8 ipl, void (*handler)(void)){ // Only for user defined vectors in INTC0 if ((source > 0) && (source < 63)) {  // Interrupts should be disabled to avoid vector problems  // and to ensure that a spurious interrupt exception can't  // be generated.  uint8 sysint = asm_set_ipl(7);  if (handler)  {   // Set interrupt priority level   MCF5282_INTC0_ICR(source) = (ipl & 0x3F);   // Set vector   mcf5xxx_set_handler(source+64, (ADDRESS)handler);   // Clear mask for this handler   if (source < 32)    MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT(source)          | MCF5282_INTC_IMRL_MASKALL);   else   {    MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_MASKALL);    MCF5282_INTC0_IMRH &= ~(MCF5282_INTC_IMRH_INT(source));   }  }  else  {   // Set vector   mcf5xxx_set_handler(source+64, (ADDRESS)handler);   // Set mask for this handler   if (source < 32)   {    MCF5282_INTC0_IMRL |= MCF5282_INTC_IMRL_INT(source);   }   else   {    MCF5282_INTC0_IMRH |= MCF5282_INTC_IMRH_INT(source);   }  }  // As you were...  asm_set_ipl(sysint); }}/********************************************************************/

 
You also probably need to read the chapter about the interrupt controller module for your CPU (although they are pretty much the same across the board).
 
Paul.
 
Edit>>>
mcf5282_interrupt_init() will also set the vector for you if your vector table is copied to RAM. The other functions called by this code are prety much standard Freescale examples which you will probably find in files in a folder called cpu in your project.

Message Edited by mccp on 2007-03-2311:36 AM

0 项奖励
回复

1,122 次查看
Manju
Contributor I
Hi,
I'm really feel this post is an effective one.

Please will you guide me in MCF5485 external interrupt settings.
I already doing my project with SLT interrupt.But i dunno how to set external interrupt.
Will you tell mesteps to be followed / basic code for external interrupt configuration....
I'm pleased if u did......


Thanks
~MD
0 项奖励
回复

1,122 次查看
flashtoo
Contributor I
Bob,
 
1) I assume you have verified the mcf_5223_vectors.s file to make sure the peripherals you are working with are not pointed to somewhere else.
 
2) Be aware that the default task switcher (tk_switch) resets the interrupt priority to the lowest setting when switching task. Since it resets it to the lowest priority it should not be your problem.
 
3) Make sure you clear the interrupt flag when in your code.
 
4) Make sure there is not some other interrupt of higher priority that is does not give your interrupt time to execute.
 
FlashToo
0 项奖励
回复