optimise GPIO read/write

Instead of performing a bitwise shift operation on every GPIO read/write. Do it at compile-time and use bit mask instead.

The pin number itself is not used anywhere.

The change saves 108 bytes of flash memory
pull/353/head
Guðni Már Gilbert 2025-11-30 17:59:16 +00:00 committed by DRracer
parent 88a241c741
commit c1aa190d05
2 changed files with 27 additions and 27 deletions

View File

@ -52,31 +52,31 @@ struct GPIO_pin {
// No constructor here in order to allow brace-initialization in old // No constructor here in order to allow brace-initialization in old
// gcc versions/standards // gcc versions/standards
GPIO_TypeDef *const port; GPIO_TypeDef *const port;
const uint8_t pin; const uint8_t pin_mask;
}; };
__attribute__((always_inline)) inline void WritePin(const GPIO_pin portPin, Level level) { __attribute__((always_inline)) inline void WritePin(const GPIO_pin portPin, Level level) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
if (level == Level::high) if (level == Level::high)
portPin.port->PORTx |= (1 << portPin.pin); portPin.port->PORTx |= portPin.pin_mask;
else else
portPin.port->PORTx &= ~(1 << portPin.pin); portPin.port->PORTx &= ~portPin.pin_mask;
} }
} }
__attribute__((always_inline)) inline Level ReadPin(const GPIO_pin portPin) { __attribute__((always_inline)) inline Level ReadPin(const GPIO_pin portPin) {
#ifdef __AVR__ #ifdef __AVR__
return (Level)((portPin.port->PINx & (1 << portPin.pin)) != 0); return (Level)((portPin.port->PINx & portPin.pin_mask) != 0);
#else #else
// Return the value modified by WritePin // Return the value modified by WritePin
return (Level)((portPin.port->PORTx & (1 << portPin.pin)) != 0); return (Level)((portPin.port->PORTx & portPin.pin_mask) != 0);
#endif #endif
} }
__attribute__((always_inline)) inline void TogglePin(const GPIO_pin portPin) { __attribute__((always_inline)) inline void TogglePin(const GPIO_pin portPin) {
#ifdef __AVR__ #ifdef __AVR__
// Optimized path for AVR, resulting in a pin toggle // Optimized path for AVR, resulting in a pin toggle
portPin.port->PINx = (1 << portPin.pin); portPin.port->PINx = portPin.pin_mask;
#else #else
WritePin(portPin, (Level)(ReadPin(portPin) != Level::high)); WritePin(portPin, (Level)(ReadPin(portPin) != Level::high));
#endif #endif
@ -85,9 +85,9 @@ __attribute__((always_inline)) inline void TogglePin(const GPIO_pin portPin) {
__attribute__((always_inline)) inline void Init(const GPIO_pin portPin, GPIO_InitTypeDef GPIO_Init) { __attribute__((always_inline)) inline void Init(const GPIO_pin portPin, GPIO_InitTypeDef GPIO_Init) {
if (GPIO_Init.mode == Mode::output) { if (GPIO_Init.mode == Mode::output) {
WritePin(portPin, GPIO_Init.level); WritePin(portPin, GPIO_Init.level);
portPin.port->DDRx |= (1 << portPin.pin); portPin.port->DDRx |= portPin.pin_mask;
} else { } else {
portPin.port->DDRx &= ~(1 << portPin.pin); portPin.port->DDRx &= ~portPin.pin_mask;
WritePin(portPin, (Level)GPIO_Init.pull); WritePin(portPin, (Level)GPIO_Init.pull);
} }
} }

View File

@ -3,28 +3,28 @@
#include "hal/gpio.h" #include "hal/gpio.h"
/// pin definitions /// pin definitions
static constexpr hal::gpio::GPIO_pin TMC2130_SPI_MISO_PIN = { GPIOB, 3 }; static constexpr hal::gpio::GPIO_pin TMC2130_SPI_MISO_PIN = { GPIOB, (1 << 3) };
static constexpr hal::gpio::GPIO_pin TMC2130_SPI_MOSI_PIN = { GPIOB, 2 }; static constexpr hal::gpio::GPIO_pin TMC2130_SPI_MOSI_PIN = { GPIOB, (1 << 2) };
static constexpr hal::gpio::GPIO_pin TMC2130_SPI_SCK_PIN = { GPIOB, 1 }; static constexpr hal::gpio::GPIO_pin TMC2130_SPI_SCK_PIN = { GPIOB, (1 << 1) };
static constexpr hal::gpio::GPIO_pin TMC2130_SPI_SS_PIN = { GPIOB, 0 }; static constexpr hal::gpio::GPIO_pin TMC2130_SPI_SS_PIN = { GPIOB, (1 << 0) };
static constexpr hal::gpio::GPIO_pin SHR16_DATA = { GPIOB, 5 }; ///DS static constexpr hal::gpio::GPIO_pin SHR16_DATA = { GPIOB, (1 << 5) }; ///DS
static constexpr hal::gpio::GPIO_pin SHR16_LATCH = { GPIOB, 6 }; ///STCP static constexpr hal::gpio::GPIO_pin SHR16_LATCH = { GPIOB, (1 << 6) }; ///STCP
static constexpr hal::gpio::GPIO_pin SHR16_CLOCK = { GPIOC, 7 }; ///SHCP static constexpr hal::gpio::GPIO_pin SHR16_CLOCK = { GPIOC, (1 << 7) }; ///SHCP
static constexpr hal::gpio::GPIO_pin USART_RX = { GPIOD, 2 }; static constexpr hal::gpio::GPIO_pin USART_RX = { GPIOD, (1 << 2) };
static constexpr hal::gpio::GPIO_pin USART_TX = { GPIOD, 3 }; static constexpr hal::gpio::GPIO_pin USART_TX = { GPIOD, (1 << 3) };
static constexpr hal::gpio::GPIO_pin PULLEY_CS_PIN = { GPIOC, 6 }; static constexpr hal::gpio::GPIO_pin PULLEY_CS_PIN = { GPIOC, (1 << 6) };
static constexpr hal::gpio::GPIO_pin PULLEY_SG_PIN = { GPIOF, 4 }; static constexpr hal::gpio::GPIO_pin PULLEY_SG_PIN = { GPIOF, (1 << 4) };
static constexpr hal::gpio::GPIO_pin PULLEY_STEP_PIN = { GPIOB, 4 }; static constexpr hal::gpio::GPIO_pin PULLEY_STEP_PIN = { GPIOB, (1 << 4) };
static constexpr hal::gpio::GPIO_pin SELECTOR_CS_PIN = { GPIOD, 7 }; static constexpr hal::gpio::GPIO_pin SELECTOR_CS_PIN = { GPIOD, (1 << 7) };
static constexpr hal::gpio::GPIO_pin SELECTOR_SG_PIN = { GPIOF, 1 }; static constexpr hal::gpio::GPIO_pin SELECTOR_SG_PIN = { GPIOF, (1 << 1) };
static constexpr hal::gpio::GPIO_pin SELECTOR_STEP_PIN = { GPIOD, 4 }; static constexpr hal::gpio::GPIO_pin SELECTOR_STEP_PIN = { GPIOD, (1 << 4) };
static constexpr hal::gpio::GPIO_pin IDLER_CS_PIN = { GPIOB, 7 }; static constexpr hal::gpio::GPIO_pin IDLER_CS_PIN = { GPIOB, (1 << 7) };
static constexpr hal::gpio::GPIO_pin IDLER_SG_PIN = { GPIOF, 0 }; static constexpr hal::gpio::GPIO_pin IDLER_SG_PIN = { GPIOF, (1 << 0) };
static constexpr hal::gpio::GPIO_pin IDLER_STEP_PIN = { GPIOD, 6 }; static constexpr hal::gpio::GPIO_pin IDLER_STEP_PIN = { GPIOD, (1 << 6) };
static constexpr hal::gpio::GPIO_pin FINDA_PIN = { GPIOF, 6 }; /// PF6 A1 ADC6/TDI static constexpr hal::gpio::GPIO_pin FINDA_PIN = { GPIOF, (1 << 6) }; /// PF6 A1 ADC6/TDI