microscpi/
commands.rs

1//! This module containts implementations of SCPI standard commands.
2use crate::{Characters, Error, ErrorHandler, ErrorQueue, SCPI_STD_VERSION};
3
4#[cfg(feature = "registers")]
5use crate::registers::{EventStatus, StatusByte, StatusRegisters};
6
7/// Error Commands
8///
9/// The [ErrorCommands] trait implements the standard SCPI commands used for
10/// error management. The only requirement to implement this trait is to provide
11/// an [ErrorQueue] via the [ErrorCommands::error_queue()] method. This crate
12/// contains an implementation of an error queue based on a statically allocated
13/// data structure: [crate::StaticErrorQueue].
14//
15/// # Implemented commands
16///
17/// * `SYSTem:ERRor:[NEXT]?`
18/// * `SYSTem:ERRor:[COUNt]?`
19pub trait ErrorCommands {
20    fn error_queue(&mut self) -> &mut impl ErrorQueue;
21
22    fn system_error_count(&mut self) -> Result<usize, Error> {
23        Ok(self.error_queue().error_count())
24    }
25
26    fn system_error_next(&mut self) -> Result<(i16, &'static str), Error> {
27        if let Some(error) = self.error_queue().pop_error() {
28            Ok((error.number(), error.into()))
29        } else {
30            Ok((0, ""))
31        }
32    }
33}
34
35impl<I> ErrorHandler for I
36where
37    I: ErrorCommands,
38{
39    fn handle_error(&mut self, error: Error) {
40        self.error_queue().push_error(error);
41    }
42}
43
44/// Standard Commands
45///
46/// # Implemented commands
47///
48/// * `SYSTem:VERSion?`
49pub trait StandardCommands {
50    fn system_version(&mut self) -> Result<Characters<'_>, Error> {
51        Ok(Characters(SCPI_STD_VERSION))
52    }
53}
54
55/// Status Commands
56///
57/// # Implemented commands
58/// * `*ESR?`
59/// * `*ESE?`
60/// * `*ESE`
61/// * `*CLS`
62/// * `*STB`
63/// * `*SRE`
64/// * `*SRE?`
65/// * `*OPC?`
66/// * `*OPC`
67#[cfg(feature = "registers")]
68pub trait StatusCommands: ErrorCommands {
69    fn status_registers(&mut self) -> &mut StatusRegisters;
70
71    fn operation_complete(&mut self) -> Result<bool, Error> {
72        self.set_operation_complete()?;
73
74        Ok(self
75            .status_registers()
76            .event_status
77            .contains(EventStatus::OPERATION_COMPLETE))
78    }
79
80    fn set_operation_complete(&mut self) -> Result<(), Error> {
81        self.status_registers()
82            .event_status
83            .set(EventStatus::OPERATION_COMPLETE, true);
84        Ok(())
85    }
86
87    /// *CLS
88    ///
89    /// Clears the status byte register and the error queue.
90    fn clear_event_status(&mut self) -> Result<(), Error> {
91        self.error_queue().clear();
92        self.status_registers().event_status = EventStatus::empty();
93        Ok(())
94    }
95
96    /// *ESE?
97    ///
98    /// Returns the event status register.
99    fn event_status_enable(&mut self) -> Result<u8, Error> {
100        Ok(self.status_registers().event_status_enable.bits())
101    }
102
103    /// *ESE <value>
104    ///
105    /// Sets the event status enable register.
106    fn set_event_status_enable(&mut self, value: u8) -> Result<(), Error> {
107        self.status_registers().event_status_enable = EventStatus::from_bits_retain(value);
108        Ok(())
109    }
110
111    /// *ESR?
112    ///
113    /// Returns the event status register and clears it.
114    fn event_status_register(&mut self) -> Result<u8, Error> {
115        let value = self.status_registers().event_status;
116        let mask = self.status_registers().event_status_enable;
117        let result = value.intersection(mask).bits();
118        
119        // Clear the event status register after reading (per SCPI standard)
120        self.status_registers().event_status = EventStatus::empty();
121        
122        Ok(result)
123    }
124
125    /// *STB?
126    ///
127    /// Returns the status byte register.
128    fn status_byte(&mut self) -> Result<u8, Error> {
129        let mut status: StatusByte = StatusByte::empty();
130
131        if self.error_queue().error_count() > 0 {
132            status.insert(StatusByte::ERROR_EVENT_QUEUE);
133        }
134
135        // Check event status without clearing it (unlike *ESR? which does clear)
136        let event_status = self.status_registers().event_status;
137        let event_enable = self.status_registers().event_status_enable;
138        if event_status.intersection(event_enable).bits() != 0 {
139            status.insert(StatusByte::STANDARD_EVENT);
140        }
141
142        Ok(status.bits())
143    }
144
145    /// *SRE?
146    ///
147    /// Returns the status enable register.
148    fn status_byte_enable(&mut self) -> Result<u8, Error> {
149        Ok(self.status_registers().status_byte_enable.bits())
150    }
151
152    /// *SRE <value>
153    ///
154    /// Sets the status enable register.
155    fn set_status_byte_enable(&mut self, value: u8) -> Result<(), Error> {
156        self.status_registers().status_byte_enable = StatusByte::from_bits_retain(value);
157        Ok(())
158    }
159}