I am working with STM32F407VGT6 MCU and I am having problem with external interrupts (EXTI). I have configured two pins as EXTI and they are PE7 and PE15. They are connected to HALL sensors driver and are detecting toot edges of trigger wheel. Ones is primary source with multiple tooth and other wheel is single tooth wheel which confirms position. The thing is they can work individually on their own without issues, but if I connect both of them, they start to interfere with each other and I am loosing position sync, because MCU is detecting false edges. I can recreate same behavior by connecting either pin to low signal and other to HALL driver. But if I disable EXTI and leave pin as a input the problem goes away. I have no idea what's going on here.
Also, I had issues with PE15 and EXTI before and it might be related to this. The EXTI was working only in EXTI_Trigger_Rising and EXTI_Trigger_Rising_Falling mode, but EXTI_Trigger_Falling was giving random edge detection, and only solution to this was to listen for both edges and debounce the one that I don't need. I couldn't find anything about this in datasheet.
This STM32F4 is giving me head aches and I running out of options. Well, the last option is to reroute the hall drivers to other pins and use input capture/timer.
Primary wheel config:
void Trigger_Configure_Primary(void) {
// GPIO
GPIOE->OSPEEDR |= (0x03 << (2 * 15)); // high speed
// EXTI
SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI15_PE; // Tell system that you will use PE15 for EXTI15
EXTI->RTSR |= (1 << 15); // rising edge
EXTI->FTSR |= (1 << 15); // falling edge
EXTI->IMR |= (1 << 15); // Unmask EXTI15 interrupt
EXTI->PR |= (1 << 15); // Clear pending bit
/* Add IRQ vector to NVIC */
NVIC_SetPriority(EXTI15_10_IRQn, 0);
NVIC_EnableIRQ(EXTI15_10_IRQn);
}
Secondary wheel config:
void Trigger_Configure_Secondary(void) {
// GPIO
GPIOE->OSPEEDR |= (0x03 << (2 * 7)); // high speed
// EXTI
SYSCFG->EXTICR[1] = SYSCFG_EXTICR2_EXTI7_PE; // Tell system that you will use PE7 for EXTI7
EXTI->RTSR |= (1 << 7); // rising edge
EXTI->FTSR |= (1 << 7); // falling edge
EXTI->IMR |= (1 << 7); // Unmask EXTI7 interrupt
EXTI->PR |= (1 << 7); // Clear pending bit
/* Add IRQ vector to NVIC */
NVIC_SetPriority(EXTI9_5_IRQn, 0);
NVIC_EnableIRQ(EXTI9_5_IRQn);
}
IRQ handlers:
void EXTI9_5_IRQHandler(void) {
__disable_irq();
/* Make sure that interrupt flag is set */
if ((EXTI->PR & EXTI_Line7) != 0) {
// Secondary trigger IRQ
uint32_t now_nt = GET_TIMESTAMP();
uint8_t edge = ((GPIOE->IDR & SECONDARY_PIN) == 0 ? 0 : 1);
TD_Decode_Secondary_Trigger_Event(
now_nt,
edge
);
#ifdef DEBUG
// Stats
secondary_ticks = (GET_TIMESTAMP() - now_nt);
#endif
/* Clear interrupt flag */
EXTI->PR |= EXTI_Line7;
++s_cnt;
}
__enable_irq();
}
void EXTI15_10_IRQHandler(void) {
__disable_irq();
/* Make sure that interrupt flag is set */
if ((EXTI->PR & EXTI_Line15) != 0) {
// Primary trigger IRQ
uint32_t now_nt = GET_TIMESTAMP();
uint8_t edge = ((GPIOE->IDR & PRIMARY_PIN) == 0 ? 0 : 1);
if (primary_edge == edge) {
TD_Decode_Primary_Trigger(now_nt);
}
#ifdef DEBUG
// Stats
primary_ticks = (GET_TIMESTAMP() - now_nt);
#endif
/* Clear interrupt flag */
EXTI->PR |= EXTI_Line15;
++p_cnt;
}
__enable_irq();
}