Module gpio_hal
GPIO Hardware Abstraction Layer behavior.
Description
This module defines the behavior that platform-specific GPIO modules must implement. It provides a common interface for basic GPIO operations across all supported platforms (ESP32, RP2, STM32).
There are two APIs for GPIO operations:
NIF-based API
The NIF-based API provides direct access to GPIO pins without requiring a driver process or port. Functions operate directly on pin numbers.
init/1- Initialize a pin for GPIO use (required on RP2, no-op on ESP32 and STM32)deinit/1- Release a pin from GPIO useset_pin_mode/2- Configure a pin as input, output, or output with open drainset_pin_pull/2- Configure internal pull resistorsdigital_write/2- Set pin output leveldigital_read/1- Read pin input level
Port-based API
The port-based API requires starting a GPIO driver using start/0 or
open/0, which returns a handle (a port on ESP32 and STM32, a pid on
RP2). This handle is passed to all subsequent operations.
start/0- Start the GPIO driver, or return an existing one if already startedopen/0- Start a new GPIO driver instanceclose/1- Stop a GPIO driver and release its resourcesstop/0- Stop the registered GPIO driver if one is runningread/2- Read pin input levelset_direction/3- Configure a pin as input, output, or output with open drainset_level/3- Set pin output levelset_int/3- Set a GPIO interrupt on a pin, notifications are sent to the calling processset_int/4- Set a GPIO interrupt on a pin, notifications are sent to the specified processremove_int/2- Remove a previously set GPIO interrupt
Pin definitions
Pin definitions vary by platform:
ESP32: a non-negative integer (e.g.
2,15)RP2: a non-negative integer, or
{wl, 0..2}for Pico-W wireless pinsSTM32: a tuple
{Bank, PinNum}where Bank is an atomathroughkand PinNum is0..15, a list of pin numbers, or the atomall
Platform differences
Interrupt support: ESP32 and STM32 support interrupts. RP2 does not (returns
{error, not_supported}).Interrupt message format: on ESP32,
{gpio_interrupt, Pin}where Pin is an integer; on STM32,{gpio_interrupt, {Bank, Pin}}.Pull modes: ESP32 and RP2 support
up,down,up_down, andfloating. STM32 supportsup,down, andfloatingonly.init/1must be called before using a pin on RP2. On ESP32 and STM32 it is a no-op.STM32 supports batch operations: multiple pins on the same bank can be configured or written at once.
Example usage (NIF-based API)
The following example configures pin 2 as an output and sets it high:
gpio:init(2),
gpio:set_pin_mode(2, output),
gpio:digital_write(2, high).
The following example configures pin 4 as an input with a pull-up resistor and reads the level:
gpio:init(4),
gpio:set_pin_mode(4, input),
gpio:set_pin_pull(4, up),
Level = gpio:digital_read(4).
Example usage (Port-based API)
GPIO = gpio:start(),
gpio:set_direction(GPIO, 2, output),
gpio:set_level(GPIO, 2, high),
gpio:set_int(GPIO, 4, rising),
receive
{gpio_interrupt, 4} -> io:format("Pin 4 triggered!~n")
end.
Data Types
direction()
direction() = input | output | output_od
The direction is used to set the mode of operation for a GPIO pin, either as an input, an output, or output with open drain.
gpio()
gpio() = port() | pid()
Handle returned by start/0 or open/0.
On ESP32 and STM32, this is a port. On RP2, this is a pid.
high_level()
high_level() = high | 1
level()
level() = low_level() | high_level()
Valid pin levels can be atom or integer representation.
low_level()
low_level() = low | 0
pull()
pull() = up | down | up_down | floating
Internal resistor pull mode.
Note: STM32 does not support up_down.
trigger()
trigger() = none | rising | falling | both | low | high
Event type that will trigger a gpio_interrupt.
Setting trigger to none disables the interrupt.