GPIO & Digital I/O
Relevant source files
The following files were used as context for generating this wiki page:
The GPIO (General Purpose Input/Output) and Digital I/O system in AtomVM provides a high-level interface for Erlang and Elixir applications to interact with physical hardware pins. It allows for digital read and write operations, pin configuration, and interrupt handling across various supported microcontrollers including the ESP32 and STM32 families. Sources: doc/src/index.rst:22, doc/src/welcome-to-atomvm.md:23
AtomVM implements GPIO functionality through two primary mechanisms: NIFs (Native Implemented Functions) for stateless, immediate operations and Port Drivers for stateful, asynchronous operations such as interrupt monitoring. This dual-architecture allows developers to choose between low-latency direct access and a process-oriented message-passing model. Sources: src/platforms/esp32/README.md:32-35, src/platforms/stm32/src/lib/gpio_driver.c:38-40
Architecture and Implementation
The GPIO system is divided into platform-specific implementations that adhere to a common interface. On platforms like the STM32, the driver utilizes the libopencm3 library to interface with hardware registers, while the ESP32 implementation leverages the ESP-IDF. Sources: src/platforms/stm32/src/lib/gpio_driver.c:26-28, src/platforms/esp32/README.md:20-22
Component Interaction Flow
The following diagram illustrates how an Erlang process interacts with the GPIO hardware through the Port Driver.
The GPIO Port Driver acts as a serialized gateway, ensuring that hardware access is managed safely within the Erlang VM's scheduling model. Sources: src/platforms/stm32/src/lib/gpio_driver.c:645-668
Configuration and Management
GPIO pins are typically referenced using a tuple format {Bank, Pin} where Bank is an atom (e.g., a, b, c) and Pin is an integer (0-15). AtomVM translates these Erlang terms into hardware-specific addresses and bitmasks. Sources: src/platforms/stm32/src/lib/gpio_driver.c:196-224
Pin Modes and Pull Settings
Supported modes include input, output, and specialized configurations like open-drain.
| Configuration | Supported Values | Description |
|---|---|---|
| Modes | input, output, output_od, af, analog | Basic digital or specialized analog/alternate functions. |
| Pull Type | up, down, floating | Internal resistor configuration. |
| Output Speed | mhz_2, mhz_25, mhz_50, mhz_100 | Slew rate and frequency limits for output pins. |
Sources: src/platforms/stm32/src/lib/gpio_driver.c:116-146
Core Driver Functions
Key internal C functions manage the lifecycle and operation of the GPIO subsystem:
setup_gpio_pin: Validates Erlang terms and configures hardware registers for a specific pin or list of pins. Sources: src/platforms/stm32/src/lib/gpio_driver.c:196gpio_digital_write: Performs a set/clear operation on the specified pin bitmask. Sources: src/platforms/stm32/src/lib/gpio_driver.c:316gpio_digital_read: Retrieves the current logical level of a pin. Sources: src/platforms/stm32/src/lib/gpio_driver.c:385
Interrupt Handling (Asynchronous I/O)
AtomVM allows Erlang processes to receive messages when a GPIO pin changes state. This is achieved through the Port Driver's interrupt subscription model. Sources: src/platforms/stm32/src/lib/gpio_driver.c:40-42
Interrupt Flow Sequence
When an external signal triggers an interrupt, the hardware ISR (Interrupt Service Routine) communicates back to the virtual machine.
The driver maintains a list of GPIOListenerData structures to track which Erlang PIDs are subscribed to specific hardware pins. Sources: src/platforms/stm32/src/lib/gpio_driver.c:83-91, src/platforms/stm32/src/lib/gpio_driver.c:489-510
Supported Interrupt Triggers
rising: Trigger on low-to-high transition.falling: Trigger on high-to-low transition.both: Trigger on any state change.
Sources: src/platforms/stm32/src/lib/gpio_driver.c:101-106
Platform Specifics
ESP32 Integration
On the ESP32, GPIO is part of a larger peripheral suite. Users can disable the GPIO driver via menuconfig ("AtomVM Built-In Components") to reduce the binary size if the application does not require digital I/O. Sources: src/platforms/esp32/README.md:46-52
STM32 Implementation Details
The STM32 implementation uses the External Interrupt/Event Controller (EXTI) and Nested Vectored Interrupt Controller (NVIC). It provides specific ISR handlers for pin groups (e.g., exti0_isr, exti9_5_isr). Sources: src/platforms/stm32/src/lib/gpio_driver.c:531-602
// Example of pin mode setup for STM32
// Sources: [src/platforms/stm32/src/lib/gpio_driver.c:284-287]
gpio_mode_setup(gpio_bank, gpio_mode, pull_up_down, gpio_pin_mask);
if (setup_output) {
gpio_set_output_options(gpio_bank, out_type, output_speed, gpio_pin_mask);
}
Summary
The GPIO & Digital I/O module provides a robust, cross-platform bridge between the BEAM virtual machine and physical microcontroller pins. By supporting both synchronous NIFs and asynchronous Port Drivers, AtomVM enables developers to build responsive IoT applications that can efficiently handle sensor inputs and actuator outputs using standard Erlang/Elixir concurrency primitives. Sources: doc/src/index.rst:26, doc/src/welcome-to-atomvm.md:47-50