STRM32F303 EXTI9_5 and EXTI15_10 external interrupt triggered either on falling or rising edge although programmed to be triggered only on rising edge, how to fix this?
Hello,
So we are building a ball shooting robot which self detects the speed the ball was launched. The average speed is in range of 80mph. To get speed we are using two light gates, one on PF9 and one on PF10. So I set up EXTI interrupts on these two input rising edges. Most of the times the logic works just fine and the speed calculated seems believable, but sometimes the interrupt is triggered on falling edge instead of rising edge. Tried the other way around and got the same result - some times interrupt is triggered on rising edge although its set to be triggered on falling edge.
I hooked up digital logic analyzer to actually see if the problem is with light gates or with STM32 interrupt. And since I'm here you already should know where the problem was.
I explicitly checked the register setup if somehow trigger for both edges is set up but also in registers everything seems okay.
So the question is whats happening?
Why sometimes interrupt is triggered on rising edge instead of falling even if it isn't enabled in registers?
How to fix this issue?
Setup:
I'm running FreeRTOS and STM32 system clock is set to 40MHz. EXTI interrupt priority is set to highest in the whole system. The interrupt service routine is as short as I could make - checks some flags, registers time, resets interrupt flag. The time between rising/falling edges is at least a millisecond.
Interrupt init code and ISR below:
void SpeedReader::init()
{
//clang-format off
/* Hardware interrupt selection
* Configure the corresponding mask bit in the EXTI_IMR register.
* Configure the Trigger Selection bits of the Interrupt line (EXTI_RTSR
and EXTI_FTSR)
* Configure the enable and mask bits that control the NVIC IRQ channel
mapped to the EXTI so that an interrupt coming from one of the EXTI line
can be correctly acknowledged.
*/
//clang-format on
/* Enable SYSCFG clock */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
/* Set interrupt source pin */
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI9_PF + SYSCFG_EXTICR3_EXTI10_PF;
/* Configure Interrupt */
EXTI->IMR |= EXTI_IMR_MR9 + EXTI_IMR_MR10;
EXTI->RTSR |= EXTI_RTSR_RT9 + EXTI_RTSR_RT10;
NVIC_SetPriority(EXTI9_5_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_SetPriority(EXTI15_10_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_EnableIRQ(EXTI9_5_IRQn);
NVIC_EnableIRQ(EXTI15_10_IRQn);
}
extern "C" {
void EXTI9_5_IRQHandler(void)
{
if (!new_shot && !shot_start)
{
/* us before ms after */
start_time = TIM6->CNT / 1e3 + TIM1->CNT;
shot_start = true;
}
/* Clear interrupt flag*/
EXTI->PR |= EXTI_PR_PR9;
}
void EXTI15_10_IRQHandler(void)
{
if (shot_start && !new_shot)
{
/* us before ms after , */
end_time = TIM6->CNT / 1e3 + TIM1->CNT;
new_shot = true;
shot_start = false;
}
/* Clear interrupt flag*/
EXTI->PR |= EXTI_PR_PR10;
}
}I'm not able to test if this issue still exists if I'm not using FreeRTOS because it's a complex system but I'm pretty convinced that FreeRTOS does not have any impact on this since there is always an ongoing USART communication which works fine and most of the time the interrupts are fired correctly! The problem seems that STM32 sometimes misinterprets on which edge interrupt should be triggered.
If any other information is necessary please let me know!
Regards,
Kuchx
