STM32F0 input capture interrupt quirk
Bare-metal STM32F030C8.
Using input capture to receive encodes.
Encodes are delimited by idle.
I need to decode only the last 10 or so transitions of each encode.
I want to perform the decode during the idle.
So I’m using circular DMA and I want the timer interrupt to
- Fire on the first update following captures (on timer overflow), where I’ll signal the app do the decode and change the interrupt to capture, so it fires on the start of the next encode
- Fire on the first capture, where I’ll change the interrupt to update, i.e. two interrupts per received encode.
But what I’m observing in the interrupt is
- In the capture interrupt, I switch to interrupt to update successfully, i.e. I see only one capture interrupt.
- But I get two or three update interrupts in succession.
This is the instrumented IRQ handler.
EDIT replaced Cube TIM_FLAG macros with "CMSIS-mandated" TIM_SR macros.
void TIMx_IRQHandler(void)
{
TIM_TypeDef *htimxInstance_p = _htimxInstance_p;
uint16_t sr = htimxInstance_p->SR;
// for testing
uint16_t debugDier = htimxInstance_p->DIER;
/* Clear the SR bits as early as possible.
* Observe interrupts with SR = 0. So appears there’s latency from clearing SR to the
* peripheral's clearing its interrupt. */
htimxInstance_p->SR = 0;
/* TIMx Capture event. */
if (sr & TIM_SR_CC1IF)
{
/* Switch the interrupt to update.
* The next interrupt will be after the encode has completed. */
htimxInstance_p->DIER = TIM_DIER_CC1DE | TIM_DIER_UIE;
}
/* TIM Update event, i.e., the timer counter has overflowed. */
else if (sr & TIM_SR_UIF)
{
/* This interrupt indicates the encode is completed.
* Switch the interrupt to capture.
* The next interrupt will be when the next encode has started.
* Incrementing encodeCount signals the app to do the decode. */
htimxInstance_p->DIER = TIM_DIER_CC1DE | TIM_DIER_CC1IE;
encodeCount++;
}
// for testing
debugSr[debugSrIdx].dier = debugDier;
debugSr[debugSrIdx].sr = sr;
if (++debugSrIdx >= ARRAY_SIZE(debugSr))
debugSrIdx = 0;
}Perhaps I might work-around it by adding state to the interrupt to signal to the app on the first update following capture.
But I’d like to fix it if possible. Any clues please?
