MPC5744P External Interrupt 0 Cause Device Reset

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

MPC5744P External Interrupt 0 Cause Device Reset

Jump to solution
1,818 Views
hangxie
Contributor III

Hi,

  I'm migrating the code from MPC5643L to MPC5744P in our own design, Now i have a problem that an unexplained reset hapenning when a external interrupt triggered (connect to PTA7) . But another interrupt source (connect to PTA8) works fine. Here is the code step-by-step, can anybody help to check the problem?

1. clear FCCU faults

void _clearFCCUfaults(void)
{
int32_t i;
for (i=0;i<3;i++)
{
FCCU.NCFK.R = FCCU_NCFK_KEY;
FCCU.NCF_S[i].R = 0xFFFFFFFF;
while (FCCU.CTRL.B.OPS != 0x3);
}
}

2. CPU Mode config

 

void _configModeEntry(void)
{
/* IRC Trim */
IRCOSC.CTL.B.USER_TRIM = 0;

/* Mode Config */
MC_ME.ME.R = ME_STOP0_EN|ME_HALT0_EN|ME_RUN3_EN|ME_RUN2_EN|ME_RUN1_EN|ME_TEST_EN;
MC_ME.DRUN_MC.R = ME_PAD_ON |ME_VREG_ON |ME_CFLASH_ON |ME_FMPLL0_OFF|ME_FMPLL1_OFF|ME_XOSC_ON |ME_FIRC_ON|ME_SYS_CLK_ON_XOSC;
MC_ME.RUN0_MC.R = ME_PAD_ON |ME_VREG_ON |ME_CFLASH_ON |ME_FMPLL0_ON |ME_FMPLL1_OFF|ME_XOSC_ON |ME_FIRC_ON|ME_SYS_CLK_ON_PRIPLL;
MC_ME.RUN1_MC.R = ME_PAD_ON |ME_VREG_ON |ME_CFLASH_ON |ME_FMPLL0_OFF |ME_FMPLL1_OFF|ME_XOSC_ON |ME_FIRC_ON|ME_SYS_CLK_ON_XOSC;
MC_ME.RUN2_MC.R = ME_PAD_ON |ME_VREG_ON |ME_CFLASH_ON |ME_FMPLL0_OFF |ME_FMPLL1_OFF|ME_XOSC_ON |ME_FIRC_ON|ME_SYS_CLK_ON_XOSC;
MC_ME.RUN3_MC.R = ME_PAD_ON |ME_VREG_ON |ME_CFLASH_ON |ME_FMPLL0_ON |ME_FMPLL1_OFF|ME_XOSC_ON |ME_FIRC_ON|ME_SYS_CLK_ON_PRIPLL;
MC_ME.HALT0_MC.R = ME_PAD_ON|ME_VREG_ON |ME_CFLASH_LPM|ME_FMPLL0_ON |ME_FMPLL1_OFF|ME_XOSC_ON |ME_FIRC_ON|ME_SYS_CLK_ON_PRIPLL;
MC_ME.STOP0_MC.R = ME_PAD_ON|ME_VREG_OFF|ME_CFLASH_OFF|ME_FMPLL0_OFF|ME_FMPLL1_OFF|ME_XOSC_OFF|ME_FIRC_OFF|ME_SYS_CLK_DISABLED;

MC_ME.RUN_PC[0].B.RUN3 = 0;
MC_ME.RUN_PC[0].B.RUN2=0;
MC_ME.RUN_PC[0].B.RUN1=0;
MC_ME.RUN_PC[0].B.RUN0=0;
MC_ME.RUN_PC[0].B.DRUN=1; // all peripherals on in DRUN to execute Peripherals setup
MC_ME.RUN_PC[0].B.SAFE=0;
MC_ME.RUN_PC[0].B.TEST=0;

MC_ME.RUN_PC[1].B.RUN3=1;
MC_ME.RUN_PC[1].B.RUN2=1;
MC_ME.RUN_PC[1].B.RUN1=1;
MC_ME.RUN_PC[1].B.RUN0=1;
MC_ME.RUN_PC[1].B.DRUN=1; // all peripherals on in DRUN to execute Peripherals setup
MC_ME.RUN_PC[1].B.SAFE=0;
MC_ME.RUN_PC[1].B.TEST=0;

MC_ME.RUN_PC[2].B.RUN3=0;
MC_ME.RUN_PC[2].B.RUN2=1;
MC_ME.RUN_PC[2].B.RUN1=0;
MC_ME.RUN_PC[2].B.RUN0=0;
MC_ME.RUN_PC[2].B.DRUN=1; // all peripherals on in DRUN to execute Peripherals setup
MC_ME.RUN_PC[2].B.SAFE=0;
MC_ME.RUN_PC[2].B.TEST=0;

MC_ME.LP_PC[0].B.STOP0=0;
MC_ME.LP_PC[0].B.HALT0=0;

MC_ME.LP_PC[1].B.STOP0=1;
MC_ME.LP_PC[1].B.HALT0=1;

MC_ME.PCTL9.R = DBGm|ME_LPPC0|ME_RUNPC0; //LFAST0
MC_ME.PCTL11.R = DBGm|ME_LPPC0|ME_RUNPC0; //SIPI_0
MC_ME.PCTL12.R = DBGm|ME_LPPC0|ME_RUNPC0; //ENET_0
MC_ME.PCTL30.R = DBGm|ME_LPPC0|ME_RUNPC1; //PIT_0
MC_ME.PCTL36.R = DBGm|ME_LPPC0|ME_RUNPC0; //DMAMUX_0
MC_ME.PCTL38.R = DBGm|ME_LPPC0|ME_RUNPC0; //CRC_0
MC_ME.PCTL77.R = DBGm|ME_LPPC0|ME_RUNPC1; //CAN_2
MC_ME.PCTL78.R = DBGm|ME_LPPC0|ME_RUNPC1; //CAN_1
MC_ME.PCTL79.R = DBGm|ME_LPPC0|ME_RUNPC1; //CAN_0
MC_ME.PCTL91.R = DBGm|ME_LPPC0|ME_RUNPC1; //LINFlex_1
MC_ME.PCTL98.R = DBGm|ME_LPPC0|ME_RUNPC0; //DSPI_1
MC_ME.PCTL99.R = DBGm|ME_LPPC0|ME_RUNPC1; //DSPI_0
MC_ME.PCTL104.R = DBGm|ME_LPPC0|ME_RUNPC0; //SENT_0
MC_ME.PCTL107.R = DBGm|ME_LPPC0|ME_RUNPC0; //FLEXRAY
MC_ME.PCTL124.R = DBGm|ME_LPPC0|ME_RUNPC1; //ADC_3
MC_ME.PCTL126.R = DBGm|ME_LPPC0|ME_RUNPC1; //ADC_1
MC_ME.PCTL137.R = DBGm|ME_LPPC0|ME_RUNPC1; //ETIMER_1
MC_ME.PCTL141.R = DBGm|ME_LPPC0|ME_RUNPC0; //CTU_1
MC_ME.PCTL144.R = DBGm|ME_LPPC0|ME_RUNPC1; //PWM_1
MC_ME.PCTL146.R = DBGm|ME_LPPC0|ME_RUNPC0; //DMAMUX_1
MC_ME.PCTL204.R = DBGm|ME_LPPC0|ME_RUNPC1; //LINFlex_0
MC_ME.PCTL208.R = DBGm|ME_LPPC0|ME_RUNPC0; //DSPI_3
MC_ME.PCTL209.R = DBGm|ME_LPPC0|ME_RUNPC1; //DSPI_2
MC_ME.PCTL214.R = DBGm|ME_LPPC0|ME_RUNPC0; //SENT_1
MC_ME.PCTL235.R = DBGm|ME_LPPC0|ME_RUNPC1; //ADC_2
MC_ME.PCTL237.R = DBGm|ME_LPPC0|ME_RUNPC1; //ADC_0
MC_ME.PCTL239.R = DBGm|ME_LPPC0|ME_RUNPC0; //SGEN_0
MC_ME.PCTL245.R = DBGm|ME_LPPC0|ME_RUNPC0; //ETIMER_2
MC_ME.PCTL247.R = DBGm|ME_LPPC0|ME_RUNPC1; //ETIMER_0
MC_ME.PCTL251.R = DBGm|ME_LPPC0|ME_RUNPC1; //CTU_0
MC_ME.PCTL255.R = DBGm|ME_LPPC0|ME_RUNPC1; //PWM_0
}

 

