use display_types::cea861::hdmi_forum::HdmiForumFrl;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LtpPattern(u8);
impl LtpPattern {
pub fn new(raw: u8) -> Self {
Self(raw)
}
pub fn value(self) -> u8 {
self.0
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, Default)]
pub struct LaneEqParams {}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, Default)]
pub struct EqParams {
pub lane0: LaneEqParams,
pub lane1: LaneEqParams,
pub lane2: LaneEqParams,
pub lane3: Option<LaneEqParams>,
}
impl EqParams {
pub fn new() -> Self {
Self::default()
}
}
pub trait HdmiPhy {
type Error;
fn set_frl_rate(&mut self, rate: HdmiForumFrl) -> Result<(), Self::Error>;
fn send_ltp(&mut self, pattern: LtpPattern) -> Result<(), Self::Error>;
fn adjust_equalization(&mut self, params: EqParams) -> Result<(), Self::Error>;
fn set_scrambling(&mut self, enabled: bool) -> Result<(), Self::Error>;
}
#[cfg(test)]
mod tests {
use super::*;
use display_types::cea861::hdmi_forum::HdmiForumFrl;
struct MockPhy {
frl_rate: Option<HdmiForumFrl>,
scrambling: Option<bool>,
eq_calls: u32,
last_ltp: Option<LtpPattern>,
}
impl MockPhy {
fn new() -> Self {
Self {
frl_rate: None,
scrambling: None,
eq_calls: 0,
last_ltp: None,
}
}
}
impl HdmiPhy for MockPhy {
type Error = core::convert::Infallible;
fn send_ltp(&mut self, pattern: LtpPattern) -> Result<(), Self::Error> {
self.last_ltp = Some(pattern);
Ok(())
}
fn set_frl_rate(&mut self, rate: HdmiForumFrl) -> Result<(), Self::Error> {
self.frl_rate = Some(rate);
Ok(())
}
fn adjust_equalization(&mut self, _params: EqParams) -> Result<(), Self::Error> {
self.eq_calls += 1;
Ok(())
}
fn set_scrambling(&mut self, enabled: bool) -> Result<(), Self::Error> {
self.scrambling = Some(enabled);
Ok(())
}
}
#[test]
fn ltp_pattern_value() {
assert_eq!(LtpPattern::new(1).value(), 1);
assert_eq!(LtpPattern::new(4).value(), 4);
}
#[test]
fn ltp_pattern_clone_eq() {
let a = LtpPattern::new(2);
assert_eq!(a, a);
assert_ne!(LtpPattern::new(1), LtpPattern::new(2));
}
#[test]
fn send_ltp_records_pattern() {
let mut phy = MockPhy::new();
phy.send_ltp(LtpPattern::new(1)).unwrap();
assert_eq!(phy.last_ltp, Some(LtpPattern::new(1)));
}
#[test]
fn send_ltp_updates_on_each_call() {
let mut phy = MockPhy::new();
phy.send_ltp(LtpPattern::new(1)).unwrap();
phy.send_ltp(LtpPattern::new(3)).unwrap();
assert_eq!(phy.last_ltp, Some(LtpPattern::new(3)));
}
#[test]
fn eq_params_constructors_are_equivalent() {
let _a = EqParams::new();
let _b = EqParams::default();
}
#[test]
fn set_frl_rate_records_rate() {
let mut phy = MockPhy::new();
phy.set_frl_rate(HdmiForumFrl::Rate6Gbps4Lanes).unwrap();
assert_eq!(phy.frl_rate, Some(HdmiForumFrl::Rate6Gbps4Lanes));
}
#[test]
fn set_frl_rate_not_supported_is_valid() {
let mut phy = MockPhy::new();
phy.set_frl_rate(HdmiForumFrl::NotSupported).unwrap();
assert_eq!(phy.frl_rate, Some(HdmiForumFrl::NotSupported));
}
#[test]
fn set_frl_rate_can_be_updated() {
let mut phy = MockPhy::new();
phy.set_frl_rate(HdmiForumFrl::Rate3Gbps3Lanes).unwrap();
phy.set_frl_rate(HdmiForumFrl::Rate12Gbps4Lanes).unwrap();
assert_eq!(phy.frl_rate, Some(HdmiForumFrl::Rate12Gbps4Lanes));
}
#[test]
fn set_scrambling_enable() {
let mut phy = MockPhy::new();
phy.set_scrambling(true).unwrap();
assert_eq!(phy.scrambling, Some(true));
}
#[test]
fn set_scrambling_disable() {
let mut phy = MockPhy::new();
phy.set_scrambling(false).unwrap();
assert_eq!(phy.scrambling, Some(false));
}
#[test]
fn set_scrambling_can_be_toggled() {
let mut phy = MockPhy::new();
phy.set_scrambling(true).unwrap();
phy.set_scrambling(false).unwrap();
assert_eq!(phy.scrambling, Some(false));
}
#[test]
fn adjust_equalization_tracks_call_count() {
let mut phy = MockPhy::new();
phy.adjust_equalization(EqParams::new()).unwrap();
phy.adjust_equalization(EqParams::new()).unwrap();
assert_eq!(phy.eq_calls, 2);
}
}