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"); |
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.
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
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.
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
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
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
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
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.
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.
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
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