1use std::{convert::Infallible, num::NonZeroU16};
2
3use crate::{
4 firmware::{
5 fpga::{SILENCER_STEPS_INTENSITY_DEFAULT, SILENCER_STEPS_PHASE_DEFAULT, SilencerTarget},
6 operation::{
7 NullOp, OperationGenerator, SilencerFixedCompletionStepsOp, SilencerFixedUpdateRateOp,
8 },
9 },
10 geometry::{Device, Geometry},
11};
12
13use super::Datagram;
14
15pub trait SilencerConfig: std::fmt::Debug + Clone + Copy {}
16impl SilencerConfig for () {}
17
18#[cfg(not(feature = "dynamic_freq"))]
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct FixedCompletionTime {
22 pub intensity: std::time::Duration,
26 pub phase: std::time::Duration,
30 pub strict_mode: bool,
38}
39#[cfg(not(feature = "dynamic_freq"))]
40impl SilencerConfig for FixedCompletionTime {}
41
42#[cfg(not(feature = "dynamic_freq"))]
43impl Default for FixedCompletionTime {
44 fn default() -> Self {
45 FixedCompletionTime {
46 intensity: SILENCER_STEPS_INTENSITY_DEFAULT as u32
47 * autd3_core::defined::ultrasound_period(),
48 phase: SILENCER_STEPS_PHASE_DEFAULT as u32 * autd3_core::defined::ultrasound_period(),
49 strict_mode: true,
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56#[repr(C)]
57pub struct FixedCompletionSteps {
58 pub intensity: NonZeroU16,
62 pub phase: NonZeroU16,
66 pub strict_mode: bool,
74}
75impl SilencerConfig for FixedCompletionSteps {}
76
77impl Default for FixedCompletionSteps {
78 fn default() -> Self {
79 FixedCompletionSteps {
80 intensity: NonZeroU16::new(SILENCER_STEPS_INTENSITY_DEFAULT).unwrap(),
81 phase: NonZeroU16::new(SILENCER_STEPS_PHASE_DEFAULT).unwrap(),
82 strict_mode: true,
83 }
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89#[repr(C)]
90pub struct FixedUpdateRate {
91 pub intensity: NonZeroU16,
95 pub phase: NonZeroU16,
99}
100impl SilencerConfig for FixedUpdateRate {}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104pub struct Silencer<T: SilencerConfig> {
105 pub config: T,
107 pub target: SilencerTarget,
109}
110
111impl<T: SilencerConfig> Silencer<T> {
112 #[must_use]
114 pub const fn new(config: T, target: SilencerTarget) -> Self {
115 Self { config, target }
116 }
117}
118
119impl Silencer<()> {
120 #[must_use]
122 pub const fn disable() -> Silencer<FixedCompletionSteps> {
123 Silencer {
124 config: FixedCompletionSteps {
125 intensity: NonZeroU16::MIN,
126 phase: NonZeroU16::MIN,
127 strict_mode: true,
128 },
129 target: SilencerTarget::Intensity,
130 }
131 }
132}
133
134impl Default for Silencer<FixedCompletionSteps> {
135 fn default() -> Self {
136 Silencer {
137 config: Default::default(),
138 target: Default::default(),
139 }
140 }
141}
142
143pub struct SilencerOpGenerator<T: SilencerConfig> {
144 config: T,
145 target: SilencerTarget,
146}
147
148impl OperationGenerator for SilencerOpGenerator<FixedUpdateRate> {
149 type O1 = SilencerFixedUpdateRateOp;
150 type O2 = NullOp;
151
152 fn generate(&mut self, _: &Device) -> (Self::O1, Self::O2) {
153 (
154 Self::O1::new(self.config.intensity, self.config.phase, self.target),
155 Self::O2 {},
156 )
157 }
158}
159
160#[cfg(not(feature = "dynamic_freq"))]
161impl OperationGenerator for SilencerOpGenerator<FixedCompletionTime> {
162 type O1 = crate::firmware::operation::SilencerFixedCompletionTimeOp;
163 type O2 = NullOp;
164
165 fn generate(&mut self, _: &Device) -> (Self::O1, Self::O2) {
166 (
167 Self::O1::new(
168 self.config.intensity,
169 self.config.phase,
170 self.config.strict_mode,
171 self.target,
172 ),
173 Self::O2 {},
174 )
175 }
176}
177
178impl OperationGenerator for SilencerOpGenerator<FixedCompletionSteps> {
179 type O1 = SilencerFixedCompletionStepsOp;
180 type O2 = NullOp;
181
182 fn generate(&mut self, _: &Device) -> (Self::O1, Self::O2) {
183 (
184 Self::O1::new(
185 self.config.intensity,
186 self.config.phase,
187 self.config.strict_mode,
188 self.target,
189 ),
190 Self::O2 {},
191 )
192 }
193}
194
195impl<T: SilencerConfig> Datagram for Silencer<T>
196where
197 SilencerOpGenerator<T>: OperationGenerator,
198{
199 type G = SilencerOpGenerator<T>;
200 type Error = Infallible;
201
202 fn operation_generator(self, _: &Geometry, _: bool) -> Result<Self::G, Self::Error> {
203 Ok(Self::G {
204 config: self.config,
205 target: self.target,
206 })
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn disable() {
216 let s = Silencer::disable();
217 assert_eq!(1, s.config.intensity.get());
218 assert_eq!(1, s.config.phase.get());
219 assert!(s.config.strict_mode);
220 assert_eq!(SilencerTarget::Intensity, s.target);
221 }
222
223 #[test]
224 fn fixed_completion_steps_default() {
225 let s: Silencer<FixedCompletionSteps> = Silencer::default();
226 assert_eq!(10, s.config.intensity.get());
227 assert_eq!(40, s.config.phase.get());
228 assert!(s.config.strict_mode);
229 assert_eq!(SilencerTarget::Intensity, s.target);
230 }
231
232 #[test]
233 #[cfg(not(feature = "dynamic_freq"))]
234 fn fixed_completion_time_default() {
235 let s: Silencer<FixedCompletionTime> =
236 Silencer::new(Default::default(), Default::default());
237 assert_eq!(std::time::Duration::from_micros(250), s.config.intensity);
238 assert_eq!(std::time::Duration::from_micros(1000), s.config.phase);
239 assert!(s.config.strict_mode);
240 assert_eq!(SilencerTarget::Intensity, s.target);
241 }
242}