Skip to main content

Crate bmi323_driver

Crate bmi323_driver 

Source
Expand description

Generic no_std driver for the Bosch BMI323 IMU.

This crate provides:

  • blocking and async drivers
  • I2C and SPI transport support
  • accelerometer and gyroscope configuration
  • burst sample reads
  • FIFO configuration and reads
  • interrupt pin electrical configuration and interrupt routing
  • feature-engine enable flow
  • any-motion and no-motion configuration
  • tap and orientation/flat configuration
  • significant-motion and tilt configuration
  • step detector and step counter support
  • alternate accel/gyro configuration switching
  • built-in accelerometer and gyroscope self-test

The API is built on top of embedded-hal 1.0 and embedded-hal-async 1.0. It does not own the external interrupt GPIO. This keeps the driver generic and makes it easy to use with Embassy or with a platform-specific interrupt layer.

§Driver variants

Both expose the same high-level BMI323 operations where practical.

§Transport model

The BMI323 uses 8-bit register addresses with 16-bit register payloads. Reads include interface-specific dummy bytes, which this crate handles internally for I2C and SPI.

§Interrupt model

BMI323 interrupt sources are routed to INT1, INT2, or I3C IBI inside the sensor. The driver configures the sensor-side routing, but the external GPIO line is managed by the application:

§Feature engine note

Advanced features such as any-motion and no-motion depend on the BMI323 feature engine. The datasheet requires the feature engine to be enabled before sensors are re-enabled for these features. The helper methods in this crate follow that model, but application code should still keep the order in mind when building its configuration sequence.

For motion-feature timing and threshold fields, prefer the conversion helpers on AnyMotionConfig and NoMotionConfig instead of hand-coding raw register values.

The report_mode and interrupt_hold fields are written to a single shared BMI323 register (EXT_GEN_SET_1). When multiple feature-engine blocks are configured, the last configure_* call’s values win for both fields. Use the same values across all configure_* calls, or set them in the intended final order.

§Startup configuration

Bmi323::init and Bmi323Async::init perform a soft reset so the sensor starts from a known state. After that reset, this driver does not assume the accelerometer or gyroscope are configured for your application. In practice, you should call Bmi323::set_accel_config and Bmi323::set_gyro_config or their async equivalents before relying on accelerometer or gyroscope sample reads.

The driver tracks local range fields initialized to AccelRange::G8 and GyroRange::Dps2000, but those are only fallback bookkeeping values until you explicitly configure the sensor through the driver.

§Example: blocking I2C

use bmi323_driver::{
    AccelConfig, AccelMode, AccelRange, AverageSamples, Bandwidth, Bmi323,
    GyroConfig, GyroMode, GyroRange, I2C_ADDRESS_PRIMARY, OutputDataRate,
};
use embedded_hal::delay::DelayNs;
use embedded_hal::i2c::I2c;

fn example<I2C, D>(i2c: I2C, delay: &mut D) -> Result<(), bmi323_driver::Error<I2C::Error>>
where
    I2C: I2c,
    D: DelayNs,
{
    let mut imu = Bmi323::new_i2c(i2c, I2C_ADDRESS_PRIMARY);
    let state = imu.init(delay)?;
    let _ = state;

    imu.set_accel_config(AccelConfig {
        odr: OutputDataRate::Hz100,
        ..Default::default()
    })?;

    imu.set_gyro_config(GyroConfig {
        odr: OutputDataRate::Hz100,
        ..Default::default()
    })?;

    let sample = imu.read_imu_data()?;
    let accel_g = sample.accel.as_g(imu.accel_range());
    let gyro_dps = sample.gyro.as_dps(imu.gyro_range());
    let _ = (accel_g, gyro_dps);
    Ok(())
}

§Example: async interrupt-driven usage

use bmi323_driver::{
    AccelConfig, AccelMode, AccelRange, ActiveLevel, AnyMotionConfig,
    AverageSamples, Bandwidth, Bmi323Async, EventReportMode,
    I2C_ADDRESS_PRIMARY, InterruptChannel, InterruptPinConfig,
    InterruptRoute, InterruptSource, MotionAxes, OutputDataRate, OutputMode,
    ReferenceUpdate,
};
use embedded_hal_async::delay::DelayNs;
use embedded_hal_async::digital::Wait;
use embedded_hal_async::i2c::I2c;

