In fsl_qtmr.c QTMR_ClearStatusFlags() and a flag that was not included in mask parameter may be accidentally cleared.
Example:
- Multiple interrupt flags are used - OverflowFlag and EdgeFlag
- OverflowFlag gets raised and triggers ISR
- Inside the ISR
QTMR_ClearStatusFlags(kQTMR_CompareFlag) is called
- Inside
QTMR_ClearStatusFlags(), EdgeFlag gets raised right after reading SCTRL register
- EdgeFlag is cleared in the same function, before being handled. Sad face
reg = base->CHANNEL[channel].SCTRL; // [reg]:OverflowFlag==1, EdgeFlag==0 [SCTRL]:OverflowFlag==1, EdgeFlag==0
/* Timer compare flag */
if ((mask & (uint32_t)kQTMR_CompareFlag) != 0U) // <----- EdgeFlag raised here
{
reg &= MCUX_MASK_INVERT_16(TMR_SCTRL_TCF_MASK); // [reg]:OverflowFlag==0, EdgeFlag==0 [SCTRL]:OverflowFlag==1, EdgeFlag==1
}
/* Timer overflow flag */
if ((mask & (uint32_t)kQTMR_OverflowFlag) != 0U)
{
reg &= MCUX_MASK_INVERT_16(TMR_SCTRL_TOF_MASK);
}
/* Input edge flag */
if ((mask & (uint32_t)kQTMR_EdgeFlag) != 0U)
{
reg &= MCUX_MASK_INVERT_16(TMR_SCTRL_IEF_MASK);
}
base->CHANNEL[channel].SCTRL = reg; // [SCTRL]: OverflowFlag==0, EdgeFlag==0
Mitigation:
Mask flag bits when reading SCTRL and CSCTRL registers:
reg = base->CHANNEL[channel].SCTRL | TMR_SCTRL_TCF_MASK | TMR_SCTRL_TOF_MASK | TMR_SCTRL_IEF_MASK;
reg = base->CHANNEL[channel].CSCTRL | TMR_CSCTRL_TCF1_MASK | TMR_CSCTRL_TCF2_MASK;
In fsl_qtmr.c
QTMR_ClearStatusFlags()and a flag that was not included inmaskparameter may be accidentally cleared.Example:
QTMR_ClearStatusFlags(kQTMR_CompareFlag)is calledQTMR_ClearStatusFlags(), EdgeFlag gets raised right after reading SCTRL registerMitigation:
Mask flag bits when reading SCTRL and CSCTRL registers: