INTC_InstallINTCInterruptHandler Not working

cancel
Showing results for 
Search instead for 
Did you mean: 

INTC_InstallINTCInterruptHandler Not working

3,263 Views
charlessaperste
Contributor II

I'm trying to use the codewarrior generated code for a MPC5554 project. I want to capture eSCI interrupts. I've turned on all the interrupts. I receive and transmit a byte. I've set a breakpoint in my ISR. It does not get hit. Any ideas?

 

INTC_InitINTCInterrupts();

INTC_InstallINTCInterruptHandler((INTCInterruptFn) eSCIA_ISR, 146,1);

INTC.MCR.B.HVEN = 1;

asm(" wrteei 1");  
Labels (1)
11 Replies

540 Views
wernermotz
Contributor II

Hello,

I could need some help implementing an ISR. I am using CW 2.10 for MPC55xx.

Although I did everything Stanislav told, my FLEXRAY_ISR Handler is never called.

Instead always the EXCEP_DefaultExceptionHandler() is called. What did I wrong?

INTC_InitINTCInterrupts();

INTC_InstallINTCInterruptHandler(FLEXRAY_ISR, 352,2);

  

INTC.CPR.R = 0;

asm("wrteei 1");   

Enable_interrupts();

void FLEXRAY_ISR(void)

{

...clear channel interrupt flag....

}

Please help me. I am looking forward to your answers.

0 Kudos

540 Views
stanish
NXP Employee
NXP Employee

Hello Werner,

In software vector mode the execution should jump into IVOR4 Exception routine first if an external interrupt occurs.

The INTC_InitINTCInterrupts() should move INTC_INTCInterruptHandler() address into IVOR4 register which causes the interrupt prolog is executed.

Can you double check that after Interrupt init. IVOR4 register contains the address of INTC_INTCInterruptHandler() and not EXCEP_DefaultExceptionHandler().

If IVOR4 address is ok than you are probably facing some other core exception (invalid instruction, MMU TLB issue,...)

Which derivative you are targeting to? MPC5554?

Stan

0 Kudos

540 Views
wernermotz
Contributor II

Hello Stan,

thank you very much for your help. Unfortunately I still could not solve the problem. I checked the registers with following results:

IVPR = 00000000

IVOR0 to IVOR34 = 00001000

but IVOR4 = 000010B0

The INTCInterruptsHandlerTable is also correct. VTES is 1 and the INTC_PSR also has the right entries. Does anyone has an

idea? My target is a MPC5567.

0 Kudos

540 Views
stanish
NXP Employee
NXP Employee

Hi Werner,

I assume the IVOR4 address 0x0000_10B0  is the start address of INTC_INTCInterruptHandler().

Can you place a breakpoint at this address? Does the execution stops at the breakpoint? If so, can you step the interrupt prolog instruction by instruction to find out where a core exception occurs.

Can you test if the same problem occur with external interrupts disabled?  asm(" wrteei 0"); 

Note: create a separate Exception handler for each IVOR to distinguish which specific exception IVOR occurs.

Stan

0 Kudos

540 Views
wernermotz
Contributor II

Hello Stan - Lord of Interrupt :smileywink:

Your idea of putting a breakpoint into the INTC_INTCInterruptHandler() was excellent.

Because my isr was never called I expected the INTC_INCTInterruptHandler() never to be called.

However the execution stops at the INTC handler. When INTC_NESTED_INTERRUPT is set to 0, the

unloved Exception handler is called right after (**handlerFn)(); Afterwards the application hangs

in the Exception handler.

The line INTC.EOIR.R = 0; is never reached.

//*************************************************************************************************************************

#if INTC_NESTED_INTERRUPT == 0

__declspec(interrupt)

__declspec(section ".__exception_handlers")

void INTC_INTCInterruptHandler(void)

{

    INTCInterruptFn *handlerFn = (INTCInterruptFn*)(*(unsigned int*)&INTC.IACKR.R);

    (**handlerFn)();

    INTC.EOIR.R = 0;

}

