Skip to content

Commit

Permalink
boards/stm32: use GPIO LL for LEDs
Browse files Browse the repository at this point in the history
This fixes a race in `LED<NUM>_TOGGLE`, which is a read-copy-write
operation. Any access to a GPIO pin on the same GPIO port that
happens concurrently could result in data corruption. Using the
GPIO LL API, which is thread-safe, fixes the issue.

Note: The used GPIO LL functions will work even in when the GPIO LL
      module is not used.
  • Loading branch information
maribu committed Apr 30, 2024
1 parent 6ac165a commit 09e8d9e
Show file tree
Hide file tree
Showing 43 changed files with 174 additions and 86 deletions.
3 changes: 3 additions & 0 deletions boards/alientek-pandora/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 7
#define LED0_PORT GPIO_PORT_E /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_E

#define LED1_PIN_NUM 8
#define LED1_PORT GPIO_PORT_E /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_E

#define LED2_PIN_NUM 9
#define LED2_PORT GPIO_PORT_E /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_E

/** @} */
Expand Down
4 changes: 4 additions & 0 deletions boards/b-l072z-lrwan1/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,19 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 5
#define LED0_PORT GPIO_PORT_A /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_A

#define LED1_PIN_NUM 5
#define LED1_PORT GPIO_PORT_B /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_B

#define LED2_PIN_NUM 6
#define LED2_PORT GPIO_PORT_B /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_B

#define LED3_PIN_NUM 7
#define LED3_PORT GPIO_PORT_B /**< GPIO port of LED 3 */
#define LED3_PORT_NUM PORT_B
/** @} */

Expand Down
2 changes: 2 additions & 0 deletions boards/b-l475e-iot01a/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 5
#define LED0_PORT GPIO_PORT_A /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_A

#define LED1_PIN_NUM 14
#define LED1_PORT GPIO_PORT_B /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_B
/** @} */

Expand Down
3 changes: 3 additions & 0 deletions boards/b-u585i-iot02a/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 13
#define LED0_PORT GPIO_PORT_E /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_E

#define LED1_PIN_NUM 6
#define LED1_PORT GPIO_PORT_H /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_H

#define LED2_PIN_NUM 7
#define LED2_PORT GPIO_PORT_H /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_H
/** @} */

