Skip to content

Latest commit

 

History

History
156 lines (112 loc) · 4.55 KB

File metadata and controls

156 lines (112 loc) · 4.55 KB

Initialization Sequence Explorer API

This document describes the API for automatically exploring and executing initialization sequences over I2C. The API is designed for embedded Rust (no_std) environments such as Arduino Uno.


Overview

The Explorer API provides tools to:

  • Automatically discover valid I2C addresses of connected devices.
  • Generate and execute valid initialization sequences.
  • Handle command dependencies and batch execution efficiently.
  • Detect cycles or failures in command dependencies.

It is intended for scenarios where the initialization sequence is unknown or needs verification.


Key Structures

Explorer<N, MAX_DEPS>

Holds information about all initialization commands and their dependencies.

  • nodes: Array of CmdNode representing commands.
  • N: Maximum number of commands.
  • MAX_DEPS: Maximum number of dependencies per command.

CmdNode

Represents a single initialization command node.

Field Type Description
bytes &'static [u8] Command bytes to send over I2C
deps &'static [u8] List of dependent node indices

Key Functions

pruning_explorer

pub fn pruning_explorer<I2C, S, const N: usize, const CMD_BUFFER_SIZE: usize, const MAX_DEPS: usize>(
    explorer: &Explorer<N, MAX_DEPS>,
    i2c: &mut I2C,
    serial: &mut S,
    prefix: u8,
) -> Result<(), ExplorerError>
  • Description: Explores all valid initialization sequences for devices found on the I2C bus. Prunes failing commands automatically.

  • Parameters:

    • explorer: Reference to an Explorer containing command nodes.
    • i2c: I2C interface implementing I2cCompat.
    • serial: Serial interface implementing core::fmt::Write for logs.
    • prefix: Command prefix byte.
  • Returns: Ok(()) if all sequences were executed successfully, or an ExplorerError on failure.

  • Errors:

    • NoValidAddressesFound
    • BufferOverflow
    • DependencyCycle
    • ExecutionFailed

one_topological_explorer

pub fn one_topological_explorer<I2C, S, const N: usize, const INIT_SEQUENCE_LEN: usize, const CMD_BUFFER_SIZE: usize, const MAX_DEPS: usize>(
    explorer: &Explorer<N, MAX_DEPS>,
    i2c: &mut I2C,
    serial: &mut S,
    prefix: u8,
) -> Result<(), ExplorerError>
  • Description: Generates a single topological sort of commands and executes it on the first detected device. Useful for testing a single valid initialization sequence.

  • Parameters:

    • explorer: Reference to an Explorer containing command nodes.
    • i2c: I2C interface implementing I2cCompat.
    • serial: Serial interface implementing core::fmt::Write for logs.
    • prefix: Command prefix byte.
  • Returns: Ok(()) on success, otherwise an ExplorerError.

  • Errors:

    • NoValidAddressesFound
    • DependencyCycle
    • ExecutionFailed

Macros

pruning_sort!

  • Usage: Wraps pruning_explorer for convenience.
// Assuming `explorer` is a reference to an Explorer instance
const N: usize = 23;
const CMD_BUFFER_SIZE: usize = 256;
const MAX_DEPS: usize = 22;
pruning_sort!(explorer, &mut i2c, &mut serial, PREFIX, N, CMD_BUFFER_SIZE, MAX_DEPS);

get_one_sort!

  • Usage: Wraps one_topological_explorer for convenience.
// Assuming `explorer` is a reference to an Explorer instance
const N: usize = 23;
const CMD_BUFFER_SIZE: usize = 256;
const MAX_DEPS: usize = 22;
get_one_sort!(explorer, &mut i2c, &mut serial, PREFIX, N, CMD_BUFFER_SIZE, MAX_DEPS);

Example Usage

const PREFIX: u8 = 0x00;
let explorer_instance = nodes! {
    prefix = PREFIX,
    [
        [0xAE],
        [0xD5, 0x51] @ [0],
        [0xA8, 0x3F] @ [1],
        ...
        [0xAF] @ [0] // Display ON
    ]
};

let _ = pruning_sort!(explorer_instance.0, &mut i2c, &mut serial, PREFIX, 23, 256, 22);

Notes & Caveats

  • Ensure the CMD_BUFFER_SIZE is sufficient for batched commands.
  • All serial logs use core::fmt::Write and may fail silently with .ok().
  • Dependency cycles will abort execution to prevent I2C conflicts.
  • Devices must respond to I2C scans; otherwise NoValidAddressesFound is returned.
  • Recommended to add small delays (e.g., arduino_hal::delay_ms) between I2C operations on slow MCUs.