Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update naming convention for GPIO control macros #23085

Merged
merged 6 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions docs/gpio_control.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@

QMK has a GPIO control abstraction layer which is microcontroller agnostic. This is done to allow easy access to pin control across different platforms.

## Functions :id=functions

The following functions provide basic control of GPIOs and are found in `platforms/<platform>/gpio.h`.

| Function | Description | Old AVR Examples | Old ChibiOS/ARM Examples |
|------------------------------|-----------------------------------------------------|-------------------------------------------------|--------------------------------------------------|
| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` |
| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` |
| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` |
| `setPinOutput(pin)` | Set pin as output (alias of `setPinOutputPushPull`) | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
| `setPinOutputPushPull(pin)` | Set pin as output, push/pull mode | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` |
| `setPinOutputOpenDrain(pin)` | Set pin as output, open-drain mode | N/A (Not implemented on AVR) | `palSetLineMode(pin, PAL_MODE_OUTPUT_OPENDRAIN)` |
| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` |
| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` |
| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` |
| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` |
| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` |
## Macros :id=macros

The following macros provide basic control of GPIOs and are found in `platforms/<platform>/gpio.h`.

|Macro |Description |
|-------------------------------------|---------------------------------------------------------------------|
|`gpio_set_pin_input(pin)` |Set pin as input with high impedance (High-Z) |
|`gpio_set_pin_input_high(pin)` |Set pin as input with builtin pull-up resistor |
|`gpio_set_pin_input_low(pin)` |Set pin as input with builtin pull-down resistor (unavailable on AVR)|
|`gpio_set_pin_output(pin)` |Set pin as output (alias of `gpio_set_pin_output_push_pull`) |
|`gpio_set_pin_output_push_pull(pin)` |Set pin as output, push/pull mode |
|`gpio_set_pin_output_open_drain(pin)`|Set pin as output, open-drain mode (unavailable on AVR and ATSAM) |
|`gpio_write_pin_high(pin)` |Set pin level as high, assuming it is an output |
|`gpio_write_pin_low(pin)` |Set pin level as low, assuming it is an output |
|`gpio_write_pin(pin, level)` |Set pin level, assuming it is an output |
|`gpio_read_pin(pin)` |Returns the level of the pin |
|`gpio_toggle_pin(pin)` |Invert pin level, assuming it is an output |

## Advanced Settings :id=advanced-settings

Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](https://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.
Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device. For AVR, the standard `avr/io.h` library is used; for STM32, the ChibiOS [PAL library](https://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used.

## Atomic Operation
## Atomic Operation :id=atomic-operation

The above functions are not always guaranteed to work atomically. Therefore, if you want to prevent interruptions in the middle of operations when using multiple combinations of the above functions, use the following `ATOMIC_BLOCK_FORCEON` macro.

Expand Down
24 changes: 12 additions & 12 deletions platforms/arm_atsam/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
#pragma once

#include "stdint.h"
#include <stdint.h>
#include "samd51j18a.h"

#include "pin_defs.h"
Expand All @@ -26,56 +26,56 @@ typedef uint8_t pin_t;
#define SAMD_PIN(pin) ((pin)&0x1f)
#define SAMD_PIN_MASK(pin) (1 << ((pin)&0x1f))

#define setPinInput(pin) \
#define gpio_set_pin_input(pin) \
do { \
PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \
PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \
} while (0)

#define setPinInputHigh(pin) \
#define gpio_set_pin_input_high(pin) \
do { \
PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \
PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \
PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \
} while (0)

#define setPinInputLow(pin) \
#define gpio_set_pin_input_low(pin) \
do { \
PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \
PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \
PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \
} while (0)

#define setPinOutputPushPull(pin) \
#define gpio_set_pin_output_push_pull(pin) \
do { \
PORT->Group[SAMD_PORT(pin)].DIRSET.reg = SAMD_PIN_MASK(pin); \
PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
} while (0)

#define setPinOutputOpenDrain(pin) _Static_assert(0, "arm_atsam platform does not implement an open-drain output")
#define gpio_set_pin_output_open_drain(pin) _Static_assert(0, "Open-drain outputs are not available on ATSAM")

#define setPinOutput(pin) setPinOutputPushPull(pin)
#define gpio_set_pin_output(pin) gpio_set_output_push_pull(pin)

#define writePinHigh(pin) \
#define gpio_write_pin_high(pin) \
do { \
PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
} while (0)

#define writePinLow(pin) \
#define gpio_write_pin_low(pin) \
do { \
PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
} while (0)

#define writePin(pin, level) \
#define gpio_write_pin(pin, level) \
do { \
if (level) \
PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
else \
PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
} while (0)

#define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0)
#define gpio_read_pin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0)

#define togglePin(pin) (PORT->Group[SAMD_PORT(pin)].OUTTGL.reg = SAMD_PIN_MASK(pin))
#define gpio_toggle_pin(pin) (PORT->Group[SAMD_PORT(pin)].OUTTGL.reg = SAMD_PIN_MASK(pin))
22 changes: 11 additions & 11 deletions platforms/avr/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ typedef uint8_t pin_t;

/* Operation of GPIO by pin. */

#define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
#define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low")
#define setPinOutputPushPull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
#define setPinOutputOpenDrain(pin) _Static_assert(0, "AVR platform does not implement an open-drain output")
#define setPinOutput(pin) setPinOutputPushPull(pin)
#define gpio_set_pin_input(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
#define gpio_set_pin_input_high(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
#define gpio_set_pin_input_low(pin) _Static_assert(0, "GPIO pulldowns in input mode are not available on AVR")
#define gpio_set_pin_output_push_pull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF))
#define gpio_set_pin_output_open_drain(pin) _Static_assert(0, "Open-drain outputs are not available on AVR")
#define gpio_set_pin_output(pin) gpio_set_output_push_pull(pin)

#define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
#define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
#define writePin(pin, level) ((level) ? writePinHigh(pin) : writePinLow(pin))
#define gpio_write_pin_high(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
#define gpio_write_pin_low(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
#define gpio_write_pin(pin, level) ((level) ? gpio_write_high(pin) : gpio_write_low(pin))

#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
#define gpio_read_pin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))

#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF))
#define gpio_toggle_pin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF))
34 changes: 17 additions & 17 deletions platforms/chibios/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@ typedef ioline_t pin_t;

/* Operation of GPIO by pin. */

#define setPinInput(pin) palSetLineMode((pin), PAL_MODE_INPUT)
#define setPinInputHigh(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLUP)
#define setPinInputLow(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLDOWN)
#define setPinOutputPushPull(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_PUSHPULL)
#define setPinOutputOpenDrain(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_OPENDRAIN)
#define setPinOutput(pin) setPinOutputPushPull(pin)
#define gpio_set_pin_input(pin) palSetLineMode((pin), PAL_MODE_INPUT)
#define gpio_set_pin_input_high(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLUP)
#define gpio_set_pin_input_low(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLDOWN)
#define gpio_set_pin_output_push_pull(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_PUSHPULL)
#define gpio_set_pin_output_open_drain(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_OPENDRAIN)
#define gpio_set_pin_output(pin) gpio_set_output_push_pull(pin)

#define writePinHigh(pin) palSetLine(pin)
#define writePinLow(pin) palClearLine(pin)
#define writePin(pin, level) \
do { \
if (level) { \
writePinHigh(pin); \
} else { \
writePinLow(pin); \
} \
#define gpio_write_pin_high(pin) palSetLine(pin)
#define gpio_write_pin_low(pin) palClearLine(pin)
#define gpio_write_pin(pin, level) \
do { \
if (level) { \
gpio_write_high(pin); \
} else { \
gpio_write_low(pin); \
} \
} while (0)

#define readPin(pin) palReadLine(pin)
#define gpio_read_pin(pin) palReadLine(pin)

#define togglePin(pin) palToggleLine(pin)
#define gpio_toggle_pin(pin) palToggleLine(pin)
19 changes: 18 additions & 1 deletion platforms/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,21 @@

#if __has_include_next("gpio.h")
# include_next "gpio.h" /* Include the platforms gpio.h */
#endif
#endif

// ======== DEPRECATED DEFINES - DO NOT USE ========

#define setPinInput(pin) gpio_set_pin_input(pin)
#define setPinInputHigh(pin) gpio_set_pin_input_high(pin)
#define setPinInputLow(pin) gpio_set_pin_input_low(pin)
#define setPinOutputPushPull(pin) gpio_set_pin_output_push_pull(pin)
#define setPinOutputOpenDrain(pin) gpio_set_pin_output_open_drain(pin)
#define setPinOutput(pin) gpio_set_pin_output_push_pull(pin)

#define writePinHigh(pin) gpio_write_pin_high(pin)
#define writePinLow(pin) gpio_write_pin_low(pin)
#define writePin(pin, level) gpio_write_pin(pin, level)

#define readPin(pin) gpio_read_pin(pin)

#define togglePin(pin) gpio_toggle_pin(pin)
Loading