This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

phantomInterrupt called, unknown reason

Other Parts Discussed in Thread: RM48L952, HALCOGEN

Hello,
I do work with the irqDispatcher mode and can observe that the phantomInterrupt is called.

In my project I want to use the nested interrupt feature and I do use the code Christian Hegert published for this.

As long as the phantom interrupt occurs, I will not be able to use this code.

So I would be very pleased, if somebody could help me to understand why the phantom interrupt is called.

  • RM48L952
  • I do use HALCoGen code, with some additions to init the LR of Systemmode, and to set flash wait states correctly
  • I do have a couple of IRQ, 2 ADC EOC, rest are communication interrupts (SCI, CAN)
  • I do use the IRQ dispatch mode with the goal to nest interrupts
  • I use one FIQ (the FIQ isr has the pragma FIQ, this should be correct I think)  
  • the phantomInterrupt() function is still surrounded with the pragmas of a interrupt IRQ, even this should not be necessary if I understand correctly.
  • Even if I do not nest any interrupt the phantom Interrupt occurs. (no enableIRQ() in my irqDispatch_c)

  • What can cause the phantom interrupt to be called?
  • An uninitialized register? Are there more system mode registers to be initalized (as the LR)?


Thank you for any hint to debug the cause for the phantom interrupt!

Roger

  • Hello Roger,

    can you please let me know the clock ratio between GCLK/HCLK versus VCLK setting for your peripheral like SCI, CAN ?

    Typically, a phantom interrupt occurs if:

    1- An interrupt has triggered to the VIM module

    2- VIM module triggers IRQ to CPU (pending interrupt)

    3- CPU requests for vector address, but there is no pending interrupt in VIM.

    VIM pending interrupt can be cleared by s/w accidentally or by h/w bug if GCLK:VCLK ratio is larger than 2:1.  See errata VIM.27 of the following link: http://www.ti.com/lit/er/spnz193/spnz193.pdf

  • Hello Henry,

    Thank you for your reply. I will check this and report as soon as I have checked it. (i'm out of office some days).

    I think it must be a software bug in my project, because I did not observe the phantomInterrupt to be called as long as I used the vectored mode with VIC mode.

    To nest interrupts I changed to dispatch mode without VIC.

    I will report about mid of next week.

    Thank you

    Roger

  • Back in office, I checked the clock ratio: it is 2:1, so this cannot be the cause.

    So it must be a software bug in my project.

    When I debug my irqDispatcherC function I see that sometimes the IRQIVEC is 58 but the IRQVECREG contains the phantomInterrupt address:

    1. line 1:   uint32_t vec = vimREG->IRQIVEC;
    2. line 2:   void (*irq_func_pnt)(void) = (void (*)(void))vimREG->IRQVECREG;

    line 1 gives me 58 for Adc2Group2 interrupt and line 2 gives me the phantomInterrupt() address.

    In which direction do I have to look for my SW bug?

    Thank you very much!

    Roger

  • Found!

    My problem was, that I restarted ADC conversions (within FIQ) before the EOC isr (IRQ) was finished.

    Exactly:

    One FIQ for "fast" ADC EOC

    Two IRQ for "slow" ADC EOC

    Every 4th FIQ I started both "slow" ADC conversions

    When setting some breakpoints in the "slow" EOC isr, this messed up the IRQ/VIM/whatever. Seems that ADC (or VIM) is somewhat "free run" when hitting a breakpoint (? not sure).

    With no breakpoint set I did not have any phantomInterrupt() called.

    When adding a delay in one of my "slow" EOC isr to make it slow, I did have exactly the same problem described. As soon as the adc conversion was restarted in FIQ before the EOC isr was finished this messed up the VIM.

    Thank you for your time.

    Roger

  • Strange...

    If I produce the same behavior of my ISRs in VIC mode or in in vectored mode, I do not observe any phantomInterrupt() call.

    I did expect the phantom interrupt to be called too, at least in vectored mode. There the VIM requests the CPU to interrupt, the CPU branches to 0x18, and there the PC is loaded with vimREG->IRQVECREG.

    But only in case of dispatch mode I can observe that vimREG->IRQVECREG contains sometimes the phantomInterrupt address.

    In dispatch mode I do read:

    1. IRQIVEC
    2. IRQVECREG

    while reading these 2 registers I am in SytemMode (does VIM bahave different in SystemMode?). IRQs are disabled (because I am in IRQ dispatcher and I did not yet re-enable the IRQ).

    If I first read IRQIVEC and then IRQVECREG:

    IRQIVEC is always correct, but IRQVECREG is sometimes phantomInterrupt

    If I first read IRQVECREG and then IRQIVEC:

    IRQVECREG is always correct, but IRQIVEC is sometimes zero

    It seams that the first read access is always correct, but the second can be wrong.

    This means that if I use this code sequence I do not encounter problems:

    uint32_t vec = vimREG->IRQIVEC;

    irq_func_pnt = vimRAM->ISR[vec]; // not reading from VIM!

    ( instead of irq_func_pnt = (void (*)(void))vimREG->IRQVECREG;)

    Questions:

    1) In which cases is it possible that the VIM data I do read (offset and isr vector) is not consistent? (= offset corresponds not to isr vector)

    2) Does reading the VIM modify the VIM?

    3) Does VIM access behave different in System mode (than in IRQ mode)

    Thanks you for clarifications!
    Roger

  • Roger,

    We are missing some very critical information from the description of the IRQ/FIQ INDEX and VECREG registers in the TRM.

    These registers reflect the index or the ISR address of the highest-priority interrupt currently pending to be services.When the application reads from either of these registers as part of the ISR, this automatically causes the register to reflect the index/ISR address for the next highest-priority pending interrupt. In case there is no other interrupt pending, the index will read 0x00 and the ISR address register will read the phantom interrupt address.

    We will add this important information in the next update to the TRMs.

    Regards, Sunil

  • Thank you Sunil for your reply.

    Does this mean that if I read the IRQ Offset, it will affect also the IRQVECREG (and vice versa)?

    This would imply that it is only ok to read one of the information, otherwise it could fail, correct?

    Best regards, and thank you for your support!

    Roger

  • Roger,

    Yes, that is correct. If you read the registers that aid in implementing the vectored-interrupt mechanism, only one read is necessary in order to identify the highest-priority pending interrupt and to clear the flag(s). If you use software-prioritization of interrupts, you will typically read from the INTREQ registers to identify all the pending interrupt requests. This read does not clear any flags, and the flag(s) need to be explicitly cleared in software.

    Regards, Sunil

  • Sunil,

    Thank you for this clarification!

    Yes, INTREQ could be used to do the SW prioritization. I started to implement nested interrupts with help of a forum thread here (link below). The solution presented did only manage the nesting and used the VIM prioritization. As this is ok for my solution I used this as it was published... And in there, Christian Hegert published the double read (which works nearly always which is a bit strange).

    Best Regards,

    Roger

    Threads of nesting interrupts:

    http://e2e.ti.com/support/microcontrollers/hercules/f/766/t/210653.aspx?pi239031349=3

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/164944.aspx?pi239031349=2