culvert_async/client/
update.rs1use hdmi_hal_async::scdc::ScdcTransport;
2
3use crate::{ScdcError, UpdateFlags};
4
5use super::Scdc;
6use super::address;
7
8impl<T: ScdcTransport> Scdc<T> {
9 pub async fn read_update_flags(&mut self) -> Result<UpdateFlags, ScdcError<T::Error>> {
11 let u0 = self
12 .transport
13 .read(address::UPDATE_0)
14 .await
15 .map_err(ScdcError::Transport)?;
16 let u1 = self
17 .transport
18 .read(address::UPDATE_1)
19 .await
20 .map_err(ScdcError::Transport)?;
21 Ok(UpdateFlags::new(
22 u0 & 0x01 != 0,
23 u0 & 0x02 != 0,
24 u0 & 0x04 != 0,
25 u1 & 0x01 != 0,
26 ))
27 }
28
29 pub async fn clear_update_flags(
34 &mut self,
35 flags: UpdateFlags,
36 ) -> Result<(), ScdcError<T::Error>> {
37 let u0 = (flags.status_update as u8)
38 | ((flags.ced_update as u8) << 1)
39 | ((flags.frl_update as u8) << 2);
40 let u1 = flags.dsc_update as u8;
41 self.transport
42 .write(address::UPDATE_0, u0)
43 .await
44 .map_err(ScdcError::Transport)?;
45 self.transport
46 .write(address::UPDATE_1, u1)
47 .await
48 .map_err(ScdcError::Transport)
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::super::Scdc;
55 use super::super::test_transport::TestTransport;
56 use crate::UpdateFlags;
57
58 #[pollster::test]
59 async fn update_flags_individual_bits() {
60 let mut sim = TestTransport::new();
62 sim.set(0x10, 0x01);
63 assert!(
64 Scdc::new(sim)
65 .read_update_flags()
66 .await
67 .unwrap()
68 .status_update
69 );
70
71 let mut sim = TestTransport::new();
73 sim.set(0x10, 0x02);
74 assert!(Scdc::new(sim).read_update_flags().await.unwrap().ced_update);
75
76 let mut sim = TestTransport::new();
78 sim.set(0x10, 0x04);
79 assert!(Scdc::new(sim).read_update_flags().await.unwrap().frl_update);
80
81 let mut sim = TestTransport::new();
83 sim.set(0x11, 0x01);
84 assert!(Scdc::new(sim).read_update_flags().await.unwrap().dsc_update);
85 }
86
87 #[pollster::test]
88 async fn clear_update_flags_w1c() {
89 let mut scdc = Scdc::new(TestTransport::new());
90 scdc.clear_update_flags(UpdateFlags::new(true, true, true, true))
91 .await
92 .unwrap();
93 let t = scdc.into_transport();
94 assert_eq!(t.get(0x10), 0x07);
95 assert_eq!(t.get(0x11), 0x01);
96 }
97
98 #[pollster::test]
99 async fn clear_update_flags_partial() {
100 let mut scdc = Scdc::new(TestTransport::new());
101 scdc.clear_update_flags(UpdateFlags::new(false, true, false, false))
102 .await
103 .unwrap();
104 let t = scdc.into_transport();
105 assert_eq!(t.get(0x10), 0x02); assert_eq!(t.get(0x11), 0x00);
107 }
108
109 #[pollster::test]
110 async fn transport_error_propagates() {
111 assert!(
113 Scdc::new(TestTransport::failing_after(0))
114 .read_update_flags()
115 .await
116 .is_err()
117 );
118 assert!(
120 Scdc::new(TestTransport::failing_after(1))
121 .read_update_flags()
122 .await
123 .is_err()
124 );
125 assert!(
127 Scdc::new(TestTransport::failing_after(0))
128 .clear_update_flags(UpdateFlags::new(false, false, false, false))
129 .await
130 .is_err()
131 );
132 assert!(
134 Scdc::new(TestTransport::failing_after(1))
135 .clear_update_flags(UpdateFlags::new(false, false, false, false))
136 .await
137 .is_err()
138 );
139 }
140}