scpi: rm duplicate code

This commit is contained in:
occheung 2020-09-16 13:08:05 +08:00
parent e1abf87351
commit ad34f6311f
1 changed files with 57 additions and 113 deletions

View File

@ -167,79 +167,44 @@ pub struct Channel0SwitchCommand {}
pub struct Channel1SwitchCommand {}
pub struct Channel2SwitchCommand {}
pub struct Channel3SwitchCommand {}
macro_rules! impl_channel_switch_command {
($($channel: literal => $command_struct: ty),*) => {
$(
impl<T: Device + UrukulTraits> Command<T> for $command_struct {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let next_state: bool = args.next_data(true)?
.map_or(
context.device.get_channel_switch_status($channel)
.map(|current| !current)
.map_err(|_| Error::new(ErrorCode::HardwareError)),
|token| token.try_into()
)?;
context.device.set_channel_switch($channel, next_state).map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
)*
};
}
impl_channel_switch_command!(
0 => Channel0SwitchCommand,
1 => Channel1SwitchCommand,
2 => Channel2SwitchCommand,
3 => Channel3SwitchCommand
);
pub struct ClockSourceCommand {}
pub struct ClockDivisionCommand {}
pub struct Channel0SystemClockCommand {}
pub struct Channel0AttenuationCommand {}
pub struct Channel1AttenuationCommand {}
pub struct Channel2AttenuationCommand {}
pub struct Channel3AttenuationCommand {}
pub struct ProfileCommand {}
pub struct Channel0Profile0Singletone {}
pub struct Channel0Profile0SingletoneFrequency {}
pub struct Channel0Profile0SingletonePhase {}
pub struct Channel0Profile0SingletoneAmplitude {}
impl<T: Device + UrukulTraits> Command<T> for Channel0SwitchCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let next_state: bool = args.next_data(true)?
.map_or(
context.device.get_channel_switch_status(0)
.map(|current| !current)
.map_err(|_| Error::new(ErrorCode::HardwareError)),
|token| token.try_into()
)?;
context.device.set_channel_switch(0, next_state).map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
impl<T: Device + UrukulTraits> Command<T> for Channel1SwitchCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let next_state: bool = args.next_data(true)?
.map_or(
context.device.get_channel_switch_status(1)
.map(|current| !current)
.map_err(|_| Error::new(ErrorCode::HardwareError)),
|token| token.try_into()
)?;
context.device.set_channel_switch(1, next_state).map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
impl<T: Device + UrukulTraits> Command<T> for Channel2SwitchCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let next_state: bool = args.next_data(true)?
.map_or(
context.device.get_channel_switch_status(2)
.map(|current| !current)
.map_err(|_| Error::new(ErrorCode::HardwareError)),
|token| token.try_into()
)?;
context.device.set_channel_switch(2, next_state).map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
impl<T: Device + UrukulTraits> Command<T> for Channel3SwitchCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let next_state: bool = args.next_data(true)?
.map_or(
context.device.get_channel_switch_status(3)
.map(|current| !current)
.map_err(|_| Error::new(ErrorCode::HardwareError)),
|token| token.try_into()
)?;
context.device.set_channel_switch(3, next_state).map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
// Handle CLOCK:SOURCE command, setup the proper source for the system clock
// Leave clock division to CLOCK:DIVision command
impl<T:Device + UrukulTraits> Command<T> for ClockSourceCommand {
@ -334,57 +299,36 @@ impl<T:Device + UrukulTraits> Command<T> for Channel0SystemClockCommand {
}
}
impl<T:Device + UrukulTraits> Command<T> for Channel0AttenuationCommand {
pub struct Channel0AttenuationCommand {}
pub struct Channel1AttenuationCommand {}
pub struct Channel2AttenuationCommand {}
pub struct Channel3AttenuationCommand {}
macro_rules! impl_channel_attenuation_command {
($($channel: literal => $command_struct: ty),*) => {
$(
impl<T:Device + UrukulTraits> Command<T> for $command_struct {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let attenuation: f32 = args.next_data(false)?
.map_or(Err(Error::new(ErrorCode::IllegalParameterValue)),
|token| token.try_into())?;
trace!("Received channel 0 attenuation input: {}", attenuation);
context.device.set_channel_attenuation(0, attenuation)
trace!("Received channel {} attenuation input: {}", $channel, attenuation);
context.device.set_channel_attenuation($channel, attenuation)
.map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
impl<T:Device + UrukulTraits> Command<T> for Channel1AttenuationCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let attenuation: f32 = args.next_data(false)?
.map_or(Err(Error::new(ErrorCode::IllegalParameterValue)),
|token| token.try_into())?;
trace!("Received channel 1 attenuation input: {}", attenuation);
context.device.set_channel_attenuation(1, attenuation)
.map_err(|_| Error::new(ErrorCode::HardwareError))
}
)*
};
}
impl<T:Device + UrukulTraits> Command<T> for Channel2AttenuationCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let attenuation: f32 = args.next_data(false)?
.map_or(Err(Error::new(ErrorCode::IllegalParameterValue)),
|token| token.try_into())?;
trace!("Received channel 2 attenuation input: {}", attenuation);
context.device.set_channel_attenuation(2, attenuation)
.map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
impl<T:Device + UrukulTraits> Command<T> for Channel3AttenuationCommand {
nquery!();
fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
let attenuation: f32 = args.next_data(false)?
.map_or(Err(Error::new(ErrorCode::IllegalParameterValue)),
|token| token.try_into())?;
trace!("Received channel 3 attenuation input: {}", attenuation);
context.device.set_channel_attenuation(3, attenuation)
.map_err(|_| Error::new(ErrorCode::HardwareError))
}
}
impl_channel_attenuation_command!(
0 => Channel0AttenuationCommand,
1 => Channel1AttenuationCommand,
2 => Channel2AttenuationCommand,
3 => Channel3AttenuationCommand
);
impl<T:Device + UrukulTraits> Command<T> for ProfileCommand {
nquery!();
@ -453,7 +397,7 @@ impl<T:Device + UrukulTraits> Command<T> for Channel0Profile0Singletone {
return Err(ErrorCode::DataOutOfRange.into());
}
// TODO: Setup single tone on DDS
trace!("Set up a single tone on channel 0, profile 0");
context.device.set_channel_single_tone_profile(0, 0, frequency.get::<hertz>(), phase.get::<degree>(), amplitude)
.map_err(|_| Error::new(ErrorCode::HardwareError))
}