3. config AIPS

 

void _configAIPS(void)
{
int32_t i;

AIPS_0.MPRA.R |= 0x77777777;
AIPS_1.MPRA.R |= 0x77777777;
for (i=0;i<8;i++)
{
if (i !=4 )
{
AIPS_0.PACR[i].R = 0x00000000;
AIPS_1.PACR[i].R = 0x00000000;
}
}
for (i=0;i<32;i++)
{
AIPS_0.OPACR[i].R = 0x00000000;
AIPS_1.OPACR[i].R = 0x00000000;
}
}

4. config PLL Clock and switch to RUN0

5. config FCCU

void _configFCCU(void)
{
/* Unlock configuration */
FCCU.TRANS_LOCK.B.TRANSKEY = 0xBC;

/* provide Config state key */
FCCU.CTRLK.R = 0x913756AF;

/* enter config state - OP1 */
FCCU.CTRL.R = 0x1;

/* Verify if state change was sucessful */
while (FCCU.CTRL.B.OPS != 0x3); //operation status successful

/* Configure FCCU to react on NCF14 with long functional reset */
FCCU.NCFS_CFG[0].B.NCFSC14 = 0x01; //short functional reset reaction

//set up the NOMAL mode of FCCU
FCCU.CTRLK.R = 0x825A132B; //key for OP2
FCCU.CTRL.R = 0x2; //set the OP2 - set up FCCU into the NORMAL mode
while (FCCU.CTRL.B.OPS != 0x3); //operational status succesfull

}

