culvert_async/client/
scrambling.rs1use hdmi_hal_async::scdc::ScdcTransport;
2
3use crate::{ScdcError, ScramblerStatus, TmdsConfig};
4
5use super::Scdc;
6use super::address;
7
8impl<T: ScdcTransport> Scdc<T> {
9 pub async fn write_tmds_config(
13 &mut self,
14 config: TmdsConfig,
15 ) -> Result<(), ScdcError<T::Error>> {
16 let byte = (config.scrambling_enable as u8) | ((config.high_tmds_clock_ratio as u8) << 1);
17 self.transport
18 .write(address::TMDS_CONFIG, byte)
19 .await
20 .map_err(ScdcError::Transport)
21 }
22
23 pub async fn read_scrambler_status(&mut self) -> Result<ScramblerStatus, ScdcError<T::Error>> {
28 let byte = self
29 .transport
30 .read(address::SCRAMBLER_STATUS)
31 .await
32 .map_err(ScdcError::Transport)?;
33 Ok(ScramblerStatus::new(byte & 0x01 != 0))
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::super::Scdc;
40 use super::super::test_transport::TestTransport;
41 use crate::{ScramblerStatus, TmdsConfig};
42
43 #[pollster::test]
44 async fn tmds_config_scrambling_only() {
45 let mut scdc = Scdc::new(TestTransport::new());
46 scdc.write_tmds_config(TmdsConfig {
47 scrambling_enable: true,
48 high_tmds_clock_ratio: false,
49 })
50 .await
51 .unwrap();
52 assert_eq!(scdc.into_transport().get(0x20), 0x01);
53 }
54
55 #[pollster::test]
56 async fn tmds_config_clock_ratio_only() {
57 let mut scdc = Scdc::new(TestTransport::new());
58 scdc.write_tmds_config(TmdsConfig {
59 scrambling_enable: false,
60 high_tmds_clock_ratio: true,
61 })
62 .await
63 .unwrap();
64 assert_eq!(scdc.into_transport().get(0x20), 0x02);
65 }
66
67 #[pollster::test]
68 async fn tmds_config_both_clear() {
69 let mut scdc = Scdc::new(TestTransport::new());
70 scdc.write_tmds_config(TmdsConfig {
71 scrambling_enable: false,
72 high_tmds_clock_ratio: false,
73 })
74 .await
75 .unwrap();
76 assert_eq!(scdc.into_transport().get(0x20), 0x00);
77 }
78
79 #[pollster::test]
80 async fn scrambler_status_bit0_set() {
81 let mut sim = TestTransport::new();
82 sim.set(0x21, 0xFF); assert_eq!(
84 Scdc::new(sim).read_scrambler_status().await.unwrap(),
85 ScramblerStatus::new(true)
86 );
87 }
88
89 #[pollster::test]
90 async fn scrambler_status_bit0_clear() {
91 let mut sim = TestTransport::new();
92 sim.set(0x21, 0xFE); assert_eq!(
94 Scdc::new(sim).read_scrambler_status().await.unwrap(),
95 ScramblerStatus::new(false)
96 );
97 }
98
99 #[pollster::test]
100 async fn transport_error_propagates() {
101 assert!(
102 Scdc::new(TestTransport::failing_after(0))
103 .write_tmds_config(TmdsConfig {
104 scrambling_enable: false,
105 high_tmds_clock_ratio: false
106 })
107 .await
108 .is_err()
109 );
110 assert!(
111 Scdc::new(TestTransport::failing_after(0))
112 .read_scrambler_status()
113 .await
114 .is_err()
115 );
116 }
117}