From ad34f6311f87f8d56266432f030f2fdd216b8f7e Mon Sep 17 00:00:00 2001 From: occheung Date: Wed, 16 Sep 2020 13:08:05 +0800 Subject: [PATCH] scpi: rm duplicate code --- src/scpi.rs | 170 ++++++++++++++++++---------------------------------- 1 file changed, 57 insertions(+), 113 deletions(-) diff --git a/src/scpi.rs b/src/scpi.rs index fc85db7..5b07a40 100644 --- a/src/scpi.rs +++ b/src/scpi.rs @@ -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 Command for $command_struct { + nquery!(); + + fn event(&self, context: &mut Context, 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 Command for Channel0SwitchCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for Channel1SwitchCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for Channel2SwitchCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for Channel3SwitchCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for ClockSourceCommand { @@ -334,57 +299,36 @@ impl Command for Channel0SystemClockCommand { } } -impl Command for Channel0AttenuationCommand { - nquery!(); +pub struct Channel0AttenuationCommand {} +pub struct Channel1AttenuationCommand {} +pub struct Channel2AttenuationCommand {} +pub struct Channel3AttenuationCommand {} - fn event(&self, context: &mut Context, 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) - .map_err(|_| Error::new(ErrorCode::HardwareError)) - } +macro_rules! impl_channel_attenuation_command { + ($($channel: literal => $command_struct: ty),*) => { + $( + impl Command for $command_struct { + nquery!(); + + fn event(&self, context: &mut Context, 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 {} attenuation input: {}", $channel, attenuation); + context.device.set_channel_attenuation($channel, attenuation) + .map_err(|_| Error::new(ErrorCode::HardwareError)) + } + } + )* + }; } -impl Command for Channel1AttenuationCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for Channel2AttenuationCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for Channel3AttenuationCommand { - nquery!(); - - fn event(&self, context: &mut Context, 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 Command for ProfileCommand { nquery!(); @@ -453,7 +397,7 @@ impl Command 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::(), phase.get::(), amplitude) .map_err(|_| Error::new(ErrorCode::HardwareError)) }