cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 HAL_EXTI_SetConfigLine() configures EXTI incorrectly.

Takemasa
Associate III

The subsequent pair of the HAL_EXTI_GetConfigLine() and HAL_EXTI_SetConfigLine() configures EXTI incorrectly.

  • CubeIDE 1.3.0
  • F7 v1.16.0

The attached demonstration.zip contains a demonstration program of this program.

How to reproduce

Follow this step to reproduce the problem

  1. Import the project "d002-nucleo-f746-exti" to CubeIDE workspace.
  2. Build
  3. Run the built program on the Nucleo F746ZG board.

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

9 REPLIES 9
Piranha
Chief II
  1. G431 source code files are empty.
  2. In F746 code you are mixing HAL_GPIO_EXTI_***() with HAL_EXTI_***().
  3. RTFM.
berendi
Principal

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) {
	}
}

Hi

  1. Thanks. I have re-uploaded.
  2. Yes. It is intended. There is no way to receive the interrupt by HAL_EXTI_*** call back, and there is no way to disable/enable EXTI from HAL_GPIO_EXTI_**. Mixing both is the only way to disable / enable interrupt.
  3. I did. And wrote my program. What are you going to point out?

By the way, thanks for your link. I didn't know there is git repository of the HAL.

Thanks

But it is touching hardware directory. I hesitate to program the register and that is the motivation of using HAL.

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.

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. 🙂

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

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... 😉

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