Hi @VaneB ,
Currently i'm working with a custom board with S32K358 where i use these eMIOS_1 channels to generate PWM of 200 Hz: ch3, ch9, ch11, ch12, ch13, ch19. Code is generated using SImulink
Putting my custom board into a climatic cell at 85°C i've observed the stucking behaviour after some time.
While i was debugging with S32DS (3.6.7) I've found out that it stuck into the ISR(EMIOS1_1_IRQ) so i've put into it some custom counter near entry/exit function, and also into Emios_Pwm_IrqHandler and Emios_Pwm_Ip_IrqHandler functions, in order to detect what parts of the code are executed.
After some tests i've found out that, when it stucks, inside
static void Emios_Pwm_IrqHandler(const uint8 Instance, const uint8 Channel)
{
/* Check that an event occurred on Emios channel */
if (0U != ((Emios_Ip_paxBase[Instance]->CH.UC[Channel].S) & (uint32)eMIOS_S_FLAG_MASK))
{
/* Check that an event occurred on EMIOS channel */
if (0U != ((Emios_Ip_paxBase[Instance]->CH.UC[Channel].C) & ((uint32)(eMIOS_C_DMA_MASK | eMIOS_C_FEN_MASK))))
{
Emios_Pwm_Ip_IrqHandler(Instance, Channel);
}
else
{
/* Do nothing - in case of spurious interrupts, return immediately */
}
}
}
the if condition:
if (0U != ((Emios_Ip_paxBase[Instance]->CH.UC[Channel].S) & (uint32)eMIOS_S_FLAG_MASK))
is always 0 because, for some reason, Emios_Ip_paxBase[Instance] points to 0. This means that nobody is clearing the interrupt flag so it enters in a loop where it cannot escape.
here's the code i've used to detect this probelm:
static void Emios_Pwm_IrqHandler(const uint8 Instance, const uint8 Channel)
{
// uint32_t s;
// uint32_t c;
// uint32_t s_flag;
// uint32_t s_ovr;
dbg_pwm_last_instance = Instance;
dbg_pwm_last_channel = Channel;
dbg_pwm_last_base_addr = (uint32_t)Emios_Ip_paxBase[Instance];
dbg_pwm_last_c_addr = (uint32_t)&Emios_Ip_paxBase[Instance]->CH.UC[Channel].C;
dbg_pwm_last_s_addr = (uint32_t)&Emios_Ip_paxBase[Instance]->CH.UC[Channel].S;
dbg_emiosipirq_static_state1++;
/* if (Instance == 1)
{
switch (Channel)
{
case 16:
dbg_emiosipirq_static_cnt_ch16++;
break;
case 17:
dbg_emiosipirq_static_cnt_ch17++;
break;
case 18:
dbg_emiosipirq_static_cnt_ch18++;
break;
case 19:
dbg_emiosipirq_static_cnt_ch19++;
break;
default:
dbg_emiosipirq_static_cnt_oth1++;
break;
}
}
else
{
dbg_emiosipirq_static_cnt_oth2++;
} */
/* Lettura reale dei registri vista dal codice */
/* s = Emios_Ip_paxBase[Instance]->CH.UC[Channel].S;
c = Emios_Ip_paxBase[Instance]->CH.UC[Channel].C;
s_flag = s & (uint32)eMIOS_S_FLAG_MASK;
s_ovr = s & (uint32)eMIOS_S_OVR_MASK;
dbg_pwm_last_s = s;
dbg_pwm_last_c = c;
dbg_pwm_flag_mask = (uint32)eMIOS_S_FLAG_MASK;
dbg_pwm_ovr_mask = (uint32)eMIOS_S_OVR_MASK;
dbg_pwm_last_s_and_flag = s_flag;
dbg_pwm_last_s_and_ovr = s_ovr;
if (s_flag != 0U)
{
dbg_pwm_s_flag_yes++;
}
else
{
dbg_pwm_s_flag_no++;
}
if (s_ovr != 0U)
{
dbg_pwm_s_ovr_yes++;
}
else
{
dbg_pwm_s_ovr_no++;
}
if ((s_flag == 0U) && (s_ovr != 0U))
{
dbg_pwm_flag0_ovr1_count++;
}
else if ((s_flag != 0U) && (s_ovr != 0U))
{
dbg_pwm_flag1_ovr1_count++;
}
else if ((s_flag != 0U) && (s_ovr == 0U))
{
dbg_pwm_flag1_ovr0_count++;
}
else
{
dbg_pwm_flag0_ovr0_count++;
} */
/* Check that an event occurred on EMIOS channel */
if (0U != ((Emios_Ip_paxBase[Instance]->CH.UC[Channel].S) & (uint32)eMIOS_S_FLAG_MASK))
{
dbg_emiosipirq_static_state2++;
/* Check that an event occurred on EMIOS channel */
if (0U != ((Emios_Ip_paxBase[Instance]->CH.UC[Channel].C) & ((uint32)(eMIOS_C_DMA_MASK | eMIOS_C_FEN_MASK))))
{
dbg_emiosipirq_static_state3++;
Emios_Pwm_Ip_IrqHandler(Instance, Channel);
}
else
{
dbg_emiosipirq_static_state4++;
/* Do nothing - in case of spurious interrupts, return immediately */
}
}
else
{
dbg_emiosipirq_static_state5++;
//Emios_Pwm_Ip_IrqHandler(Instance, Channel);
//Emios_Pwm_Ip_IrqHandler(1, 19);
}
}
These are the global vars in which i've stored the addresses which Emios_Ip_paxBase should point to:
dbg_pwm_last_base_addr = (uint32_t)Emios_Ip_paxBase[Instance];
dbg_pwm_last_c_addr = (uint32_t)&Emios_Ip_paxBase[Instance]->CH.UC[Channel].C;
dbg_pwm_last_s_addr = (uint32_t)&Emios_Ip_paxBase[Instance]->CH.UC[Channel].S;
I've put also some custom code to read NVIC registers run time: attached you can find the file with Thread, general registers, NVIC registers and variables expressions, EMIOS registers, for 6 tests i made.
Also i will provide you the S32DS project i used to test this behaviour in a private message.
I hope all these information could be usefull. I remain at your disposal for any further information.
BR,
SImon