Expand Down
1 change: 1 addition & 0 deletions boards/blackpill-stm32f103c8/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern "C" {
* @name Macros for controlling the on-board LED.
* @{
*/
#define LED0_PORT GPIO_PORT_B /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_B /**< GPIO Port number the LED is connected to */
#define LED0_PIN_NUM 12 /**< Pin number the LED is connected to */
/** @} */
Expand Down
1 change: 1 addition & 0 deletions boards/blackpill-stm32f103cb/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern "C" {
* @name Macros for controlling the on-board LED.
* @{
*/
#define LED0_PORT GPIO_PORT_B /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_B /**< GPIO Port number the LED is connected to */
#define LED0_PIN_NUM (12) /**< Pin number the LED is connected to */
/** @} */
Expand Down
1 change: 1 addition & 0 deletions boards/bluepill-stm32f030c8/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 13
#define LED0_PORT GPIO_PORT_C /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_C
#define LED0_IS_INVERTED 1
/** @} */
Expand Down
1 change: 1 addition & 0 deletions boards/common/blxxxpill/include/board_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern "C" {
* @{
*/
#ifndef LED0_PORT_NUM
#define LED0_PORT GPIO_PORT_C /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_C /**< GPIO Port number the LED is connected to */

Check warning on line 37 in boards/common/blxxxpill/include/board_common.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
#endif
#ifndef LED0_PIN_NUM
Expand Down
3 changes: 3 additions & 0 deletions boards/common/iotlab/include/board_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,15 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 2
#define LED0_PORT GPIO_PORT_D /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_D

#define LED1_PIN_NUM 5
#define LED1_PORT GPIO_PORT_B /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_B

#define LED2_PIN_NUM 10
#define LED2_PORT GPIO_PORT_C /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_C
/** @} */

Expand Down
6 changes: 6 additions & 0 deletions boards/common/nucleo144/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,29 @@ extern "C" {
#if defined(CPU_MODEL_STM32L496ZG) || defined(CPU_MODEL_STM32L4R5ZI) || \
defined(CPU_MODEL_STM32L552ZE) || defined(CPU_MODEL_STM32U575ZI)
#define LED0_PIN_NUM 7
#define LED0_PORT GPIO_PORT_C /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_C
#else
#define LED0_PIN_NUM 0
#define LED0_PORT GPIO_PORT_B /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_B
#endif

#define LED1_PIN_NUM 7
#define LED1_PORT GPIO_PORT_B /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_B

#if defined(CPU_MODEL_STM32L552ZE)
#define LED2_PIN_NUM 9
#define LED2_PORT GPIO_PORT_A /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_A
#elif defined(CPU_MODEL_STM32U575ZI)
#define LED2_PIN_NUM 2
#define LED2_PORT GPIO_PORT_G /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_G
#else
#define LED2_PIN_NUM 14
#define LED2_PORT GPIO_PORT_B /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_B
#endif
/** @} */
Expand Down
1 change: 1 addition & 0 deletions boards/common/nucleo32/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 3
#define LED0_PORT GPIO_PORT_B /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_B
/** @} */

Expand Down
2 changes: 2 additions & 0 deletions boards/common/nucleo64/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ extern "C" {
*/
#if defined(CPU_MODEL_STM32F302R8) || defined(CPU_MODEL_STM32L433RC)
#define LED0_PIN_NUM 13
#define LED0_PORT GPIO_PORT_B /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_B
#else
#define LED0_PIN_NUM 5
#define LED0_PORT GPIO_PORT_A /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_A
#endif
/** @} */
Expand Down
128 changes: 60 additions & 68 deletions boards/common/stm32/include/stm32_leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
*
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*
* This idea is that STM32 boards only define the pin and port number of LEDs
* and this header provides the rest of the defines
* This idea is that STM32 boards only define the pin number, port number and
* port of LEDs and this header provides the rest of the defines
*/

#ifndef STM32_LEDS_H
#define STM32_LEDS_H

/* Using gpio_ll_arch for the gpio_port() function. This even works when
* GPIO LL is not in used */
/* Using gpio_ll_arch for GPIO access. This even works when GPIO LL is not in
* used, as long as we do not need `gpio_ll_init()` etc. */
#include "gpio_ll_arch.h"
#include "kernel_defines.h"

Expand All @@ -37,115 +37,107 @@ extern "C" {
* @{
*/
#if defined(LED0_PORT_NUM) && defined (LED0_PIN_NUM)
# define LED0_PORT ((GPIO_TypeDef *)gpio_port(LED0_PORT_NUM))
# define LED0_PIN GPIO_PIN(LED0_PORT_NUM, LED0_PIN_NUM)
# define LED0_MASK (1 << LED0_PIN_NUM)
# define LED0_PIN GPIO_PIN(LED0_PORT_NUM, LED0_PIN_NUM)
# define LED0_MASK (1 << LED0_PIN_NUM)
# if IS_ACTIVE(LED0_IS_INVERTED)
# define LED0_ON (LED0_PORT->BSRR = (LED0_MASK << 16))
# define LED0_OFF (LED0_PORT->BSRR = LED0_MASK)
# define LED0_ON gpio_ll_clear(LED0_PORT, LED0_MASK)
# define LED0_OFF gpio_ll_set(LED0_PORT, LED0_MASK)
# else
# define LED0_ON (LED0_PORT->BSRR = LED0_MASK)
# define LED0_OFF (LED0_PORT->BSRR = (LED0_MASK << 16))
# define LED0_ON gpio_ll_set(LED0_PORT, LED0_MASK)
# define LED0_OFF gpio_ll_clear(LED0_PORT, LED0_MASK)
# endif
# define LED0_TOGGLE (LED0_PORT->ODR ^= LED0_MASK)
# define LED0_TOGGLE gpio_ll_toggle(LED0_PORT, LED0_MASK)
#endif

#if defined(LED1_PORT_NUM) && defined (LED1_PIN_NUM)
# define LED1_PORT ((GPIO_TypeDef *)gpio_port(LED1_PORT_NUM))
# define LED1_PIN GPIO_PIN(LED1_PORT_NUM, LED1_PIN_NUM)
# define LED1_MASK (1 << LED1_PIN_NUM)
# define LED1_PIN GPIO_PIN(LED1_PORT_NUM, LED1_PIN_NUM)
# define LED1_MASK (1 << LED1_PIN_NUM)
# if IS_ACTIVE(LED1_IS_INVERTED)
# define LED1_ON (LED1_PORT->BSRR = (LED1_MASK << 16))
# define LED1_OFF (LED1_PORT->BSRR = LED1_MASK)
# define LED1_ON gpio_ll_clear(LED1_PORT, LED1_MASK)
# define LED1_OFF gpio_ll_set(LED1_PORT, LED1_MASK)
# else
# define LED1_ON (LED1_PORT->BSRR = LED1_MASK)
# define LED1_OFF (LED1_PORT->BSRR = (LED1_MASK << 16))
# define LED1_ON gpio_ll_set(LED1_PORT, LED1_MASK)
# define LED1_OFF gpio_ll_clear(LED1_PORT, LED1_MASK)
# endif
# define LED1_TOGGLE (LED1_PORT->ODR ^= LED1_MASK)
# define LED1_TOGGLE gpio_ll_toggle(LED1_PORT, LED1_MASK)
#endif

#if defined(LED2_PORT_NUM) && defined (LED2_PIN_NUM)
# define LED2_PORT ((GPIO_TypeDef *)gpio_port(LED2_PORT_NUM))
# define LED2_PIN GPIO_PIN(LED2_PORT_NUM, LED2_PIN_NUM)
# define LED2_MASK (1 << LED2_PIN_NUM)
# define LED2_PIN GPIO_PIN(LED2_PORT_NUM, LED2_PIN_NUM)
# define LED2_MASK (1 << LED2_PIN_NUM)
# if IS_ACTIVE(LED2_IS_INVERTED)
# define LED2_ON (LED2_PORT->BSRR = (LED2_MASK << 16))
# define LED2_OFF (LED2_PORT->BSRR = LED2_MASK)
# define LED2_ON gpio_ll_clear(LED2_PORT, LED2_MASK)
# define LED2_OFF gpio_ll_set(LED2_PORT, LED2_MASK)
# else
# define LED2_ON (LED2_PORT->BSRR = LED2_MASK)
# define LED2_OFF (LED2_PORT->BSRR = (LED2_MASK << 16))
# define LED2_ON gpio_ll_set(LED2_PORT, LED2_MASK)
# define LED2_OFF gpio_ll_clear(LED2_PORT, LED2_MASK)
# endif
# define LED2_TOGGLE (LED2_PORT->ODR ^= LED2_MASK)
# define LED2_TOGGLE gpio_ll_toggle(LED2_PORT, LED2_MASK)
#endif

#if defined(LED3_PORT_NUM) && defined (LED3_PIN_NUM)
# define LED3_PORT ((GPIO_TypeDef *)gpio_port(LED3_PORT_NUM))
# define LED3_PIN GPIO_PIN(LED3_PORT_NUM, LED3_PIN_NUM)
# define LED3_MASK (1 << LED3_PIN_NUM)
# define LED3_PIN GPIO_PIN(LED3_PORT_NUM, LED3_PIN_NUM)
# define LED3_MASK (1 << LED3_PIN_NUM)
# if IS_ACTIVE(LED3_IS_INVERTED)
# define LED3_ON (LED3_PORT->BSRR = (LED3_MASK << 16))
# define LED3_OFF (LED3_PORT->BSRR = LED3_MASK)
# define LED3_ON gpio_ll_clear(LED3_PORT, LED3_MASK)
# define LED3_OFF gpio_ll_set(LED3_PORT, LED3_MASK)
# else
# define LED3_ON (LED3_PORT->BSRR = LED3_MASK)
# define LED3_OFF (LED3_PORT->BSRR = (LED3_MASK << 16))
# define LED3_ON gpio_ll_set(LED3_PORT, LED3_MASK)
# define LED3_OFF gpio_ll_clear(LED3_PORT, LED3_MASK)
# endif
# define LED3_TOGGLE (LED3_PORT->ODR ^= LED3_MASK)
# define LED3_TOGGLE gpio_ll_toggle(LED3_PORT, LED3_MASK)
#endif

#if defined(LED4_PORT_NUM) && defined (LED4_PIN_NUM)
# define LED4_PORT ((GPIO_TypeDef *)gpio_port(LED4_PORT_NUM))
# define LED4_PIN GPIO_PIN(LED4_PORT_NUM, LED4_PIN_NUM)
# define LED4_MASK (1 << LED4_PIN_NUM)
# define LED4_PIN GPIO_PIN(LED4_PORT_NUM, LED4_PIN_NUM)
# define LED4_MASK (1 << LED4_PIN_NUM)
# if IS_ACTIVE(LED4_IS_INVERTED)
# define LED4_ON (LED4_PORT->BSRR = (LED4_MASK << 16))
# define LED4_OFF (LED4_PORT->BSRR = LED4_MASK)
# define LED4_ON gpio_ll_clear(LED4_PORT, LED4_MASK)
# define LED4_OFF gpio_ll_set(LED4_PORT, LED4_MASK)
# else
# define LED4_ON (LED4_PORT->BSRR = LED4_MASK)
# define LED4_OFF (LED4_PORT->BSRR = (LED4_MASK << 16))
# define LED4_ON gpio_ll_set(LED4_PORT, LED4_MASK)
# define LED4_OFF gpio_ll_clear(LED4_PORT, LED4_MASK)
# endif
# define LED4_TOGGLE (LED4_PORT->ODR ^= LED4_MASK)
# define LED4_TOGGLE gpio_ll_toggle(LED4_PORT, LED4_MASK)
#endif

#if defined(LED5_PORT_NUM) && defined (LED5_PIN_NUM)
# define LED5_PORT ((GPIO_TypeDef *)gpio_port(LED5_PORT_NUM))
# define LED5_PIN GPIO_PIN(LED5_PORT_NUM, LED5_PIN_NUM)
# define LED5_MASK (1 << LED5_PIN_NUM)
# define LED5_PIN GPIO_PIN(LED5_PORT_NUM, LED5_PIN_NUM)
# define LED5_MASK (1 << LED5_PIN_NUM)
# if IS_ACTIVE(LED5_IS_INVERTED)
# define LED5_ON (LED5_PORT->BSRR = (LED5_MASK << 16))
# define LED5_OFF (LED5_PORT->BSRR = LED5_MASK)
# define LED5_ON gpio_ll_clear(LED5_PORT, LED5_MASK)
# define LED5_OFF gpio_ll_set(LED5_PORT, LED5_MASK)
# else
# define LED5_ON (LED5_PORT->BSRR = LED5_MASK)
# define LED5_OFF (LED5_PORT->BSRR = (LED5_MASK << 16))
# define LED5_ON gpio_ll_set(LED5_PORT, LED5_MASK)
# define LED5_OFF gpio_ll_clear(LED5_PORT, LED5_MASK)
# endif
# define LED5_TOGGLE (LED5_PORT->ODR ^= LED5_MASK)
# define LED5_TOGGLE gpio_ll_toggle(LED5_PORT, LED5_MASK)
#endif

#if defined(LED6_PORT_NUM) && defined (LED6_PIN_NUM)
# define LED6_PORT ((GPIO_TypeDef *)gpio_port(LED6_PORT_NUM))
# define LED6_PIN GPIO_PIN(LED6_PORT_NUM, LED6_PIN_NUM)
# define LED6_MASK (1 << LED6_PIN_NUM)
# define LED6_PIN GPIO_PIN(LED6_PORT_NUM, LED6_PIN_NUM)
# define LED6_MASK (1 << LED6_PIN_NUM)
# if IS_ACTIVE(LED6_IS_INVERTED)
# define LED6_ON (LED6_PORT->BSRR = (LED6_MASK << 16))
# define LED6_OFF (LED6_PORT->BSRR = LED6_MASK)
# define LED6_ON gpio_ll_clear(LED6_PORT, LED6_MASK)
# define LED6_OFF gpio_ll_set(LED6_PORT, LED6_MASK)
# else
# define LED6_ON (LED6_PORT->BSRR = LED6_MASK)
# define LED6_OFF (LED6_PORT->BSRR = (LED6_MASK << 16))
# define LED6_ON gpio_ll_set(LED6_PORT, LED6_MASK)
# define LED6_OFF gpio_ll_clear(LED6_PORT, LED6_MASK)
# endif
# define LED6_TOGGLE (LED6_PORT->ODR ^= LED6_MASK)
# define LED6_TOGGLE gpio_ll_toggle(LED6_PORT, LED6_MASK)
#endif

#if defined(LED7_PORT_NUM) && defined (LED7_PIN_NUM)
# define LED7_PORT ((GPIO_TypeDef *)gpio_port(LED7_PORT_NUM))
# define LED7_PIN GPIO_PIN(LED7_PORT_NUM, LED7_PIN_NUM)
# define LED7_MASK (1 << LED7_PIN_NUM)
# define LED7_PIN GPIO_PIN(LED7_PORT_NUM, LED7_PIN_NUM)
# define LED7_MASK (1 << LED7_PIN_NUM)
# if IS_ACTIVE(LED7_IS_INVERTED)
# define LED7_ON (LED7_PORT->BSRR = (LED7_MASK << 16))
# define LED7_OFF (LED7_PORT->BSRR = LED7_MASK)
# define LED7_ON gpio_ll_clear(LED7_PORT, LED7_MASK)
# define LED7_OFF gpio_ll_set(LED7_PORT, LED7_MASK)
# else
# define LED7_ON (LED7_PORT->BSRR = LED7_MASK)
# define LED7_OFF (LED7_PORT->BSRR = (LED7_MASK << 16))
# define LED7_ON gpio_ll_set(LED7_PORT, LED7_MASK)
# define LED7_OFF gpio_ll_clear(LED7_PORT, LED7_MASK)
# endif
# define LED7_TOGGLE (LED7_PORT->ODR ^= LED7_MASK)
# define LED7_TOGGLE gpio_ll_toggle(LED7_PORT, LED7_MASK)
#endif

/** @} */
Expand Down
1 change: 1 addition & 0 deletions boards/common/weact-f4x1cx/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 13
#define LED0_PORT GPIO_PORT_C /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_C
#define LED0_IS_INVERTED 1
/** @} */
Expand Down
3 changes: 3 additions & 0 deletions boards/f4vi1/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 1
#define LED0_PORT GPIO_PORT_A /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_A

#define LED1_PIN_NUM 3
#define LED1_PORT GPIO_PORT_A /**< GPIO port of LED 1 */
#define LED1_PORT_NUM PORT_A

#define LED2_PIN_NUM 2
#define LED2_PORT GPIO_PORT_A /**< GPIO port of LED 2 */
#define LED2_PORT_NUM PORT_A
/** @} */

Expand Down
1 change: 1 addition & 0 deletions boards/limifrog-v1/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 3
#define LED0_PORT GPIO_PORT_C /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_C
/** @} */

Expand Down
1 change: 1 addition & 0 deletions boards/lobaro-lorabox/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ extern "C" {
* @{
*/
#define LED0_PIN_NUM 1
#define LED0_PORT GPIO_PORT_A /**< GPIO port of LED 0 */
#define LED0_PORT_NUM PORT_A
#define LED0_IS_INVERTED 1

Expand Down

0 comments on commit 09e8d9e

Please sign in to comment.