autd3_driver/
error.rs

1use std::{convert::Infallible, time::Duration};
2
3use autd3_core::{
4    datagram::CombinedError, derive::SamplingConfigError, gain::GainError, link::LinkError,
5    modulation::ModulationError,
6};
7use thiserror::Error;
8
9use crate::{firmware::cpu::GainSTMMode, firmware::fpga::*};
10
11/// A interface for error handling in autd3-driver.
12#[derive(Error, Debug, PartialEq, Clone)]
13#[non_exhaustive]
14pub enum AUTDDriverError {
15    /// Modulation buffer size is out of range.
16    #[error(
17        "Modulation buffer size ({0}) is out of range ([{min}, {max}])",
18        min = MOD_BUF_SIZE_MIN,
19        max = MOD_BUF_SIZE_MAX
20    )]
21    ModulationSizeOutOfRange(usize),
22
23    /// Invalid silencer completion time.
24    #[error("Silencer completion time ({0:?}) must be a multiple of the ultrasound period")]
25    InvalidSilencerCompletionTime(Duration),
26    /// Silencer completion time is out of range.
27    #[error("Silencer completion time ({0:?}) is out of range")]
28    SilencerCompletionTimeOutOfRange(Duration),
29
30    /// Sampling config error
31    #[error("{0}")]
32    SamplingConfig(#[from] SamplingConfigError),
33
34    /// Invalid STM period.
35    #[error("STM sampling period ({1:?}/{0}) must be integer")]
36    STMPeriodInvalid(usize, Duration),
37
38    /// FociSTM buffer size is out of range.
39    #[error(
40        "FociSTM size ({0}) is out of range ([{min}, {max}])",
41        min = STM_BUF_SIZE_MIN,
42        max = FOCI_STM_BUF_SIZE_MAX
43    )]
44    FociSTMPointSizeOutOfRange(usize),
45    /// Number of foci is out of range.
46    #[error(
47        "Number of foci ({0}) is out of range ([{min}, {max}])",
48        min = 1,
49        max = FOCI_STM_FOCI_NUM_MAX
50    )]
51    FociSTMNumFociOutOfRange(usize),
52    /// FociSTM point is out of range.
53    #[error(
54        "Point coordinate ({0}, {1}, {2}) is out of range ([{x_min}, {x_max}], [{y_min}, {y_max}], [{z_min}, {z_max}])",
55        x_min = FOCI_STM_FIXED_NUM_UNIT * FOCI_STM_FIXED_NUM_LOWER_X as f32,
56        x_max = FOCI_STM_FIXED_NUM_UNIT * FOCI_STM_FIXED_NUM_UPPER_X as f32,
57        y_min = FOCI_STM_FIXED_NUM_UNIT * FOCI_STM_FIXED_NUM_LOWER_Y as f32,
58        y_max = FOCI_STM_FIXED_NUM_UNIT * FOCI_STM_FIXED_NUM_UPPER_Y as f32,
59        z_min = FOCI_STM_FIXED_NUM_UNIT * FOCI_STM_FIXED_NUM_LOWER_Z as f32,
60        z_max = FOCI_STM_FIXED_NUM_UNIT * FOCI_STM_FIXED_NUM_UPPER_Z as f32,
61    )]
62    FociSTMPointOutOfRange(f32, f32, f32),
63    /// GainSTM buffer size is out of range.
64    #[error(
65        "GainSTM size ({0}) is out of range ([{min}, {max}])",
66        min = STM_BUF_SIZE_MIN,
67        max = GAIN_STM_BUF_SIZE_MAX
68    )]
69    GainSTMSizeOutOfRange(usize),
70    /// GainSTM mode is not supported.
71    #[error("GainSTMMode ({0:?}) is not supported")]
72    GainSTMModeNotSupported(GainSTMMode),
73
74    /// Error in the modulation.
75    #[error("{0}")]
76    Modulation(#[from] ModulationError),
77    /// Error in the gain.
78    #[error("{0}")]
79    Gain(#[from] GainError),
80    /// Error in the Link.
81    #[error("{0}")]
82    Link(#[from] LinkError),
83
84    /// Link is closed.
85    #[error("Link is closed")]
86    LinkClosed,
87    /// Failed to confirm the response from the device.
88    #[error("Failed to confirm the response from the device")]
89    ConfirmResponseFailed,
90
91    /// Invalid date time.
92    #[error("The input data is invalid.")]
93    InvalidDateTime,
94
95    #[cfg(feature = "dynamic_freq")]
96    #[error("Ultrasound frequency ({0:?}) is not supported")]
97    /// Invalid ultrasound frequency.
98    InvalidFrequency(autd3_core::defined::Freq<u32>),
99
100    /// Not supported tag.
101    ///
102    /// Occurs when the software is not compatible with the firmware.
103    #[error("Not supported tag")]
104    NotSupportedTag,
105    #[doc(hidden)]
106    #[error("Invalid message ID")]
107    InvalidMessageID,
108    #[doc(hidden)]
109    #[error("Invalid info type")]
110    InvalidInfoType,
111    #[doc(hidden)]
112    #[error("Invalid GainSTM mode")]
113    InvalidGainSTMMode,
114    #[doc(hidden)]
115    #[error("Unknown firmware error: {0}")]
116    UnknownFirmwareError(u8),
117    /// Invalid segment transition.
118    #[error("Invalid segment transition")]
119    InvalidSegmentTransition,
120    /// Invalid segment transition mode.
121    #[error("Invalid transition mode")]
122    InvalidTransitionMode,
123    /// Miss transition time.
124    #[error("Miss transition time")]
125    MissTransitionTime,
126    /// Silencer cannot complete phase/intensity completion in the specified sampling period.
127    #[error(
128        "Silencer cannot complete phase/intensity completion in the specified sampling period. Please lower the sampling frequency or make the completion time of Silencer longer than the sampling period."
129    )]
130    InvalidSilencerSettings,
131}
132
133impl AUTDDriverError {
134    #[doc(hidden)]
135    #[must_use]
136    pub const fn firmware_err(ack: u8) -> Self {
137        match ack {
138            0x80 => AUTDDriverError::NotSupportedTag,
139            0x81 => AUTDDriverError::InvalidMessageID,
140            0x84 => AUTDDriverError::InvalidInfoType,
141            0x85 => AUTDDriverError::InvalidGainSTMMode,
142            0x88 => AUTDDriverError::InvalidSegmentTransition,
143            0x8B => AUTDDriverError::MissTransitionTime,
144            0x8E => AUTDDriverError::InvalidSilencerSettings,
145            0x8F => AUTDDriverError::InvalidTransitionMode,
146            _ => AUTDDriverError::UnknownFirmwareError(ack),
147        }
148    }
149}
150
151// GRCOV_EXCL_START
152impl From<Infallible> for AUTDDriverError {
153    fn from(_: Infallible) -> Self {
154        unreachable!()
155    }
156}
157
158impl<E1, E2> From<CombinedError<E1, E2>> for AUTDDriverError
159where
160    E1: std::error::Error,
161    E2: std::error::Error,
162    AUTDDriverError: From<E1> + From<E2>,
163{
164    fn from(err: CombinedError<E1, E2>) -> Self {
165        match err {
166            CombinedError::E1(e) => AUTDDriverError::from(e),
167            CombinedError::E2(e) => AUTDDriverError::from(e),
168        }
169    }
170}
171// GRCOV_EXCL_STOP
172
173#[cfg(test)]
174mod tests {
175    use super::*;
176    use std::error::Error;
177
178    #[test]
179    fn test_unknown_firmware_err() {
180        let err = AUTDDriverError::firmware_err(0xFF);
181        assert!(err.source().is_none());
182        assert_eq!(format!("{}", err), "Unknown firmware error: 255");
183        assert_eq!(format!("{:?}", err), "UnknownFirmwareError(255)");
184    }
185}