Skip to main content

autd3_rs_core/
error.rs

1use thiserror::Error;
2
3use crate::mirror::{BankLoop, SilencerAxis};
4use crate::value::{PulseWidthError, SamplingConfigError, TransitionMode};
5
6#[derive(Debug, Error)]
7pub enum Error {
8    #[error("device {device} firmware error {code:#04x}: {}", crate::protocol::describe_device_error(*code))]
9    DeviceError { device: usize, code: u8 },
10
11    #[error(
12        "device {device}: strict silencer {axis:?} completion {completion_steps} steps exceeds sampling divider {sampling_div}"
13    )]
14    SilencerConstraint {
15        device: usize,
16        axis: SilencerAxis,
17        completion_steps: u16,
18        sampling_div: u16,
19    },
20
21    #[error(
22        "device {device}: transition mode {transition_mode:?} is invalid for a {bank_loop:?} loop bank"
23    )]
24    TransitionConstraint {
25        device: usize,
26        transition_mode: TransitionMode,
27        bank_loop: BankLoop,
28    },
29
30    #[error("ack timeout after {cycles} cycles")]
31    Timeout { cycles: u32 },
32
33    #[error("link error: {0}")]
34    Link(String),
35
36    #[error("invalid payload: {0}")]
37    InvalidPayload(PayloadError),
38
39    #[error("client RT worker is no longer alive")]
40    RtClosed,
41}
42
43#[derive(Clone, Copy, Debug, PartialEq, Error)]
44pub enum PayloadError {
45    #[error("max_inflight must be <= {max}")]
46    MaxInFlightTooLarge { max: usize },
47
48    #[error("link must expose 1..={max} devices, got {got}")]
49    DeviceCountOutOfRange { got: usize, max: usize },
50
51    #[error("geometry has {geometry} device(s) but link exposes {link}")]
52    GeometryDeviceMismatch { geometry: usize, link: usize },
53
54    #[error("expected {expected} datagram(s) (one per device), got {got}")]
55    DatagramCountMismatch { expected: usize, got: usize },
56
57    #[error("focus coordinate {axis} = {value} out of range {min}..={max}")]
58    FocusOutOfRange {
59        axis: &'static str,
60        value: i32,
61        min: i32,
62        max: i32,
63    },
64
65    #[error("modulation size {size} out of range 1..={max}")]
66    ModulationSizeOutOfRange { size: usize, max: usize },
67
68    #[error("modulation data must not be empty")]
69    ModulationDataEmpty,
70
71    #[error("modulation offset {offset} must be even (word-write-only RAM)")]
72    ModulationOffsetNotEven { offset: usize },
73
74    #[error("modulation write [{offset}, {end}) exceeds buffer capacity {capacity}")]
75    ModulationWriteExceedsCapacity {
76        offset: usize,
77        end: usize,
78        capacity: usize,
79    },
80
81    #[error("modulation sample count exceeds usize")]
82    SampleCountOverflow,
83
84    #[error("sine modulation value is out of range [0, 255]")]
85    SineValueOutOfRange,
86
87    #[error("square duty {duty} must be in range 0..=1")]
88    DutyOutOfRange { duty: f32 },
89
90    #[error("fourier components must not be empty")]
91    FourierComponentsEmpty,
92
93    #[error("all fourier components must have the same sampling config")]
94    FourierSamplingConfigMismatch,
95
96    #[error("fourier modulation value is out of range [0, 255]")]
97    FourierValueOutOfRange,
98
99    #[error("foci must not be empty")]
100    FociEmpty,
101
102    #[error("foci write [{offset}, {end}) exceeds capacity {capacity}")]
103    FociWriteExceedsCapacity {
104        offset: usize,
105        end: usize,
106        capacity: usize,
107    },
108
109    #[error("xor_hash data too large: max {max} bytes, got {len}")]
110    XorHashDataTooLarge { len: usize, max: usize },
111
112    #[error("silencer completion time {0:?} must be a multiple of the ultrasound period")]
113    SilencerCompletionTimeNotMultiple(core::time::Duration),
114
115    #[error("silencer completion time {0:?} is out of range (1..=65535 ultrasound periods)")]
116    SilencerCompletionTimeOutOfRange(core::time::Duration),
117
118    #[error("pattern size must be >= 1")]
119    PatternSizeZero,
120
121    #[error("num_foci {num_foci} out of range 1..={max}")]
122    NumFociOutOfRange { num_foci: u8, max: u8 },
123
124    #[error("STM size {size} x num_foci {num_foci} exceeds capacity {capacity}")]
125    StmFociExceedCapacity {
126        size: usize,
127        num_foci: u8,
128        capacity: usize,
129    },
130
131    #[error("sound_speed must be >= 1")]
132    SoundSpeedZero,
133
134    #[error("STM size {size} out of range 1..={max}")]
135    StmSizeOutOfRange { size: usize, max: usize },
136
137    #[error("emissions has {len} entr(ies) but device {device} was requested")]
138    EmissionsDeviceOutOfRange { device: usize, len: usize },
139
140    #[error("device {device} has {got} transducer entr(ies) but {expected} are required")]
141    TransducerCountMismatch {
142        device: usize,
143        got: usize,
144        expected: usize,
145    },
146
147    #[error("pattern STM index {index} out of range 0..{max}")]
148    PatternIndexOutOfRange { index: usize, max: usize },
149
150    #[error("device {device} has no group key")]
151    GroupKeyMissing { device: usize },
152
153    #[error("device {device} maps to an unknown key")]
154    GroupKeyUnknown { device: usize },
155
156    #[error("frequency {hz} Hz is equal to or greater than the Nyquist frequency ({nyquist} Hz)")]
157    FrequencyAboveNyquist { hz: f64, nyquist: f32 },
158
159    #[error("modulation frequency must not be zero")]
160    FrequencyZero,
161
162    #[error("frequency {hz} Hz must be a valid positive value")]
163    FrequencyNotPositive { hz: f32 },
164
165    #[error("frequency {hz} Hz cannot be output with the current sampling config")]
166    FrequencyNotRepresentable { hz: f32 },
167
168    #[error("modulation frequency must be a valid value")]
169    FrequencyNaN,
170
171    #[error(transparent)]
172    SamplingConfig(#[from] SamplingConfigError),
173
174    #[error(transparent)]
175    PulseWidth(#[from] PulseWidthError),
176}