1use super::*;
7
8#[derive(Default, Debug)]
10pub struct Ff800Protocol;
11
12const MIXER_OFFSET: u64 = 0x000080080000;
13const OUTPUT_OFFSET: u64 = 0x000080081f80;
14const METER_OFFSET: u64 = 0x000080100000;
15const STATUS_OFFSET: u64 = 0x0000801c0000;
16const CFG_OFFSET: u64 = 0x0000fc88f014;
17
18#[allow(dead_code)]
20const TCO_STATUS_OFFSET: usize = 0x0000801f0000;
21
22#[allow(dead_code)]
24const TCO_CFG_OFFSET: usize = 0x0000810f0020;
25
26impl RmeFfFormerSpecification for Ff800Protocol {
27 const ANALOG_INPUT_COUNT: usize = 10;
28 const SPDIF_INPUT_COUNT: usize = 2;
29 const ADAT_INPUT_COUNT: usize = 16;
30 const STREAM_INPUT_COUNT: usize = 28;
31
32 const ANALOG_OUTPUT_COUNT: usize = 10;
33 const SPDIF_OUTPUT_COUNT: usize = 2;
34 const ADAT_OUTPUT_COUNT: usize = 16;
35}
36
37impl RmeFfFormerMeterSpecification for Ff800Protocol {
38 const METER_OFFSET: u64 = METER_OFFSET;
39}
40
41impl RmeFfWhollyUpdatableParamsOperation<FormerOutputVolumeState> for Ff800Protocol {
42 fn update_wholly(
43 req: &mut FwReq,
44 node: &mut FwNode,
45 params: &FormerOutputVolumeState,
46 timeout_ms: u32,
47 ) -> Result<(), Error> {
48 let mut raw = Self::serialize_offsets(params);
49 req.transaction_sync(
50 node,
51 FwTcode::WriteBlockRequest,
52 OUTPUT_OFFSET,
53 raw.len(),
54 &mut raw,
55 timeout_ms,
56 )
57 }
58}
59
60impl RmeFfPartiallyUpdatableParamsOperation<FormerOutputVolumeState> for Ff800Protocol {
61 fn update_partially(
62 req: &mut FwReq,
63 node: &mut FwNode,
64 params: &mut FormerOutputVolumeState,
65 update: FormerOutputVolumeState,
66 timeout_ms: u32,
67 ) -> Result<(), Error> {
68 let old = Self::serialize_offsets(params);
69 let mut new = Self::serialize_offsets(&update);
70
71 (0..(new.len() / 4))
72 .try_for_each(|i| {
73 let pos = i * 4;
74 if new[pos..(pos + 4)] != old[pos..(pos + 4)] {
75 req.transaction_sync(
76 node,
77 FwTcode::WriteBlockRequest,
78 OUTPUT_OFFSET + pos as u64,
79 4,
80 &mut new[pos..(pos + 4)],
81 timeout_ms,
82 )
83 } else {
84 Ok(())
85 }
86 })
87 .map(|_| *params = update)
88 }
89}
90
91impl RmeFormerMixerSpecification for Ff800Protocol {
92 const MIXER_OFFSET: u64 = MIXER_OFFSET;
93 const AVAIL_COUNT: usize = 32;
94}
95
96#[derive(Debug, Copy, Clone, PartialEq, Eq)]
98pub enum Ff800ClkSrc {
99 Internal,
100 WordClock,
101 AdatA,
102 AdatB,
103 Spdif,
104 Tco,
105}
106
107impl Default for Ff800ClkSrc {
108 fn default() -> Self {
109 Self::AdatA
110 }
111}
112
113const Q0_SYNC_WORD_CLOCK_MASK: u32 = 0x40000000;
115const Q0_LOCK_WORD_CLOCK_MASK: u32 = 0x20000000;
116const Q0_EXT_CLK_RATE_MASK: u32 = 0x1e000000;
117const Q0_EXT_CLK_RATE_192000_FLAGS: u32 = 0x12000000;
118const Q0_EXT_CLK_RATE_176400_FLAGS: u32 = 0x10000000;
119const Q0_EXT_CLK_RATE_128000_FLAGS: u32 = 0x0c000000;
120const Q0_EXT_CLK_RATE_96000_FLAGS: u32 = 0x0e000000;
121const Q0_EXT_CLK_RATE_88200_FLAGS: u32 = 0x0a000000;
122const Q0_EXT_CLK_RATE_64000_FLAGS: u32 = 0x08000000;
123const Q0_EXT_CLK_RATE_48000_FLAGS: u32 = 0x06000000;
124const Q0_EXT_CLK_RATE_44100_FLAGS: u32 = 0x04000000;
125const Q0_EXT_CLK_RATE_32000_FLAGS: u32 = 0x02000000;
126const Q0_ACTIVE_CLK_SRC_MASK: u32 = 0x01c00000;
127const Q0_ACTIVE_CLK_SRC_INTERNAL_FLAGS: u32 = 0x01c00000;
128const Q0_ACTIVE_CLK_SRC_TCO_FLAGS: u32 = 0x01800000;
129const Q0_ACTIVE_CLK_SRC_WORD_CLK_FLAGS: u32 = 0x01000000;
130const Q0_ACTIVE_CLK_SRC_SPDIF_FLAGS: u32 = 0x00c00000;
131const Q0_ACTIVE_CLK_SRC_ADAT_B_FLAGS: u32 = 0x00400000;
132const Q0_ACTIVE_CLK_SRC_ADAT_A_FLAGS: u32 = 0x00000000;
133const Q0_SYNC_SPDIF_MASK: u32 = 0x00100000;
134const Q0_LOCK_SPDIF_MASK: u32 = 0x00040000;
135const Q0_SPDIF_RATE_MASK: u32 = 0x0003c000;
136const Q0_SPDIF_RATE_192000_FLAGS: u32 = 0x00024000;
137const Q0_SPDIF_RATE_176400_FLAGS: u32 = 0x00020000;
138const Q0_SPDIF_RATE_128000_FLAGS: u32 = 0x0001c000;
139const Q0_SPDIF_RATE_96000_FLAGS: u32 = 0x00018000;
140const Q0_SPDIF_RATE_88200_FLAGS: u32 = 0x00014000;
141const Q0_SPDIF_RATE_64000_FLAGS: u32 = 0x00010000;
142const Q0_SPDIF_RATE_48000_FLAGS: u32 = 0x0000c000;
143const Q0_SPDIF_RATE_44100_FLAGS: u32 = 0x00008000;
144const Q0_SPDIF_RATE_32000_FLAGS: u32 = 0x00004000;
145const Q0_LOCK_ADAT_B_MASK: u32 = 0x00002000;
146const Q0_LOCK_ADAT_A_MASK: u32 = 0x00001000;
147const Q0_SYNC_ADAT_B_MASK: u32 = 0x00000800;
148const Q0_SYNC_ADAT_A_MASK: u32 = 0x00000400;
149
150const Q1_SYNC_TCO_MASK: u32 = 0x00800000;
152const Q1_LOCK_TCO_MASK: u32 = 0x00400000;
153const Q1_WORD_OUT_SINGLE_MASK: u32 = 0x00002000;
154const Q1_CONF_CLK_SRC_MASK: u32 = 0x00001c01;
155const Q1_CONF_CLK_SRC_TCO_FLAGS: u32 = 0x00001800;
156const Q1_CONF_CLK_SRC_WORD_CLK_FLAGS: u32 = 0x00001000;
157const Q1_CONF_CLK_SRC_SPDIF_FLAGS: u32 = 0x00000c00;
158const Q1_CONF_CLK_SRC_ADAT_B_FLAGS: u32 = 0x00000400;
159const Q1_CONF_CLK_SRC_INTERNAL_FLAGS: u32 = 0x00000001;
160const Q1_CONF_CLK_SRC_ADAT_A_FLAGS: u32 = 0x00000000;
161const Q1_SPDIF_IN_IFACE_MASK: u32 = 0x00000200;
162const Q1_OPT_OUT_SIGNAL_MASK: u32 = 0x00000100;
163const Q1_SPDIF_OUT_EMPHASIS_MASK: u32 = 0x00000040;
164const Q1_SPDIF_OUT_FMT_MASK: u32 = 0x00000020;
165const Q1_CONF_CLK_RATE_MASK: u32 = 0x0000001e;
166const Q1_CONF_CLK_RATE_192000_FLAGS: u32 = 0x00000016;
167const Q1_CONF_CLK_RATE_176400_FLAGS: u32 = 0x00000010;
168const Q1_CONF_CLK_RATE_128000_FLAGS: u32 = 0x00000012;
169const Q1_CONF_CLK_RATE_96000_FLAGS: u32 = 0x0000000e;
170const Q1_CONF_CLK_RATE_88200_FLAGS: u32 = 0x00000008;
171const Q1_CONF_CLK_RATE_64000_FLAGS: u32 = 0x0000000a;
172const Q1_CONF_CLK_RATE_48000_FLAGS: u32 = 0x00000006;
173const Q1_CONF_CLK_RATE_44100_FLAGS: u32 = 0x00000000;
174const Q1_CONF_CLK_RATE_32000_FLAGS: u32 = 0x00000002;
175
176#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
178pub struct Ff800ClkLockStatus {
179 pub adat_a: bool,
180 pub adat_b: bool,
181 pub spdif: bool,
182 pub word_clock: bool,
183 pub tco: bool,
184}
185
186impl Ff800ClkLockStatus {
187 const QUADLET_COUNT: usize = 2;
188}
189
190fn serialize_lock_status(status: &Ff800ClkLockStatus, quads: &mut [u32]) {
191 assert!(quads.len() >= Ff800ClkLockStatus::QUADLET_COUNT);
192
193 quads[0] &= !Q0_LOCK_ADAT_A_MASK;
194 if status.adat_a {
195 quads[0] |= Q0_LOCK_ADAT_A_MASK;
196 }
197
198 quads[0] &= !Q0_LOCK_ADAT_B_MASK;
199 if status.adat_b {
200 quads[0] |= Q0_LOCK_ADAT_B_MASK;
201 }
202
203 quads[0] &= !Q0_LOCK_SPDIF_MASK;
204 if status.spdif {
205 quads[0] |= Q0_LOCK_SPDIF_MASK;
206 }
207
208 quads[0] &= !Q0_LOCK_WORD_CLOCK_MASK;
209 if status.word_clock {
210 quads[0] |= Q0_LOCK_WORD_CLOCK_MASK;
211 }
212
213 quads[1] &= !Q1_LOCK_TCO_MASK;
214 if status.tco {
215 quads[1] |= Q1_LOCK_TCO_MASK;
216 }
217}
218
219fn deserialize_lock_status(status: &mut Ff800ClkLockStatus, quads: &[u32]) {
220 assert!(quads.len() >= Ff800ClkLockStatus::QUADLET_COUNT);
221
222 status.adat_a = quads[0] & Q0_LOCK_ADAT_A_MASK > 0;
223 status.adat_b = quads[0] & Q0_LOCK_ADAT_B_MASK > 0;
224 status.spdif = quads[0] & Q0_LOCK_SPDIF_MASK > 0;
225 status.word_clock = quads[0] & Q0_LOCK_WORD_CLOCK_MASK > 0;
226 status.tco = quads[1] & Q1_LOCK_TCO_MASK > 0;
227}
228
229#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
231pub struct Ff800ClkSyncStatus {
232 pub adat_a: bool,
233 pub adat_b: bool,
234 pub spdif: bool,
235 pub word_clock: bool,
236 pub tco: bool,
237}
238
239impl Ff800ClkSyncStatus {
240 const QUADLET_COUNT: usize = 2;
241}
242
243fn serialize_sync_status(status: &Ff800ClkSyncStatus, quads: &mut [u32]) {
244 assert!(quads.len() >= Ff800ClkSyncStatus::QUADLET_COUNT);
245
246 quads[0] &= !Q0_SYNC_ADAT_A_MASK;
247 if status.adat_a {
248 quads[0] |= Q0_SYNC_ADAT_A_MASK;
249 }
250
251 quads[0] &= !Q0_SYNC_ADAT_B_MASK;
252 if status.adat_b {
253 quads[0] |= Q0_SYNC_ADAT_B_MASK;
254 }
255
256 quads[0] &= !Q0_SYNC_SPDIF_MASK;
257 if status.spdif {
258 quads[0] |= Q0_SYNC_SPDIF_MASK;
259 }
260
261 quads[0] &= !Q0_SYNC_WORD_CLOCK_MASK;
262 if status.word_clock {
263 quads[0] |= Q0_SYNC_WORD_CLOCK_MASK;
264 }
265
266 quads[1] &= !Q1_SYNC_TCO_MASK;
267 if status.tco {
268 quads[1] |= Q1_SYNC_TCO_MASK;
269 }
270}
271
272fn deserialize_sync_status(status: &mut Ff800ClkSyncStatus, quads: &[u32]) {
273 assert!(quads.len() >= Ff800ClkSyncStatus::QUADLET_COUNT);
274
275 status.adat_a = quads[0] & Q0_SYNC_ADAT_A_MASK > 0;
276 status.adat_b = quads[0] & Q0_SYNC_ADAT_B_MASK > 0;
277 status.spdif = quads[0] & Q0_SYNC_SPDIF_MASK > 0;
278 status.word_clock = quads[0] & Q0_SYNC_WORD_CLOCK_MASK > 0;
279 status.tco = quads[1] & Q1_SYNC_TCO_MASK > 0;
280}
281
282#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
284pub struct Ff800Status {
285 pub spdif_in: SpdifInput,
287 pub spdif_out: FormerSpdifOutput,
289 pub opt_out_signal: OpticalOutputSignal,
291 pub word_out_single: bool,
293 pub sync: Ff800ClkSyncStatus,
295 pub lock: Ff800ClkLockStatus,
297
298 pub spdif_rate: Option<ClkNominalRate>,
299 pub active_clk_src: Ff800ClkSrc,
300 pub external_clk_rate: Option<ClkNominalRate>,
301 pub configured_clk_src: Ff800ClkSrc,
302 pub configured_clk_rate: ClkNominalRate,
303}
304
305impl Ff800Status {
306 const QUADLET_COUNT: usize = FORMER_STATUS_SIZE / 4;
307}
308
309impl RmeFfOffsetParamsSerialize<Ff800Status> for Ff800Protocol {
310 fn serialize_offsets(params: &Ff800Status) -> Vec<u8> {
311 let mut quads = [0; Ff800Status::QUADLET_COUNT];
312
313 serialize_lock_status(¶ms.lock, &mut quads);
314 serialize_sync_status(¶ms.sync, &mut quads);
315
316 quads[0] &= !Q0_SPDIF_RATE_MASK;
317 if let Some(rate) = ¶ms.spdif_rate {
318 let flag = match rate {
319 ClkNominalRate::R32000 => Q0_SPDIF_RATE_32000_FLAGS,
320 ClkNominalRate::R44100 => Q0_SPDIF_RATE_44100_FLAGS,
321 ClkNominalRate::R48000 => Q0_SPDIF_RATE_48000_FLAGS,
322 ClkNominalRate::R64000 => Q0_SPDIF_RATE_64000_FLAGS,
323 ClkNominalRate::R88200 => Q0_SPDIF_RATE_88200_FLAGS,
324 ClkNominalRate::R96000 => Q0_SPDIF_RATE_96000_FLAGS,
325 ClkNominalRate::R128000 => Q0_SPDIF_RATE_128000_FLAGS,
326 ClkNominalRate::R176400 => Q0_SPDIF_RATE_176400_FLAGS,
327 ClkNominalRate::R192000 => Q0_SPDIF_RATE_192000_FLAGS,
328 };
329 quads[0] |= flag;
330 }
331
332 quads[0] &= !Q0_ACTIVE_CLK_SRC_MASK;
333 let flag = match ¶ms.active_clk_src {
334 Ff800ClkSrc::AdatA => Q0_ACTIVE_CLK_SRC_ADAT_A_FLAGS,
335 Ff800ClkSrc::AdatB => Q0_ACTIVE_CLK_SRC_ADAT_B_FLAGS,
336 Ff800ClkSrc::Spdif => Q0_ACTIVE_CLK_SRC_SPDIF_FLAGS,
337 Ff800ClkSrc::WordClock => Q0_ACTIVE_CLK_SRC_WORD_CLK_FLAGS,
338 Ff800ClkSrc::Tco => Q0_ACTIVE_CLK_SRC_TCO_FLAGS,
339 Ff800ClkSrc::Internal => Q0_ACTIVE_CLK_SRC_INTERNAL_FLAGS,
340 };
341 quads[0] |= flag;
342
343 quads[0] &= !Q0_EXT_CLK_RATE_MASK;
344 if let Some(rate) = ¶ms.external_clk_rate {
345 let flag = match rate {
346 ClkNominalRate::R32000 => Q0_EXT_CLK_RATE_32000_FLAGS,
347 ClkNominalRate::R44100 => Q0_EXT_CLK_RATE_44100_FLAGS,
348 ClkNominalRate::R48000 => Q0_EXT_CLK_RATE_48000_FLAGS,
349 ClkNominalRate::R64000 => Q0_EXT_CLK_RATE_64000_FLAGS,
350 ClkNominalRate::R88200 => Q0_EXT_CLK_RATE_88200_FLAGS,
351 ClkNominalRate::R96000 => Q0_EXT_CLK_RATE_96000_FLAGS,
352 ClkNominalRate::R128000 => Q0_EXT_CLK_RATE_128000_FLAGS,
353 ClkNominalRate::R176400 => Q0_EXT_CLK_RATE_176400_FLAGS,
354 ClkNominalRate::R192000 => Q0_EXT_CLK_RATE_192000_FLAGS,
355 };
356 quads[0] |= flag;
357 }
358
359 quads[1] &= !Q1_SPDIF_IN_IFACE_MASK;
360 if params.spdif_in.iface == SpdifIface::Optical {
361 quads[1] |= Q1_SPDIF_IN_IFACE_MASK;
362 }
363
364 quads[1] &= !Q1_SPDIF_OUT_FMT_MASK;
365 if params.spdif_out.format == SpdifFormat::Professional {
366 quads[1] |= Q1_SPDIF_OUT_FMT_MASK;
367 }
368
369 quads[1] &= !Q1_SPDIF_OUT_EMPHASIS_MASK;
370 if params.spdif_out.emphasis {
371 quads[1] |= Q1_SPDIF_OUT_EMPHASIS_MASK;
372 }
373
374 quads[1] &= !Q1_OPT_OUT_SIGNAL_MASK;
375 if params.opt_out_signal == OpticalOutputSignal::Spdif {
376 quads[1] |= Q1_OPT_OUT_SIGNAL_MASK;
377 }
378
379 quads[1] &= !Q1_WORD_OUT_SINGLE_MASK;
380 if params.word_out_single {
381 quads[1] |= Q1_WORD_OUT_SINGLE_MASK;
382 }
383
384 quads[1] &= !Q1_CONF_CLK_SRC_MASK;
385 let flag = match ¶ms.configured_clk_src {
386 Ff800ClkSrc::Internal => Q1_CONF_CLK_SRC_INTERNAL_FLAGS,
387 Ff800ClkSrc::AdatB => Q1_CONF_CLK_SRC_ADAT_B_FLAGS,
388 Ff800ClkSrc::Spdif => Q1_CONF_CLK_SRC_SPDIF_FLAGS,
389 Ff800ClkSrc::WordClock => Q1_CONF_CLK_SRC_WORD_CLK_FLAGS,
390 Ff800ClkSrc::Tco => Q1_CONF_CLK_SRC_TCO_FLAGS,
391 Ff800ClkSrc::AdatA => Q1_CONF_CLK_SRC_ADAT_A_FLAGS,
392 };
393 quads[1] |= flag;
394
395 quads[1] &= !Q1_CONF_CLK_RATE_MASK;
396 let flag = match ¶ms.configured_clk_rate {
397 ClkNominalRate::R32000 => Q1_CONF_CLK_RATE_32000_FLAGS,
398 ClkNominalRate::R44100 => Q1_CONF_CLK_RATE_44100_FLAGS,
399 ClkNominalRate::R48000 => Q1_CONF_CLK_RATE_48000_FLAGS,
400 ClkNominalRate::R64000 => Q1_CONF_CLK_RATE_64000_FLAGS,
401 ClkNominalRate::R88200 => Q1_CONF_CLK_RATE_88200_FLAGS,
402 ClkNominalRate::R96000 => Q1_CONF_CLK_RATE_96000_FLAGS,
403 ClkNominalRate::R128000 => Q1_CONF_CLK_RATE_128000_FLAGS,
404 ClkNominalRate::R176400 => Q1_CONF_CLK_RATE_176400_FLAGS,
405 ClkNominalRate::R192000 => Q1_CONF_CLK_RATE_192000_FLAGS,
406 };
407 quads[1] |= flag;
408
409 quads.iter().flat_map(|quad| quad.to_le_bytes()).collect()
410 }
411}
412
413impl RmeFfOffsetParamsDeserialize<Ff800Status> for Ff800Protocol {
414 fn deserialize_offsets(params: &mut Ff800Status, raw: &[u8]) {
415 assert!(raw.len() >= FORMER_STATUS_SIZE);
416
417 let mut quads = [0; Ff800Status::QUADLET_COUNT];
418 let mut quadlet = [0; 4];
419 quads.iter_mut().enumerate().for_each(|(i, quad)| {
420 let pos = i * 4;
421 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
422 *quad = u32::from_le_bytes(quadlet);
423 });
424
425 deserialize_lock_status(&mut params.lock, &quads);
426 deserialize_sync_status(&mut params.sync, &quads);
427
428 params.spdif_rate = match quads[0] & Q0_SPDIF_RATE_MASK {
429 Q0_SPDIF_RATE_32000_FLAGS => Some(ClkNominalRate::R32000),
430 Q0_SPDIF_RATE_44100_FLAGS => Some(ClkNominalRate::R44100),
431 Q0_SPDIF_RATE_48000_FLAGS => Some(ClkNominalRate::R48000),
432 Q0_SPDIF_RATE_64000_FLAGS => Some(ClkNominalRate::R64000),
433 Q0_SPDIF_RATE_88200_FLAGS => Some(ClkNominalRate::R88200),
434 Q0_SPDIF_RATE_96000_FLAGS => Some(ClkNominalRate::R96000),
435 Q0_SPDIF_RATE_128000_FLAGS => Some(ClkNominalRate::R128000),
436 Q0_SPDIF_RATE_176400_FLAGS => Some(ClkNominalRate::R176400),
437 Q0_SPDIF_RATE_192000_FLAGS => Some(ClkNominalRate::R192000),
438 _ => None,
439 };
440
441 params.active_clk_src = match quads[0] & Q0_ACTIVE_CLK_SRC_MASK {
442 Q0_ACTIVE_CLK_SRC_ADAT_A_FLAGS => Ff800ClkSrc::AdatA,
443 Q0_ACTIVE_CLK_SRC_ADAT_B_FLAGS => Ff800ClkSrc::AdatB,
444 Q0_ACTIVE_CLK_SRC_SPDIF_FLAGS => Ff800ClkSrc::Spdif,
445 Q0_ACTIVE_CLK_SRC_WORD_CLK_FLAGS => Ff800ClkSrc::WordClock,
446 Q0_ACTIVE_CLK_SRC_TCO_FLAGS => Ff800ClkSrc::Tco,
447 Q0_ACTIVE_CLK_SRC_INTERNAL_FLAGS => Ff800ClkSrc::Internal,
448 _ => unreachable!(),
449 };
450
451 params.external_clk_rate = match quads[0] & Q0_EXT_CLK_RATE_MASK {
452 Q0_EXT_CLK_RATE_32000_FLAGS => Some(ClkNominalRate::R32000),
453 Q0_EXT_CLK_RATE_44100_FLAGS => Some(ClkNominalRate::R44100),
454 Q0_EXT_CLK_RATE_48000_FLAGS => Some(ClkNominalRate::R48000),
455 Q0_EXT_CLK_RATE_64000_FLAGS => Some(ClkNominalRate::R64000),
456 Q0_EXT_CLK_RATE_88200_FLAGS => Some(ClkNominalRate::R88200),
457 Q0_EXT_CLK_RATE_96000_FLAGS => Some(ClkNominalRate::R96000),
458 Q0_EXT_CLK_RATE_128000_FLAGS => Some(ClkNominalRate::R128000),
459 Q0_EXT_CLK_RATE_176400_FLAGS => Some(ClkNominalRate::R176400),
460 Q0_EXT_CLK_RATE_192000_FLAGS => Some(ClkNominalRate::R192000),
461 _ => None,
462 };
463
464 params.spdif_in.iface = if quads[1] & Q1_SPDIF_IN_IFACE_MASK > 0 {
465 SpdifIface::Optical
466 } else {
467 SpdifIface::Coaxial
468 };
469
470 params.spdif_out.format = if quads[1] & Q1_SPDIF_OUT_FMT_MASK > 0 {
471 SpdifFormat::Professional
472 } else {
473 SpdifFormat::Consumer
474 };
475
476 params.spdif_out.emphasis = quads[1] & Q1_SPDIF_OUT_EMPHASIS_MASK > 0;
477
478 params.opt_out_signal = if quads[1] & Q1_OPT_OUT_SIGNAL_MASK > 0 {
479 OpticalOutputSignal::Spdif
480 } else {
481 OpticalOutputSignal::Adat
482 };
483
484 params.word_out_single = quads[1] & Q1_WORD_OUT_SINGLE_MASK > 0;
485
486 params.configured_clk_src = match quads[1] & Q1_CONF_CLK_SRC_MASK {
487 Q1_CONF_CLK_SRC_INTERNAL_FLAGS => Ff800ClkSrc::Internal,
488 Q1_CONF_CLK_SRC_ADAT_B_FLAGS => Ff800ClkSrc::AdatB,
489 Q1_CONF_CLK_SRC_SPDIF_FLAGS => Ff800ClkSrc::Spdif,
490 Q1_CONF_CLK_SRC_WORD_CLK_FLAGS => Ff800ClkSrc::WordClock,
491 Q1_CONF_CLK_SRC_TCO_FLAGS => Ff800ClkSrc::Tco,
492 Q1_CONF_CLK_SRC_ADAT_A_FLAGS | _ => Ff800ClkSrc::AdatA,
493 };
494
495 params.configured_clk_rate = match quads[1] & Q1_CONF_CLK_RATE_MASK {
496 Q1_CONF_CLK_RATE_32000_FLAGS => ClkNominalRate::R32000,
497 Q1_CONF_CLK_RATE_48000_FLAGS => ClkNominalRate::R48000,
498 Q1_CONF_CLK_RATE_64000_FLAGS => ClkNominalRate::R64000,
499 Q1_CONF_CLK_RATE_88200_FLAGS => ClkNominalRate::R88200,
500 Q1_CONF_CLK_RATE_96000_FLAGS => ClkNominalRate::R96000,
501 Q1_CONF_CLK_RATE_128000_FLAGS => ClkNominalRate::R128000,
502 Q1_CONF_CLK_RATE_176400_FLAGS => ClkNominalRate::R176400,
503 Q1_CONF_CLK_RATE_192000_FLAGS => ClkNominalRate::R192000,
504 Q1_CONF_CLK_RATE_44100_FLAGS | _ => ClkNominalRate::R44100,
505 };
506 }
507}
508
509impl RmeFfCacheableParamsOperation<Ff800Status> for Ff800Protocol {
510 fn cache_wholly(
511 req: &mut FwReq,
512 node: &mut FwNode,
513 params: &mut Ff800Status,
514 timeout_ms: u32,
515 ) -> Result<(), Error> {
516 read_status::<Ff800Protocol, Ff800Status>(req, node, STATUS_OFFSET, params, timeout_ms)
517 }
518}
519
520const Q0_LINE_OUT_LEVEL_MASK: u32 = 0x00001c00;
522const Q0_LINE_OUT_LEVEL_CON_FLAG: u32 = 0x00001000;
523const Q0_LINE_OUT_LEVEL_PRO_FLAG: u32 = 0x00000800;
524const Q0_LINE_OUT_LEVEL_HIGH_FLAG: u32 = 0x00000400;
525const Q0_INPUT_0_INST_DRIVE_MASK: u32 = 0x00000200;
526const Q0_INPUT_9_POWERING_MASK: u32 = 0x00000100;
527const Q0_INPUT_7_POWERING_MASK: u32 = 0x00000080;
528const Q0_LINE_IN_LEVEL_MASK: u32 = 0x00000038;
529const Q0_LINE_IN_LEVEL_PRO_FLAG: u32 = 0x00000010;
530const Q0_LINE_IN_LEVEL_CON_FLAG: u32 = 0x00000020;
531const Q0_LINE_IN_LEVEL_LOW_FLAG: u32 = 0x00000008;
532const Q0_INPUT_0_INST_SPKR_EMU_MASK: u32 = 0x00000004;
533const Q0_INPUT_8_POWERING_MASK: u32 = 0x00000002;
534const Q0_INPUT_6_POWERING_MASK: u32 = 0x00000001;
535
536const Q1_INPUT_0_FRONT_JACK_MASK: u32 = 0x00000800;
538const Q1_INPUT_0_INST_DRIVE_MASK: u32 = 0x00000200;
539const Q1_INPUT_7_REAR_JACK_MASK: u32 = 0x00000100;
540const Q1_INPUT_7_FRONT_JACK_MASK: u32 = 0x00000080;
541const Q1_INPUT_6_REAR_JACK_MASK: u32 = 0x00000040;
542const Q1_INPUT_6_FRONT_JACK_MASK: u32 = 0x00000020;
543const Q1_LINE_OUT_LEVEL_MASK: u32 = 0x00000018;
544const Q1_LINE_OUT_LEVEL_PRO_FLAG: u32 = 0x00000018;
545const Q1_LINE_OUT_LEVEL_HIGH_FLAG: u32 = 0x00000010;
546const Q1_LINE_OUT_LEVEL_CON_FLAG: u32 = 0x00000008;
547const Q1_INPUT_0_REAR_JACK_MASK: u32 = 0x00000004;
548const Q1_LINE_IN_LEVEL_MASK: u32 = 0x00000003;
549const Q1_LINE_IN_LEVEL_CON_FLAG: u32 = 0x00000003;
550const Q1_LINE_IN_LEVEL_PRO_FLAG: u32 = 0x00000002;
551const Q1_LINE_IN_LEVEL_LOW_FLAG: u32 = 0x00000000;
552
553const Q2_SPDIF_IN_USE_PREEMBLE: u32 = 0x40000000;
555const Q2_INPUT_0_INST_LIMITTER_MASK: u32 = 0x00010000;
556const Q2_WORD_OUT_SINGLE_SPEED_MASK: u32 = 0x00002000;
557const Q2_CLK_SRC_MASK: u32 = 0x00001c01;
558const Q2_CLK_SRC_TCO_FLAG: u32 = 0x00001c00;
559const Q2_CLK_SRC_WORD_CLK_FLAG: u32 = 0x00001400;
560const Q2_CLK_SRC_SPDIF_FLAG: u32 = 0x00000c00;
561const Q2_CLK_SRC_ADAT_B_FLAG: u32 = 0x00000400;
562const Q2_CLK_SRC_INTERNAL_FLAG: u32 = 0x00000001;
563const Q2_CLK_SRC_ADAT_A_FLAG: u32 = 0x00000000;
564const Q2_SPDIF_IN_IFACE_OPT_MASK: u32 = 0x00000200;
565const Q2_OPT_OUT_SIGNAL_MASK: u32 = 0x00000100;
566const Q2_SPDIF_OUT_NON_AUDIO_MASK: u32 = 0x00000080;
567const Q2_SPDIF_OUT_EMPHASIS_MASK: u32 = 0x00000040;
568const Q2_SPDIF_OUT_FMT_PRO_MASK: u32 = 0x00000020;
569const Q2_CLK_AVAIL_RATE_QUADRUPLE_MASK: u32 = 0x00000010;
570const Q2_CLK_AVAIL_RATE_DOUBLE_MASK: u32 = 0x00000008;
571const Q2_CLK_AVAIL_RATE_BASE_48000_MASK: u32 = 0x00000004;
572const Q2_CLK_AVAIL_RATE_BASE_44100_MASK: u32 = 0x00000002;
573const Q2_CONTINUE_AT_ERRORS: u32 = 0x80000000;
574
575#[derive(Debug, Copy, Clone, PartialEq, Eq)]
577pub struct Ff800ClkConfig {
578 pub primary_src: Ff800ClkSrc,
579 avail_rate_44100: bool,
580 avail_rate_48000: bool,
581 avail_rate_double: bool,
582 avail_rate_quadruple: bool,
583}
584
585impl Default for Ff800ClkConfig {
586 fn default() -> Self {
587 Self {
588 primary_src: Ff800ClkSrc::default(),
589 avail_rate_44100: true,
590 avail_rate_48000: true,
591 avail_rate_double: true,
592 avail_rate_quadruple: true,
593 }
594 }
595}
596
597impl Ff800ClkConfig {
598 const QUADLET_COUNT: usize = 3;
599}
600
601fn serialize_clock_config(config: &Ff800ClkConfig, quads: &mut [u32]) {
602 assert!(quads.len() >= Ff800ClkConfig::QUADLET_COUNT);
603
604 quads[2] &= !Q2_CLK_SRC_MASK;
605 let flag = match config.primary_src {
606 Ff800ClkSrc::Internal => Q2_CLK_SRC_INTERNAL_FLAG,
607 Ff800ClkSrc::WordClock => Q2_CLK_SRC_WORD_CLK_FLAG,
608 Ff800ClkSrc::AdatA => Q2_CLK_SRC_ADAT_A_FLAG,
609 Ff800ClkSrc::AdatB => Q2_CLK_SRC_ADAT_B_FLAG,
610 Ff800ClkSrc::Spdif => Q2_CLK_SRC_SPDIF_FLAG,
611 Ff800ClkSrc::Tco => Q2_CLK_SRC_TCO_FLAG,
612 };
613 quads[2] |= flag;
614
615 quads[2] &= !Q2_CLK_AVAIL_RATE_BASE_44100_MASK;
616 if config.avail_rate_44100 {
617 quads[2] |= Q2_CLK_AVAIL_RATE_BASE_44100_MASK;
618 }
619
620 quads[2] &= !Q2_CLK_AVAIL_RATE_BASE_48000_MASK;
621 if config.avail_rate_48000 {
622 quads[2] |= Q2_CLK_AVAIL_RATE_BASE_48000_MASK;
623 }
624
625 quads[2] &= !Q2_CLK_AVAIL_RATE_DOUBLE_MASK;
626 if config.avail_rate_double {
627 quads[2] |= Q2_CLK_AVAIL_RATE_DOUBLE_MASK;
628 }
629
630 quads[2] &= !Q2_CLK_AVAIL_RATE_QUADRUPLE_MASK;
631 if config.avail_rate_quadruple {
632 quads[2] |= Q2_CLK_AVAIL_RATE_QUADRUPLE_MASK;
633 }
634}
635
636fn deserialize_clock_config(config: &mut Ff800ClkConfig, quads: &[u32]) {
637 assert!(quads.len() >= Ff800ClkConfig::QUADLET_COUNT);
638
639 config.primary_src = match quads[2] & Q2_CLK_SRC_MASK {
640 Q2_CLK_SRC_INTERNAL_FLAG => Ff800ClkSrc::Internal,
641 Q2_CLK_SRC_WORD_CLK_FLAG => Ff800ClkSrc::WordClock,
642 Q2_CLK_SRC_ADAT_B_FLAG => Ff800ClkSrc::AdatB,
643 Q2_CLK_SRC_SPDIF_FLAG => Ff800ClkSrc::Spdif,
644 Q2_CLK_SRC_TCO_FLAG => Ff800ClkSrc::Tco,
645 Q2_CLK_SRC_ADAT_A_FLAG | _ => Ff800ClkSrc::AdatA,
646 };
647
648 config.avail_rate_44100 = quads[2] & Q2_CLK_AVAIL_RATE_BASE_44100_MASK > 0;
649 config.avail_rate_48000 = quads[2] & Q2_CLK_AVAIL_RATE_BASE_48000_MASK > 0;
650 config.avail_rate_double = quads[2] & Q2_CLK_AVAIL_RATE_DOUBLE_MASK > 0;
651 config.avail_rate_quadruple = quads[2] & Q2_CLK_AVAIL_RATE_QUADRUPLE_MASK > 0;
652}
653
654#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
656pub struct Ff800InstConfig {
657 pub drive: bool,
659 pub limitter: bool,
661 pub speaker_emulation: bool,
663}
664
665impl Ff800InstConfig {
666 const QUADLET_COUNT: usize = 3;
667}
668
669fn serialize_instrument_config(config: &Ff800InstConfig, quads: &mut [u32]) {
670 assert!(quads.len() >= Ff800InstConfig::QUADLET_COUNT);
671
672 quads[0] &= !Q0_INPUT_0_INST_DRIVE_MASK;
673 quads[1] &= !Q1_INPUT_0_INST_DRIVE_MASK;
674 if config.drive {
675 quads[0] |= Q0_INPUT_0_INST_DRIVE_MASK;
676 quads[1] |= Q1_INPUT_0_INST_DRIVE_MASK;
677 }
678
679 quads[2] &= !Q2_INPUT_0_INST_LIMITTER_MASK;
680 if config.limitter {
681 quads[2] |= Q2_INPUT_0_INST_LIMITTER_MASK;
682 }
683
684 quads[0] &= !Q0_INPUT_0_INST_SPKR_EMU_MASK;
685 if config.speaker_emulation {
686 quads[0] |= Q0_INPUT_0_INST_SPKR_EMU_MASK;
687 }
688}
689
690fn deserialize_instrument_config(config: &mut Ff800InstConfig, quads: &[u32]) {
691 assert!(quads.len() >= Ff800InstConfig::QUADLET_COUNT);
692
693 config.drive =
694 quads[0] & Q0_INPUT_0_INST_DRIVE_MASK > 0 && quads[0] & Q1_INPUT_0_INST_DRIVE_MASK > 0;
695 config.limitter = quads[2] & Q2_INPUT_0_INST_LIMITTER_MASK > 0;
696 config.speaker_emulation = quads[0] & Q0_INPUT_0_INST_SPKR_EMU_MASK > 0;
697}
698
699#[derive(Debug, Copy, Clone, PartialEq, Eq)]
701pub enum Ff800AnalogInputJack {
702 Front,
703 Rear,
704 FrontRear,
705}
706
707impl Default for Ff800AnalogInputJack {
708 fn default() -> Self {
709 Self::Front
710 }
711}
712
713#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
715pub struct Ff800AnalogInConfig {
716 pub jacks: [Ff800AnalogInputJack; 3],
718 pub line_level: FormerLineInNominalLevel,
720 pub phantom_powering: [bool; 4],
722 pub inst: Ff800InstConfig,
724}
725
726impl Ff800AnalogInConfig {
727 const QUADLET_COUNT: usize = 2;
728}
729
730fn serialize_analog_input_config(config: &Ff800AnalogInConfig, quads: &mut [u32]) {
731 assert!(quads.len() >= Ff800AnalogInConfig::QUADLET_COUNT);
732
733 [
734 (Q1_INPUT_0_REAR_JACK_MASK, Q1_INPUT_0_FRONT_JACK_MASK),
735 (Q1_INPUT_6_REAR_JACK_MASK, Q1_INPUT_6_FRONT_JACK_MASK),
736 (Q1_INPUT_7_REAR_JACK_MASK, Q1_INPUT_7_FRONT_JACK_MASK),
737 ]
738 .iter()
739 .zip(&config.jacks)
740 .for_each(|(&(rear_mask, front_mask), &jack)| {
741 if jack != Ff800AnalogInputJack::Front {
742 quads[1] |= rear_mask;
743 }
744 if jack != Ff800AnalogInputJack::Rear {
745 quads[1] |= front_mask;
746 }
747 });
748
749 quads[0] &= !Q0_LINE_IN_LEVEL_MASK;
750 quads[1] &= !Q1_LINE_IN_LEVEL_MASK;
751 match config.line_level {
752 FormerLineInNominalLevel::Low => {
753 quads[0] |= Q0_LINE_IN_LEVEL_LOW_FLAG;
754 quads[1] |= Q1_LINE_IN_LEVEL_LOW_FLAG;
755 }
756 FormerLineInNominalLevel::Consumer => {
757 quads[0] |= Q0_LINE_IN_LEVEL_CON_FLAG;
758 quads[1] |= Q1_LINE_IN_LEVEL_CON_FLAG;
759 }
760 FormerLineInNominalLevel::Professional => {
761 quads[0] |= Q0_LINE_IN_LEVEL_PRO_FLAG;
762 quads[1] |= Q1_LINE_IN_LEVEL_PRO_FLAG;
763 }
764 }
765
766 if config.phantom_powering[0] {
767 quads[0] |= Q0_INPUT_6_POWERING_MASK;
768 }
769 if config.phantom_powering[1] {
770 quads[0] |= Q0_INPUT_7_POWERING_MASK;
771 }
772 if config.phantom_powering[2] {
773 quads[0] |= Q0_INPUT_8_POWERING_MASK;
774 }
775 if config.phantom_powering[3] {
776 quads[0] |= Q0_INPUT_9_POWERING_MASK;
777 }
778
779 serialize_instrument_config(&config.inst, quads);
780}
781
782fn deserialize_analog_input_config(config: &mut Ff800AnalogInConfig, quads: &[u32]) {
783 assert!(quads.len() >= Ff800AnalogInConfig::QUADLET_COUNT);
784
785 [
786 (Q1_INPUT_0_REAR_JACK_MASK, Q1_INPUT_0_FRONT_JACK_MASK),
787 (Q1_INPUT_6_REAR_JACK_MASK, Q1_INPUT_6_FRONT_JACK_MASK),
788 (Q1_INPUT_7_REAR_JACK_MASK, Q1_INPUT_7_FRONT_JACK_MASK),
789 ]
790 .iter()
791 .zip(&mut config.jacks)
792 .for_each(|(&(rear_mask, front_mask), jack)| {
793 *jack = match (quads[1] & rear_mask > 0, quads[1] & front_mask > 0) {
794 (true, true) => Ff800AnalogInputJack::FrontRear,
795 (true, false) => Ff800AnalogInputJack::Rear,
796 (false, true) => Ff800AnalogInputJack::Front,
797 _ => unreachable!(),
798 };
799 });
800
801 let pair = (
802 quads[0] & Q0_LINE_IN_LEVEL_MASK,
803 quads[1] & Q1_LINE_IN_LEVEL_MASK,
804 );
805 config.line_level = match pair {
806 (Q0_LINE_IN_LEVEL_LOW_FLAG, Q1_LINE_IN_LEVEL_LOW_FLAG) => FormerLineInNominalLevel::Low,
807 (Q0_LINE_IN_LEVEL_CON_FLAG, Q1_LINE_IN_LEVEL_CON_FLAG) => {
808 FormerLineInNominalLevel::Consumer
809 }
810 (Q0_LINE_IN_LEVEL_PRO_FLAG, Q1_LINE_IN_LEVEL_PRO_FLAG) => {
811 FormerLineInNominalLevel::Professional
812 }
813 _ => unreachable!(),
814 };
815
816 config.phantom_powering[0] = quads[0] & Q0_INPUT_6_POWERING_MASK > 0;
817 config.phantom_powering[1] = quads[0] & Q0_INPUT_7_POWERING_MASK > 0;
818 config.phantom_powering[2] = quads[0] & Q0_INPUT_8_POWERING_MASK > 0;
819 config.phantom_powering[3] = quads[0] & Q0_INPUT_9_POWERING_MASK > 0;
820
821 deserialize_instrument_config(&mut config.inst, quads);
822}
823
824#[derive(Debug, Copy, Clone, PartialEq, Eq)]
826pub struct Ff800Config {
827 pub clk: Ff800ClkConfig,
829 pub analog_in: Ff800AnalogInConfig,
831 pub line_out_level: LineOutNominalLevel,
833 pub spdif_in: SpdifInput,
835 pub spdif_out: FormerSpdifOutput,
837 pub opt_out_signal: OpticalOutputSignal,
839 pub word_out_single: bool,
841 continue_at_errors: bool,
843}
844
845impl Default for Ff800Config {
846 fn default() -> Self {
847 Self {
848 clk: Default::default(),
849 analog_in: Default::default(),
850 line_out_level: Default::default(),
851 spdif_in: Default::default(),
852 spdif_out: Default::default(),
853 opt_out_signal: Default::default(),
854 word_out_single: Default::default(),
855 continue_at_errors: true,
856 }
857 }
858}
859
860impl Ff800Config {
861 const QUADLET_COUNT: usize = FORMER_CONFIG_SIZE / 4;
862
863 pub fn init(&mut self, status: &Ff800Status) {
866 self.clk.primary_src = status.configured_clk_src;
867 self.spdif_in = status.spdif_in;
868 self.spdif_out = status.spdif_out;
869 self.opt_out_signal = status.opt_out_signal;
870 self.word_out_single = status.word_out_single;
871 }
872}
873
874impl RmeFfOffsetParamsSerialize<Ff800Config> for Ff800Protocol {
875 fn serialize_offsets(params: &Ff800Config) -> Vec<u8> {
876 let mut quads = [0; Ff800Config::QUADLET_COUNT];
877
878 serialize_clock_config(¶ms.clk, &mut quads);
879 serialize_analog_input_config(¶ms.analog_in, &mut quads);
880
881 quads[0] &= !Q0_LINE_OUT_LEVEL_MASK;
882 quads[1] &= !Q1_LINE_OUT_LEVEL_MASK;
883 match params.line_out_level {
884 LineOutNominalLevel::High => {
885 quads[0] |= Q0_LINE_OUT_LEVEL_HIGH_FLAG;
886 quads[1] |= Q1_LINE_OUT_LEVEL_HIGH_FLAG;
887 }
888 LineOutNominalLevel::Consumer => {
889 quads[0] |= Q0_LINE_OUT_LEVEL_CON_FLAG;
890 quads[1] |= Q1_LINE_OUT_LEVEL_CON_FLAG;
891 }
892 LineOutNominalLevel::Professional => {
893 quads[0] |= Q0_LINE_OUT_LEVEL_PRO_FLAG;
894 quads[1] |= Q1_LINE_OUT_LEVEL_PRO_FLAG;
895 }
896 }
897
898 quads[2] &= !Q2_SPDIF_IN_IFACE_OPT_MASK;
899 if params.spdif_in.iface == SpdifIface::Optical {
900 quads[2] |= Q2_SPDIF_IN_IFACE_OPT_MASK;
901 }
902
903 quads[2] &= !Q2_SPDIF_IN_USE_PREEMBLE;
904 if params.spdif_in.use_preemble {
905 quads[2] |= Q2_SPDIF_IN_USE_PREEMBLE;
906 }
907
908 quads[2] &= !Q2_OPT_OUT_SIGNAL_MASK;
909 if params.opt_out_signal == OpticalOutputSignal::Spdif {
910 quads[2] |= Q2_OPT_OUT_SIGNAL_MASK;
911 }
912
913 quads[2] &= !Q2_SPDIF_OUT_FMT_PRO_MASK;
914 if params.spdif_out.format == SpdifFormat::Professional {
915 quads[2] |= Q2_SPDIF_OUT_FMT_PRO_MASK;
916 }
917
918 quads[2] &= !Q2_SPDIF_OUT_EMPHASIS_MASK;
919 if params.spdif_out.emphasis {
920 quads[2] |= Q2_SPDIF_OUT_EMPHASIS_MASK;
921 }
922
923 quads[2] &= !Q2_SPDIF_OUT_NON_AUDIO_MASK;
924 if params.spdif_out.non_audio {
925 quads[2] |= Q2_SPDIF_OUT_NON_AUDIO_MASK;
926 }
927
928 quads[2] &= !Q2_WORD_OUT_SINGLE_SPEED_MASK;
929 if params.word_out_single {
930 quads[2] |= Q2_WORD_OUT_SINGLE_SPEED_MASK;
931 }
932
933 quads[2] &= !Q2_CONTINUE_AT_ERRORS;
934 if params.continue_at_errors {
935 quads[2] |= Q2_CONTINUE_AT_ERRORS;
936 }
937
938 quads.iter().flat_map(|quad| quad.to_le_bytes()).collect()
939 }
940}
941
942impl RmeFfOffsetParamsDeserialize<Ff800Config> for Ff800Protocol {
943 fn deserialize_offsets(params: &mut Ff800Config, raw: &[u8]) {
944 let mut quads = [0; Ff800Config::QUADLET_COUNT];
945
946 let mut quadlet = [0; 4];
947 quads.iter_mut().enumerate().for_each(|(i, quad)| {
948 let pos = i * 4;
949 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
950 *quad = u32::from_le_bytes(quadlet);
951 });
952
953 deserialize_clock_config(&mut params.clk, &quads);
954 deserialize_analog_input_config(&mut params.analog_in, &quads);
955
956 let pair = (
957 quads[0] & Q0_LINE_OUT_LEVEL_MASK,
958 quads[1] & Q1_LINE_OUT_LEVEL_MASK,
959 );
960 params.line_out_level = match pair {
961 (Q0_LINE_OUT_LEVEL_HIGH_FLAG, Q1_LINE_OUT_LEVEL_HIGH_FLAG) => LineOutNominalLevel::High,
962 (Q0_LINE_OUT_LEVEL_CON_FLAG, Q1_LINE_OUT_LEVEL_CON_FLAG) => {
963 LineOutNominalLevel::Consumer
964 }
965 (Q0_LINE_OUT_LEVEL_PRO_FLAG, Q1_LINE_OUT_LEVEL_PRO_FLAG) => {
966 LineOutNominalLevel::Professional
967 }
968 _ => unreachable!(),
969 };
970
971 params.spdif_in.iface = if quads[2] & Q2_SPDIF_IN_IFACE_OPT_MASK > 0 {
972 SpdifIface::Optical
973 } else {
974 SpdifIface::Coaxial
975 };
976 params.spdif_in.use_preemble = quads[2] & Q2_SPDIF_IN_USE_PREEMBLE > 0;
977
978 params.spdif_out.format = if quads[2] & Q2_SPDIF_OUT_FMT_PRO_MASK > 0 {
979 SpdifFormat::Professional
980 } else {
981 SpdifFormat::Consumer
982 };
983 params.spdif_out.emphasis = quads[2] & Q2_SPDIF_OUT_EMPHASIS_MASK > 0;
984 params.spdif_out.non_audio = quads[2] & Q2_SPDIF_OUT_NON_AUDIO_MASK > 0;
985
986 params.opt_out_signal = if quads[2] & Q2_OPT_OUT_SIGNAL_MASK > 0 {
987 OpticalOutputSignal::Spdif
988 } else {
989 OpticalOutputSignal::Adat
990 };
991
992 params.word_out_single = quads[2] & Q2_WORD_OUT_SINGLE_SPEED_MASK > 0;
993 params.continue_at_errors = quads[2] & Q2_CONTINUE_AT_ERRORS > 0;
994 }
995}
996
997impl RmeFfWhollyUpdatableParamsOperation<Ff800Config> for Ff800Protocol {
998 fn update_wholly(
999 req: &mut FwReq,
1000 node: &mut FwNode,
1001 params: &Ff800Config,
1002 timeout_ms: u32,
1003 ) -> Result<(), Error> {
1004 write_config::<Ff800Protocol, Ff800Config>(req, node, CFG_OFFSET, params, timeout_ms)
1005 }
1006}
1007
1008#[cfg(test)]
1009mod test {
1010 use super::*;
1011
1012 #[test]
1013 fn lock_status_serdes() {
1014 let orig = Ff800ClkLockStatus {
1015 adat_a: true,
1016 adat_b: true,
1017 spdif: true,
1018 word_clock: true,
1019 tco: true,
1020 };
1021 let mut quads = [0; Ff800ClkLockStatus::QUADLET_COUNT];
1022 serialize_lock_status(&orig, &mut quads);
1023 let mut target = Ff800ClkLockStatus::default();
1024 deserialize_lock_status(&mut target, &quads);
1025
1026 assert_eq!(target, orig);
1027 }
1028
1029 #[test]
1030 fn sync_status_serdes() {
1031 let orig = Ff800ClkSyncStatus {
1032 adat_a: true,
1033 adat_b: true,
1034 spdif: true,
1035 word_clock: true,
1036 tco: true,
1037 };
1038 let mut quads = [0; Ff800ClkSyncStatus::QUADLET_COUNT];
1039 serialize_sync_status(&orig, &mut quads);
1040 let mut target = Ff800ClkSyncStatus::default();
1041 deserialize_sync_status(&mut target, &quads);
1042
1043 assert_eq!(target, orig);
1044 }
1045
1046 fn quads_to_bytes(quads: &[u32]) -> Vec<u8> {
1047 quads.iter().flat_map(|quad| quad.to_le_bytes()).collect()
1048 }
1049
1050 #[test]
1051 fn status_serdes() {
1052 let mut status = Ff800Status::default();
1053
1054 let quads = [0x02001000, 0x00000000];
1055 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1056 assert_eq!(status.lock.adat_a, true);
1057
1058 let quads = [0x02002000, 0x00000000];
1059 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1060 assert_eq!(status.lock.adat_b, true);
1061
1062 let quads = [0x02040000, 0x00000000];
1063 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1064 assert_eq!(status.lock.spdif, true);
1065
1066 let quads = [0x22000000, 0x00000000];
1067 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1068 assert_eq!(status.lock.word_clock, true);
1069
1070 let quads = [0x02000400, 0x00000000];
1071 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1072 assert_eq!(status.sync.adat_a, true);
1073
1074 let quads = [0x02000800, 0x00000000];
1075 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1076 assert_eq!(status.sync.adat_b, true);
1077
1078 let quads = [0x02100800, 0x00000000];
1079 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1080 assert_eq!(status.sync.spdif, true);
1081
1082 let quads = [0x42000000, 0x00000000];
1083 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1084 assert_eq!(status.sync.word_clock, true);
1085
1086 let quads = [0x02000000, 0x00800000];
1087 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1088 assert_eq!(status.sync.tco, true);
1089
1090 let quads = [0x02004000, 0x00000000];
1091 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1092 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R32000));
1093
1094 let quads = [0x02008000, 0x00000000];
1095 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1096 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R44100));
1097
1098 let quads = [0x0200c000, 0x00000000];
1099 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1100 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R48000));
1101
1102 let quads = [0x02010000, 0x00000000];
1103 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1104 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R64000));
1105
1106 let quads = [0x02014000, 0x00000000];
1107 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1108 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R88200));
1109
1110 let quads = [0x02018000, 0x00000000];
1111 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1112 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R96000));
1113
1114 let quads = [0x0201c000, 0x00000000];
1115 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1116 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R128000));
1117
1118 let quads = [0x02020000, 0x00000000];
1119 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1120 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R176400));
1121
1122 let quads = [0x02024000, 0x00000000];
1123 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1124 assert_eq!(status.spdif_rate, Some(ClkNominalRate::R192000));
1125
1126 let quads = [0x02000000, 0x00000000];
1127 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1128 assert_eq!(status.active_clk_src, Ff800ClkSrc::AdatA);
1129
1130 let quads = [0x02400000, 0x00000000];
1131 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1132 assert_eq!(status.active_clk_src, Ff800ClkSrc::AdatB);
1133
1134 let quads = [0x02c00000, 0x00000000];
1135 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1136 assert_eq!(status.active_clk_src, Ff800ClkSrc::Spdif);
1137
1138 let quads = [0x03000000, 0x00000000];
1139 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1140 assert_eq!(status.active_clk_src, Ff800ClkSrc::WordClock);
1141
1142 let quads = [0x03800000, 0x00000000];
1143 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1144 assert_eq!(status.active_clk_src, Ff800ClkSrc::Tco);
1145
1146 let quads = [0x03c00000, 0x00000000];
1147 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1148 assert_eq!(status.active_clk_src, Ff800ClkSrc::Internal);
1149
1150 let quads = [0x02000000, 0x00000000];
1151 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1152 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R32000));
1153
1154 let quads = [0x04000000, 0x00000000];
1155 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1156 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R44100));
1157
1158 let quads = [0x06000000, 0x00000000];
1159 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1160 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R48000));
1161
1162 let quads = [0x08000000, 0x00000000];
1163 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1164 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R64000));
1165
1166 let quads = [0x0a000000, 0x00000000];
1167 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1168 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R88200));
1169
1170 let quads = [0x0e000000, 0x00000000];
1171 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1172 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R96000));
1173
1174 let quads = [0x0c000000, 0x00000000];
1175 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1176 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R128000));
1177
1178 let quads = [0x10000000, 0x00000000];
1179 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1180 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R176400));
1181
1182 let quads = [0x12000000, 0x00000000];
1183 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1184 assert_eq!(status.external_clk_rate, Some(ClkNominalRate::R192000));
1185
1186 let quads = [0x02000000, 0x00400000];
1187 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1188 assert_eq!(status.lock.tco, true);
1189
1190 let quads = [0x02000000, 0x00800000];
1191 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1192 assert_eq!(status.sync.tco, true);
1193
1194 let quads = [0x02000000, 0x00002000];
1195 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1196 assert_eq!(status.word_out_single, true);
1197
1198 let quads = [0x02000000, 0x00000200];
1199 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1200 assert_eq!(status.spdif_in.iface, SpdifIface::Optical);
1201
1202 let quads = [0x02000000, 0x00000100];
1203 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1204 assert_eq!(status.opt_out_signal, OpticalOutputSignal::Spdif);
1205
1206 let quads = [0x02000000, 0x00000040];
1207 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1208 assert_eq!(status.spdif_out.emphasis, true);
1209
1210 let quads = [0x02000000, 0x00000020];
1211 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1212 assert_eq!(status.spdif_out.format, SpdifFormat::Professional);
1213
1214 let quads = [0x02000000, 0x00000002];
1215 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1216 assert_eq!(status.configured_clk_rate, ClkNominalRate::R32000);
1217
1218 let quads = [0x02000000, 0x00000000];
1219 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1220 assert_eq!(status.configured_clk_rate, ClkNominalRate::R44100);
1221
1222 let quads = [0x02000000, 0x00000006];
1223 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1224 assert_eq!(status.configured_clk_rate, ClkNominalRate::R48000);
1225
1226 let quads = [0x02000000, 0x0000000a];
1227 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1228 assert_eq!(status.configured_clk_rate, ClkNominalRate::R64000);
1229
1230 let quads = [0x02000000, 0x00000008];
1231 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1232 assert_eq!(status.configured_clk_rate, ClkNominalRate::R88200);
1233
1234 let quads = [0x02000000, 0x0000000e];
1235 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1236 assert_eq!(status.configured_clk_rate, ClkNominalRate::R96000);
1237
1238 let quads = [0x02000000, 0x00000012];
1239 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1240 assert_eq!(status.configured_clk_rate, ClkNominalRate::R128000);
1241
1242 let quads = [0x02000000, 0x00000010];
1243 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1244 assert_eq!(status.configured_clk_rate, ClkNominalRate::R176400);
1245
1246 let quads = [0x02000000, 0x00000016];
1247 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1248 assert_eq!(status.configured_clk_rate, ClkNominalRate::R192000);
1249
1250 let quads = [0x02000000, 0x00001000];
1251 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1252 assert_eq!(status.configured_clk_src, Ff800ClkSrc::WordClock);
1253
1254 let quads = [0x02000000, 0x00001800];
1255 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1256 assert_eq!(status.configured_clk_src, Ff800ClkSrc::Tco);
1257
1258 let quads = [0x02000000, 0x00000c00];
1259 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1260 assert_eq!(status.configured_clk_src, Ff800ClkSrc::Spdif);
1261
1262 let quads = [0x02000000, 0x00000400];
1263 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1264 assert_eq!(status.configured_clk_src, Ff800ClkSrc::AdatB);
1265
1266 let quads = [0x02000000, 0x00000001];
1267 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1268 assert_eq!(status.configured_clk_src, Ff800ClkSrc::Internal);
1269
1270 let quads = [0x02000000, 0x00000000];
1271 Ff800Protocol::deserialize_offsets(&mut status, &quads_to_bytes(&quads));
1272 assert_eq!(status.configured_clk_src, Ff800ClkSrc::AdatA);
1273
1274 let raw = Ff800Protocol::serialize_offsets(&status);
1275 let mut target = Ff800Status::default();
1276 Ff800Protocol::deserialize_offsets(&mut target, &raw);
1277 assert_eq!(target, status);
1278 }
1279
1280 #[test]
1281 fn clock_config_serdes() {
1282 let mut orig = Ff800ClkConfig::default();
1283 let mut cfg = Ff800ClkConfig::default();
1284
1285 orig.primary_src = Ff800ClkSrc::Internal;
1286 let mut quads = [0u32; 3];
1287 serialize_clock_config(&orig, &mut quads);
1288 assert_eq!(quads[2], 0x0000001f);
1289 deserialize_clock_config(&mut cfg, &quads);
1290 assert_eq!(cfg, orig);
1291
1292 orig.primary_src = Ff800ClkSrc::WordClock;
1293 let mut quads = [0u32; 3];
1294 serialize_clock_config(&orig, &mut quads);
1295 assert_eq!(quads[2], 0x0000141e);
1296 deserialize_clock_config(&mut cfg, &quads);
1297 assert_eq!(cfg, orig);
1298
1299 orig.primary_src = Ff800ClkSrc::AdatA;
1300 let mut quads = [0u32; 3];
1301 serialize_clock_config(&orig, &mut quads);
1302 assert_eq!(quads[2], 0x0000001e);
1303 deserialize_clock_config(&mut cfg, &quads);
1304 assert_eq!(cfg, orig);
1305
1306 orig.primary_src = Ff800ClkSrc::AdatB;
1307 let mut quads = [0u32; 3];
1308 serialize_clock_config(&orig, &mut quads);
1309 assert_eq!(quads[2], 0x0000041e);
1310 deserialize_clock_config(&mut cfg, &quads);
1311 assert_eq!(cfg, orig);
1312
1313 orig.primary_src = Ff800ClkSrc::Spdif;
1314 let mut quads = [0u32; 3];
1315 serialize_clock_config(&orig, &mut quads);
1316 assert_eq!(quads[2], 0x00000c1e);
1317 deserialize_clock_config(&mut cfg, &quads);
1318 assert_eq!(cfg, orig);
1319
1320 orig.primary_src = Ff800ClkSrc::Tco;
1321 let mut quads = [0u32; 3];
1322 serialize_clock_config(&orig, &mut quads);
1323 assert_eq!(quads[2], 0x00001c1e);
1324 deserialize_clock_config(&mut cfg, &quads);
1325 assert_eq!(cfg, orig);
1326 }
1327
1328 #[test]
1329 fn instrument_config_serdes() {
1330 let mut orig = Ff800InstConfig::default();
1331 let mut cfg = Ff800InstConfig::default();
1332
1333 orig.drive = false;
1334 orig.limitter = false;
1335 orig.speaker_emulation = false;
1336 let mut quads = [0u32; 3];
1337 serialize_instrument_config(&orig, &mut quads);
1338 assert_eq!(&quads[..], &[0x00000000, 0x00000000, 0x00000000]);
1339 deserialize_instrument_config(&mut cfg, &quads);
1340 assert_eq!(cfg, orig);
1341
1342 orig.drive = true;
1343 let mut quads = [0u32; 3];
1344 serialize_instrument_config(&orig, &mut quads);
1345 assert_eq!(&quads[..], &[0x00000200, 0x00000200, 0x00000000]);
1346 deserialize_instrument_config(&mut cfg, &quads);
1347 assert_eq!(cfg, orig);
1348
1349 orig.limitter = true;
1350 let mut quads = [0u32; 3];
1351 serialize_instrument_config(&orig, &mut quads);
1352 assert_eq!(&quads[..], &[0x00000200, 0x00000200, 0x00010000]);
1353 deserialize_instrument_config(&mut cfg, &quads);
1354 assert_eq!(cfg, orig);
1355
1356 orig.speaker_emulation = true;
1357 let mut quads = [0u32; 3];
1358 serialize_instrument_config(&orig, &mut quads);
1359 assert_eq!(&quads[..], &[0x00000204, 0x00000200, 0x00010000]);
1360 deserialize_instrument_config(&mut cfg, &quads);
1361 assert_eq!(cfg, orig);
1362 }
1363
1364 #[test]
1365 fn analog_input_config_serdes() {
1366 let mut orig = Ff800AnalogInConfig::default();
1367 let mut cfg = Ff800AnalogInConfig::default();
1368
1369 orig.jacks[0] = Ff800AnalogInputJack::FrontRear;
1370 let mut quads = [0u32; 3];
1371 serialize_analog_input_config(&orig, &mut quads);
1372 assert_eq!(&quads[..], &[0x00000008, 0x000008a4, 0x00000000]);
1373 deserialize_analog_input_config(&mut cfg, &quads);
1374 assert_eq!(cfg, orig);
1375
1376 orig.jacks[1] = Ff800AnalogInputJack::FrontRear;
1377 let mut quads = [0u32; 3];
1378 serialize_analog_input_config(&orig, &mut quads);
1379 assert_eq!(&quads[..], &[0x00000008, 0x000008e4, 0x00000000]);
1380 deserialize_analog_input_config(&mut cfg, &quads);
1381 assert_eq!(cfg, orig);
1382
1383 orig.jacks[2] = Ff800AnalogInputJack::FrontRear;
1384 let mut quads = [0u32; 3];
1385 serialize_analog_input_config(&orig, &mut quads);
1386 assert_eq!(&quads[..], &[0x00000008, 0x000009e4, 0x00000000]);
1387 deserialize_analog_input_config(&mut cfg, &quads);
1388 assert_eq!(cfg, orig);
1389
1390 orig.line_level = FormerLineInNominalLevel::Consumer;
1391 let mut quads = [0u32; 3];
1392 serialize_analog_input_config(&orig, &mut quads);
1393 assert_eq!(&quads[..], &[0x00000020, 0x000009e7, 0x00000000]);
1394 deserialize_analog_input_config(&mut cfg, &quads);
1395 assert_eq!(cfg, orig);
1396
1397 orig.line_level = FormerLineInNominalLevel::Professional;
1398 let mut quads = [0u32; 3];
1399 serialize_analog_input_config(&orig, &mut quads);
1400 assert_eq!(&quads[..], &[0x00000010, 0x000009e6, 0x00000000]);
1401 deserialize_analog_input_config(&mut cfg, &quads);
1402 assert_eq!(cfg, orig);
1403
1404 orig.phantom_powering[0] = true;
1405 let mut quads = [0u32; 3];
1406 serialize_analog_input_config(&orig, &mut quads);
1407 assert_eq!(&quads[..], &[0x00000011, 0x000009e6, 0x00000000]);
1408 deserialize_analog_input_config(&mut cfg, &quads);
1409 assert_eq!(cfg, orig);
1410
1411 orig.phantom_powering[1] = true;
1412 let mut quads = [0u32; 3];
1413 serialize_analog_input_config(&orig, &mut quads);
1414 assert_eq!(&quads[..], &[0x00000091, 0x000009e6, 0x00000000]);
1415 deserialize_analog_input_config(&mut cfg, &quads);
1416 assert_eq!(cfg, orig);
1417
1418 orig.phantom_powering[2] = true;
1419 let mut quads = [0u32; 3];
1420 serialize_analog_input_config(&orig, &mut quads);
1421 assert_eq!(&quads[..], &[0x00000093, 0x000009e6, 0x00000000]);
1422 deserialize_analog_input_config(&mut cfg, &quads);
1423 assert_eq!(cfg, orig);
1424
1425 orig.phantom_powering[3] = true;
1426 let mut quads = [0u32; 3];
1427 serialize_analog_input_config(&orig, &mut quads);
1428 assert_eq!(&quads[..], &[0x00000193, 0x000009e6, 0x00000000]);
1429 deserialize_analog_input_config(&mut cfg, &quads);
1430 assert_eq!(cfg, orig);
1431 }
1432
1433 fn config_to_quads(raw: &[u8]) -> Vec<u32> {
1434 let mut quadlet = [0; 4];
1435 (0..Ff800Config::QUADLET_COUNT)
1436 .map(|i| {
1437 let pos = i * 4;
1438 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1439 u32::from_le_bytes(quadlet)
1440 })
1441 .collect()
1442 }
1443
1444 #[test]
1445 fn config_serdes() {
1446 let mut orig = Ff800Config::default();
1447 let mut cfg = Ff800Config::default();
1448
1449 orig.line_out_level = LineOutNominalLevel::High;
1450 let raw = Ff800Protocol::serialize_offsets(&orig);
1451 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1452 assert_eq!(cfg, orig);
1453 let quads = config_to_quads(&raw);
1454 assert_eq!(&quads[..], &[0x00000408, 0x000008b0, 0x8000001e]);
1455
1456 orig.line_out_level = LineOutNominalLevel::Consumer;
1457 let raw = Ff800Protocol::serialize_offsets(&orig);
1458 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1459 assert_eq!(cfg, orig);
1460 let quads = config_to_quads(&raw);
1461 assert_eq!(&quads[..], &[0x00001008, 0x000008a8, 0x8000001e]);
1462
1463 orig.line_out_level = LineOutNominalLevel::Professional;
1464 let raw = Ff800Protocol::serialize_offsets(&orig);
1465 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1466 assert_eq!(cfg, orig);
1467 let quads = config_to_quads(&raw);
1468 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0x8000001e]);
1469
1470 orig.spdif_in.iface = SpdifIface::Optical;
1471 let raw = Ff800Protocol::serialize_offsets(&orig);
1472 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1473 assert_eq!(cfg, orig);
1474 let quads = config_to_quads(&raw);
1475 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0x8000021e]);
1476
1477 orig.spdif_in.use_preemble = true;
1478 let raw = Ff800Protocol::serialize_offsets(&orig);
1479 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1480 assert_eq!(cfg, orig);
1481 let quads = config_to_quads(&raw);
1482 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0xc000021e]);
1483
1484 orig.opt_out_signal = OpticalOutputSignal::Spdif;
1485 let raw = Ff800Protocol::serialize_offsets(&orig);
1486 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1487 assert_eq!(cfg, orig);
1488 let quads = config_to_quads(&raw);
1489 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0xc000031e]);
1490
1491 orig.spdif_out.format = SpdifFormat::Professional;
1492 let raw = Ff800Protocol::serialize_offsets(&orig);
1493 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1494 assert_eq!(cfg, orig);
1495 let quads = config_to_quads(&raw);
1496 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0xc000033e]);
1497
1498 orig.spdif_out.emphasis = true;
1499 let raw = Ff800Protocol::serialize_offsets(&orig);
1500 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1501 assert_eq!(cfg, orig);
1502 let quads = config_to_quads(&raw);
1503 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0xc000037e]);
1504
1505 orig.spdif_out.non_audio = true;
1506 let raw = Ff800Protocol::serialize_offsets(&orig);
1507 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1508 assert_eq!(cfg, orig);
1509 let quads = config_to_quads(&raw);
1510 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0xc00003fe]);
1511
1512 orig.word_out_single = true;
1513 let raw = Ff800Protocol::serialize_offsets(&orig);
1514 Ff800Protocol::deserialize_offsets(&mut cfg, &raw);
1515 assert_eq!(cfg, orig);
1516 let quads = config_to_quads(&raw);
1517 assert_eq!(&quads[..], &[0x00000808, 0x000008b8, 0xc00023fe]);
1518 }
1519}