Skip to main content

instrument/classes/
fgen.rs

1use super::dialect_io;
2use instrument_core::error::Result;
3use instrument_core::kind::InstrumentKind;
4use instrument_core::scpi::ScpiSession;
5use instrument_core::scpi_commands;
6use instrument_core::InstrumentSession;
7
8/// Waveform shape for function generators.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Waveform {
11    Sine,
12    Square,
13    Ramp,
14    Pulse,
15    Noise,
16    Dc,
17}
18
19impl Waveform {
20    pub(crate) fn scpi_name(self) -> &'static str {
21        match self {
22            Self::Sine => "SIN",
23            Self::Square => "SQU",
24            Self::Ramp => "RAMP",
25            Self::Pulse => "PULS",
26            Self::Noise => "NOIS",
27            Self::Dc => "DC",
28        }
29    }
30}
31
32/// Function / arbitrary waveform generator session view.
33pub struct FunctionGenerator {
34    session: InstrumentSession,
35}
36
37impl FunctionGenerator {
38    pub fn new(session: InstrumentSession) -> Self {
39        Self { session }
40    }
41
42    pub fn session(&self) -> &InstrumentSession {
43        &self.session
44    }
45
46    pub fn session_mut(&mut self) -> &mut InstrumentSession {
47        &mut self.session
48    }
49
50    fn dialect(&self) -> &'static instrument_core::DialectProfile {
51        self.session.dialect_for(InstrumentKind::FunctionGenerator)
52    }
53
54    fn cmd(&self, key: &str, vars: &[(&str, String)], fallback: String) -> String {
55        dialect_io::try_formatted(self.dialect(), key, vars, fallback)
56    }
57
58    /// Sets the output waveform.
59    pub fn set_waveform(&mut self, waveform: Waveform) -> Result<()> {
60        let name = waveform.scpi_name();
61        let cmd = self.cmd(
62            "set_waveform",
63            &[("scpi_name", name.into())],
64            scpi_commands::fgen_set_waveform(name),
65        );
66        self.session.scpi_mut().write(&cmd)
67    }
68
69    /// Sets output frequency in hertz (SI).
70    pub fn set_frequency(&mut self, hz: f64) -> Result<()> {
71        let cmd = self.cmd(
72            "set_frequency",
73            &[("hz", dialect_io::f64_text(hz))],
74            scpi_commands::fgen_set_frequency(hz),
75        );
76        self.session.scpi_mut().write(&cmd)
77    }
78
79    /// Sets peak-to-peak amplitude in volts (SI).
80    pub fn set_amplitude(&mut self, vpp: f64) -> Result<()> {
81        let cmd = self.cmd(
82            "set_amplitude",
83            &[("vpp", dialect_io::f64_text(vpp))],
84            scpi_commands::fgen_set_amplitude(vpp),
85        );
86        self.session.scpi_mut().write(&cmd)
87    }
88
89    /// Sets DC offset in volts (SI).
90    pub fn set_offset(&mut self, volts: f64) -> Result<()> {
91        let cmd = self.cmd(
92            "set_offset",
93            &[("volts", dialect_io::f64_text(volts))],
94            scpi_commands::fgen_set_offset(volts),
95        );
96        self.session.scpi_mut().write(&cmd)
97    }
98
99    /// Sets square-wave duty cycle in percent.
100    pub fn set_duty_cycle(&mut self, percent: f64) -> Result<()> {
101        let cmd = self.cmd(
102            "set_duty_cycle",
103            &[("percent", dialect_io::f64_text(percent))],
104            scpi_commands::fgen_set_duty_cycle(percent),
105        );
106        self.session.scpi_mut().write(&cmd)
107    }
108
109    /// Sets output load impedance in ohms (SI); use `INFinity` via vendor-specific call if needed.
110    pub fn set_load(&mut self, ohms: f64) -> Result<()> {
111        let cmd = self.cmd(
112            "set_load",
113            &[("ohms", dialect_io::f64_text(ohms))],
114            scpi_commands::fgen_set_load(ohms),
115        );
116        self.session.scpi_mut().write(&cmd)
117    }
118
119    /// Enables or disables the output.
120    pub fn output_enable(&mut self, enabled: bool) -> Result<()> {
121        let state = if enabled { "ON" } else { "OFF" };
122        let cmd = self.cmd(
123            "output_enable",
124            &[("state", state.into())],
125            scpi_commands::fgen_output_enable(state),
126        );
127        self.session.scpi_mut().write(&cmd)
128    }
129
130    /// Sets burst cycle count.
131    pub fn set_burst_count(&mut self, count: u32) -> Result<()> {
132        let cmd = self.cmd(
133            "burst_count",
134            &[("count", count.to_string())],
135            scpi_commands::fgen_burst_count(count),
136        );
137        self.session.scpi_mut().write(&cmd)
138    }
139
140    /// Enables or disables burst mode.
141    pub fn set_burst_state(&mut self, enabled: bool) -> Result<()> {
142        let state = if enabled { "ON" } else { "OFF" };
143        let cmd = self.cmd(
144            "burst_state",
145            &[("state", state.into())],
146            scpi_commands::fgen_burst_state(state),
147        );
148        self.session.scpi_mut().write(&cmd)
149    }
150
151    /// Sets burst trigger source (e.g. `IMM`, `EXT`, `BUS`).
152    pub fn set_burst_trigger_source(&mut self, source: &str) -> Result<()> {
153        let cmd = self.cmd(
154            "burst_trigger",
155            &[("source", source.into())],
156            scpi_commands::fgen_burst_trigger(source),
157        );
158        self.session.scpi_mut().write(&cmd)
159    }
160
161    /// Reads the configured frequency in hertz (SI).
162    pub fn read_frequency(&mut self) -> Result<f64> {
163        let cmd = dialect_io::try_command(
164            self.dialect(),
165            "read_frequency",
166            scpi_commands::FGEN_READ_FREQUENCY,
167        );
168        let resp = self.session.scpi_mut().query(cmd)?;
169        ScpiSession::parse_f64(&resp)
170    }
171}