use hdmi_hal::scdc::ScdcTransport;
use crate::error::ScdcError;
use crate::register::UpdateFlags;
use crate::register::address;
use super::Scdc;
impl<T: ScdcTransport> Scdc<T> {
pub fn read_update_flags(&mut self) -> Result<UpdateFlags, ScdcError<T::Error>> {
let u0 = self
.transport
.read(address::UPDATE_0)
.map_err(ScdcError::Transport)?;
let u1 = self
.transport
.read(address::UPDATE_1)
.map_err(ScdcError::Transport)?;
Ok(UpdateFlags {
status_update: u0 & 0x01 != 0,
ced_update: u0 & 0x02 != 0,
frl_update: u0 & 0x04 != 0,
dsc_update: u1 & 0x01 != 0,
})
}
pub fn clear_update_flags(&mut self, flags: UpdateFlags) -> Result<(), ScdcError<T::Error>> {
let u0 = (flags.status_update as u8)
| ((flags.ced_update as u8) << 1)
| ((flags.frl_update as u8) << 2);
let u1 = flags.dsc_update as u8;
self.transport
.write(address::UPDATE_0, u0)
.map_err(ScdcError::Transport)?;
self.transport
.write(address::UPDATE_1, u1)
.map_err(ScdcError::Transport)
}
}
#[cfg(test)]
mod tests {
use super::super::Scdc;
use super::super::test_transport::TestTransport;
use crate::register::UpdateFlags;
#[test]
fn update_flags_individual_bits() {
let mut sim = TestTransport::new();
sim.set(0x10, 0x01);
assert!(Scdc::new(sim).read_update_flags().unwrap().status_update);
let mut sim = TestTransport::new();
sim.set(0x10, 0x02);
assert!(Scdc::new(sim).read_update_flags().unwrap().ced_update);
let mut sim = TestTransport::new();
sim.set(0x10, 0x04);
assert!(Scdc::new(sim).read_update_flags().unwrap().frl_update);
let mut sim = TestTransport::new();
sim.set(0x11, 0x01);
assert!(Scdc::new(sim).read_update_flags().unwrap().dsc_update);
}
#[test]
fn clear_update_flags_w1c() {
let mut scdc = Scdc::new(TestTransport::new());
scdc.clear_update_flags(UpdateFlags::new(true, true, true, true))
.unwrap();
let t = scdc.into_transport();
assert_eq!(t.get(0x10), 0x07);
assert_eq!(t.get(0x11), 0x01);
}
#[test]
fn clear_update_flags_partial() {
let mut scdc = Scdc::new(TestTransport::new());
scdc.clear_update_flags(UpdateFlags::new(false, true, false, false))
.unwrap();
let t = scdc.into_transport();
assert_eq!(t.get(0x10), 0x02); assert_eq!(t.get(0x11), 0x00);
}
#[test]
fn transport_error_propagates() {
assert!(
Scdc::new(TestTransport::failing_after(0))
.read_update_flags()
.is_err()
);
assert!(
Scdc::new(TestTransport::failing_after(1))
.read_update_flags()
.is_err()
);
assert!(
Scdc::new(TestTransport::failing_after(0))
.clear_update_flags(UpdateFlags::new(false, false, false, false))
.is_err()
);
assert!(
Scdc::new(TestTransport::failing_after(1))
.clear_update_flags(UpdateFlags::new(false, false, false, false))
.is_err()
);
}
}