Skip to main content
Visitor II
March 7, 2020
Question

STM32F7 HAL_EXTI_SetConfigLine() configures EXTI incorrectly.

  • March 7, 2020
  • 2 replies
  • 4114 views

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

    This topic has been closed for replies.

    2 replies

    Graduate II
    March 7, 2020
    1. G431 source code files are empty.
    2. In F746 code you are mixing HAL_GPIO_EXTI_***() with HAL_EXTI_***().
    3. RTFM.
    TakemasaAuthor
    Visitor II
    March 8, 2020

    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.

    Graduate II
    March 8, 2020

    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. :)

    Visitor II
    March 7, 2020

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

    TakemasaAuthor
    Visitor II
    March 8, 2020

    Thanks

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

    Visitor II
    March 8, 2020

    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.