plumbob-async
Async FRL link training state machine for HDMI 2.1.
plumbob-async is the async companion to plumbob,
following the same design split as embedded-hal / embedded-hal-async. It mirrors the
four-phase FRL training state machine with async fn methods, yielding to the executor
between poll iterations instead of spinning. All shared protocol and training types are
re-exported from plumbob; nothing is duplicated.
Usage
[]
= "0.1"
Implement ScdcClient against your async SCDC transport:
use ;
Construct an FrlTrainer and step down through rates until one succeeds:
use HdmiForumFrl;
use ;
let mut trainer = new;
let config = default;
let rates = ;
for rate in rates
The HdmiPhy bound on P is hdmi_hal_async::phy::HdmiPhy. The FrlConfig,
TrainingConfig, TrainingOutcome, TrainingError, and all protocol types are
re-exported from plumbob and are identical between the sync and async APIs.
Training procedure
train_at_rate runs all four phases for a single rate attempt and .awaits each SCDC
and PHY call, yielding to the executor between iterations. FallbackRequired means the
link did not converge at this rate; TrainingError means a hard I/O failure. The two are
kept distinct so a caller diagnosing a failure knows whether it came from the protocol or
the bus.
flowchart TD
A["train_at_rate(rate, config).await"]
B["Phase 1\nwrite_frl_config · set_frl_rate"]
C["Phase 2\nawait flt_ready"]
D["Phase 3\nawait frl_start"]
E["Phase 4\nLTP loop · send_ltp"]
F(["Success { achieved_rate }"])
G(["FallbackRequired"])
H(["TrainingError"])
A --> B --> C
C -- asserted --> D
C -- timeout --> G
D -- asserted --> E
D -- timeout --> G
E -- "ltp_req == None" --> F
E -- timeout --> G
B & C & D & E -- I/O error --> H
Diagnostics
Enable the alloc feature to get train_at_rate_traced, which returns a TrainingTrace
alongside the outcome. The trace type and its TrainingEvent variants are the same as in
plumbob; a sync trace and an async trace are directly comparable.
let = trainer.train_at_rate_traced.await?;
println!;
for event in &trace.events
Features
| Feature | Default | Description |
|---|---|---|
std |
no | Implies alloc; no additional API surface |
alloc |
no | Enables TrainingTrace, TrainingEvent, and train_at_rate_traced |
No features are enabled by default.
no_std builds
plumbob-async declares #![no_std] throughout. The bare crate provides the full
four-phase async state machine without an allocator. The alloc feature adds
train_at_rate_traced; std implies alloc.
# no_std, no heap
= { = "0.1" }
# no_std + trace support
= { = "0.1", = ["alloc"] }
# std targets
= { = "0.1", = ["std"] }
No executor is assumed. The traits impose no constraint on which async runtime is used — Embassy, Tokio, and async-std are all valid implementors.
Stack position
flowchart LR
dt["display-types"]
hal["hdmi-hal"]
hal_async["hdmi-hal-async"]
plumbob["plumbob"]
plumbob_async["plumbob-async"]
dt --> hal --> hal_async --> plumbob_async
dt --> plumbob --> plumbob_async
plumbob-async depends on plumbob for all shared data types and on hdmi-hal-async
for the async HdmiPhy trait. It does not depend on any executor or runtime crate.
Out of scope
- Rate fallback policy —
train_at_ratereturnsFallbackRequired; the caller decides the retry sequence. - SCDC register decoding — plumbob-async reads typed values from
ScdcClientand does not decode raw register bytes. - PHY vendor sequences — plumbob-async calls
HdmiPhy::send_ltpandset_frl_rate; the register sequences live in platform PHY backends. - Timing and inter-poll delay — plumbob-async does not insert delays between polls.
The iteration limits in
TrainingConfigare the only timeout mechanism; callers that need a delay between polls implement it inside theirScdcClient. - Executor dependency — no runtime crate is in the dependency graph.
Documentation
doc/architecture.md— role, scope, interface boundaries, and design principles
License
Licensed under the Mozilla Public License 2.0.