IRQ1 stops occuring due to IRQ7

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IRQ1 stops occuring due to IRQ7

5,336 Views
sowmya
Contributor II
Hi,
 
I am using two edge port interrupts in my design - IRQ7 and IRQ1. The issue I am facing is, when my system is running, my IRQ1 works fine for some time but later on, it stops occuring. The reason is possibly that, I get an IRQ1 interrupt while my IRQ7 is processing and I do not service it and hence, my IRQ1 never occurs again. Am I right in my understanding? How do I fix this issue?
 
Thanks very much.
Labels (1)
0 Kudos
Reply
16 Replies

2,272 Views
suddenlygeek
Contributor I
Hi,
Is it ok to miss servicing the IRQ1 interrupt while IRQ7 is there? If yes, then one solution could be to clear the IRQ1 interrupt flag at the end of the ISR routine of IRQ7; so that at least the subsequent IRQ1 interrupts keep coming.

Kunal.

0 Kudos
Reply

2,272 Views
sowmya
Contributor II
Hi,
 
Thanks. I get your point. But I do not want to miss processing this interrupt. What should I do in such a case?
0 Kudos
Reply

2,272 Views
mjbcswitzerland
Specialist V
Hi

The edge port interrupts are independent from each other and so they shouldn't disturb each other in any way. The only way to miss an interrupt is it is if it is cleared before it is serviced.

Check how you are clearing the interrupts (verify that one IRQ doesn't incorrectly clear another)?

Eg.

static __interrupt__ void _irq1_handler(void)

    EPFR0 = 0x02;                                                        // clear interrupt flag
    ... IRQ 1 handler code
}

static __interrupt__ void _irq7_handler(void)

    EPFR0 = 0x80;                                                        // clear interrupt flag
    ... IRQ 7 handler code
}


Check also that the IRQ levels are set differently (eg. IRQ1 to level 1, IRQ7 to level 3). Their priorities are fixed (at Midpoint priority) but the rule is never to set two interrupts in the system with the same level and priority - otherwise undetermined operation could result.

By default IRQ routines disable further interrupts. If an IRQ is however given level 7 it will become a non-maskable interrupt and so be able to interrupt another interrupt in progress - this can lead to unexpected results of it is not considered.

See the following for details about the IRQ handling behaviour in respect to interrupt mask level, and also how to control it using CodeWarrior:
http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=2021


Regards

Mark

www.uTasker.com


0 Kudos
Reply

2,272 Views
taigbr
Contributor I
Hi Mark,

there is a nice table explaining level and priority in the 5275 manual addendum:
http://www.freescale.com/files/32bit/doc/ref_manual/MCF5275RMAD.pdf?fpsp=1
But it is also written in the 52235 ref man.
Of course an int with a higher level will interrupt one of a lower one
if one doesn't inhibit it.
Regards, Georg

0 Kudos
Reply

2,272 Views
suddenlygeek
Contributor I

Hi,
Mark's explanation is absolutely fine.
But I have a slightly off track issue regarding the IRQ levels that comes up from his reply. The reference manual says that : "The level and priority is fully programmable for all sources except interrupt sources 1–7. Interrupt source 1–7 (from the Edge Port module) are fixed at the corresponding level’s midpoint priority." Does this not mean IRQ1 is at level 1 and IRQ7 at level 7 ??

Kunal.

0 Kudos
Reply

2,272 Views
mjbcswitzerland
Specialist V
Kunal

The details about the fixed priorities / levels were never absolutely clear for from the manual - (although I have to admit that the if it is read with emphasis on the "level's" ) it is probably exact.

I just did a test since I have to admit that I was also not absolutely sure (I tested on the M52211 but I think that there will be no difference to any others). While testing I found that my interface routine previously supported setting a level but I had removed this about a year ago (presumably I was convinced then that the levels are fixed and can not be changed).

These are my findings:
1. The ICR control registers (ICR1..ICR7) in interrupt controller 0 are initialised at reset with the values 0x08, 0x10, 0x18...0x38 (LEVEL1..LEVEL7), priority reads back 0 but this is also expained in the manual that this reads 000b, although it is fixed at midpoint priority. The manual doesn't inform about the initialisation values (actually they are probably not initilised at reset but are fixed, but this is effectively the same).

2. The debugger doesn't let you change these values.

3. The program also can not change these values - these 7 registers are therefore read only! There is no access error when trying to writethem though.

4. When the interrupts arrive, the SR is set with the interrupt level mask according to the initialised values (IRQ1 = 1, ...IRQ7 = 7).

Therefore my remark about being able to set the level is wrong. They are really pre-defined and fixed (level and priority).

Note that some devices have 15 edge ports. I believe that the IRQ8..IRQ15 can be assigned any level and priority.

Regards

Mark




Message Edited by mjbcswitzerland on 2008-09-17 03:23 PM
0 Kudos
Reply

2,272 Views
suddenlygeek
Contributor I

Hi Mark,
Thanks for looking into the matter so deeply and reasserting what the manual says in an obscure way. Just wondering though that why can't the manual/docs be more specific and clear on so many issues?

Kunal.
0 Kudos
Reply

2,272 Views
JRBurke
Contributor I
Hi - I'm having the same troubles with interrupts 1-7 and I was hoping that you could clear something up for me.

I understand that interrupts 1-7 are fixed in level and priority, but does that mean that you cannot effectively manage them at the same time?