6. config GPIO PTA7

#define GPIO_IBE(x)   SIUL2.MSCR[x].B.IBE

#define IMCR_PADSEL(x) SIUL2.IMCR[x].B.SSS 

 

int32_t drv_gpio_initialize(void)

{

   GPIO_IBE(SP4) = 1;               // SP4 Define to 7
   IMCR_PADSEL(180) = 1;

}

7. enable External Interrupt, Channel is 7, ExtiEvent is FALLING, Enable is TRUE

int32_t drv_exti_set(EXTITypedef Channel,EXTIEventTypedef ExtiEvent,uint8_t Enable)
{
if (Channel >= MAX_EXTI_CHANNELS) //Range Check
return EINVAL;
if (Enable == TRUE)
{
SIUL2.DIRER0.R &= ~_BV(Channel); // Disable first.
if (ExtiEvent == FALLING)                    //Falling Edge
{
SIUL2.IFEER0.R |= _BV(Channel); //Enable Falling
SIUL2.IREER0.R &= ~_BV(Channel); //Disable Rising
}
else if (ExtiEvent == RISING)
{
SIUL2.IREER0.R |= _BV(Channel); //Enable Rising
SIUL2.IFEER0.R &= ~_BV(Channel); //Disable Falling
}
SIUL2.IFER0.R |= _BV(Channel); //Enable Filter
SIUL2.DISR0.R |= _BV(Channel); //Clear Flag First
SIUL2.DIRER0.R |= _BV(Channel); //Enable 
}
else 
{
SIUL2.DIRER0.R &= ~_BV(Channel); 
}
return EOK;
}

8. External Interrupt 0 Handler

void SIUExternalIRQ0To7(void)
{
uint32_t Flag = SIUL2.DISR0.R&0x000000FF;
SIUL2.DISR0.R=0x000000FF;
drv_exti_irq_handler(Flag);
}

 

void (*drv_exti_irq_callback[MAX_EXTI_CHANNELS])(void);

void drv_exti_irq_handler(uint32_t Flag)
{
uint32_t i;
for (i=0; i<MAX_EXTI_CHANNELS; i++)
{
if (drv_exti_irq_callback[i] != NULL && (Flag&_BV(i)))
drv_exti_irq_callback[i]();
}
}

Labels (1)
1 Solution
1,252 Views
martin_kovar
NXP Employee
NXP Employee

Hello,

the problem you deal with is little bit complicated, but I will try to explain.

SIUL2 external interrupt IRQ0 causes fault NCF32 in FCCU. This is the NCF32 fault description:

Error input pin of this device. Because of the lack of a dedicated pin for this purpose, SIUL2 External Interrupt_0 can be used to indicate if any other MCU is going into Error state. Note: If interrupt is configured as the reaction of this NCF then the interrupt controller may observe two interrupts one due to FCCU and another due to the SIUL IRQ[0]. So, appropriate configuration must be done.

By default, this NCF32 is enabled in FCCU (see registers NCF_E1), but no reaction is set.

