max30101-rs
MAX30101 Rust Driver
Pure-Rust, no_std (with alloc) driver for the MAX30101 PPG (photoplethysmography) sensor.
This crate is a low-level, register-oriented implementation derived from the MAX30101 datasheet. It exposes a compact, register-centric API and a small transport abstraction so you can plug in your preferred I2C implementation.
This Rust crate is licensed under MIT OR Apache-2.0.
Design Goals
no_stdcompatible (withalloc)- Support both synchronous (
blocking) and asynchronous (async) I2C usage - Small, register-oriented API close to the datasheet
- Transport-agnostic: users provide the concrete I2C implementation
Crate Features
async— enable asynchronous transport support usingembedded-hal-asyncandasync-trait.blocking— enable blocking transport support usingembedded-haltraits.shared-bus— enable support for sharing a single bus instance between drivers (usesembassy-syncmutex types).
Quick Overview
High-Level Device Object
The crate exposes Max30101<T>, where T is a transport implementation. The reg module exposes register addresses, bitflags and small newtypes (enums and wrappers) for convenient and type-safe register manipulation.
Commonly-used items:
max30101_rs::Max30101— main driver type.max30101_rs::transport::I2cTransport— provided I2C transport adapter.max30101_rs::reg::MAX30101_I2C_ADDR— default 7-bit I2C address.
API highlights
Below are some functions, types and registers you will likely use when integrating this driver:
-
Driver construction
Max30101::new(transport)— create the device instance.Max30101::destroy(self)— consume the driver and return the underlying transport.
-
Register access helpers
read_reg/write_reg— low-level register read/write helpers (async or blocking depending on feature).
-
Interrupts
interrupts_st_get()— read current interrupt status registers.interrupts_en_set()/interrupts_en_get()— enable/inspect enabled interrupt sources.- Registers:
MAX30101_INTERRUPT_STATUS_1,MAX30101_INTERRUPT_STATUS_2,MAX30101_INTERRUPT_ENABLE_1,MAX30101_INTERRUPT_ENABLE_2.
-
FIFO / samples
fifo_config_set()/fifo_config_get()— configure FIFO almost-full threshold, rollover and averaging.MAX30101_FIFO_DATA— FIFO sample read register.
-
Mode & reset
mode_set()/mode_get()— switch chip mode (Modeenum:HeartRate,SpO2,MultiLED).reset_set(true)/reset_get()— trigger and query chip reset.shutdown_set()/shutdown_get()— enter/exit shutdown mode.- Registers:
MAX30101_MODE_CONFIG,MAX30101_PART_ID,MAX30101_REV_ID.
-
LED configuration
led_pw_set()/led_pw_get()— set ADC resolution / LED pulse width (LEDPW).ledx_pa_set()/ledx_pa_get()andled1_pa_set()..led4_pa_set()— set per-LED pulse amplitude (LED current).- Registers:
MAX30101_LED1_PA..MAX30101_LED4_PA,MAX30101_SPO2_CONFIG.
-
Sample rate & ADC range
sample_rate_set()/sample_rate_get()— configure sample rate (SampleRateenum).adc_range_set()/adc_range_get()— configure ADC dynamic range (ADCRange).
-
Transport helpers
transport::I2cTransport::new(bus, address)— adapter the crate provides to wrap an I2C bus and device address.
See the reg module for bitflags and small enums (e.g. Mode, LEDPW, SampleRate, SmpAve, ADCRange) to work with register fields in a type-safe way.
Transport Abstraction
Max30101<T> is generic over a Transport implementation exposed in transport. Depending on enabled features the expected bus type differs:
- Without
shared-bus: pass your concrete I2C implementation directly (e.g. anembedded-haltype). - With
shared-bus: pass a shared/mutex-wrapped bus (the crate expectsembassy-syncmutex types whenshared-busis enabled).
The crate provides I2cTransport::new(bus, address) to construct a transport wrapper; the bus argument type depends on active features as described above.
Examples
Below are minimal examples showing how to construct the driver for the async feature. Replace the ... with your platform's concrete I2C type.
The blocking example is similar, just replace the async/await keywords and use blocking I2C types.
use ;
// `I2C` should implement the embedded-hal-async I2C traits
let i2c = /* your embedded-hal I2C instance */;
let transport = new;
let mut dev = new;
// Reset the device, and wait for it to be ready
loop
// Make sure the device is not in shutdown mode
device.shutdown_set.await.unwrap;
// Wait some time for the device to be ready after exiting shutdown mode
// Test reading some device information
let part_id = device.part_id_get.await.unwrap;
let rev_id = device.rev_id_get.await.unwrap;
// Perform the rest of the setup here
// Use the device as specified in the datasheet
Contributing
Contributions are welcome — PRs that add missing register APIs, improve examples, or enhance documentation are especially appreciated.
License
The crate is dual-licensed under MIT or Apache-2.0 — see LICENSE for details.
Contact / Author
Author: Jérôme Hendrick jerome.hendrick@gmail.com
Thanks for checking out this driver!