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#[derive(Debug, PartialEq, Clone)]
18#[non_exhaustive]
19pub enum AUTDDriverError {
20 InvalidSilencerCompletionTime(Duration),
22 SilencerCompletionTimeOutOfRange(Duration),
24 SamplingConfig(SamplingConfigError),
26
27 STMPeriodInvalid(usize, Duration),
29
30 ModulationSizeOutOfRange(usize),
32
33 FociSTMTotalSizeOutOfRange(usize),
35 FociSTMNumFociOutOfRange(usize),
37 FociSTMPointOutOfRange(f32, f32, f32),
39 GainSTMSizeOutOfRange(usize),
41
42 UnsupportedGPIOOutputType(String),
44
45 PulseWidth(PulseWidthError),
47
48 Modulation(ModulationError),
50 Gain(GainError),
52 Link(LinkError),
54
55 UnknownKey(String),
57 UnusedKey(String),
59
60 ConfirmResponseFailed,
62
63 ReadFirmwareVersionFailed(Vec<bool>),
65
66 InvalidDateTime,
68
69 FirmwareVersionMismatch,
71
72 UnsupportedOperation,
74 UnsupportedFirmware,
76
77 NotSupportedTag,
81 #[doc(hidden)]
82 InvalidMessageID,
83 #[doc(hidden)]
84 InvalidInfoType,
85 #[doc(hidden)]
86 InvalidGainSTMMode,
87 #[doc(hidden)]
88 UnknownFirmwareError(u8),
89 InvalidSegmentTransition,
91 InvalidTransitionMode,
93 MissTransitionTime,
95 InvalidSilencerSettings,
97}
98
99impl 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