Does CPSID command cause interrupt loss?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Does CPSID command cause interrupt loss?

1,912 次查看
郑文豪
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 项奖励
回复
7 回复数

1,898 次查看
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 项奖励
回复

1,895 次查看
郑文豪
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 项奖励
回复

1,890 次查看
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 项奖励
回复

1,864 次查看
郑文豪
Contributor I

Any progress or idea?

0 项奖励
回复

1,861 次查看
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 项奖励
回复

1,837 次查看
郑文豪
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 项奖励
回复

1,888 次查看
郑文豪
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 项奖励
回复