2020-03-06 09:23 PM
The subsequent pair of the HAL_EXTI_GetConfigLine() and HAL_EXTI_SetConfigLine() configures EXTI incorrectly.
The attached demonstration.zip contains a demonstration program of this program.
How to reproduce
Follow this step to reproduce the problem
If you see both Blue and Red LED on, it is problematic.
Explanation of the demo program
This program is toggling Red and Blue LED alternately in the EXT call back routine. This EXTI interrupt is tied with the B1 button switch input ( EXTI 13 ).
Thus, it you must see red or blue LED for each time you push the B1 button switch on the Nucleo board.
But you can see both red and blue LED on. That mean, EXTI interrupt is raised continuously. This is not expected case.
The actual problem is inside the HAL_EXTI_SetConfigLine() API. In this program, this API is simply restores the saved EXTI configuration by preceding HAL_EXTI_GetConfigLine().
```
// Get the handle of the EXTI 13 ( B1 switch )
HAL_EXTI_GetHandle(&hexti_b1, EXTI_LINE_13);
// Save the configuration of the EXTI 13. This is set as edge interrupt, by initializer.
HAL_EXTI_GetConfigLine(
&hexti_b1,
&hexti_b1_config
);
// Clear the EXTI 13. Interrupt is disabled.
HAL_EXTI_ClearConfigLine(&hexti_b1);
// Restore the EXTI13 configuration. Now, it should be edge trigger.
HAL_EXTI_SetConfigLine(&hexti_b1, &hexti_b1_config);
```
Control experiment
You can import the d002-nucleo-g431rb-control project from the attached demonstration.zip to your work space. If you run this program on the Nucleo G431RB board, you will see the green LED blinks for each time you push the B1 button switch. This is expected behavior.
Please investigate and fix.
Takemasa
2020-03-06 10:26 PM
2020-03-07 02:48 AM
Make sure that the interrupt handler clears EXTI->PR before it does anything else.
This example works on a STM32F476 Discovery board, which has buttons and leds elsewhere
void EXTI15_10_IRQHandler(void) {
static int f;
uint32_t pr;
pr = EXTI->PR;
if(pr & (1 << 11)) { // check for bit 11
EXTI->PR = 1 << 11; // clear bit 11
f = !f;
if(f) {
GPIOD->BSRR = 1 << 5; GPIOI->BSRR = 1 << 1; // toggle leds
} else {
GPIOD->BSRR = 1 << 21; GPIOI->BSRR = 1 << 17; toggle leds
}
}
}
void test_exti(void) {
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOIEN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
GPIOD->MODER = (GPIOD->MODER & ~GPIO_MODER_MODER5) | GPIO_MODER_MODER5_0; // PD5 output, led #1
GPIOI->MODER = (GPIOI->MODER & ~GPIO_MODER_MODER1) | GPIO_MODER_MODER1_0; // PI1 output, led #2
GPIOI->MODER = (GPIOI->MODER & ~GPIO_MODER_MODER11); // PI11 input, pushbutton
SYSCFG->EXTICR[2] = (SYSCFG->EXTICR[2] & 0xFFFF0FFF) | 0b1000 << 12; // EXTICR3 (=EXTICR[2]) bits 12:15 to 0b1000, map PI11 to EXTI11
EXTI->RTSR |= EXTI_RTSR_TR11; // interrupt on rising edge
EXTI->IMR |= EXTI_IMR_IM11; // enable EXTI interrupt request
NVIC_EnableIRQ(EXTI15_10_IRQn); // enable interrupt in NVIC
while(1) {
}
}
2020-03-07 11:21 PM
Hi
By the way, thanks for your link. I didn't know there is git repository of the HAL.
2020-03-07 11:24 PM
Thanks
But it is touching hardware directory. I hesitate to program the register and that is the motivation of using HAL.
2020-03-08 12:03 AM
May I ask why do you hesitate?
The register interface is extensively documented, and apparently working. The HAL functions are barely documented and apparently not working.
2020-03-08 12:45 AM
You have not done your homework... ;) HAL_EXTI_ClearConfigLine() disables EXTI. HAL_EXTI_RegisterCallback() registers callback function. This API is more sane as you can have a separate callback function for each EXTI line. And for this to work, you have to call HAL_EXTI_IRQHandler() from interrupt handler.
I'm also against HAL/CubeMX code, because it's full of major flaws, bugs, inflexible and bloated, but, if you use it, at least do it correctly and thoroughly. :)
2022-04-16 11:45 PM
Hello,
after two yeras, I don't know if you will read this mail, but I am trying to clarify some things about HAL_EXTI_*** and I have had problems with systems STM32F4xxx (I have perennial interrupts).
In point 2 you say
: "In F746 code you are mixing HAL_GPIO_EXTI _ *** () with HAL_EXTI _ *** ()".
Is this not allowed?
The HAL_GPIO_EXTI _ *** part is automatically generated by MX;
conflicts with the HAL_EXTI _ ***?
is it possible to deactivate it or do you have to delete it by hand?
lv
2022-04-23 12:39 PM
I write my own code and libraries and don't use code generation and the whole Cube/HAL/LL broken bloatware. As for those EXTI APIs - it probably depends on specific functions used. Analyze the code of both and look at which functions will (or not) be conflicting in which usage scenarios.
You are torturing yourself by using libraries written by incompetent fools... ;)
2022-04-24 01:27 AM
Salutations, your answer put me in a good mood ... or maybe not.
I'll try to be clearer with an example in a few days.
LV