BMI323 (bmi323 v0.1.0)
Copy MarkdownDriver for the Bosch BMI323 6-DoF inertial measurement unit.
Communicates over I²C (or any other Wafer
transport that implements the Wafer.I2C protocol).
Protocol notes
The BMI323 uses an unusual word-oriented register protocol:
- Every register is 16 bits wide, little-endian.
- Every read returns two dummy bytes before the payload; this driver strips them transparently.
- Writes have no dummy bytes — just the 8-bit address followed by the 16-bit value(s).
- Multi-word reads and writes auto-increment the register address.
Example
{:ok, i2c} = Wafer.Driver.Circuits.I2C.acquire(bus_name: "i2c-1", address: 0x68)
{:ok, bmi} = BMI323.acquire(conn: i2c)
Summary
Functions
Wrap an existing Wafer connection in a BMI323 struct.
Read the device's CHIP_ID register, returning the 7-bit identifier
(high byte of the 16-bit register is reserved and discarded).
Configure the accelerometer and cache the chosen range for later scaling.
Configure the gyroscope and cache the chosen range for later scaling.
The default 7-bit I²C address (0x68, SDO pin tied to GND).
Populate the cached ranges by reading ACC_CONF and GYR_CONF.
The expected CHIP_ID value (0x43) returned by an unmodified BMI323.
Read the accelerometer x/y/z sample and return scaled values in m/s².
Read the gyroscope x/y/z sample and return scaled values in rad/s.
Read accelerometer + gyroscope + temperature in a single 7-word burst.
Read the 32-bit sensor time counter.
Read the temperature sample and return °C. Returns {:error, :invalid_sample}
if the device reports the invalid sentinel 0x8000.
The sensor time counter's tick period in microseconds (39.0625 µs).
Issue a soft reset by writing the 0xDEAF command to the CMD register.
Types
@type acquire_option() :: {:conn, Wafer.Conn.t()} | {:soft_reset, boolean()} | {:verify_chip_id, boolean()}
@type chip_id() :: byte()
@type t() :: %BMI323{ accelerometer_range: BMI323.Config.accelerometer_range() | nil, conn: Wafer.Conn.t(), gyroscope_range: BMI323.Config.gyroscope_range() | nil }
Functions
@spec acquire([acquire_option()]) :: {:ok, t()} | {:error, term()}
Wrap an existing Wafer connection in a BMI323 struct.
Options
:conn(required) — a Wafer connection that implements theWafer.I2Cprotocol, e.g.Wafer.Driver.Circuits.I2CorWafer.Driver.Fake.:soft_reset(defaultfalse) — whentrue, issue a soft reset immediately after wrapping the connection. Seesoft_reset/1.:verify_chip_id(defaulttrue) — whentrue, readCHIP_IDand return{:error, {:chip_id_mismatch, got: byte, expected: 0x43}}if the device does not identify as a BMI323.
Read the device's CHIP_ID register, returning the 7-bit identifier
(high byte of the 16-bit register is reserved and discarded).
Configure the accelerometer and cache the chosen range for later scaling.
See BMI323.Config.encode_acc_conf/1 for the supported options. :mode and
:odr are required; :range, :bandwidth, and :averaging have defaults.
Configure the gyroscope and cache the chosen range for later scaling.
See BMI323.Config.encode_gyr_conf/1 for the supported options.
@spec default_i2c_address() :: 104
The default 7-bit I²C address (0x68, SDO pin tied to GND).
The alternate address 0x69 is selected by tying SDO to VDDIO.
Populate the cached ranges by reading ACC_CONF and GYR_CONF.
Useful after acquire/1 when the device has already been configured by
some other process and you need to scale samples without reconfiguring.
@spec expected_chip_id() :: 67
The expected CHIP_ID value (0x43) returned by an unmodified BMI323.
Read the accelerometer x/y/z sample and return scaled values in m/s².
Requires the accelerometer range to be cached on the struct — call
configure_accelerometer/2 or detect_ranges/1 first.
Read the gyroscope x/y/z sample and return scaled values in rad/s.
Requires the gyroscope range to be cached on the struct — call
configure_gyroscope/2 or detect_ranges/1 first.
@spec read_imu(t()) :: {:ok, imu_sample()} | {:error, term()}
Read accelerometer + gyroscope + temperature in a single 7-word burst.
Requires both ranges to be cached on the struct.
@spec read_sensor_time(t()) :: {:ok, non_neg_integer()} | {:error, term()}
Read the 32-bit sensor time counter.
One LSB equals 39.0625 µs. Multiply by
sensor_time_tick_us/0 to get microseconds.
Read the temperature sample and return °C. Returns {:error, :invalid_sample}
if the device reports the invalid sentinel 0x8000.
@spec sensor_time_tick_us() :: float()
The sensor time counter's tick period in microseconds (39.0625 µs).
Issue a soft reset by writing the 0xDEAF command to the CMD register.
The device returns to suspend mode and all user configuration is restored to its power-on default. Blocks for 10 ms to satisfy the device's post-reset start-up time before returning.