pub struct Scdc<T> { /* private fields */ }Expand description
Async typed client for the HDMI 2.1 SCDC (Status and Control Data Channel) register map.
Scdc<T> wraps an async ScdcTransport and exposes one typed async fn per register
group. It holds no protocol state; all sequencing logic belongs in the caller.
§Example
use culvert_async::Scdc;
use hdmi_hal_async::scdc::ScdcTransport;
struct StubTransport;
impl ScdcTransport for StubTransport {
type Error = core::convert::Infallible;
async fn read(&self, _reg: u8) -> Result<u8, Self::Error> { Ok(0) }
async fn write(&mut self, _reg: u8, _value: u8) -> Result<(), Self::Error> { Ok(()) }
}
let mut scdc = Scdc::new(StubTransport);
let sink_version = scdc.read_sink_version().await.unwrap();
scdc.write_source_version(1).await.unwrap();Implementations§
Source§impl<T: ScdcTransport> Scdc<T>
impl<T: ScdcTransport> Scdc<T>
Sourcepub async fn read_ced(&mut self) -> Result<CedCounters, ScdcError<T::Error>>
pub async fn read_ced(&mut self) -> Result<CedCounters, ScdcError<T::Error>>
Reads per-lane character error counts from ERR_DET registers (0x50–0x55 for
lanes 0–2, 0x57–0x58 for lane 3; 0x56 is the CED checksum).
Each lane’s counter is decoded from a low/high byte pair. The high byte’s
bit 7 is a validity flag; if it is not set the lane’s counter is None.
Each byte is a separate read, so a counter the sink updates between its low and high byte can be torn, and the CED checksum (0x56) is not verified. Treat the counts as diagnostics.
Sourcepub async fn read_rs_correction(
&mut self,
) -> Result<Option<RsCorrectionCount>, ScdcError<T::Error>>
pub async fn read_rs_correction( &mut self, ) -> Result<Option<RsCorrectionCount>, ScdcError<T::Error>>
Reads the Reed-Solomon correction count from RS_Correction_L/H (0x59/0x5A).
Returns None if the high byte’s validity bit (bit 7) is not set. The count is
maintained by the sink in FRL mode; UpdateFlags::rsed_update signals a change.
The two bytes are separate reads, so a count the sink updates between them can be torn. Treat it as a diagnostic.
Source§impl<T: ScdcTransport> Scdc<T>
impl<T: ScdcTransport> Scdc<T>
Sourcepub async fn write_frl_config(
&mut self,
config: FrlConfig,
) -> Result<(), ScdcError<T::Error>>
pub async fn write_frl_config( &mut self, config: FrlConfig, ) -> Result<(), ScdcError<T::Error>>
Writes FRL training configuration to Config_1 (0x31).
Encodes FRL_Rate into bits[3:0] and FFE_Levels into bits[7:4].
Returns crate::ProtocolError::FfeLevelsOutOfRange without writing anything if
the FFE levels exceed FfeLevels::max_for the
requested rate.
Sourcepub async fn write_config_0(
&mut self,
config: Config0,
) -> Result<(), ScdcError<T::Error>>
pub async fn write_config_0( &mut self, config: Config0, ) -> Result<(), ScdcError<T::Error>>
Writes Config_0 (0x30): RR_Enable (bit 0) and FLT_No_Retrain (bit 1).
Sourcepub async fn read_source_test_config(
&mut self,
) -> Result<SourceTestConfig, ScdcError<T::Error>>
pub async fn read_source_test_config( &mut self, ) -> Result<SourceTestConfig, ScdcError<T::Error>>
Reads Source_Test_Configuration (0x35), written by the sink to instruct the
source during compliance testing.
Sourcepub async fn read_status_flags(
&mut self,
) -> Result<StatusFlags, ScdcError<T::Error>>
pub async fn read_status_flags( &mut self, ) -> Result<StatusFlags, ScdcError<T::Error>>
Reads Status_Flags_0 (0x40): clock detection, lane lock, FLT_Ready and DSC
decode failure.
Sourcepub async fn read_ltp_requests(
&mut self,
) -> Result<LtpRequests, ScdcError<T::Error>>
pub async fn read_ltp_requests( &mut self, ) -> Result<LtpRequests, ScdcError<T::Error>>
Reads the per-lane link training pattern requests from Status_Flags_1 (0x41,
lanes 0–1) and Status_Flags_2 (0x42, lanes 2–3).
A value the HDMI 2.1 specification leaves undefined (0x9–0xD) is
LtpReq::Reserved, not an error.
Source§impl<T: ScdcTransport> Scdc<T>
impl<T: ScdcTransport> Scdc<T>
Sourcepub async fn write_tmds_config(
&mut self,
config: TmdsConfig,
) -> Result<(), ScdcError<T::Error>>
pub async fn write_tmds_config( &mut self, config: TmdsConfig, ) -> Result<(), ScdcError<T::Error>>
Writes scrambling configuration to TMDS_Config (0x20).
Sets Scrambling_Enable (bit 0) and TMDS_Bit_Clock_Ratio (bit 1).
Sourcepub async fn read_scrambler_status(
&mut self,
) -> Result<ScramblerStatus, ScdcError<T::Error>>
pub async fn read_scrambler_status( &mut self, ) -> Result<ScramblerStatus, ScdcError<T::Error>>
Reads scrambler acknowledgement from Scrambler_Status (0x21).
Returns ScramblerStatus::scrambling_active set when the sink confirms
that TMDS scrambling is active (bit 0).
Source§impl<T: ScdcTransport> Scdc<T>
impl<T: ScdcTransport> Scdc<T>
Sourcepub async fn read_update_flags(
&mut self,
) -> Result<UpdateFlags, ScdcError<T::Error>>
pub async fn read_update_flags( &mut self, ) -> Result<UpdateFlags, ScdcError<T::Error>>
Reads update flags from Update_0 (0x10).
Sourcepub async fn clear_update_flags(
&mut self,
flags: ClearableUpdateFlags,
) -> Result<(), ScdcError<T::Error>>
pub async fn clear_update_flags( &mut self, flags: ClearableUpdateFlags, ) -> Result<(), ScdcError<T::Error>>
Clears the specified update flags in Update_0 (0x10).
Each flag set to true in flags is cleared (write-1-to-clear). Flags
set to false are left unchanged, and so is RR_Test, which the source does not
clear (ClearableUpdateFlags has no field for it). To acknowledge every flag just
read, pass UpdateFlags::clearable.
Source§impl<T: ScdcTransport> Scdc<T>
impl<T: ScdcTransport> Scdc<T>
Source§impl<T: ScdcTransport> Scdc<T>
impl<T: ScdcTransport> Scdc<T>
Sourcepub fn into_transport(self) -> T
pub fn into_transport(self) -> T
Consumes the client and returns the underlying transport.
Trait Implementations§
Source§impl<T: ScdcTransport> ScdcClient for Scdc<T>
Available on crate feature plumbob-async only.Typed SCDC access for plumbob-async’s link training.
impl<T: ScdcTransport> ScdcClient for Scdc<T>
plumbob-async only.Typed SCDC access for plumbob-async’s link training.
Scdc does not wait between calls. plumbob’s state machine polls read_flt_ready and
read_update_flags in a loop whose limits assume one poll every 2 ms by default; await
that interval inside those two methods, in an ScdcClient of your own that wraps
Scdc<T> and forwards the other six (doc/architecture.md shows one). A deadline or
cancel signal belongs there too, following plumbob’s “Stopping early” rule. Not in the
transport: there a wait applies to every register access, and a transport cannot tell
the polled reads from LTS:L’s.
Source§async fn read_update_flags(&mut self) -> Result<UpdateFlags, Self::Error>
async fn read_update_flags(&mut self) -> Result<UpdateFlags, Self::Error>
Update_0 flags the state machine uses. Read moreSource§async fn clear_update_flags(
&mut self,
flags: ClearableUpdateFlags,
) -> Result<(), Self::Error>
async fn clear_update_flags( &mut self, flags: ClearableUpdateFlags, ) -> Result<(), Self::Error>
Update_0 flags (write 1 to clear). Read moreSource§async fn read_ltp_requests(&mut self) -> Result<LtpRequests, Self::Error>
async fn read_ltp_requests(&mut self) -> Result<LtpRequests, Self::Error>
Status_Flags_1/2. Read moreSource§async fn read_source_test_config(
&mut self,
) -> Result<SourceTestConfig, Self::Error>
async fn read_source_test_config( &mut self, ) -> Result<SourceTestConfig, Self::Error>
Source_Test_Configuration (0x35). Read more