cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f4 external interrupt problem

EPora.1
Associate II

Hello,

I'm using an stm32f411ce with an lsm6ds3 IMU and I want to trigger a read from the IMU with an EXTI. I've set it all in the code below and activated the interrupt on the IMU. the interrupt is set in PR register but handler is never called.

Thanks,

Eyal

void EXTIsetup(void)
{
	//PB3 ---- IMU INT1 gyro
	//PB12 --- IMU INT2 accel
	//PB0 ---- BAR INT
	
	
	//1. Enable the SYSCFG/AFIO bit in RCC register 
	//2. Configure the EXTI configuration Register in the SYSCFG/AFIO
	//3. Disable the EXTI Mask using Interrupt Mask Register (IMR)
	//4. Configure the Rising Edge / Falling Edge Trigger
	//5. Set the Interrupt Priority
	//6. Enable the interrupt
	
	RCC ->AHB1ENR |= (1 << 1); //enable the GPIOB bus clock
	
	//set the moder values
	//GPIOB ->MODER &= ~(3 << 0);
	GPIOB ->MODER &= ~(3 << 6);
	//GPIOB ->MODER &= ~(3 << 24);
	
	//set pull down on all three pins
	//GPIOB ->PUPDR |= (1 << 1);
	GPIOB ->PUPDR |= (1 << 7);
	//GPIOB ->PUPDR |= (1 << 25);
	
	RCC ->APB2ENR |= (1 << 14); //enable SYSCNFG
	
	//SYSCFG ->EXTICR[0] |= (1 << 0); //EXTI0 --> PB PB0
	SYSCFG ->EXTICR[0] |= (1 << 12); //EXTI3 --> PB PB3
	//SYSCFG ->EXTICR[3] |= (1 << 0); //EXTI12 --> PB PB12
	
	//EXTI ->IMR |= (1 << 0); //dsb mask MR0
	EXTI ->IMR |= (1 << 3); //dsb mask MR3
	//EXTI ->IMR |= (1 << 12); //dsb mask MR12
	
	//EXTI ->RTSR |= (1 << 0); //enable rising edge on line 0
	EXTI ->RTSR |= (1 << 3); //enable rising edge on line 3
	//EXTI ->RTSR |= (1 << 12); //enable rising edge on line 12
	
	//EXTI ->FTSR &= ~(1 << 0); //disable falling edge on line 0
	EXTI ->FTSR &= ~(1 << 3); //disable falling edge on line 3
	//EXTI ->FTSR &= ~(1 << 12); //disable falling edge on line 12
	
	
	//setting the priority of the interrupts
	NVIC_SetPriority(EXTI3_IRQn, 1);
	//NVIC_SetPriority (EXTI4_IRQn, 1);
	
	//enable the interrupts
	NVIC_EnableIRQ(EXTI3_IRQn);
	//NVIC_EnableIRQ(EXTI4_IRQn);
	
}

1 ACCEPTED SOLUTION

Accepted Solutions

So it has C++ linkage, not C linkage, which means the linker doesn't see it as EXTI3_IRQHandler.

To fix, surround it in extern "C" braces.

extern "C" {
 
void EXTI3_IRQHandler() {
  ...
}
 
}

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

17 REPLIES 17
TDK
Guru

Looks like you're doing the right things. Are interrupts globally enabled? Can you look in peripheral view and verify that all relevant register settings are correct? Particularly, SYSCFG, which may need a delay after setting the clock before modifying values.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for your response!

What do you mean by interrupts are globally enabled? all of the registers are seem to set correctly using an st-link.

__enable_irq();

They should be enabled by default.

If you feel a post has answered your question, please click "Accept as Solution".

> interrupt is set in PR register but handler is never called

How do you check that?

Check, if the handler's address is correctly inserted in the vector table. This is best to be seen in disassembly view.

Make sure you are not stuck in an ISR with higher priority.

Some interrupt-related remarks here.

JW

I'll check that

I'm using the Keil IDE pre generated startup and core files so I guess it should be correct. but also I've checked the vector table and it says that

EXTI3_IRQn                  = 9,

so that should be correct.

I didn't set any other interrupt and the priority is 1, from what I understood it's the lowest

You did not answer my question, how do you check that the handler is not executed.

> I'm using the Keil IDE pre generated startup and core files so I guess it should be correct.

Don't guess, check it.

> EXTI3_IRQn = 9,

No that's not the vector table; the vector table is in the startup code, located normally at the beginning of FLASH, unless you've changed the VTOR register.

https://github.com/STMicroelectronics/STM32CubeF4/blob/4aba24d78fef03d797a82b258f37dbc84728bbb5/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/arm/startup_stm32f411xe.s#L55

Nonetheless, if interrupts are enabled - both EXTI3 and globally - and if respective bit in EXTI's pending register is set, then some ISR must be executed - so, in debugger, where is the program counter?

JW

EPora.1
Associate II

In the int handler I have added an LED toggle and turned off the bit 3 in the PR register by writing 1 to it. this never happens and the bit 3 is active on.

the vector table is as default.

This is what I see in the NVIC window 0693W00000FChWOQA1.pngand also in the code I just have a while loop after the EXTI and IMU initialization and whenever I stop the code with the debugger it goes to the brakepointed line0693W00000FChWdQAL.png

TDK
Guru

VECTACTIVE = 0x19, which means the processor is currently within the EXTI3_IRQ interrupt. So the interrupt is firing just fine.

Likely you just don't have the function implemented in your program anywhere so it defaults to the default handler. Check that the function you want it to call matches exactly with the name in the vector table (EXTI3_IRQHandler) and that it has C linkage. The output from the linker should tell you where EXTI3_IRQHandler is pointing.

If you feel a post has answered your question, please click "Accept as Solution".