1use super::{
87 tcat::{extension::*, tcd22xx_spec::*, *},
88 *,
89};
90
91#[derive(Default, Debug)]
115pub struct Mbox3Protocol;
116
117impl TcatOperation for Mbox3Protocol {}
118
119impl TcatGlobalSectionSpecification for Mbox3Protocol {}
120
121impl TcatExtensionOperation for Mbox3Protocol {}
122
123impl Tcd22xxSpecification for Mbox3Protocol {
124 const INPUTS: &'static [Input] = &[
125 Input {
126 id: SrcBlkId::Ins0,
127 offset: 0,
128 count: 6,
129 label: None,
130 },
131 Input {
132 id: SrcBlkId::Ins1,
133 offset: 0,
134 count: 2,
135 label: Some("Reverb"),
136 },
137 Input {
138 id: SrcBlkId::Aes,
139 offset: 0,
140 count: 2,
141 label: None,
142 },
143 ];
144 const OUTPUTS: &'static [Output] = &[
145 Output {
146 id: DstBlkId::Ins0,
147 offset: 0,
148 count: 6,
149 label: None,
150 },
151 Output {
152 id: DstBlkId::Ins1,
153 offset: 0,
154 count: 4,
155 label: Some("Headphone"),
156 },
157 Output {
158 id: DstBlkId::Ins1,
159 offset: 4,
160 count: 2,
161 label: Some("Reverb"),
162 },
163 Output {
164 id: DstBlkId::Aes,
165 offset: 0,
166 count: 2,
167 label: None,
168 },
169 Output {
170 id: DstBlkId::Reserved(0x08),
171 offset: 0,
172 count: 2,
173 label: Some("ControlRoom"),
174 },
175 ];
176 const FIXED: &'static [SrcBlk] = &[
177 SrcBlk {
178 id: SrcBlkId::Ins0,
179 ch: 0,
180 },
181 SrcBlk {
182 id: SrcBlkId::Ins0,
183 ch: 1,
184 },
185 SrcBlk {
186 id: SrcBlkId::Ins0,
187 ch: 2,
188 },
189 SrcBlk {
190 id: SrcBlkId::Ins0,
191 ch: 3,
192 },
193 ];
194}
195
196#[derive(Debug, Copy, Clone, PartialEq, Eq)]
198pub enum StandaloneUseCase {
199 Preamp,
201 AdDa,
203 Mixer,
205 Undefined,
207}
208
209impl Default for StandaloneUseCase {
210 fn default() -> Self {
211 Self::Preamp
212 }
213}
214
215impl StandaloneUseCase {
216 const MIXER: u32 = 0x00;
217 const AD_DA: u32 = 0x01;
218 const PREAMP: u32 = 0x02;
219 const UNDEFINED: u32 = 0x03;
220
221 const MASK: u32 = 0x03;
222}
223
224fn serialize_standalone_use_case(
225 use_case: &StandaloneUseCase,
226 raw: &mut [u8],
227) -> Result<(), String> {
228 assert!(raw.len() >= 4);
229
230 let mut val = 0u32;
231 deserialize_u32(&mut val, raw);
232
233 let flag = match use_case {
234 StandaloneUseCase::Mixer => StandaloneUseCase::MIXER,
235 StandaloneUseCase::AdDa => StandaloneUseCase::AD_DA,
236 StandaloneUseCase::Preamp => StandaloneUseCase::PREAMP,
237 StandaloneUseCase::Undefined => StandaloneUseCase::UNDEFINED,
238 };
239
240 val &= !StandaloneUseCase::MASK;
241 val |= flag;
242 serialize_u32(&val, raw);
243
244 Ok(())
245}
246
247fn deserialize_standalone_use_case(
248 use_case: &mut StandaloneUseCase,
249 raw: &[u8],
250) -> Result<(), String> {
251 assert!(raw.len() >= 4);
252
253 let mut val = 0u32;
254 deserialize_u32(&mut val, raw);
255
256 val &= StandaloneUseCase::MASK;
257 *use_case = match val {
258 StandaloneUseCase::MIXER => StandaloneUseCase::Mixer,
259 StandaloneUseCase::AD_DA => StandaloneUseCase::AdDa,
260 StandaloneUseCase::PREAMP => StandaloneUseCase::Preamp,
261 _ => StandaloneUseCase::Undefined,
262 };
263
264 Ok(())
265}
266
267const MASTER_KNOB_MASK: u32 = 0x0000003f;
268
269fn serialize_master_knob_assigns(assigns: &[bool; 6], raw: &mut [u8]) -> Result<(), String> {
270 assert!(raw.len() >= 4);
271
272 let mut val = 0u32;
273 deserialize_u32(&mut val, raw);
274 val &= !MASTER_KNOB_MASK;
275
276 assigns
277 .iter()
278 .enumerate()
279 .filter(|(_, &assign)| assign)
280 .for_each(|(i, _)| val |= 1 << i);
281 serialize_u32(&val, raw);
282
283 Ok(())
284}
285
286fn deserialize_master_knob_assigns(assigns: &mut [bool; 6], raw: &[u8]) -> Result<(), String> {
287 assert!(raw.len() >= 4);
288
289 let mut val = 0u32;
290 deserialize_u32(&mut val, raw);
291 assigns
292 .iter_mut()
293 .enumerate()
294 .for_each(|(i, assign)| *assign = val & (1 << i) > 0);
295
296 Ok(())
297}
298
299#[derive(Debug, Copy, Clone, PartialEq, Eq)]
301pub enum MuteLedState {
302 Off,
304 Blink,
306 On,
308}
309
310impl Default for MuteLedState {
311 fn default() -> Self {
312 Self::Off
313 }
314}
315
316impl MuteLedState {
317 const LED_MASK: u32 = 0x00000003;
318 const LED_BLINK_MASK: u32 = 0x00000001;
319}
320
321fn serialize_mute_led_state(state: &MuteLedState, raw: &mut [u8]) -> Result<(), String> {
322 assert!(raw.len() >= 4);
323
324 let mut val = 0u32;
325 deserialize_u32(&mut val, raw);
326 val &= !MuteLedState::LED_MASK;
327
328 match state {
329 MuteLedState::Off => (),
330 MuteLedState::Blink => val |= MuteLedState::LED_BLINK_MASK,
331 MuteLedState::On => val |= MuteLedState::LED_MASK & !MuteLedState::LED_BLINK_MASK,
332 }
333
334 serialize_u32(&val, raw);
335
336 Ok(())
337}
338
339fn deserialize_mute_led_state(state: &mut MuteLedState, raw: &[u8]) -> Result<(), String> {
340 assert!(raw.len() >= 4);
341
342 let mut val = 0u32;
343 deserialize_u32(&mut val, raw);
344
345 *state = if val & MuteLedState::LED_MASK == 0 {
346 MuteLedState::Off
347 } else if val & MuteLedState::LED_BLINK_MASK > 0 {
348 MuteLedState::Blink
349 } else {
350 MuteLedState::On
351 };
352
353 Ok(())
354}
355
356#[derive(Debug, Copy, Clone, PartialEq, Eq)]
358pub enum MonoLedState {
359 Off,
361 On,
363}
364
365impl Default for MonoLedState {
366 fn default() -> Self {
367 Self::Off
368 }
369}
370
371impl MonoLedState {
372 const LED_MASK: u32 = 0x0000000c;
373}
374
375fn serialize_mono_led_state(state: &MonoLedState, raw: &mut [u8]) -> Result<(), String> {
376 assert!(raw.len() >= 4);
377
378 let mut val = 0u32;
379 deserialize_u32(&mut val, raw);
380 val &= !MonoLedState::LED_MASK;
381
382 match state {
383 MonoLedState::Off => (),
384 MonoLedState::On => val |= MonoLedState::LED_MASK,
385 }
386
387 serialize_u32(&val, raw);
388
389 Ok(())
390}
391
392fn deserialize_mono_led_state(state: &mut MonoLedState, raw: &[u8]) -> Result<(), String> {
393 assert!(raw.len() >= 4);
394
395 let mut val = 0u32;
396 deserialize_u32(&mut val, raw);
397
398 *state = if val & MonoLedState::LED_MASK > 0 {
399 MonoLedState::On
400 } else {
401 MonoLedState::Off
402 };
403
404 Ok(())
405}
406
407#[derive(Debug, Copy, Clone, PartialEq, Eq)]
409pub enum SpkrLedState {
410 Off,
412 Green,
414 GreenBlink,
416 Red,
418 RedBlink,
420 Orange,
422 OrangeBlink,
424}
425
426impl Default for SpkrLedState {
427 fn default() -> Self {
428 Self::Off
429 }
430}
431
432impl SpkrLedState {
433 const COLOR_MASK: u32 = 0x00000060;
434 const COLOR_SHIFT: usize = 5;
435 const BLINK_MASK: u32 = 0x00000010;
436 const BLINK_SHIFT: u32 = 4;
437
438 const NONE: u32 = 0;
439 const GREEN: u32 = 1;
440 const RED: u32 = 2;
441 const ORANGE: u32 = 3;
442}
443
444fn serialize_spkr_led_state(state: &SpkrLedState, raw: &mut [u8]) -> Result<(), String> {
445 assert!(raw.len() >= 4);
446
447 let mut val = 0u32;
448 deserialize_u32(&mut val, raw);
449 val &= !(SpkrLedState::COLOR_MASK | SpkrLedState::BLINK_MASK);
450
451 let (color, blink) = match state {
452 SpkrLedState::GreenBlink => (SpkrLedState::GREEN, true),
453 SpkrLedState::Green => (SpkrLedState::GREEN, false),
454 SpkrLedState::RedBlink => (SpkrLedState::RED, true),
455 SpkrLedState::Red => (SpkrLedState::RED, false),
456 SpkrLedState::OrangeBlink => (SpkrLedState::RED, true),
457 SpkrLedState::Orange => (SpkrLedState::ORANGE, false),
458 SpkrLedState::Off => (SpkrLedState::NONE, false),
459 };
460
461 val |= color << SpkrLedState::COLOR_SHIFT;
462 if blink {
463 val |= SpkrLedState::BLINK_MASK;
464 }
465
466 serialize_u32(&val, raw);
467
468 Ok(())
469}
470
471fn deserialize_spkr_led_state(state: &mut SpkrLedState, raw: &[u8]) -> Result<(), String> {
472 assert!(raw.len() >= 4);
473
474 let mut val = 0u32;
475 deserialize_u32(&mut val, raw);
476
477 let color = (val & SpkrLedState::COLOR_MASK) >> SpkrLedState::COLOR_SHIFT;
478 let blink = (val & SpkrLedState::BLINK_MASK) >> SpkrLedState::BLINK_SHIFT > 0;
479
480 *state = match color {
481 SpkrLedState::NONE => SpkrLedState::Off,
482 SpkrLedState::GREEN => {
483 if blink {
484 SpkrLedState::GreenBlink
485 } else {
486 SpkrLedState::Green
487 }
488 }
489 SpkrLedState::RED => {
490 if blink {
491 SpkrLedState::RedBlink
492 } else {
493 SpkrLedState::Red
494 }
495 }
496 SpkrLedState::ORANGE => {
497 if blink {
498 SpkrLedState::OrangeBlink
499 } else {
500 SpkrLedState::Orange
501 }
502 }
503 _ => Err(format!("Speaker LED state not found for value {}", val))?,
504 };
505
506 Ok(())
507}
508
509const PHANTOM_POWERING_MASK: u32 = 0x00000001;
510const INPUT_HPF_ENABLES_MASK: u32 = 0x000000f0;
511const INPUT_HPF_ENABLES_SHIFT: usize = 4;
512
513fn serialize_phantom_powering(enable: &bool, raw: &mut [u8]) -> Result<(), String> {
514 assert!(raw.len() >= 4);
515
516 let mut val = 0u32;
517 deserialize_u32(&mut val, raw);
518 val &= !PHANTOM_POWERING_MASK;
519
520 if *enable {
521 val |= PHANTOM_POWERING_MASK;
522 }
523
524 serialize_u32(&val, raw);
525
526 Ok(())
527}
528
529fn deserialize_phantom_powering(enable: &mut bool, raw: &[u8]) -> Result<(), String> {
530 assert!(raw.len() >= 4);
531
532 let mut val = 0u32;
533 deserialize_u32(&mut val, raw);
534
535 *enable = val & PHANTOM_POWERING_MASK > 0;
536
537 Ok(())
538}
539
540fn serialize_hpf_enables(enables: &[bool; 4], raw: &mut [u8]) -> Result<(), String> {
541 assert!(raw.len() >= 4);
542
543 let mut val = 0u32;
544 deserialize_u32(&mut val, raw);
545 val &= !INPUT_HPF_ENABLES_MASK;
546
547 enables
548 .iter()
549 .enumerate()
550 .filter(|(_, &enabled)| enabled)
551 .for_each(|(i, _)| val |= 1 << (i + INPUT_HPF_ENABLES_SHIFT));
552
553 serialize_u32(&val, raw);
554
555 Ok(())
556}
557
558fn deserialize_hpf_enables(enables: &mut [bool; 4], raw: &[u8]) -> Result<(), String> {
559 assert!(raw.len() >= 4);
560
561 let mut val = 0u32;
562 deserialize_u32(&mut val, raw);
563
564 enables
565 .iter_mut()
566 .enumerate()
567 .for_each(|(i, enabled)| *enabled = val & (1 << (i + INPUT_HPF_ENABLES_SHIFT)) > 0);
568
569 Ok(())
570}
571
572fn serialize_output_trims(trims: &[u8; 6], raw: &mut [u8]) -> Result<(), String> {
573 assert!(raw.len() >= 24);
574
575 trims.iter().enumerate().for_each(|(i, &trim)| {
576 let pos = i * 4;
577 serialize_u8(&(u8::MAX - trim), &mut raw[pos..(pos + 4)]);
578 });
579
580 Ok(())
581}
582
583fn deserialize_output_trims(trims: &mut [u8; 6], raw: &[u8]) -> Result<(), String> {
584 assert!(raw.len() >= 24);
585
586 let mut val = 0u8;
587 trims.iter_mut().enumerate().for_each(|(i, trim)| {
588 let pos = i * 4;
589 deserialize_u8(&mut val, &raw[pos..(pos + 4)]);
590 *trim = u8::MAX - val;
591 });
592
593 Ok(())
594}
595
596#[derive(Debug, Copy, Clone, PartialEq, Eq)]
598pub enum ReverbType {
599 Room1,
601 Room2,
603 Room3,
605 Hall1,
607 Hall2,
609 Plate,
611 Delay,
613 Echo,
615}
616
617impl Default for ReverbType {
618 fn default() -> Self {
619 Self::Room1
620 }
621}
622
623impl ReverbType {
624 const ROOM_1: u32 = 0x01;
625 const ROOM_2: u32 = 0x04;
626 const ROOM_3: u32 = 0x05;
627 const HALL_1: u32 = 0x06;
628 const HALL_2: u32 = 0x08;
629 const PLATE: u32 = 0x0b;
630 const DELAY: u32 = 0x13;
631 const ECHO: u32 = 0x14;
632}
633
634fn serialize_reverb_type(reverb_type: &ReverbType, raw: &mut [u8]) -> Result<(), String> {
635 assert!(raw.len() >= 4);
636
637 let val = match reverb_type {
638 ReverbType::Room1 => ReverbType::ROOM_1,
639 ReverbType::Room2 => ReverbType::ROOM_2,
640 ReverbType::Room3 => ReverbType::ROOM_3,
641 ReverbType::Hall1 => ReverbType::HALL_1,
642 ReverbType::Hall2 => ReverbType::HALL_2,
643 ReverbType::Plate => ReverbType::PLATE,
644 ReverbType::Delay => ReverbType::DELAY,
645 ReverbType::Echo => ReverbType::ECHO,
646 };
647 serialize_u32(&val, raw);
648
649 Ok(())
650}
651
652fn deserialize_reverb_type(reverb_type: &mut ReverbType, raw: &[u8]) -> Result<(), String> {
653 assert!(raw.len() >= 4);
654
655 let mut val = 0u32;
656 deserialize_u32(&mut val, raw);
657
658 *reverb_type = match val {
659 ReverbType::ROOM_1 => ReverbType::Room1,
660 ReverbType::ROOM_2 => ReverbType::Room2,
661 ReverbType::ROOM_3 => ReverbType::Room3,
662 ReverbType::HALL_1 => ReverbType::Hall1,
663 ReverbType::HALL_2 => ReverbType::Hall2,
664 ReverbType::PLATE => ReverbType::Plate,
665 ReverbType::DELAY => ReverbType::Delay,
666 ReverbType::ECHO => ReverbType::Echo,
667 _ => Err(format!("Reverb type not found for value {}", val))?,
668 };
669
670 Ok(())
671}
672
673#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
675pub struct Mbox3SpecificParams {
676 pub standalone_use_case: StandaloneUseCase,
678 pub master_knob_value: u8,
680 pub master_knob_assigns: [bool; 6],
682 pub mute_led: MuteLedState,
684 pub mono_led: MonoLedState,
686 pub spkr_led: SpkrLedState,
688 pub dim_led: bool,
690 pub duration_hold: u8,
692 pub phantom_powering: bool,
694 pub hpf_enables: [bool; 4],
696 pub output_trims: [u8; 6],
698 pub reverb_type: ReverbType,
700 pub reverb_volume: u8,
702 pub reverb_duration: u8,
704 pub reverb_feedback: u8,
706}
707
708const MIN_SIZE: usize = 0x50;
709
710fn serialize(params: &Mbox3SpecificParams, raw: &mut [u8]) -> Result<(), String> {
711 assert!(raw.len() >= MIN_SIZE);
712
713 serialize_standalone_use_case(¶ms.standalone_use_case, &mut raw[..0x04])?;
714 serialize_u8(¶ms.master_knob_value, &mut raw[0x08..0x0c]);
715 serialize_master_knob_assigns(¶ms.master_knob_assigns, &mut raw[0x0c..0x10])?;
716 serialize_mute_led_state(¶ms.mute_led, &mut raw[0x10..0x14])?;
717 serialize_mono_led_state(¶ms.mono_led, &mut raw[0x14..0x18])?;
718 serialize_spkr_led_state(¶ms.spkr_led, &mut raw[0x14..0x18])?;
719 serialize_bool(¶ms.dim_led, &mut raw[0x1c..0x20]);
720 serialize_u8(¶ms.duration_hold, &mut raw[0x20..0x24]);
721 serialize_phantom_powering(¶ms.phantom_powering, &mut raw[0x24..0x28])?;
722 serialize_hpf_enables(¶ms.hpf_enables, &mut raw[0x24..0x28])?;
723 serialize_output_trims(¶ms.output_trims, &mut raw[0x28..0x40])?;
724 serialize_reverb_type(¶ms.reverb_type, &mut raw[0x40..0x44])?;
725 serialize_u8(¶ms.reverb_volume, &mut raw[0x44..0x48]);
726 serialize_u8(¶ms.reverb_duration, &mut raw[0x48..0x4c]);
727 serialize_u8(¶ms.reverb_feedback, &mut raw[0x4c..0x50]);
728
729 Ok(())
730}
731
732fn deserialize(params: &mut Mbox3SpecificParams, raw: &[u8]) -> Result<(), String> {
733 assert!(raw.len() >= MIN_SIZE);
734
735 deserialize_standalone_use_case(&mut params.standalone_use_case, &raw[..0x04])?;
736 deserialize_u8(&mut params.master_knob_value, &raw[0x08..0x0c]);
737 deserialize_master_knob_assigns(&mut params.master_knob_assigns, &raw[0x0c..0x10])?;
738 deserialize_mute_led_state(&mut params.mute_led, &raw[0x10..0x14])?;
739 deserialize_mono_led_state(&mut params.mono_led, &raw[0x14..0x18])?;
740 deserialize_spkr_led_state(&mut params.spkr_led, &raw[0x14..0x18])?;
741 deserialize_bool(&mut params.dim_led, &raw[0x1c..0x20]);
742 deserialize_u8(&mut params.duration_hold, &raw[0x20..0x24]);
743 deserialize_phantom_powering(&mut params.phantom_powering, &raw[0x24..0x28])?;
744 deserialize_hpf_enables(&mut params.hpf_enables, &raw[0x24..0x28])?;
745 deserialize_output_trims(&mut params.output_trims, &raw[0x28..0x40])?;
746 deserialize_reverb_type(&mut params.reverb_type, &raw[0x40..0x44])?;
747 deserialize_u8(&mut params.reverb_volume, &raw[0x44..0x48]);
748 deserialize_u8(&mut params.reverb_duration, &raw[0x48..0x4c]);
749 deserialize_u8(&mut params.reverb_feedback, &raw[0x4c..0x50]);
750
751 Ok(())
752}
753
754const PHANTOM_POWERING_CHANGED: u32 = 0x10000000;
755const MASTER_KNOB_CHANGED: u32 = 0x08000000;
756const SPKR_BUTTON_PUSHED: u32 = 0x04000000;
757const SPKR_BUTTON_HELD: u32 = 0x02000000;
758const MONO_BUTTON_PUSHED: u32 = 0x00800000;
759const MUTE_BUTTON_PUSHED: u32 = 0x00400000;
760const MUTE_BUTTON_HELD: u32 = 0x00200000;
761
762impl TcatExtensionSectionParamsOperation<Mbox3SpecificParams> for Mbox3Protocol {
763 fn cache_extension_whole_params(
764 req: &FwReq,
765 node: &FwNode,
766 sections: &ExtensionSections,
767 _: &ExtensionCaps,
768 params: &mut Mbox3SpecificParams,
769 timeout_ms: u32,
770 ) -> Result<(), Error> {
771 let mut raw = vec![0u8; MIN_SIZE];
772 Self::read_extension(req, node, §ions.application, 0, &mut raw, timeout_ms)?;
773 deserialize(params, &raw).map_err(|cause| Error::new(ProtocolExtensionError::Appl, &cause))
774 }
775}
776
777impl TcatExtensionSectionPartialMutableParamsOperation<Mbox3SpecificParams> for Mbox3Protocol {
778 fn update_extension_partial_params(
779 req: &FwReq,
780 node: &FwNode,
781 sections: &ExtensionSections,
782 _: &ExtensionCaps,
783 params: &Mbox3SpecificParams,
784 prev: &mut Mbox3SpecificParams,
785 timeout_ms: u32,
786 ) -> Result<(), Error> {
787 let mut new = vec![0u8; MIN_SIZE];
788 serialize(params, &mut new)
789 .map_err(|cause| Error::new(ProtocolExtensionError::Appl, &cause))?;
790
791 let mut old = vec![0u8; MIN_SIZE];
792 serialize(prev, &mut old)
793 .map_err(|cause| Error::new(ProtocolExtensionError::Appl, &cause))?;
794
795 (0..MIN_SIZE).step_by(4).try_for_each(|pos| {
796 if new[pos..(pos + 4)] != old[pos..(pos + 4)] {
797 Self::write_extension(
798 req,
799 node,
800 §ions.application,
801 pos,
802 &mut new[pos..(pos + 4)],
803 timeout_ms,
804 )
805 } else {
806 Ok(())
807 }
808 })?;
809
810 deserialize(prev, &new).map_err(|cause| Error::new(ProtocolExtensionError::Appl, &cause))
811 }
812}
813
814impl TcatExtensionSectionNotifiedParamsOperation<Mbox3SpecificParams> for Mbox3Protocol {
815 fn cache_extension_notified_params(
816 req: &FwReq,
817 node: &FwNode,
818 sections: &ExtensionSections,
819 caps: &ExtensionCaps,
820 params: &mut Mbox3SpecificParams,
821 msg: u32,
822 timeout_ms: u32,
823 ) -> Result<(), Error> {
824 if msg & (PHANTOM_POWERING_CHANGED | MASTER_KNOB_CHANGED) > 0 {
825 Self::cache_extension_whole_params(req, node, sections, caps, params, timeout_ms)?;
826 }
827
828 let mut p = params.clone();
829 if msg & SPKR_BUTTON_PUSHED > 0 {
830 p.spkr_led = match params.spkr_led {
831 SpkrLedState::Off => SpkrLedState::Green,
832 SpkrLedState::GreenBlink => SpkrLedState::Green,
833 SpkrLedState::Green => SpkrLedState::Red,
834 SpkrLedState::RedBlink => SpkrLedState::Red,
835 SpkrLedState::Red => SpkrLedState::Orange,
836 SpkrLedState::OrangeBlink => SpkrLedState::Orange,
837 SpkrLedState::Orange => SpkrLedState::Off,
838 };
839 }
840
841 if msg & SPKR_BUTTON_HELD > 0 {
842 p.spkr_led = match params.spkr_led {
843 SpkrLedState::Off => SpkrLedState::Off,
844 SpkrLedState::GreenBlink => SpkrLedState::Green,
845 SpkrLedState::Green => SpkrLedState::GreenBlink,
846 SpkrLedState::RedBlink => SpkrLedState::Red,
847 SpkrLedState::Red => SpkrLedState::RedBlink,
848 SpkrLedState::OrangeBlink => SpkrLedState::Orange,
849 SpkrLedState::Orange => SpkrLedState::OrangeBlink,
850 };
851 }
852
853 if msg & MONO_BUTTON_PUSHED > 0 {
854 p.mono_led = match params.mono_led {
855 MonoLedState::Off => MonoLedState::On,
856 MonoLedState::On => MonoLedState::Off,
857 };
858 }
859
860 if msg & MUTE_BUTTON_PUSHED > 0 {
861 p.mute_led = match params.mute_led {
862 MuteLedState::Off => MuteLedState::On,
863 MuteLedState::Blink => MuteLedState::On,
864 MuteLedState::On => MuteLedState::Off,
865 };
866 }
867
868 if msg & MUTE_BUTTON_HELD > 0 {
869 p.mute_led = match params.mute_led {
870 MuteLedState::Off => MuteLedState::Off,
871 MuteLedState::Blink => MuteLedState::On,
872 MuteLedState::On => MuteLedState::Blink,
873 };
874 }
875
876 if !p.eq(params) {
877 Self::update_extension_partial_params(
878 req, node, sections, caps, &p, params, timeout_ms,
879 )?;
880 }
881
882 Ok(())
883 }
884}
885
886#[cfg(test)]
887mod test {
888 use super::*;
889
890 #[test]
891 fn mbox3_specific_params_serdes() {
892 let params = Mbox3SpecificParams {
893 standalone_use_case: StandaloneUseCase::AdDa,
894 master_knob_value: 0xf9,
895 master_knob_assigns: [true, false, true, true, false, true],
896 mute_led: MuteLedState::Blink,
897 mono_led: MonoLedState::On,
898 spkr_led: SpkrLedState::RedBlink,
899 dim_led: false,
900 duration_hold: 10,
901 phantom_powering: true,
902 hpf_enables: [false, false, true, false],
903 output_trims: [0, 1, 2, 3, 4, 5],
904 reverb_type: ReverbType::Hall2,
905 reverb_volume: 0xb3,
906 reverb_duration: 0xa5,
907 reverb_feedback: 0x17,
908 };
909
910 let mut raw = [0; MIN_SIZE];
911 serialize(¶ms, &mut raw).unwrap();
912
913 let mut p = Mbox3SpecificParams::default();
914 deserialize(&mut p, &raw).unwrap();
915
916 assert_eq!(params, p);
917 }
918}