//*************************************************************************************************************************

#else

__declspec(interrupt)

__declspec(section ".__exception_handlers")

__asm void INTC_INTCInterruptHandler(void)

{

nofralloc

prolog:

    stwu    r1, -0x50 (r1)    /* Create stack frame */

    stw r0,  0x24 (r1)        /* Store r0 working register  */

    /* Save SRR0 and SRR1 */

    mfsrr1  r0                /* Store SRR1 (must be done before enabling EE) */

    stw     r0,  0x10 (r1)

    mfsrr0  r0                /* Store SRR0 (must be done before enabling EE) */

    stw     r0,  0x0C (r1)

    /* Clear request to processor; r3 contains the address of the ISR */

    stw     r3,  0x28 (r1)    /* Store r3 */

    lis     r3, INTC_IACKR@h  /* Read pointer into ISR Vector Table & store in r3     */

    ori     r3, r3, INTC_IACKR@l

    lwz     r3, 0x0(r3)       /* Load INTC_IACKR, which clears request to processor   */

    lwz     r3, 0x0(r3)       /* Read ISR address from ISR Vector Table using pointer */

    /* Enable processor recognition of interrupts */

    wrteei  1                   /* Set MSR[EE]=1  */

    /* Save rest of context required by EABI */

    stw     r12, 0x4C (r1)      /* Store r12 */

    stw     r11, 0x48 (r1)      /* Store r11 */

    stw     r10, 0x44 (r1)      /* Store r10 */

    stw     r9,  0x40 (r1)      /* Store r9 */

    stw     r8,  0x3C (r1)      /* Store r8 */

    stw     r7,  0x38 (r1)      /* Store r7 */

    stw     r6,  0x34 (r1)      /* Store r6 */

    stw     r5,  0x30 (r1)      /* Store r5 */

    stw     r4,  0x2C (r1)      /* Store r4 */

    mfcr    r0                  /* Store CR */

    stw     r0,  0x20 (r1)

    mfxer   r0                  /* Store XER */

    stw     r0,  0x1C (r1)

    mfctr   r0                  /* Store CTR */

    stw     r0,  0x18 (r1)

    mflr    r0                  /* Store LR */

    stw     r0,  0x14 (r1)

    /* Branch to ISR handler address from SW vector table */

    mtlr    r3                  /* Store ISR address to LR to use for branching later */

    blrl                        /* Branch to ISR, but return here */

epilog:

    /* Restore context required by EABI (except working registers) */

    lwz     r0,  0x14 (r1)      /* Restore LR */

    mtlr    r0

    lwz     r0,  0x18 (r1)      /* Restore CTR */

    mtctr   r0

    lwz     r0,  0x1C (r1)      /* Restore XER */

    mtxer   r0

    lwz     r0,  0x20 (r1)      /* Restore CR */

    mtcrf   0xff, r0

    lwz     r5,  0x30 (r1)      /* Restore r5 */

    lwz     r6,  0x34 (r1)      /* Restore r6 */

    lwz     r7,  0x38 (r1)      /* Restore r7 */

    lwz     r8,  0x3C (r1)      /* Restore r8 */

    lwz     r9,  0x40 (r1)      /* Restore r9 */

    lwz     r10, 0x44 (r1)      /* Restore r10 */

    lwz     r11, 0x48 (r1)      /* Restore r11 */

    lwz     r12, 0x4C (r1)      /* Restore r12 */

    /* Disable processor recognition of interrupts */

    wrteei  0

    /* Ensure interrupt flag has finished clearing */

    mbar    0

    /* Write 0 to INTC_EOIR, informing INTC to lower priority */

    li      r3, 0

    lis     r4, INTC_EOIR@h     /* Load upper half of INTC_EOIR address to r4 */

    ori     r4, r4, INTC_EOIR@l

    stw     r3, 0(r4)           /* Write 0 to INTC_EOIR */

    /* Restore Working Registers */

    lwz     r3,  0x28 (r1)      /* Restore r3 */

    lwz     r4,  0x2C (r1)      /* Restore r4 */

    /* Retrieve SRR0 and SRR1 */

    lwz     r0,  0x0C (r1)      /* Restore SRR0 */

    mtsrr0  r0

    lwz     r0,  0x10 (r1)      /* Restore SRR1 */

    mtsrr1  r0

    /* Restore Other Working Registers */

    lwz     r0,  0x24 (r1)      /* Restore r0 */

    /* Restore space on stack */

    addi    r1, r1, 0x50

    /* End of Interrupt */

    rfi

}

