cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt handling with STM32F4xx_DSP_StdPeriph_Lib (EXTI0)

simo zz
Senior
Posted on October 30, 2017 at 13:38

Hello,

I am studying the STM32F4xx_DSP_StdPeriph_Lib and I am trying to understand how to handleEXTI0 interrupts using the STM32F4xx Discovery Board.

The firmware should execute the interrupt when the GPIOA0 is triggered (in this case with the User button) and sequentially toggle the GPIOD[12:15] pins.

The code I wrote is the following:

#include <stm32f4xx.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_exti.h>
uint8_t gpioDIndex;
// ISR
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0))
{
EXTI_ClearITPendingBit(EXTI_Line0);
gpioDIndex++;
if(gpioDIndex > 3)
gpioDIndex = 0;
}
}
int main(void)
{
// GPIO, NVIC and EXTI declarations
GPIO_InitTypeDef GPIO_t;
NVIC_InitTypeDef NVIC_t;
EXTI_InitTypeDef EXTI_t;
// SYCFG and GPIOA GPIOD Clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);
// configure GPIOA0 as input
GPIO_t.GPIO_Pin = GPIO_Pin_0;
GPIO_t.GPIO_Mode = GPIO_Mode_IN;
//GPIO_t.GPIO_OType = GPIO_OType_PP;
GPIO_t.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_t.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_t);
// Configure GPIOD[12:15] as output
GPIO_t.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_t.GPIO_Mode = GPIO_Mode_OUT;
GPIO_t.GPIO_OType = GPIO_OType_PP;
GPIO_t.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_t.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_t);
// Configure external interrupt for PA0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_t.EXTI_Line = EXTI_Line0;
EXTI_t.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_t.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_t.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_t);
// enable EXTI0 interrupt for NVIC
NVIC_t.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_t.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_t.NVIC_IRQChannelSubPriority = 0;
NVIC_t.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_t);
gpioDIndex = 1;
uint16_t gpioDValue[4] = {GPIO_Pin_12, GPIO_Pin_13, GPIO_Pin_14, GPIO_Pin_15};
while(1)
{
GPIO_SetBits(GPIOD, gpioDValue[gpioDIndex]);
}
return 0;
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

However, it seems the interrupt is never executed since the GPIOD[12:15] state is not changing.

What's wrong with my code on interrupt handling ?

Thank you in advance,

Simon

23 REPLIES 23
Posted on October 30, 2017 at 16:01

reicher.romain

‌ I solved the debugger problem (

I was missing ncurses5:i386 on my debian x86_64).

I can run it now but I cannot emulate the execution of the interrupt, as the debug remain stuck into the while (1) loop.

Any hint ?

Regards,

Simon

Posted on October 30, 2017 at 16:16

This hardly looks to be a robust/safe test, what happens if multiple bits are asserted?

 if(EXTI->PR == EXTI_PR_PR0)
 EXTI->PR = EXTI_PR_PR0;

>>This is a C code in a C file. I am not using C++.

This can be a command line setting, you're using some non-portable C methods for defining variables in the middle of the compound statement.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 30, 2017 at 16:20

Your code run correctly for me (see capture below)

Breakpoint is reach when PA0 [USER_BLUE_BUTTON] is pressed and PORTD LED onbard are set.

I can share with you SW4STM32 project. But I'm use Windows OS.

To see if interrupt occurs, you must place a breakpoint into EXTI0_IRQHandler() and run the debugger.

0690X00000608oDQAQ.png

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on October 30, 2017 at 16:23

I wonder how does this work with SWD/JTAG

 GPIOA->MODER |= 0x55555554;
JW

Posted on October 30, 2017 at 16:34

Waclawek.Jan

‌ that code is old and it's just an example. I am working on SPL since I don't want to go

bitwise crazy.

Posted on October 30, 2017 at 16:39

reicher.romain

‌, I notice you put the

EXTI0_IRQHandler inside the file

stm32f4xx_it.c while I don't, because I don't have this file included in my project. I only have its header file

stm32f4xx_it.h included (automatically).

Where is the stm32f4xx_it.c file ?

The interrupt in my code is never executed.

Posted on October 30, 2017 at 16:52

I don't want to go bitwise crazy

This is why the CMSIS mandates device headers with symbols.

[agenda] Pity ST still does not define the bitfields values. [/agenda]

that code is old and it's just an example

The point is still the same: that code might've worked with SWD as the write might've been ignored due to vicinity of clock enable, see 'Delay after an RCC peripheral clock enabling' erratum. You still have a similar sequence in the 'new' code; I can imagine an aggressive optimization setting may get these close enough for the erratum to bite.

So instead of jumping around, I'd suggest to read back and check all the relevant GPIO, SYSCFG, EXTI, NVIC registers, check the content of vector table against the location of the ISR, and read the disasm of the ISR.

JW

simo zz
Senior
Posted on October 30, 2017 at 17:53

OK, I can figure out where the problem comes from.

When I create the project and decide to use SPL, the openstm32 somehow generates a wrong startup_stms which misses a lot of definitions. Of course misses theEXTI0_IRQHandler definition as well. I attach the wrong Assembly file generated by openstm

If I choose to use HAL library from the first steps of project settings, the project manager setup attaches the correct Assembly file with all the interrupts definitions..

The correct Assembly file inside the SPL folder is located at

SW4STM32/firmwares/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Device/ST/STM32F4xx/Source/Templates/SW4STM32/startup_stm32f40xx.s

If I use the correct Assembly file everything works, but it should be generated/copied automatically..

See that the SPL version I am using is the 1.8.0, the latest.

Is this error related to openstm32 or to SPL ?

Simon

________________

Attachments :

startup_stm32_WRONG.s : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyET&d=%2Fa%2F0X0000000b6G%2FijRrHJVQU_n0MfEz2uR.8Umyz2f7usSTIUy3oG35FIQ&asPdf=false
Posted on October 30, 2017 at 17:52

Hi Simo,

It does not matter if the function EXTI0_IRQHandler is written in the file stm32f4xx_it.c you can call it from anywhere.

I just used a Standard Periph Library template file.

Moreover you will find this stm32f4xx_it.c and the associated .h in one of the examples of this library.

The function EXTI0_IRQHandler is called from the interrupt vector that has the same name.

All interrupt vectors are in the file startup_stm32f4xx.s (check if this file is include into the project)

I have three questions to ask you:

  1. Are you able to debug a simple toggle program. and you place a breakpoint? In this way you can validate the execution in debug mode.
  2. When to start the debugger, can you execute the code step by step?
  3. When you stop the debugger to which line of code this one stops?

Please check that your program does not stop on a Hard Fault which could signal that your EXTI0 interrupts are not properly called (startup_stm32f4xx.s missing)

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on October 30, 2017 at 18:15

Interesting.

http://www.openstm32.org/forumthread266