async fn example<I2C, D, P>(
    i2c: I2C,
    delay: &mut D,
    int1_pin: &mut P,
) -> Result<(), bmi323_driver::Error<I2C::Error>>
where
    I2C: I2c,
    D: DelayNs,
    P: Wait,
{
    let mut imu = Bmi323Async::new_i2c(i2c, I2C_ADDRESS_PRIMARY);
    imu.init(delay).await?;
    imu.enable_feature_engine().await?;
    imu.set_accel_config(AccelConfig {
        mode: AccelMode::HighPerformance,
        odr: OutputDataRate::Hz100,
        ..Default::default()
    }).await?;
    imu.configure_any_motion(AnyMotionConfig {
        axes: MotionAxes::XYZ,
        threshold: AnyMotionConfig::threshold_from_g(0.08),
        hysteresis: AnyMotionConfig::hysteresis_from_g(0.02),
        duration: 5, // 5 / 50 s = 100 ms above threshold before event
        wait_time: 1, // 1 / 50 s = 20 ms clear delay after slope drops
        reference_update: ReferenceUpdate::EverySample,
        report_mode: EventReportMode::AllEvents,
        interrupt_hold: 3, // 0.625 ms * 2^3 = 5 ms interrupt hold
    }).await?;
    imu.set_interrupt_latching(true).await?;
    imu.configure_interrupt_pin(
        InterruptChannel::Int1,
        InterruptPinConfig {
            active_level: ActiveLevel::High,
            output_mode: OutputMode::PushPull,
            enabled: true,
        },
    ).await?;
    imu.map_interrupt(InterruptSource::AnyMotion, InterruptRoute::Int1).await?;

    let status = imu.wait_for_interrupt(int1_pin, InterruptChannel::Int1).await?;
    if status.any_motion() {
        let accel = imu.read_accel().await?;
        let _ = accel;
    }
    Ok(())
}

Structs§

AccelConfig
High-level accelerometer configuration written to ACC_CONF.
AltAccelConfig
Reduced accelerometer configuration used by the BMI323 alternate mode.
AltAccelSwitchProfile
Convenience bundle for a common accel-only alternate-configuration setup.
AltConfigControl
Automatic switching policy between user and alternate accel/gyro configurations.
AltGyroConfig
Reduced gyroscope configuration used by the BMI323 alternate mode.
AltStatus
Current active accel/gyro configuration selection reported by the BMI323.
AnyMotionConfig
Configuration for the BMI323 any-motion feature.
AsyncI2cTransport
Async I2C transport wrapper used by Bmi323Async.
AsyncSpiTransport
Async SPI transport wrapper used by Bmi323Async.
AxisData
Raw 3-axis sample from the accelerometer or gyroscope.
Bmi323
Blocking BMI323 driver.
Bmi323Async
Async BMI323 driver.
DeviceState
Result returned by Bmi323::init and Bmi323Async::init.
ErrorWord
Decoded contents of the BMI323 ERR_REG register.
FifoConfig
FIFO enable and behavior configuration.
FlatConfig
Configuration for the BMI323 flat-detection feature.
GyroConfig
High-level gyroscope configuration written to GYR_CONF.
ImuData
Combined accelerometer and gyroscope sample read in one burst.
InterruptPinConfig
Electrical configuration for INT1 or INT2.
InterruptStatus
Decoded interrupt status for INT1, INT2, or I3C IBI.
MotionAxes
Per-axis enable mask for motion features.
NoMotionConfig
Configuration for the BMI323 no-motion feature.
OrientationConfig
Configuration for the BMI323 orientation-detection feature.
SelfTestDetail
Detailed self-test result bits read from the BMI323 st_result extended register.
SelfTestResult
Result of a completed BMI323 self-test run.
SignificantMotionConfig
Configuration for the BMI323 significant-motion feature.
StatusWord
Decoded contents of the BMI323 STATUS register.
StepCounterConfig
Configuration for the BMI323 feature-engine step counter block.
SyncI2cTransport
Blocking I2C transport wrapper used by Bmi323.
SyncSpiTransport
Blocking SPI transport wrapper used by Bmi323.
TapConfig
Configuration for the BMI323 tap-detection feature.
TiltConfig
Configuration for the BMI323 tilt-detection feature.

Enums§

AccelMode
Accelerometer operating mode.
AccelRange
Accelerometer full-scale measurement range.
ActiveLevel
Electrical active level for an interrupt output pin.
AltConfigSwitchSource
Supported feature-engine sources that can switch between user and alternate sensor configurations.
AverageSamples
Sample averaging depth used in supported sensor modes.
Bandwidth
Low-pass filter bandwidth relative to output data rate.
Error
Driver error type.
EventReportMode
Event reporting policy for supported feature-engine motion detectors.
FeatureBlockingMode
Shared blocking behavior used by flat and orientation detection.
GyroMode
Gyroscope operating mode.
GyroRange
Gyroscope full-scale measurement range.
InterruptChannel
Interrupt output channel inside the BMI323.
InterruptRoute
Mapping destination for an interrupt source.
InterruptSource
Interrupt source that can be mapped to an output channel.
OrientationMode
Configuration mode for orientation spread between portrait and landscape.
OutputDataRate
Output data rate selection used by accel and gyro configuration.
OutputMode
Electrical driver mode for an interrupt output pin.
ReferenceUpdate
Reference update policy for supported motion detectors.
SelfTestSelection
Self-test selection written to the BMI323 st_select extended register.
TapAxis
Dominant accelerometer axis used for tap detection.
TapDetectionMode
Detection profile for tap recognition.
TapReportingMode
Reporting policy for tap gesture confirmation.

Constants§

I2C_ADDRESS_ALTERNATE
Alternate 7-bit BMI323 I2C address.
I2C_ADDRESS_PRIMARY
Primary 7-bit BMI323 I2C address.

Traits§

AsyncAccess
Low-level async register access contract used by the async driver.
SyncAccess
Low-level blocking register access contract used by the blocking driver.