#endif

//*************************************************************************************************************************

If I set INTC_NESTED_INTERRUPT to 1, I can step through the #else part. Here the Execution handler

is called after reaching the line blrl (Branch to ISR, but return here). The epilog part of the INTC handler

is never reached.

Do you have any idea why? Thank you very much.

Werner

0 Kudos

540 Views
edgarsevilla
Contributor II

Hi werner,

I had the same problem. All I did was this:

void INTC_INTCInterruptHandler(void)
{

    //INTCInterruptFn *handlerFn = (INTCInterruptFn*)(*(unsigned int*)&INTC.IACKR.R);
    INTCInterruptFn *handlerFn = &INTCInterruptsHandlerTable[INTC.IACKR.B.INTVEC_PRC0];

    (**handlerFn)();

    INTC.EOIR.R = 0;
}

I don´t know why "**handlerFn" points to IACKR. This register do not contain the address of ISR function that you installed.

You can see the register definition on section 18.5.2.3 INTC Interrupt Acknowledge Register (INTC_IACKR) (MPC5607BRM.pdf Rev. 7.2, 05/2012)

Hope it helps.

Edgar

540 Views
stanish
NXP Employee
NXP Employee

Hi Werner,

Thanks for this original title ... I should update my business card  :smileywink:

I suspect the problem could be caused by an uninitialized vector in the vector table INTCInterruptsHandlerTable[]

I'm not a FlexRay expert but please make sure that the interrupt request number 352 matches with the interrupt that has really occurred.


INTC_InstallINTCInterruptHandler(FLEXRAY_ISR, 352,2);


You can read  the register INTC_IACKR  when you hit the breakpoint to get the INTC vector table address.

If the address is different then address of INTCInterruptsHandlerTable[352] then probably a different Interrupt which has no ISR routine assigned occurred. 

Note: you can create a dummy ISR and adjust the INTCInterruptsHandlerTable[] definition in IntcInterrupts.c in order to initialize all uninitialized vectors to point at this dummy_ISR() (see below). This initialization is C99 feature therefore you need to enable this feature in compiler settings (ALT+F7 -> "C/C++ Language" -> check "Enable C99 Extensions")

void dummy_ISR(void);

#define INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE  (360)

INTCInterruptFn INTCInterruptsHandlerTable[INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE] =  {[0 ... INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE-1] = (INTCInterruptFn)&dummy_ISR};

...

void dummy_ISR(void)

{

  while(1);

}

Hope it helps.

Stan

0 Kudos

540 Views
wernermotz
Contributor II

Good morning Stan,

I created a dummy ISR for all the uninitialized vectors and believe it or not it is called :smileyhappy:

Now I have two more problems:

First Problem:

Although the FlexRay channel interrupt flag should be on table position [352] and accordingly [350] (FlexRay modul interrupt flag) (datasheet MPC5567),

my interrupts are only called if i bind them on position 10 (MIF) and 12 (CHIF). If I bind them on position [350] and [352] no interrupt is called. 

//**********************************************************************************************************************************

for(uint32_t position = 0; position<INTC_INTERRUPTS_REQUEST_VECTOR_TABLE_SIZE; position++)

    {

   INTCInterruptsHandlerTable[position] = (INTCInterruptFn)&Fr_interrupt_handler;

    }

   

   //MIF
   INTCInterruptsHandlerTable[10] = (INTCInterruptFn)&dummy_ISR;
   INTC.PSR[350].B.PRI = 2;

   //CHIF
   INTCInterruptsHandlerTable[12] = (INTCInterruptFn)&dummy_ISR2;
   INTC.PSR[352].B.PRI = 2;

