2019-08-30 12:41 AM
External interrupt errata?
I have setup EXTI_Line12 and EXTI_Line14 to generate en interrupt.
But the EXTI15_10_IRQHandler() fails to execute a second interrupt if it happens too close to the first interrupt.
But it seems only happen when I use bit-banding to check and clear the bits in the EXTI->PR register. If I access the EXTI->PR directly at the normal address it does not happen.
Is this a known problem?
I read something similar in another chip errata (but on an STM8):
When an interrupt handler starts executing a service routine and an external interrupt (EXTI) request is pending or arrives during the same cycle, the external interrupt is not executed.
void EXTI15_10_IRQHandler(void)
{
GPIO_SetBits(GPIOB, GPIO_Pin_10); // Toggle PB10 to show we are entering the interrupt
GPIO_ResetBits(GPIOB, GPIO_Pin_10);
// NOTE:
// PERIPH_GET_BIT is a macro that reads one bit using bit-banding
// PERIPH_SET_BIT is a macro that sets a bit using bit-banding
#ifdef USE_BIT_BANDING
if (PERIPH_GET_BIT(EXTI->PR, EXTI_Line12))
#else
if (EXTI->PR & EXTI_Line12)
#endif
{
// Clear the EXTI line pending bit
#ifdef USE_BIT_BANDING
PERIPH_SET_BIT(EXTI->PR, EXTI_Line12);
#else
EXTI->PR = EXTI_Line12;
#endif
// Keep PB10 high as long as we do stuff A
GPIO_SetBits(GPIOB, GPIO_Pin_10);
do_stuff_a();
GPIO_ResetBits(GPIOB, GPIO_Pin_10);
}
#ifdef USE_BIT_BANDING
if (PERIPH_GET_BIT(EXTI->PR, EXTI_Line14))
#else
if (EXTI->PR & EXTI_Line14)
#endif
{
// Clear the EXTI line pending bit
#ifdef USE_BIT_BANDING
PERIPH_SET_BIT(EXTI->PR, EXTI_Line14);
#else
EXTI->PR = EXTI_Line14;
#endif
// Keep PB10 high as long as we do stuff B
GPIO_SetBits(GPIOB, GPIO_Pin_10);
do_stuff_b();
GPIO_ResetBits(GPIOB, GPIO_Pin_10);
}
}
Solved! Go to Solution.
2019-08-30 03:27 PM
You are not supposed to use a read-modify-write to clear the EXTI->PR bit, you should use a direct write. Bit-bandig writes are internally read-modify-write.
While this writeup is focused on the timer, the point is the same. (Sorry for the formatting, messed up courtesy of ST's forum software migration.)
JW
2019-08-30 01:05 AM
If I remember correctly, there was a race condition problem when you cleared an interrupt flag late in the handler, while another instance happened.
This is AFAIK a core-related issue (ARM), not STM32 related.
2019-08-30 01:08 AM
Yes, I know. I hade that problem in a timer interrupt where I only cleared the interrupt flag and toggle an IO-pin. I needed to insert a dummy read/write access to a variable before leaving the interrupt to let the interrupt flag get time to clear.
2019-08-30 03:27 PM
You are not supposed to use a read-modify-write to clear the EXTI->PR bit, you should use a direct write. Bit-bandig writes are internally read-modify-write.
While this writeup is focused on the timer, the point is the same. (Sorry for the formatting, messed up courtesy of ST's forum software migration.)
JW