2017-10-30 05:38 AM
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
Solved! Go to Solution.
2017-10-30 09:01 AM
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
2017-10-30 09:16 AM
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.
2017-10-30 09:20 AM
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.
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.
2017-10-30 09:23 AM
I wonder how does this work with SWD/JTAG
GPIOA->MODER |= 0x55555554;
JW
2017-10-30 09:34 AM
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.2017-10-30 09:39 AM
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.
2017-10-30 09:52 AM
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
2017-10-30 09:53 AM
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=false2017-10-30 10:52 AM
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:
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.
2017-10-30 11:15 AM
Interesting.