//************************************************************************************************************************************

Second Problem:

After calling the interrupt (here CHIF) the application never comes out of it, the interrupt is called repeatedly although

I handle all the CHIF flags.

//************************************************************************************************************************************

void dummy_ISR2(void)

{

    if(FR.GIFER.B.CHIF == 1)

    {

        FR.CHIERFR.B.FRLBEF &= FR.CHIERFR.B.FRLBEF; /* flame lost channel B error flag */

        FR.CHIERFR.B.FRLAEF &= FR.CHIERFR.B.FRLAEF; /* frame lost channel A error flag */

        FR.CHIERFR.B.PCMIEF &= FR.CHIERFR.B.PCMIEF; /* command ignored error flag */

        FR.CHIERFR.B.FOVBEF &= FR.CHIERFR.B.FOVBEF;/* receive FIFO overrun channel B error flag */

        FR.CHIERFR.B.FOVAEF &= FR.CHIERFR.B.FOVAEF;/* receive FIFO overrun channel A error flag */

        FR.CHIERFR.B.MSBEF  &= FR.CHIERFR.B.MSBEF; /* message buffer search error flag */

        FR.CHIERFR.B.MBUEF  &= FR.CHIERFR.B.MBUEF; /* message buffer utilization error flag */

        FR.CHIERFR.B.LCKEF  &= FR.CHIERFR.B.LCKEF; /* lock error flag */

        FR.CHIERFR.B.DBLEF  &= FR.CHIERFR.B.DBLEF; /* double transmit message buffer lock error flag */

        FR.CHIERFR.B.SBCFEF &= FR.CHIERFR.B.SBCFEF;/* system bus communication failure error flag */

        FR.CHIERFR.B.FIDEF  &= FR.CHIERFR.B.FIDEF; /* frame ID error flag */

        FR.CHIERFR.B.DPLEF  &= FR.CHIERFR.B.DPLEF; /* dynamic payload length error flag */

        FR.CHIERFR.B.SPLEF  &= FR.CHIERFR.B.SPLEF; /* static payload length error flag */

        FR.CHIERFR.B.NMLEF  &= FR.CHIERFR.B.NMLEF; /* network management length error flag */

        FR.CHIERFR.B.NMFEF  &= FR.CHIERFR.B.NMFEF; /* network management frame error flag */

        FR.CHIERFR.B.ILSAEF &= FR.CHIERFR.B.ILSAEF;/* illegal access error flag */

       

        FR.GIFER.B.CHIF &= FR.GIFER.B.CHIF;

    }

}

//************************************************************************************************************************************

Thank you for your help.

0 Kudos

540 Views
charlessaperste
Contributor II

Yes I did. I removed the call to INTC_InstallINTCInterruptHandler() and defined CALL_USR_INIT and it started to work. I had previously tried all of the above except take out the function call. May I misspelt the preprocessor directive.

0 Kudos

540 Views
stanish
NXP Employee
NXP Employee

Hello Charles,

Have you modified INTC_CPR  register?

It's set to prevent all priority interrupts by default .

Add the line below to  enable all priority interrupts:

INTC.CPR.R = 0;

Stan

0 Kudos

540 Views
trytohelp
NXP Employee
NXP Employee

Hi Charles,

I've checked with colleague and see below their answer.

+++++++++++++++++

The real problem here is that the eSCI example project included within CodeWarrior tool is using polling but interrupt to transmit and receive data.  

If you did not add code to enable interrupts in ESCIx_CR1 for eSCI, the related ISR installed by INTC_InstallINTCInterruptHandler will have no chance to be scheduled for running.

Please let the ctm check his project to make sure the related interrupts of eSCI have been enabled.

+++++++++++++++++

Regards

Pascal

0 Kudos