Dear NXP support,
we have the following problem:
Brief bug description:
After the PIT timer interrupt request raised, it can be cleared by writing the INTC CPR register
with the same value it already contains. This CPR value is lower, than the PIT interrupt
request priority.
Assumptions:
* The INTC CPR has lower value than the PIT timer interrupt
Scenario:
* Disable the interrupts globally (EE clear)
* Start the PIT timer channel
* Wait the PIT channel to expire and cause an interrupt request
* Disable the timer channel interrupt (TIE), as the request was already queued
* Write the same lower value to the INTC CPR
* Enable the interrupts globally (EE set)
* (The queued interrupt shall be raised now)
If the INTC CPR is not updated, the PIT interrupt happens.
This means the INTC CPR write clears the queued interrupt.
Example code:
#include <ppc_ghs.h>
#include "./inc/MPC5748G.h"
#define PIT_CH_ID 0U
#define PIT_CH_ID_PSR 226U
#define PRODUCE_ISSUE
void initPIT(void)
{
PIT.PITMCR.B.MDIS = (vuint32_t)1U; /* disable the RTI timer module */
PIT.PITMCR.B.FRZ = (vuint32_t)1U; /* Timer is stopped in debug mode. Needed for easier debug. */
PIT.PITMCR.B.MDIS = (vuint32_t)0U; /* enable the PIT timer module */
}
void initPIT_CH_ISR(void)
{
PIT.CH[PIT_CH_ID].TFLG.B.TIF = (vuint32_t) 1U; /* Delete any previous interrupts */
PIT.CH[PIT_CH_ID].LDVAL.R = (vuint32_t) 0x00FFFFFFU; /* Set a not so large value */
}
int main(void)
{
initPIT();
initPIT_CH_ISR();
/* Set the initial 0 value to CPR */
INTC.CPR[0U].B.PRI = (vuint32_t) 0U;
/* Set PIT channel priority to 1, which is higher than the CPR value */
INTC.PSR[PIT_CH_ID_PSR].B.PRC_SELN = (vuint32_t) 0U;
INTC.PSR[PIT_CH_ID_PSR].B.PRIN = (vuint32_t) 1U;
/* Disable interrupts globally (delete EE) */
__DIR();
/* Start the timer */
PIT.CH[PIT_CH_ID].TCTRL.B.TEN = (vuint32_t) 1U;
/* Wait for timer to tick */
while(PIT.CH[PIT_CH_ID].TFLG.B.TIF != (vuint32_t) 1U);
/*
* The interrupt for PIT timer channel shall be latched in the INTC queue.
*/
/* Disable the timer channel interrupt, as the request was already queued. */
PIT.CH[PIT_CH_ID].TCTRL.B.TIE = (vuint32_t) 0U;
#ifdef PRODUCE_ISSUE
/* Set CPR to the same value as it was, and which is lower than the corresponding timer interrupt priority */
INTC.CPR[0U].B.PRI = (vuint32_t) 0U;
#endif
/* Re-enable interrupts globally (set EE) */
__EIR();
/*
* The timer interrupt shall be raised here
*/
return 0;
}
Thank you for your help in advance.
Regards,
Janos Bai
Hello,
I checked your configuration and the behavior seems to be incorrect. I need to contact application team and ask them about additional information. I will write you back as soon as possible.
Regards,
Martin
Hello,
Is there any news?
Regards,
Tamas Petz
Hello,
I discussed your question with my colleague who is application engineer and result is following:
For correct behavior it is recommended to clear TIE bit inside the PIT interrupt (together with TIF bit). This ensures that interrupt will be executed once, but the issue you have encountered does not appear. So correct procedure is following:
1) Disable EE bit
2) Enable PIT, wait for TIF flag
3) Write to INTC CPR
4) Enable EE bit
5) In PIT interrupt service routine clear TIE at first and then clear TIF.
We have also found another workaround. If you write at first to INTC CPR and then clear TIE, interrupt is executed. But we are waiting for additional information from design team regarding this behavior.
I recommend you to use the procedure write above.
If you have any other question, please feel free to write me back.
Regards,
Martin
Hello,
unfortunately I am still waiting for information from application team. But I found that if you do not disable TIE bit in PIT MCR register, interrupt will be executed.
So from my point of view the best workaround is to disable TIE bit inside interrupt service routine.
Regards,
Martin