firewire_dice_protocols/tcat/
ext_sync_section.rs

1// SPDX-License-Identifier: LGPL-3.0-or-later
2// Copyright (c) 2020 Takashi Sakamoto
3
4//! External synchronization section in general protocol defined by TCAT for ASICs of DICE.
5//!
6//! The module includes structure, enumeration, and trait and its implementation for extended
7//! synchronization section in general protocol defined by TCAT for ASICs of DICE.
8
9use super::{global_section::*, *};
10
11/// Parameters in extended synchronization section.
12#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
13pub struct ExtendedSyncParameters {
14    /// Current clock source; read-only.
15    pub clk_src: ClockSource,
16    /// Clock source is locked (boolean); read-only.
17    pub clk_src_locked: bool,
18    /// Current sample rate (CLOCK_RATE_* >> CLOCK_RATE_SHIFT), _32000-_192000 or _NONE; read-only.
19    pub clk_rate: ClockRate,
20    /// ADAT user data bits; read-only.
21    pub adat_user_data: Option<u8>,
22}
23
24const ADAT_USER_DATA_MASK: u32 = 0x0f;
25const ADAT_USER_DATA_UNAVAIL: u32 = 0x10;
26
27impl<O: TcatOperation> TcatSectionSerdes<ExtendedSyncParameters> for O {
28    const MIN_SIZE: usize = 16;
29
30    const ERROR_TYPE: GeneralProtocolError = GeneralProtocolError::ExtendedSync;
31
32    fn serialize(_: &ExtendedSyncParameters, _: &mut [u8]) -> Result<(), String> {
33        // All of fields are read-only.
34        Ok(())
35    }
36
37    fn deserialize(params: &mut ExtendedSyncParameters, raw: &[u8]) -> Result<(), String> {
38        let mut val = 0u8;
39        deserialize_u8(&mut val, &raw[..4]);
40        deserialize_clock_source(&mut params.clk_src, &val)?;
41
42        let mut val = 0u32;
43        deserialize_u32(&mut val, &raw[4..8]);
44        params.clk_src_locked = val > 0;
45
46        let mut val = 0u8;
47        deserialize_u8(&mut val, &raw[8..12]);
48        deserialize_clock_rate(&mut params.clk_rate, &val)?;
49
50        let mut val = 0u32;
51        deserialize_u32(&mut val, &raw[12..16]);
52        params.adat_user_data = if val & ADAT_USER_DATA_UNAVAIL > 0 {
53            None
54        } else {
55            Some((val & ADAT_USER_DATA_MASK) as u8)
56        };
57
58        Ok(())
59    }
60}
61
62impl<O: TcatOperation> TcatSectionOperation<ExtendedSyncParameters> for O {}
63
64#[cfg(test)]
65mod test {
66    use super::*;
67
68    struct Protocol;
69
70    impl TcatOperation for Protocol {}
71
72    #[test]
73    fn ext_sync_params_serdes() {
74        let raw = [0, 0, 0, 0xa, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 7];
75        let mut params = ExtendedSyncParameters::default();
76        Protocol::deserialize(&mut params, &raw).unwrap();
77
78        assert_eq!(params.clk_src, ClockSource::Arx3);
79        assert_eq!(params.clk_src_locked, true);
80        assert_eq!(params.clk_rate, ClockRate::R176400);
81        assert_eq!(params.adat_user_data, Some(0x7));
82    }
83}