max30101-rs

Crates.iomax30101-rs
lib.rsmax30101-rs
version0.1.0
created_at2025-12-22 18:19:41.105607+00
updated_at2025-12-22 18:19:41.105607+00
descriptionPure Rust driver for the MAX30101 PPG sensor.
homepagehttps://github.com/JeromeHen/max30101-rs#readme
repositoryhttps://github.com/JeromeHen/max30101-rs
max_upload_size
id2000109
size108,694
Jérôme Hendrick (JeromeHen)

documentation

https://docs.rs/max30101-rs

README

max30101-rs

crates.io docs.rs CI License: MIT OR Apache-2.0

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_std compatible (with alloc)
  • 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 using embedded-hal-async and async-trait.
  • blocking — enable blocking transport support using embedded-hal traits.
  • shared-bus — enable support for sharing a single bus instance between drivers (uses embassy-sync mutex 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 (Mode enum: 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() and led1_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 (SampleRate enum).
    • 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. an embedded-hal type).
  • With shared-bus: pass a shared/mutex-wrapped bus (the crate expects embassy-sync mutex types when shared-bus is 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 max30101_rs::{Max30101, transport::I2cTransport, reg::MAX30101_I2C_ADDR};

// `I2C` should implement the embedded-hal-async I2C traits
let i2c = /* your embedded-hal I2C instance */;
let transport = I2cTransport::new(i2c, MAX30101_I2C_ADDR);
let mut dev = Max30101::new(transport);

// Reset the device, and wait for it to be ready
loop {
    if device.reset_set(true).await.is_ok() {
        break;
    }

    // Wait some time before retrying
}

// Make sure the device is not in shutdown mode
device.shutdown_set(false).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!

Commit count: 0

cargo fmt