Does CPSID command cause interrupt loss?

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

Does CPSID command cause interrupt loss?

1,138 Views
郑文豪
Contributor I

Condition:S32K146 MCAL4.2 ICU Measurement mode. Input signal is 1KHz 5% square wave.

About 70us from Cpsid to Cpsie,about 930us form cpsie to cpsid.

Why does ICU interrupt lost in this case?

Code:

while(1)
{
Dio_WriteChannel(0x24,1);
__asm volatile
(
"cpsid i \n"
);

for(i=0;i<300;i++)
{;}

__asm volatile
(
"cpsie i \n"
);
Dio_WriteChannel(0x24,0);
for(i=0;i<4000;i++)
{;}

}

 

0 Kudos
7 Replies

1,124 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @郑文豪,

When Primask is set, all interrupts become pending - you should see them pending in the NVIC_ISPR registers.

If an interrupt gets lost, it means the interrupt occurred while the interrupt was already pending.

 

BR, Daniel

0 Kudos

1,121 Views
郑文豪
Contributor I

Does it means interrupt occured twice in one Primask set time ,so it will missing?

But Primask set only 70us in 1ms time,and ICU interrupt only trigger once a 1ms.Why  the interrupt still missing?

ICU interrrupt processing time is about 40us.

 

 

 

0 Kudos

1,116 Views
danielmartynek
NXP TechSupport
NXP TechSupport

How do you know the interrupt is missing?

What FTM IC mode do you use, signle-edge / dual-edge?

Do you measure the period, duty-cycle or a time stamp of a single edge?

 

BR, Daniel

0 Kudos

1,090 Views
郑文豪
Contributor I

Any progress or idea?

0 Kudos

1,087 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hard to say. There should be only one interrupt in the dual-edge mode once both edges are captured.

And this interrupt becomes pending if it occurs while the interrupts are masked.

Once the interrupt are unmasked, the interrupt routine should be called.

But in the image you posted, the interrupt does not seem to be delayed, it is just missing, as If the FTM flag (or the NVIC flag) got cleared.

Can you poll the NVIC registers while PRIMASK = 1?

BTW, if you want to measure how long the PRIMASK is set, you need to put Dio_WriteChannel(0x24,0); before cpsie i. Because cpsie i enables interrupts, therefore, the DIO write will get deleyed by the ISRs.

 

BR, Daniel

0 Kudos

1,063 Views
郑文豪
Contributor I

The green line is Pin 0x24.It will be high while interrupt are masked.If interrupt not becomes pending before unmasked(I read NVICISPR3 register),It will be set low.And it also be cleared in the end of ICU interrupt.

The yellow line is Pin 0x84.It will be high in the begining of ICU interrupt and be low in the ending of interrupt.

The blue point indicates interrupt loss.At the same time,the green line indicates interrupt

not becomes pending while interrupt be masked.

 

dso_95.png

Code:

volatile uint32 setflag=0;
for(;;)
{

__asm volatile
(
"cpsid i \n"
);
Dio_WriteChannel(0x24,1);

for(i=0;i<300;i++)
{;}

setflag=REG_READ32(NVIC_BASEADDR+0x10C);

if(setflag==0)
Dio_WriteChannel(0x24,0);

__asm volatile
(
"cpsie i \n"
);

for(i=0;i<5900;i++)
{;}

 

 

 

INTERRUPT Code:

ISR(FTM_0_CH_0_CH_1_ISR)
{
Dio_WriteChannel(0x83,1);
/** @violates @ref FTM_COMMON_C_REF_1 Cast from unsigned int to pointer */
CONST(uint32, MCL_CONST) u32IsrStatus = REG_READ32(FTM_STATUS_ADDR32(FTM_0));

if ((u32IsrStatus & FTM_CH_0_MASK_U32) == FTM_CH_0_MASK_U32)
{
#if (defined GPT_FTM_0_CH_0_CH_1_ISR_USED)
Gpt_Ftm_ProcessCommonInterrupt((uint8)FTM_0_CH_0);
#endif

#if (defined PWM_FTM_0_CH_0_CH_1_ISR_USED)
Pwm_Ftm_ProcessCommonInterrupt((uint8)FTM_0_CH_0);
#endif

#if (defined ICU_FTM_0_CH_0_CH_1_ISR_USED)
Icu_Ftm_ProcessInterrupt((uint8)FTM_0_CH_0);
#endif

#if (defined OCU_FTM_0_CH_0_CH_1_ISR_USED)
Ocu_Ftm_ProcessCommonInterrupt((uint8)FTM_0_CH_0);
#endif
}

if ((u32IsrStatus & FTM_CH_1_MASK_U32) == FTM_CH_1_MASK_U32)
{
#if (defined GPT_FTM_0_CH_0_CH_1_ISR_USED)
Gpt_Ftm_ProcessCommonInterrupt((uint8)FTM_0_CH_1);
#endif

#if (defined PWM_FTM_0_CH_0_CH_1_ISR_USED)
Pwm_Ftm_ProcessCommonInterrupt((uint8)FTM_0_CH_1);
#endif

#if (defined ICU_FTM_0_CH_0_CH_1_ISR_USED)
Icu_Ftm_ProcessInterrupt((uint8)FTM_0_CH_1);
#endif

#if (defined OCU_FTM_0_CH_0_CH_1_ISR_USED)
Ocu_Ftm_ProcessCommonInterrupt((uint8)FTM_0_CH_1);
#endif
}
EXIT_INTERRUPT();
Dio_WriteChannel(0x83,0);
Dio_WriteChannel(0x24,0);
}

0 Kudos

1,114 Views
郑文豪
Contributor I

Dual-edge mode.

I set port in ICU(FTM) interrupt in the beginning and clear in the endding.

Normally ,the port flip frequence is 1KHz.When interrupt missing ,the frequence is 500Hz.

IMG_20220629_095804.jpg

The yellow line is input signal,the green line is port flip in interrupt.

0 Kudos