Communication Protocols (I2C, SPI, UART)
Relevant source files
The following files were used as context for generating this wiki page:
AtomVM provides a rich set of APIs and hardware abstractions for interfacing with standard device protocols commonly used in IoT and embedded development. Specifically, it supports I2C (Inter-Integrated Circuit), SPI (Serial Peripheral Interface), and UART (Universal Asynchronous Receiver-Transmitter). These protocols are implemented to allow Erlang and Elixir applications to interact with sensors, actuators, and other micro-controllers directly from high-level functional code.
Sources: doc/src/welcome-to-atomvm.md:23-28, doc/src/index.rst:19-21
Architectural Overview
The integration of communication protocols in AtomVM is designed to bridge the gap between the BEAM virtual machine and physical hardware. On platforms like the ESP32, these protocols are integrated with the underlying SDKs (such as the Espressif IDF) to provide high-performance, low-level access.
Integration Patterns
Protocol support is typically implemented using two primary mechanisms within AtomVM:
- NIFs (Native Implemented Functions): Stateless functions implemented in C that provide direct, synchronous access to hardware functions.
- Ports: Stateful entities implemented in C that behave like lightweight Erlang processes, managing the lifecycle and asynchronous state of a hardware peripheral.
Sources: src/platforms/esp32/README.md:21-23, src/platforms/esp32/README.md:32-35
Protocol Stack Visualization
The following diagram illustrates how an Erlang/Elixir application communicates with hardware peripherals through the AtomVM abstraction layer.
This diagram shows the flow from high-level application code through the virtual machine's native interfaces to the physical hardware.
Protocol-Specific Implementations
I2C (Inter-Integrated Circuit)
AtomVM provides a 2-wire interface for communicating with various peripheral devices. On the ESP32 platform, this is implemented as an integration with the IDF SDK's I2C driver.
- Platform Support: Extensively supported on ESP32; also planned for other micro-controllers.
- Customization: I2C support can be excluded from the build via
menuconfigto reduce image size if the application does not require 2-wire communication.
Sources: src/platforms/esp32/README.md:21-23, src/platforms/esp32/README.md:37-43
SPI (Serial Peripheral Interface)
The SPI interface allows for high-speed synchronous serial communication. Similar to I2C, it is implemented as a built-in component in the ESP32 port.
- Implementation: Typically handled via Port drivers to manage the state of the SPI bus and connected slaves.
- Build Configuration: Users can disable the SPI interface in "AtomVM Built-In Components" to optimize RAM usage and flash size.
Sources: src/platforms/esp32/README.md:21-23, src/platforms/esp32/README.md:42-45
UART (Universal Asynchronous Receiver-Transmitter)
UART is used for asynchronous serial communication, often utilized for console output, GPS modules, or inter-chip communication.
- Standard Output: By default, on many platforms like STM32,
stdoutandstderrare directed to a specific UART controller (e.g., USART2). - Configuration: For the STM32F4Discovery, UART transmission is typically 115200 baud, 8N1, with no flow control.
Sources: doc/src/getting-started-guide.md:243-247, src/platforms/esp32/README.md:21-23
Configuration and Management
AtomVM allows developers to fine-tune which protocols are included in the virtual machine build to manage the constrained resources of micro-controllers.
Component Summary Table
| Protocol | Implementation Type | Platform Availability | Configurable via MenuConfig |
|---|---|---|---|
| I2C | NIF / Port | ESP32, STM32 (Planned) | Yes |
| SPI | NIF / Port | ESP32 | Yes |
| UART | NIF / Port | ESP32, STM32, RP2 | Yes |
Sources: src/platforms/esp32/README.md:32-45, doc/src/getting-started-guide.md:243-245
Build-Time Optimization
For developers targeting devices with limited Flash or RAM (e.g., ESP32 with 520K RAM), disabling unused protocols is a key optimization step.
This flowchart depicts how selective protocol inclusion impacts the final AtomVM image and runtime performance.
Sources: src/platforms/esp32/README.md:37-45
Usage in Applications
Applications access these protocols through specialized Erlang/Elixir libraries (e.g., eavmlib). The tooling provided by AtomVM (such as atomvm_rebar3_plugin or ExAtomVM) ensures that the necessary BEAM modules are packed into the .avm file for the application to interact with these native drivers.
Sources: doc/src/atomvm-tooling.md:12-16, doc/src/atomvm-tooling.md:188-192
Summary
Communication protocols (I2C, SPI, UART) in AtomVM provide the essential bridge between functional BEAM applications and physical hardware. By offering these as modular built-in components, AtomVM allows developers to build efficient, networked IoT applications while maintaining the ability to optimize for memory and storage constraints through granular build configuration.