culvert_async/client/
update.rs1use hdmi_hal_async::scdc::ScdcTransport;
2
3use crate::ScdcError;
4use crate::{ClearableUpdateFlags, UpdateFlags};
5use culvert::codec;
6
7use super::Scdc;
8
9impl<T: ScdcTransport> Scdc<T> {
10 pub async fn read_update_flags(&mut self) -> Result<UpdateFlags, ScdcError<T::Error>> {
12 let update_0 = self
13 .transport
14 .read(codec::UPDATE_0)
15 .await
16 .map_err(ScdcError::Transport)?;
17 Ok(codec::decode_update_flags(update_0))
18 }
19
20 pub async fn clear_update_flags(
27 &mut self,
28 flags: ClearableUpdateFlags,
29 ) -> Result<(), ScdcError<T::Error>> {
30 let byte = codec::encode_clear_update_flags(flags);
31 self.transport
32 .write(codec::UPDATE_0, byte)
33 .await
34 .map_err(ScdcError::Transport)
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::super::Scdc;
41 use super::super::test_transport::{Op, TestTransport};
42 use crate::ScdcError;
43 use crate::{ClearableUpdateFlags, UpdateFlags};
44
45 fn read(byte: u8) -> UpdateFlags {
46 let mut sim = TestTransport::new();
47 sim.set(0x10, byte);
48 pollster::block_on(Scdc::new(sim).read_update_flags()).unwrap()
49 }
50
51 #[pollster::test]
52 async fn update_flags_individual_bits() {
53 assert!(read(0x01).status_update);
54 assert!(read(0x02).ced_update);
55 assert!(read(0x04).rr_test);
56 assert!(read(0x08).source_test_update);
57 assert!(read(0x10).frl_start);
58 assert!(read(0x20).flt_update);
59 assert!(read(0x40).rsed_update);
60 assert_eq!(
61 read(0x00),
62 UpdateFlags::new(false, false, false, false, false, false, false)
63 );
64 }
65
66 #[pollster::test]
67 async fn update_1_is_not_read() {
68 let mut sim = TestTransport::new();
69 sim.set(0x11, 0xFF);
70 assert_eq!(
71 Scdc::new(sim).read_update_flags().await.unwrap(),
72 UpdateFlags::new(false, false, false, false, false, false, false)
73 );
74 }
75
76 #[pollster::test]
77 async fn clear_update_flags_w1c() {
78 let mut scdc = Scdc::new(TestTransport::new());
79 scdc.clear_update_flags(ClearableUpdateFlags::new(
80 true, true, true, true, true, true,
81 ))
82 .await
83 .unwrap();
84 let t = scdc.into_transport();
85 assert_eq!(t.get(0x10), 0x7B); assert_eq!(t.get(0x11), 0x00);
87 }
88
89 #[pollster::test]
90 async fn read_then_clear_acknowledges_every_flag_but_rr_test() {
91 let mut sim = TestTransport::new();
94 sim.set(0x10, 0x24); let mut scdc = Scdc::new(sim);
96 let flags = scdc.read_update_flags().await.unwrap();
97 assert!(flags.rr_test && flags.flt_update);
98 scdc.clear_update_flags(flags.clearable()).await.unwrap();
99 assert_eq!(scdc.into_transport().get(0x10), 0x20);
100 }
101
102 #[pollster::test]
103 async fn clear_update_flags_partial() {
104 let mut scdc = Scdc::new(TestTransport::new());
105 scdc.clear_update_flags(ClearableUpdateFlags::new(
107 false, false, false, false, true, false,
108 ))
109 .await
110 .unwrap();
111 assert_eq!(scdc.into_transport().get(0x10), 0x20);
112 }
113
114 #[pollster::test]
115 async fn clear_update_flags_is_one_write() {
116 let mut scdc = Scdc::new(TestTransport::new());
117 scdc.clear_update_flags(ClearableUpdateFlags::new(
118 false, false, false, true, true, false,
119 ))
120 .await
121 .unwrap();
122 assert_eq!(
123 scdc.into_transport().log()[..2],
124 [Some(Op::Write(0x10, 0x30)), None]
125 );
126 }
127
128 #[pollster::test]
129 async fn transport_error_propagates() {
130 assert!(
131 Scdc::new(TestTransport::failing_after(0))
132 .read_update_flags()
133 .await
134 .is_err_and(|error| matches!(error, ScdcError::Transport(())))
135 );
136 assert!(
137 Scdc::new(TestTransport::failing_after(0))
138 .clear_update_flags(ClearableUpdateFlags::default())
139 .await
140 .is_err_and(|error| matches!(error, ScdcError::Transport(())))
141 );
142 }
143}