cancel
Showing results for 
Search instead for 
Did you mean: 

Bizarre GPIO behaviour: HAL_GPIO_TogglePin() doesn't allow toggle multiple pins

JTang.1
Associate II

I am using the STM32F4 family. I have configured a GPIO pin as output push pull with no pullups. Speed is also set to low frequency. On some occasions, the GPIO pin seems to switch polarity on its own eg. when I set to low, it will sometimes switch it back to high. There is nowhere else in my code that sets or resets this pin. I have also added traces to the code to ensure that the pins are set and reset accordingly and that there is no other possible code paths that could set or reset this pin. It is hard to reproduce this behaviour and it can sometimes take very long for it to occur.

I now believe there is something else that could be causing this issue. Can anyone offer any plausible explanation as to why this could happen? What can I do or try?

Thanks in advance.

16 REPLIES 16
TDK
Guru

Using the HAL_GPIO_TogglePin function would have prevented this issue:

/**
  * @brief  Toggles the specified GPIO pins.
  * @param  GPIOx Where x can be (A..K) to select the GPIO peripheral for STM32F429X device or
  *                      x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices.
  * @param  GPIO_Pin Specifies the pins to be toggled.
  * @retval None
  */
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
 
  if ((GPIOx->ODR & GPIO_Pin) == GPIO_Pin)
  {
    GPIOx->BSRR = (uint32_t)GPIO_Pin << GPIO_NUMBER;
  }
  else
  {
    GPIOx->BSRR = GPIO_Pin;
  }
}

If you feel a post has answered your question, please click "Accept as Solution".

@TDK​ There are minors visiting this forum, next time could you please mark this kind of code as don't try this at home

The code seems perfect to me. Maybe I'm missing the joke here...

If you feel a post has answered your question, please click "Accept as Solution".

PA0 is low, PA1 is high, toggle them both with

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1);

What happens? Try following the code.

Can you see it now how deceptive it is?

A one-liner function bloated to 21 lines, comments explaining trivial aspects in true Captain Obvious style, a useless but possibly dangerous assert.

The "documentation" states it toggles pins, in plural. Twice, for emphasis. Then it goes into some detail about which GPIOs can be used. Only existing ones, thank you again, Captain Obvious.

The program lines doing the actual work are not commented at all. Comments are there apparently only to fill a quota enforced by some nonsense coding standard.

It does everything possible to draw the attention away from the lines (not) doing the actual work.

That it comes from the chip maker itself, endorsed as the starting point for people starting to learn embedded software development and are perceived as somehow authorative, does not help either.

The only way this piece of code is useful is to demonstrate how not to do it. Please use it responsibly, only as a counter-example.

Piranha
Chief II

I want to note that @berendi​ has managed to strip off one instruction from our previous offered versions. The optimization is based on this text in reference manuals: "Note: If both BSx and BRx are set, BSx has priority." Thanks to him, now my pin toggle implementation is as simple as this:

hPort->BSRR = (fPins << 16u) | (~hPort->ODR & fPins);

The flaws of pin toggle code have been reported and improvements provided many times (for example here and here) by many people. This version is the ultimate evolution of all those suggestions.

How many years will it require for ST to fix such a "complex and enormous" feature as a pin toggling in HAL and LL drivers?

@Amel NASRI​ ​, @Imen DAHMEN​, someone?​

Imen.D
ST Employee

Hello All,

Thank you for your contribution and reported issues .

I escalated the related threads internally to the IP Owner to fix the GPIO HAL and LL drivers.

Thank you for your understanding.

Best Regards,

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen