autd3_driver/
error.rs

1use std::{convert::Infallible, time::Duration};
2
3use autd3_core::{
4    datagram::CombinedError,
5    firmware::{
6        FOCI_STM_BUF_SIZE_MAX, FOCI_STM_FOCI_NUM_MAX, FOCI_STM_FOCI_NUM_MIN, FOCI_STM_LOWER_X,
7        FOCI_STM_LOWER_Y, FOCI_STM_LOWER_Z, FOCI_STM_UPPER_X, FOCI_STM_UPPER_Y, FOCI_STM_UPPER_Z,
8        GAIN_STM_BUF_SIZE_MAX, MOD_BUF_SIZE_MAX, MOD_BUF_SIZE_MIN, PulseWidthError,
9        STM_BUF_SIZE_MIN, SamplingConfigError,
10    },
11    gain::GainError,
12    link::LinkError,
13    modulation::ModulationError,
14};
15
16/// A interface for error handling in autd3-driver.
17#[derive(Debug, PartialEq, Clone)]
18#[non_exhaustive]
19pub enum AUTDDriverError {
20    /// Invalid silencer completion time.
21    InvalidSilencerCompletionTime(Duration),
22    /// Silencer completion time is out of range.
23    SilencerCompletionTimeOutOfRange(Duration),
24    /// Sampling config error
25    SamplingConfig(SamplingConfigError),
26
27    /// Invalid STM period.
28    STMPeriodInvalid(usize, Duration),
29
30    /// Modulation buffer size is out of range.
31    ModulationSizeOutOfRange(usize),
32
33    /// FociSTM buffer size is out of range.
34    FociSTMTotalSizeOutOfRange(usize),
35    /// Number of foci is out of range.
36    FociSTMNumFociOutOfRange(usize),
37    /// FociSTM point is out of range.
38    FociSTMPointOutOfRange(f32, f32, f32),
39    /// GainSTM buffer size is out of range.
40    GainSTMSizeOutOfRange(usize),
41
42    /// GPIO output type is not supported.
43    UnsupportedGPIOOutputType(String),
44
45    /// Pulse width error.
46    PulseWidth(PulseWidthError),
47
48    /// Error in the modulation.
49    Modulation(ModulationError),
50    /// Error in the gain.
51    Gain(GainError),
52    /// Error in the Link.
53    Link(LinkError),
54
55    /// Unknown group key.
56    UnknownKey(String),
57    /// Unused group key.
58    UnusedKey(String),
59
60    /// Failed to confirm the response from the device.
61    ConfirmResponseFailed,
62
63    /// Failed to read firmware version.
64    ReadFirmwareVersionFailed(Vec<bool>),
65
66    /// Invalid date time.
67    InvalidDateTime,
68
69    /// Firmware version mismatch.
70    FirmwareVersionMismatch,
71
72    /// Unsupported operation.
73    UnsupportedOperation,
74    /// Unsupported firmware.
75    UnsupportedFirmware,
76
77    /// Not supported tag.
78    ///
79    /// Occurs when the software is not compatible with the firmware.
80    NotSupportedTag,
81    #[doc(hidden)]
82    InvalidMessageID,
83    #[doc(hidden)]
84    InvalidInfoType,
85    #[doc(hidden)]
86    InvalidGainSTMMode,
87    #[doc(hidden)]
88    UnknownFirmwareError(u8),
89    /// Invalid segment transition.
90    InvalidSegmentTransition,
91    /// Invalid transition mode.
92    InvalidTransitionMode,
93    /// Miss transition time.
94    MissTransitionTime,
95    /// Silencer cannot complete phase/intensity interpolation in the specified sampling period.
96    InvalidSilencerSettings,
97}
98
99// GRCOV_EXCL_START
100impl From<SamplingConfigError> for AUTDDriverError {
101    fn from(e: SamplingConfigError) -> Self {
102        AUTDDriverError::SamplingConfig(e)
103    }
104}
105
106impl From<PulseWidthError> for AUTDDriverError {
107    fn from(e: PulseWidthError) -> Self {
108        AUTDDriverError::PulseWidth(e)
109    }
110}
111
112impl From<ModulationError> for AUTDDriverError {
113    fn from(e: ModulationError) -> Self {
114        AUTDDriverError::Modulation(e)
115    }
116}
117
118impl From<GainError> for AUTDDriverError {
119    fn from(e: GainError) -> Self {
120        AUTDDriverError::Gain(e)
121    }
122}
123
124impl From<LinkError> for AUTDDriverError {
125    fn from(e: LinkError) -> Self {
126        AUTDDriverError::Link(e)
127    }
128}
129
130impl std::fmt::Display for AUTDDriverError {
131    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132        match self {
133            AUTDDriverError::InvalidSilencerCompletionTime(d) => write!(
134                f,
135                "Silencer completion time ({:?}) must be a multiple of the ultrasound period",
136                d
137            ),
138            AUTDDriverError::SilencerCompletionTimeOutOfRange(d) => {
139                write!(f, "Silencer completion time ({:?}) is out of range", d)
140            }
141            AUTDDriverError::SamplingConfig(e) => write!(f, "{}", e),
142            AUTDDriverError::STMPeriodInvalid(size, period) => write!(
143                f,
144                "STM sampling period ({:?}/{}) must be integer",
145                period, size
146            ),
147            AUTDDriverError::ModulationSizeOutOfRange(size) => write!(
148                f,
149                "Modulation buffer size ({}) is out of range ([{}, {}])",
150                size, MOD_BUF_SIZE_MIN, MOD_BUF_SIZE_MAX
151            ),
152            AUTDDriverError::FociSTMTotalSizeOutOfRange(size) => write!(
153                f,
154                "The number of total foci ({}) is out of range ([{}, {}])",
155                size, STM_BUF_SIZE_MIN, FOCI_STM_BUF_SIZE_MAX
156            ),
157            AUTDDriverError::FociSTMNumFociOutOfRange(size) => write!(
158                f,
159                "Number of foci ({}) is out of range ([{}, {}])",
160                size, FOCI_STM_FOCI_NUM_MIN, FOCI_STM_FOCI_NUM_MAX
161            ),
162            AUTDDriverError::FociSTMPointOutOfRange(x, y, z) => write!(
163                f,
164                "Point coordinate ({}, {}, {}) is out of range ([{}, {}], [{}, {}], [{}, {}])",
165                x,
166                y,
167                z,
168                FOCI_STM_LOWER_X,
169                FOCI_STM_UPPER_X,
170                FOCI_STM_LOWER_Y,
171                FOCI_STM_UPPER_Y,
172                FOCI_STM_LOWER_Z,
173                FOCI_STM_UPPER_Z,
174            ),
175            AUTDDriverError::GainSTMSizeOutOfRange(size) => write!(
176                f,
177                "GainSTM size ({}) is out of range ([{}, {}])",
178                size, STM_BUF_SIZE_MIN, GAIN_STM_BUF_SIZE_MAX
179            ),
180            AUTDDriverError::UnsupportedGPIOOutputType(t) => {
181                write!(f, "GPIO output type ({}) is not supported", t)
182            }
183            AUTDDriverError::PulseWidth(e) => write!(f, "{}", e),
184            AUTDDriverError::Modulation(e) => write!(f, "{}", e),
185            AUTDDriverError::Gain(e) => write!(f, "{}", e),
186            AUTDDriverError::Link(e) => write!(f, "{}", e),
187            AUTDDriverError::UnknownKey(key) => write!(f, "Unknown group key({})", key),
188            AUTDDriverError::UnusedKey(key) => write!(f, "Unused group key({})", key),
189            AUTDDriverError::ConfirmResponseFailed => {
190                write!(f, "Failed to confirm the response from the device")
191            }
192            AUTDDriverError::ReadFirmwareVersionFailed(versions) => write!(
193                f,
194                "Read firmware info failed: {}",
195                versions
196                    .iter()
197                    .enumerate()
198                    .filter(|&(_, &b)| !b)
199                    .map(|(i, _)| i.to_string())
200                    .collect::<Vec<_>>()
201                    .join(", ")
202            ),
203            AUTDDriverError::InvalidDateTime => write!(f, "The input data is invalid."),
204            AUTDDriverError::FirmwareVersionMismatch => write!(f, "Firmware version mismatch"),
205            AUTDDriverError::UnsupportedOperation => write!(f, "Unsupported operation"),
206            AUTDDriverError::UnsupportedFirmware => write!(f, "Unsupported firmware"),
207            AUTDDriverError::NotSupportedTag => write!(f, "Not supported tag"),
208            AUTDDriverError::InvalidMessageID => write!(f, "Invalid message ID"),
209            AUTDDriverError::InvalidInfoType => write!(f, "Invalid info type"),
210            AUTDDriverError::InvalidGainSTMMode => write!(f, "Invalid GainSTM mode"),
211            AUTDDriverError::UnknownFirmwareError(e) => write!(f, "Unknown firmware error: {}", e),
212            AUTDDriverError::InvalidSegmentTransition => write!(f, "Invalid segment transition"),
213            AUTDDriverError::InvalidTransitionMode => write!(f, "Invalid transition mode"),
214            AUTDDriverError::MissTransitionTime => write!(f, "Miss transition time"),
215            AUTDDriverError::InvalidSilencerSettings => write!(
216                f,
217                "Silencer cannot complete phase/intensity interpolation in the specified sampling period. Please lower the sampling frequency or make the completion time of Silencer longer than the sampling period of the AM/STM."
218            ),
219        }
220    }
221}
222
223impl std::error::Error for AUTDDriverError {
224    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
225        match self {
226            AUTDDriverError::SamplingConfig(e) => Some(e),
227            AUTDDriverError::PulseWidth(e) => Some(e),
228            AUTDDriverError::Modulation(e) => Some(e),
229            AUTDDriverError::Gain(e) => Some(e),
230            AUTDDriverError::Link(e) => Some(e),
231            _ => None,
232        }
233    }
234}
235
236impl From<Infallible> for AUTDDriverError {
237    fn from(_: Infallible) -> Self {
238        unreachable!()
239    }
240}
241
242impl<E1, E2> From<CombinedError<E1, E2>> for AUTDDriverError
243where
244    E1: std::error::Error,
245    E2: std::error::Error,
246    AUTDDriverError: From<E1> + From<E2>,
247{
248    fn from(err: CombinedError<E1, E2>) -> Self {
249        match err {
250            CombinedError::E1(e) => AUTDDriverError::from(e),
251            CombinedError::E2(e) => AUTDDriverError::from(e),
252        }
253    }
254}
255// GRCOV_EXCL_STOP