Skip to main content

instrument/classes/
spectrum_analyzer.rs

1use super::dialect_io;
2use instrument_core::error::Result;
3use instrument_core::kind::InstrumentKind;
4use instrument_core::scpi::{parse_f64_csv, ScpiSession};
5use instrument_core::InstrumentSession;
6
7/// Spectrum analyzer session view.
8pub struct SpectrumAnalyzer {
9    session: InstrumentSession,
10}
11
12impl SpectrumAnalyzer {
13    pub fn new(session: InstrumentSession) -> Self {
14        Self { session }
15    }
16
17    pub fn session(&self) -> &InstrumentSession {
18        &self.session
19    }
20
21    pub fn session_mut(&mut self) -> &mut InstrumentSession {
22        &mut self.session
23    }
24
25    fn dialect(&self) -> &'static instrument_core::DialectProfile {
26        self.session.dialect_for(InstrumentKind::SpectrumAnalyzer)
27    }
28
29    fn write_dialect(&mut self, key: &str, vars: &[(&str, String)]) -> Result<()> {
30        let cmd = dialect_io::formatted(self.dialect(), key, vars)?;
31        self.session.scpi_mut().write(&cmd)
32    }
33
34    fn query_dialect(&mut self, key: &str) -> Result<String> {
35        let cmd = dialect_io::command(self.dialect(), key)?;
36        self.session.scpi_mut().query(cmd)
37    }
38
39    /// Sets center frequency in hertz (SI).
40    pub fn set_center_frequency(&mut self, hz: f64) -> Result<()> {
41        self.write_dialect("center_frequency", &[("hz", dialect_io::f64_text(hz))])
42    }
43
44    /// Sets frequency span in hertz (SI).
45    pub fn set_span(&mut self, hz: f64) -> Result<()> {
46        self.write_dialect("span", &[("hz", dialect_io::f64_text(hz))])
47    }
48
49    /// Sets resolution bandwidth in hertz (SI).
50    pub fn set_rbw(&mut self, hz: f64) -> Result<()> {
51        self.write_dialect("rbw", &[("hz", dialect_io::f64_text(hz))])
52    }
53
54    /// Sets video bandwidth in hertz (SI).
55    pub fn set_vbw(&mut self, hz: f64) -> Result<()> {
56        self.write_dialect("vbw", &[("hz", dialect_io::f64_text(hz))])
57    }
58
59    /// Sets reference level in dBm.
60    pub fn set_ref_level(&mut self, dbm: f64) -> Result<()> {
61        self.write_dialect("ref_level", &[("dbm", dialect_io::f64_text(dbm))])
62    }
63
64    /// Fetches TRACE1 as ASCII comma-separated amplitude samples.
65    pub fn fetch_trace_ascii(&mut self) -> Result<Vec<f64>> {
66        parse_f64_csv(&self.query_dialect("trace_data")?)
67    }
68
69    /// Moves marker to peak.
70    pub fn marker_peak(&mut self) -> Result<()> {
71        let cmd = dialect_io::command(self.dialect(), "marker_peak")?;
72        self.session.scpi_mut().write(cmd)
73    }
74
75    /// Reads marker X (typically frequency in Hz).
76    pub fn marker_x(&mut self) -> Result<f64> {
77        let resp = self.query_dialect("marker_x")?;
78        ScpiSession::parse_f64(&resp)
79    }
80
81    /// Reads marker Y (typically amplitude in dBm).
82    pub fn marker_y(&mut self) -> Result<f64> {
83        let resp = self.query_dialect("marker_y")?;
84        ScpiSession::parse_f64(&resp)
85    }
86
87    /// Enables or disables continuous sweep.
88    pub fn sweep_continuous(&mut self, enabled: bool) -> Result<()> {
89        let state = if enabled { "ON" } else { "OFF" };
90        self.write_dialect("sweep_continuous", &[("state", state.into())])
91    }
92
93    /// Triggers a single sweep.
94    pub fn single_sweep(&mut self) -> Result<()> {
95        let cmd = dialect_io::command(self.dialect(), "single_sweep")?;
96        self.session.scpi_mut().write(cmd)
97    }
98
99    /// Waits for operation complete (*OPC?).
100    pub fn wait_opc(&mut self) -> Result<()> {
101        let _ = self.query_dialect("wait_opc")?;
102        Ok(())
103    }
104
105    /// Writes a dialect-formatted command (advanced).
106    pub fn write_dialect_command(&mut self, key: &str, vars: &[(&str, String)]) -> Result<()> {
107        self.write_dialect(key, vars)
108    }
109}