BMI323. Fifo
(bmi323 v0.1.0)
Copy Markdown
FIFO frame protocol encoding and decoding for the BMI323.
The BMI323's on-chip FIFO stores frames in a fixed canonical order:
accelerometer (3 words) → gyroscope (3 words) → temperature (1 word) → sensor_time (1 word)Each source can be independently enabled or disabled in FIFO_CONF;
disabled sources are omitted from frames, so the frame width depends on
which sources are active. This module encodes FIFO_CONF values from a
source list, decodes them back, and parses raw FIFO bytes into a list of
scaled sample maps.
Dummy frames (signalling a configuration change or sensor not ready) are detected by inspecting the first word against the per-source signatures in table 18 of the datasheet and dropped silently.
References: BMI323 Datasheet BST-BMI323-DS000-12 §5.7.
Summary
Types
A parsed FIFO frame. Contains only the keys for sources enabled at parse time.
Map of configured sensor ranges. Entries are required only for sources that
need scaling (:accelerometer and :gyroscope).
A FIFO data source.
Functions
Canonical ordering of FIFO sources within a frame.
Decode a FIFO_CONF binary into a map describing the enabled sources and
the stop_on_full flag.
Return the dummy-frame signature (first 16-bit word) for the given source
list, or nil if no source produces a detectable dummy.
Encode a FIFO_CONF value from a list of enabled sources.
Number of bytes per frame for the given source list.
Number of 16-bit words per frame for the given source list.
Normalise a user-supplied source list: validate each entry, sort into canonical order, deduplicate, and reject the empty list.
Parse a raw FIFO buffer into a list of scaled frames, dropping dummy frames.
Types
@type frame() :: %{ optional(:accelerometer) => BMI323.axes(), optional(:gyroscope) => BMI323.axes(), optional(:temperature) => float() | :invalid, optional(:sensor_time) => 0..65535 }
A parsed FIFO frame. Contains only the keys for sources enabled at parse time.
:accelerometer/:gyroscope—%{x: float, y: float, z: float}in m/s² and rad/s respectively.:temperature— float °C, or:invalidif the device emitted the0x8000sentinel for this frame.:sensor_time— raw 16-bit counter (low word). Multiply byBMI323.sensor_time_tick_us/0to get microseconds.
@type ranges() :: %{ optional(:accelerometer) => BMI323.Config.accelerometer_range(), optional(:gyroscope) => BMI323.Config.gyroscope_range() }
Map of configured sensor ranges. Entries are required only for sources that
need scaling (:accelerometer and :gyroscope).
@type source() :: :accelerometer | :gyroscope | :temperature | :sensor_time
A FIFO data source.
Functions
@spec canonical_order() :: [source()]
Canonical ordering of FIFO sources within a frame.
Decode a FIFO_CONF binary into a map describing the enabled sources and
the stop_on_full flag.
@spec dummy_signature([source()]) :: 0..65535 | nil
Return the dummy-frame signature (first 16-bit word) for the given source
list, or nil if no source produces a detectable dummy.
Per datasheet table 18, dummy frames are identified by inspecting the first word. The signature is determined by the highest-priority source in the frame:
- accelerometer →
0x7F01 - gyroscope (without accelerometer) →
0x7F02 - temperature (without accelerometer or gyroscope) →
0x8000 - sensor_time only → no dummy signature exists (the timer counter never goes invalid).
Encode a FIFO_CONF value from a list of enabled sources.
Options
:stop_on_full(defaultfalse) — whentrue, the FIFO stops accepting new data on overflow. Whenfalse, the oldest frame is overwritten (streaming mode).
@spec frame_byte_count([source()]) :: pos_integer()
Number of bytes per frame for the given source list.
@spec frame_word_count([source()]) :: pos_integer()
Number of 16-bit words per frame for the given source list.
Normalise a user-supplied source list: validate each entry, sort into canonical order, deduplicate, and reject the empty list.
Parse a raw FIFO buffer into a list of scaled frames, dropping dummy frames.
ranges must contain entries for any scaled sources in sources
(i.e. :accelerometer and :gyroscope). Missing ranges raise
ArgumentError.
Trailing bytes that do not constitute a full frame are silently discarded.