For example, if IRQ1 has been started, but IRQ7 interrupts it, will it ignore the rest of the routine for IRQ1?

Is there any way to avoid IRQ1 being "missed" because IRQ7 has taken place?

In other words, does the fact that the SR register is given a higher value when IRQ7 takes place mean that IRQ1 is completely disabled? In this case, is IRQ1 disabled or just delayed?
0 Kudos
Reply

2,272 Views
mjbcswitzerland
Specialist V
Hi

Nested interrupts operate much the same way as a single interrupt when normal code is running. The interrupt will interrupt the normal code to perform its handling routine and then the control returns to the point of normal code which was interrupted.

A nested interrupt simply interrupts another interrupt routine in progress and after its handler has completed the original interrupt routine continues from the point that it was interrupted.

Therefore lower priority interrupts should never be missed, only delayed due to a higher priority one pending before it started or due to temporary interruption during handling.

Regards

Mark

www.uTasker.com



0 Kudos
Reply

2,272 Views
JRBurke
Contributor I
Thanks for the help. Unfortunately, I'm really not seeing this behavior in practice. In other words, it appears that the interrupt never returns to the previously started interrupt.

Is there anyway to prevent a IRQ7 from interrupting IRQ1? Is it safe to set the SR level using asm code within the IRQ1 interrupt?

Also, I'm using code warrior to compile c code. (Code Warrior version 7) is it possible that the code is being compiled such that it won't return properly to the previous interrupt?


0 Kudos
Reply

2,272 Views
JRBurke
Contributor I

If I go into an interrupt routine, say IRQ6. If immediately after that I receive a request for IRQ5, is the request for IRQ5 lost?

I'm trying to determine why I seem to be "missing" interrupts on IRQ1-7.http://forums.freescale.com/post?board.id=CFCOMM&message.reply_to_id=5445#" rel="nofollow" target="_...
0 Kudos
Reply

2,272 Views
mjbcswitzerland
Specialist V
Hi

It is not possible to stop IRQ7 from interrupting an IRQ1..IRQ6 routine since it has NMI status (except if it is masked in the edge port module or interrupt controller).

It is possible to change the interrupt mask in the SR in an interrupt routine (CW changes it to 7 by default - all IRQs lower than level 7 are thus  automatically masked).

I would suggest trying to debug (and study the assembler code) by causing an IRQ1..6 interrupt which then hangs in its interrupt routine (eg. forever loop). Then generate an IRQ7 with a break point in its handler. Step out of the routine (in assembler mode) to see what happens. It must return to the forever loop in the first interrupt routine....

Regards

Mark

www.uTasker.com

0 Kudos
Reply

2,272 Views
JRBurke
Contributor I
Thanks I'll try that.

I did find a forum in which you can use __declspec(interrupt:0) instead of __interrupt in the compiler to prevent the SR from being changed to 2700 inside each interrupt. This seemed to really help my code.

So, I guess another question would be:

If the SR is at 2700 and and interrupt such as IRQ1 comes in on an edge trigger (using Eport module), does that mean that the IRQ is lost forever at that point? Or does it "queue up" somewhere to be issued after the SR returns to 2000.


Message Edited by JRBurke on 2008-10-08 10:38 PM
0 Kudos
Reply

2,272 Views
mjbcswitzerland
Specialist V
Hi

Edge port events (edges, not levels) cause the corresponding EPFR flag sto be set. The flag(s) remain set until cleared by the SW (by writing the bit with '1'). These cause IRQs to occur and so are queued - they are not lost due to not neing serviced immediately or becasue they occurred while another IRQ was being handled. The only way to lose them is to incorrectly reset the IRQ event while doing something else.

Regards

Mark

www.uTasker.com

0 Kudos
Reply

2,272 Views
sowmya
Contributor II
Hi,
 
Mark thanks for your suggestions, I did try checking the way my flags are cleared and also the interrupt levels and priorities - I do not seem to have an issue there.
 
I use the __declspec(interrupt) for declaring my interrupts.
 
Edge port interrupts IRQ1 is at level 1 and IRQ7 at level 7.
 
In my case, my IRQ1 does not seem to happen and hence using __declspec(interrupt:0x2100) for IRQ1 and  __declspec(interrupt:0x2700) for IRQ7 (which is not needed anyways) does not help me solve the issue.
 
This is a scenario where the IRQ7 seems to do something to my IRQ1 due to which i cannot get it come after that.
 
Any other suggestions to solve the issue are more than welcome.
 
Thanks.
0 Kudos
Reply

2,272 Views
sowmya
Contributor II
Hi,
 
I infact tried something like what kunal suggested just to find out if it fixes the problem (even if i miss servicing an interrupt)
 
In my IRQ7 I did something like this at the end:-
 

MCF_EPORT_EPFR0 = (uint8)(MCF_EPORT_EPFR0 |MCF_EPORT_EPFR_EPF7 | MCF_EPORT_EPFR_EPF1);

 
and my last line of IRQ1 looks like this
 

MCF_EPORT_EPFR0 =(uint8)(MCF_EPORT_EPFR0 | MCF_EPORT_EPFR_EPF1);

where MCF_EPORT_EPFR_EPF1 = 0x02 and MCF_EPORT_EPFR_EPF7 = 0x80
 
Does not help much though. Is it that IRQ7 is an NMI and hence it prevents my IRQ1 from occuring?
 
Any help is deeply appreciated.
 
Thanks.
0 Kudos
Reply