bmi323-driver
bmi323-driver is a no_std Rust driver for the Bosch Sensortec BMI323 6-DoF IMU.
The datasheet is available at Bosch Sensortec web site: https://www.bosch-sensortec.com/en/products/motion-sensors/imus/bmi323
This driver is designed to be transport-agnostic, small, and usable both in generic embedded-hal applications and in async Embassy-based firmware.
init() performs a soft reset, so the driver starts from a known sensor state.
After init(), configure the accelerometer and gyroscope explicitly before
depending on sample reads. The driver does not promise application-ready accel
or gyro settings immediately after initialization.
The API is built on top of embedded-hal 1.0 and embedded-hal-async 1.0.
The driver does not own the external interrupt GPIO, which keeps it transport
agnostic and easy to integrate with Embassy or platform-specific interrupt
handling.
Features
embedded-hal1.0 blocking API supportembedded-hal-async1.0 async API support- I2C and SPI transports
- accelerometer and gyroscope configuration
- burst accel/gyro reads
- FIFO configuration and reads
- interrupt pin electrical configuration and interrupt routing
- feature-engine enable sequence
- 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
Feature flags
Async mode is the default when no feature flags are set. The blocking feature
opts into the synchronous embedded-hal API. Enabling both simultaneously
causes a compile error.
async: no-op marker; async is the default behavior withoutblockingblocking: synchronous driver usingembedded-haltraitsdefmt: derivesdefmt::Formatfor public value types
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 both 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:
- in blocking applications, poll the GPIO or an MCU interrupt flag yourself,
then call
read_interrupt_status() - in async applications, either wait on the GPIO yourself or use
wait_for_interrupt()with a pin implementingembedded_hal_async::digital::Wait
Feature engine notes
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.
The driver tracks local range fields initialized to AccelRange::G2 and
GyroRange::Dps125 to match the BMI323 power-on reset defaults
(ACC_CONF/GYR_CONF = 0x0000).
Blocking I2C example
#
#
#
Async interrupt-driven advanced example
#
#
#
Repository examples
examples/blocking_i2c_basic.rsBlocking I2C configuration and sample reads.examples/async_i2c_basic.rsAsync I2C configuration and sample reads usingembedded-hal-async.examples/async_i2c_any_motion.rsGeneric async any-motion detection setup usingembedded-hal-async.examples/async_i2c_no_motion.rsGeneric async no-motion detection setup usingembedded-hal-async.examples/async_i2c_tap.rsGeneric async tap-detection setup usingembedded-hal-async.examples/async_i2c_orientation.rsGeneric async orientation-detection setup usingembedded-hal-async.examples/async_i2c_flat.rsGeneric async flat-detection setup usingembedded-hal-async.examples/async_i2c_significant_motion.rsGeneric async significant-motion detection setup usingembedded-hal-async.examples/async_i2c_tilt.rsGeneric async tilt-detection setup usingembedded-hal-async.examples/async_i2c_step_counter.rsGeneric async step-detector and step-counter setup usingembedded-hal-async.examples/async_i2c_alt_config.rsGeneric async alternate accel-configuration switching using any-motion and no-motion.examples/async_i2c_self_test.rsGeneric async built-in accelerometer and gyroscope self-test.
Hardware-specific STM32G030F6 Embassy examples are in the separate sub-crate embassy-stm32g030f6-examples.
STM32 Motion Detection Example
This screenshot shows the embassy-stm32g030f6-examples/src/bin/motion.rs
example running on an STM32G030F6 and printing detected accelerometer samples
after BMI323 motion interrupts fire.

License
MIT. See LICENSE.