use super::{Channel, Error};
pub trait AttenuatorInterface {
fn set_attenuation(
&mut self,
channel: Channel,
attenuation: f32,
) -> Result<f32, Error> {
let attenuation = Self::validate(attenuation)?;
let attenuation_code = (attenuation * 2.0) as u8;
let mut channels = [0_u8; 4];
self.transfer_attenuators(&mut channels)?;
channels[channel as usize] = !(attenuation_code << 2);
self.transfer_attenuators(&mut channels)?;
self.latch_attenuator(channel)?;
Ok(attenuation_code as f32 / 2.0)
}
fn get_attenuation(&mut self, channel: Channel) -> Result<f32, Error> {
let mut channels = [0_u8; 4];
self.transfer_attenuators(&mut channels)?;
self.transfer_attenuators(&mut channels)?;
let attenuation_code = (!channels[channel as usize]) >> 2;
Ok(attenuation_code as f32 / 2.0)
}
fn reset_attenuators(&mut self) -> Result<(), Error>;
fn latch_attenuator(&mut self, channel: Channel) -> Result<(), Error>;
fn transfer_attenuators(
&mut self,
channels: &mut [u8; 4],
) -> Result<(), Error>;
fn validate(attenuation: f32) -> Result<f32, Error> {
if !(0.0..=31.5).contains(&attenuation) {
Err(Error::Bounds)
} else {
Ok(attenuation)
}
}
}