From 8a72f3411f5697a7a61517df9fa85eec044c5c18 Mon Sep 17 00:00:00 2001 From: Andrey Dyldin Date: Fri, 29 Jan 2021 15:03:36 +0200 Subject: [PATCH] cleaning --- src/fe/mod.rs | 16 +++++---- src/fe/status.rs | 90 +++++++++++++++++++++++++----------------------- src/fe/sys.rs | 72 +++++++++++++++++++++----------------- 3 files changed, 97 insertions(+), 81 deletions(-) diff --git a/src/fe/mod.rs b/src/fe/mod.rs index b44619d..cf0661a 100644 --- a/src/fe/mod.rs +++ b/src/fe/mod.rs @@ -231,21 +231,22 @@ impl FeDevice { for p in cmdseq { match p.cmd { DTV_FREQUENCY => { - let v = p.get_data(); + let v = unsafe { p.u.data }; ensure!( self.frequency_range.contains(&v), FeError::InvalidFrequency ); } DTV_SYMBOL_RATE => { - let v = p.get_data(); + let v = unsafe { p.u.data }; ensure!( self.symbolrate_range.contains(&v), FeError::InvalidSymbolrate ); } DTV_INVERSION => { - if p.get_data() == INVERSION_AUTO { + let v = unsafe { p.u.data }; + if v == INVERSION_AUTO { ensure!( self.caps & FE_CAN_INVERSION_AUTO != 0, FeError::NoAutoInversion @@ -253,7 +254,8 @@ impl FeDevice { } } DTV_TRANSMISSION_MODE => { - if p.get_data() == TRANSMISSION_MODE_AUTO { + let v = unsafe { p.u.data }; + if v == TRANSMISSION_MODE_AUTO { ensure!( self.caps & FE_CAN_TRANSMISSION_MODE_AUTO != 0, FeError::NoAutoTransmitMode @@ -261,7 +263,8 @@ impl FeDevice { } } DTV_GUARD_INTERVAL => { - if p.get_data() == GUARD_INTERVAL_AUTO { + let v = unsafe { p.u.data }; + if v == GUARD_INTERVAL_AUTO { ensure!( self.caps & FE_CAN_GUARD_INTERVAL_AUTO != 0, FeError::NoAutoGuardInterval @@ -269,7 +272,8 @@ impl FeDevice { } } DTV_HIERARCHY => { - if p.get_data() == HIERARCHY_AUTO { + let v = unsafe { p.u.data }; + if v == HIERARCHY_AUTO { ensure!( self.caps & FE_CAN_HIERARCHY_AUTO != 0, FeError::NoAutoHierarchy diff --git a/src/fe/status.rs b/src/fe/status.rs index 3758975..f96a878 100644 --- a/src/fe/status.rs +++ b/src/fe/status.rs @@ -21,22 +21,32 @@ use { /// Frontend status -#[derive(Default, Debug, Copy, Clone)] +#[derive(Debug)] pub struct FeStatus { /// `sys::frontend::fe_status` status: u32, - /// signal level in dBm - signal: Option, + /// properties + props: [DtvProperty; 4], +} - /// signal-to-noise ratio in dB - snr: Option, - /// number of bit errors before the forward error correction coding - ber: Option, - - /// number of block errors after the outer forward error correction coding - unc: Option, +impl Default for FeStatus { + fn default() -> FeStatus { + FeStatus { + status: 0, + props: [ + // 0: signal level + DtvProperty::new(DTV_STAT_SIGNAL_STRENGTH, 0), + // 1: signal-to-noise ratio + DtvProperty::new(DTV_STAT_CNR, 0), + // 2: ber - number of bit errors + DtvProperty::new(DTV_STAT_PRE_ERROR_BIT_COUNT, 0), + // 3: unc - number of block errors + DtvProperty::new(DTV_STAT_ERROR_BLOCK_COUNT, 0), + ], + } + } } @@ -67,12 +77,8 @@ impl<'a> FeStatusDisplay<'a> { } write!(f, " S:")?; - if let Some(signal) = self.inner.signal { - // TODO: config for lo/hi - let lo: f64 = -85.0; - let hi: f64 = -6.0; - let relative = 100.0 - (signal - hi) * 100.0 / (lo - hi); - write!(f, "{:.02}dBm ({:.0}%)", signal, relative)?; + if let Some((decibel, relative)) = self.inner.get_signal_level() { + write!(f, "{:.02}dBm ({:.0}%)", decibel, relative)?; } else { write!(f, "-")?; } @@ -82,9 +88,8 @@ impl<'a> FeStatusDisplay<'a> { } write!(f, " Q:")?; - if let Some(snr) = self.inner.snr { - let relative = 5 * snr as u32; - write!(f, "{:.02}dB ({}%)", snr, relative)?; + if let Some((decibel, relative)) = self.inner.get_signal_noise_ratio() { + write!(f, "{:.02}dB ({}%)", decibel, relative)?; } else { write!(f, "-")?; } @@ -94,14 +99,14 @@ impl<'a> FeStatusDisplay<'a> { } write!(f, " BER:")?; - if let Some(ber) = self.inner.ber { + if let Some(ber) = self.inner.props[2].get_stats_counter() { write!(f, "{}", ber & 0xFFFF)?; } else { write!(f, "-")?; } write!(f, " UNC:")?; - if let Some(unc) = self.inner.unc { + if let Some(unc) = self.inner.props[3].get_stats_counter() { write!(f, "{}", unc & 0xFFFF) } else { write!(f, "-") @@ -130,12 +135,8 @@ impl<'a> FeStatusDisplay<'a> { } write!(f, "\nSignal: ")?; - if let Some(signal) = self.inner.signal { - // TODO: config for lo/hi - let lo: f64 = -85.0; - let hi: f64 = -6.0; - let relative = 100.0 - (signal - hi) * 100.0 / (lo - hi); - write!(f, "{:.02}dBm ({:.0}%)", signal, relative)?; + if let Some((decibel, relative)) = self.inner.get_signal_level() { + write!(f, "{:.02}dBm ({:.0}%)", decibel, relative)?; } else { write!(f, "-")?; } @@ -145,9 +146,8 @@ impl<'a> FeStatusDisplay<'a> { } write!(f, "\nSNR: ")?; - if let Some(snr) = self.inner.snr { - let relative = 5 * snr as u32; - write!(f, "{:.02}dB ({}%)", snr, relative)?; + if let Some((decibel, relative)) = self.inner.get_signal_noise_ratio() { + write!(f, "{:.02}dB ({}%)", decibel, relative)?; } else { write!(f, "-")?; } @@ -157,14 +157,14 @@ impl<'a> FeStatusDisplay<'a> { } write!(f, "\nBER: ")?; - if let Some(ber) = self.inner.ber { + if let Some(ber) = self.inner.props[2].get_stats_counter() { write!(f, "{}", ber & 0xFFFF)?; } else { write!(f, "-")?; } write!(f, "\nUNC: ")?; - if let Some(unc) = self.inner.unc { + if let Some(unc) = self.inner.props[3].get_stats_counter() { write!(f, "{}", unc & 0xFFFF) } else { write!(f, "-") @@ -206,6 +206,19 @@ impl FeStatus { } } + fn get_signal_level(&self) -> Option<(f64, u64)> { + // TODO: config for lo/hi + // let lo: f64 = -85.0; + // let hi: f64 = -6.0; + // let relative = 100.0 - (decibel - hi) * 100.0 / (lo - hi); + None + } + + fn get_signal_noise_ratio(&self) -> Option<(f64, u64)> { + // let relative = 5 * decibel as u32; + None + } + /// Reads frontend status pub fn read(&mut self, fe: &FeDevice) -> Result<()> { self.status = FE_NONE; @@ -220,18 +233,7 @@ impl FeStatus { return Ok(()); } - let mut cmdseq = [ - DtvProperty::new(DTV_STAT_SIGNAL_STRENGTH, 0), - DtvProperty::new(DTV_STAT_CNR, 0), - DtvProperty::new(DTV_STAT_PRE_ERROR_BIT_COUNT, 0), - DtvProperty::new(DTV_STAT_ERROR_BLOCK_COUNT, 0), - ]; - fe.get_properties(&mut cmdseq)?; - - self.signal = (unsafe { cmdseq[0].u.st }).get_decibel(); - self.snr = (unsafe { cmdseq[1].u.st }).get_decibel(); - self.ber = (unsafe { cmdseq[2].u.st }).get_counter(); - self.unc = (unsafe { cmdseq[3].u.st }).get_counter(); + fe.get_properties(&mut self.props)?; Ok(()) } diff --git a/src/fe/sys.rs b/src/fe/sys.rs index 77c0b89..515c366 100644 --- a/src/fe/sys.rs +++ b/src/fe/sys.rs @@ -454,7 +454,7 @@ impl fmt::Debug for DtvStats { } FE_SCALE_RELATIVE => { s.field(FIELD_SCALE, &"FE_SCALE_RELATIVE"); - s.field(FIELD_VALUE, &{self.value as u64}); + s.field(FIELD_VALUE, &{(self.value as u64) * 100 / 65535}); } FE_SCALE_COUNTER => { s.field(FIELD_SCALE, &"FE_SCALE_COUNTER"); @@ -484,33 +484,8 @@ pub struct DtvFrontendStats { impl fmt::Debug for DtvFrontendStats { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let stats = &self.stat[0 .. self.len as usize]; - f.debug_list().entries(stats.iter()).finish() - } -} - - -impl DtvFrontendStats { - pub fn get_counter(&self) -> Option { - for i in 0 .. ::std::cmp::min(self.len as usize, self.stat.len()) { - let s = &self.stat[i]; - if s.scale == FE_SCALE_COUNTER { - return Some(s.value as u64); - } - } - - None - } - - pub fn get_decibel(&self) -> Option { - for i in 0 .. ::std::cmp::min(self.len as usize, self.stat.len()) { - let s = &self.stat[i]; - if s.scale == FE_SCALE_DECIBEL { - return Some((s.value as f64) / 1000.0); - } - } - - None + let len = ::std::cmp::min(self.len as usize, self.stat.len()); + f.debug_list().entries(self.stat[0 .. len].iter()).finish() } } @@ -708,14 +683,31 @@ impl fmt::Debug for DtvProperty { s.field(FIELD_CMD, &"DTV_STAT_CNR"); s.field(FIELD_STATS, unsafe { &self.u.st }); } + DTV_STAT_PRE_ERROR_BIT_COUNT => { s.field(FIELD_CMD, &"DTV_STAT_PRE_ERROR_BIT_COUNT"); s.field(FIELD_STATS, unsafe { &self.u.st }); } + DTV_STAT_PRE_TOTAL_BIT_COUNT => { + s.field(FIELD_CMD, &"DTV_STAT_PRE_TOTAL_BIT_COUNT"); + s.field(FIELD_STATS, unsafe { &self.u.st }); + } + DTV_STAT_POST_ERROR_BIT_COUNT => { + s.field(FIELD_CMD, &"DTV_STAT_POST_ERROR_BIT_COUNT"); + s.field(FIELD_STATS, unsafe { &self.u.st }); + } + DTV_STAT_POST_TOTAL_BIT_COUNT => { + s.field(FIELD_CMD, &"DTV_STAT_POST_TOTAL_BIT_COUNT"); + s.field(FIELD_STATS, unsafe { &self.u.st }); + } DTV_STAT_ERROR_BLOCK_COUNT => { s.field(FIELD_CMD, &"DTV_STAT_ERROR_BLOCK_COUNT"); s.field(FIELD_STATS, unsafe { &self.u.st }); } + DTV_STAT_TOTAL_BLOCK_COUNT => { + s.field(FIELD_CMD, &"DTV_STAT_TOTAL_BLOCK_COUNT"); + s.field(FIELD_STATS, unsafe { &self.u.st }); + } // TODO: more values _ => {} @@ -738,9 +730,27 @@ impl DtvProperty { } } - #[inline] - pub fn get_data(&self) -> u32 { - unsafe { self.u.data } + pub fn get_stats_counter(&self) -> Option { + match self.cmd { + DTV_STAT_PRE_ERROR_BIT_COUNT | + DTV_STAT_PRE_TOTAL_BIT_COUNT | + DTV_STAT_POST_ERROR_BIT_COUNT | + DTV_STAT_POST_TOTAL_BIT_COUNT | + DTV_STAT_ERROR_BLOCK_COUNT | + DTV_STAT_TOTAL_BLOCK_COUNT => { + let stats = unsafe { &self.u.st }; + if stats.len > 0 { + let s = &stats.stat[0]; + if s.scale == FE_SCALE_COUNTER { + return Some(s.value as u64); + } + } + } + + _ => {} + } + + None } }