Files
kaptan/firmware/libs/kaptan-i2c/src/lib.rs
T
Onur Özkan f9a61a086f feat(firmware): validate configuration and migrate sensor-driven flight APIs
Validate configuration through its owning schemas and keep board
declarations separate from shared F722 resource ownership. Bound USB
transitions, isolate transport failures and retain restart-only activation.

Migrate navigation and flight consumers with the sensor and schema
contracts. Require explicit installation data and synchronous output
authority; board motor outputs remain inhibited.

Validation: assembled-prefix host tests, strict Clippy, platform/USB tests
and both ARM release builds. Final-source coverage and scoped Miri/Kani
evidence are retained separately from hardware qualification.
2026-11-07 18:12:11 +03:00

77 lines
3.2 KiB
Rust

//! Non-blocking I²C transaction contract.
//!
//! Controllers own in-flight transfer storage. Implementations may use
//! interrupts or DMA, but must never make a driver wait for a peripheral
//! status flag.
#![no_std]
use kaptan_time::Timestamp;
/// Terminal outcome reported by an I²C controller.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum I2cCompletion {
/// The bound interrupt had no terminal transaction event.
NotPending,
/// The submitted transaction completed and read bytes are valid.
Complete,
/// The submitted transaction failed and read bytes are unusable.
TransferFault,
}
/// Completion admission or cancellation failure. Errors never copy read bytes.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CompletionError {
NotPending,
NotActive,
InvalidLength,
TransferFault,
/// Physical STOP was not observed by the shutdown deadline. The controller
/// is halted and cannot accept another transaction during this boot.
StopUnproven,
}
/// Owns a non-blocking I²C controller route and its in-flight storage.
///
/// Each operation sends a STOP on successful completion. Controllers copy a
/// submitted write into owned storage before returning. A completed read is
/// copied into the caller-provided destination only from
/// [`Self::complete_transaction`], after the hardware no longer accesses the
/// controller-owned storage. This avoids retaining pointers to caller slices
/// across interrupt boundaries.
pub trait I2cBus {
/// Failure to submit a transaction.
type StartError;
/// Starts one address-scoped write transaction ending with a STOP.
fn start_write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::StartError>;
/// Starts one address-scoped read transaction ending with a STOP.
fn start_read(&mut self, address: u8, length: usize) -> Result<(), Self::StartError>;
/// Releases controller ownership after a hardware ISR acknowledged the
/// terminal event and, for a successful read, copies into `read`.
///
/// This must not poll or wait. `NotPending` is entirely nonmutating. A
/// successful read requires a matching destination length and controller
/// proof of the current transaction's STOP, not just a caller notification.
/// Old IRQs/completions must not retire or copy out a newer transaction.
fn complete_transaction(
&mut self,
completion: I2cCompletion,
read: Option<&mut [u8]>,
) -> Result<(), CompletionError>;
/// Cancels an in-flight transaction after a platform-selected timeout.
///
/// Requests STOP without waiting. Admission remains closed until STOP is
/// proven. This is not permission to reuse or free in-flight storage.
fn cancel_transaction(&mut self, now: Timestamp);
/// Services cancellation deadlines even without interrupts. The caller must
/// invoke this periodically with its monotonic boot clock. A bounded STOP
/// failure halts admission and returns `StopUnproven`. Storage must outlive
/// all hardware access, including owner drop/forget and failed cancellation.
fn service(&mut self, now: Timestamp) -> Result<(), CompletionError>;
}