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

frame()

@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 :invalid if the device emitted the 0x8000 sentinel for this frame.
  • :sensor_time — raw 16-bit counter (low word). Multiply by BMI323.sensor_time_tick_us/0 to get microseconds.

ranges()

@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).

source()

@type source() :: :accelerometer | :gyroscope | :temperature | :sensor_time

A FIFO data source.

Functions

canonical_order()

@spec canonical_order() :: [source()]

Canonical ordering of FIFO sources within a frame.

decode_fifo_conf(arg)

@spec decode_fifo_conf(<<_::16>>) :: %{sources: [source()], stop_on_full: boolean()}

Decode a FIFO_CONF binary into a map describing the enabled sources and the stop_on_full flag.

dummy_signature(sources)

@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_fifo_conf(sources, opts \\ [])

@spec encode_fifo_conf(
  [source()],
  keyword()
) :: <<_::16>>

Encode a FIFO_CONF value from a list of enabled sources.

Options

  • :stop_on_full (default false) — when true, the FIFO stops accepting new data on overflow. When false, the oldest frame is overwritten (streaming mode).

frame_byte_count(sources)

@spec frame_byte_count([source()]) :: pos_integer()

Number of bytes per frame for the given source list.

frame_word_count(sources)

@spec frame_word_count([source()]) :: pos_integer()

Number of 16-bit words per frame for the given source list.

normalise_sources(sources)

@spec normalise_sources([source()]) :: [source()]

Normalise a user-supplied source list: validate each entry, sort into canonical order, deduplicate, and reject the empty list.

parse_frames(data, sources, ranges)

@spec parse_frames(binary(), [source()], ranges()) :: [frame()]

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.