FOSU is enabled by setting any bit of NCF_E and correspondingly same bit in any of the NMI_EN, IRQ_ALARM_EN, EOUT_SIG_EN or NCFS_CFG (in your case it is NCFS_CFG[0] - watchdog, NCF14).  As soon as external interrupt occurs, FOSU triggers its own internal watchdog and waits for NCF32 fault reaction. Because this reaction is not set, device is reset after FOSU internal watchdog timeout.

There are three ways, how to resolve your problem:

1) Disable the NCF32 fault in NCF_Ex register.

2) Configure reaction for the NCF32 fault (interrupt)

3) Use IRQ1 external interrupt instead of IRQ0. Do not forget about external interrupt routing to INTC controller.

pastedImage_4.png

Use the pads, which have function REQ8 and higher. These are routed to IRQ1 - IRQ3.

pastedImage_5.png

Hope it helps.

Regards,

Martin

View solution in original post

4 Replies
1,252 Views
martin_kovar
NXP Employee
NXP Employee

Hi,

I posted some simple example for external interrupt to this thread:

https://community.nxp.com/thread/390644 

Regards,

Martin

0 Kudos
1,252 Views
hangxie
Contributor III

Hi, 

     I found the problem is caused by the FCCU configuration, If I remove the following function _configFCCU() , then the cpu will not reset when external interrupt 0 happened.

     But this function only config the cpu to reset when SWT timeout, why it can effect the external interrupt?

     By the way, the SWT is disabled in my test.

void _configFCCU(void)
{
/* Unlock configuration */
FCCU.TRANS_LOCK.B.TRANSKEY = 0xBC;

/* provide Config state key */
FCCU.CTRLK.R = 0x913756AF;

/* enter config state - OP1 */
FCCU.CTRL.R = 0x1;

/* Verify if state change was sucessful */
while (FCCU.CTRL.B.OPS != 0x3); //operation status successful

/* Configure FCCU to react on NCF14 with long functional reset */
FCCU.NCFS_CFG[0].B.NCFSC14 = 0x01; //short functional reset reaction

//set up the NOMAL mode of FCCU
FCCU.CTRLK.R = 0x825A132B; //key for OP2
FCCU.CTRL.R = 0x2; //set the OP2 - set up FCCU into the NORMAL mode
while (FCCU.CTRL.B.OPS != 0x3); //operational status succesfull

}

1,253 Views
martin_kovar
NXP Employee
NXP Employee

Hello,

the problem you deal with is little bit complicated, but I will try to explain.

SIUL2 external interrupt IRQ0 causes fault NCF32 in FCCU. This is the NCF32 fault description:

Error input pin of this device. Because of the lack of a dedicated pin for this purpose, SIUL2 External Interrupt_0 can be used to indicate if any other MCU is going into Error state. Note: If interrupt is configured as the reaction of this NCF then the interrupt controller may observe two interrupts one due to FCCU and another due to the SIUL IRQ[0]. So, appropriate configuration must be done.

By default, this NCF32 is enabled in FCCU (see registers NCF_E1), but no reaction is set.

FOSU is enabled by setting any bit of NCF_E and correspondingly same bit in any of the NMI_EN, IRQ_ALARM_EN, EOUT_SIG_EN or NCFS_CFG (in your case it is NCFS_CFG[0] - watchdog, NCF14).  As soon as external interrupt occurs, FOSU triggers its own internal watchdog and waits for NCF32 fault reaction. Because this reaction is not set, device is reset after FOSU internal watchdog timeout.

There are three ways, how to resolve your problem:

1) Disable the NCF32 fault in NCF_Ex register.

2) Configure reaction for the NCF32 fault (interrupt)

3) Use IRQ1 external interrupt instead of IRQ0. Do not forget about external interrupt routing to INTC controller.

pastedImage_4.png

Use the pads, which have function REQ8 and higher. These are routed to IRQ1 - IRQ3.

pastedImage_5.png

Hope it helps.

Regards,

Martin

1,252 Views
hangxie
Contributor III

Hi,

   Thanks your reply, in our design, there two interrupt source REQ7 and REQ8 in use, and can not change it to another (use the same board from MPC5643L, need to forward compatible the previous product), so I try to disable the NCF32 fault in NCF_E[1] during FCCU config, now the problem solved, great thanks!

  /* Disable NCF32 */
  FCCU.NCF_E[1].B.NCFE0 = 0x0;
0 Kudos