ssp/types/
sequence_id.rs

1use crate::std::{self, fmt};
2
3use crate::{bool_enum, impl_default};
4
5pub mod bitmask {
6    pub const SEQUENCE_ID: u8 = 0x7f;
7}
8
9bool_enum!(
10    SequenceFlag,
11    r"
12 Each time the master sends a new packet to a device it alternates the sequence flag. If a
13 device receives a packet with the same sequence flag as the last one, it does not execute
14 the command but simply repeats its last reply. In a reply packet the address and sequence
15 flag match the command packet.
16"
17);
18
19impl SequenceFlag {
20    /// Creates a new [SequenceFlag].
21    ///
22    /// Defaults to unset.
23    pub const fn new() -> Self {
24        Self::Unset
25    }
26}
27
28impl_default!(SequenceFlag);
29
30/// A combination of two items of data: the sequence flag (MSB, bit7) and the address of the
31/// device (bit 6 to bit 0, LSB).
32///
33/// For example a SMART Hopper by default has an address of 0x10 (16 decimal). When the
34/// sync bit is equal to 1 the byte sent to the Hopper is 0x90. On the next command, the sync
35/// bit is toggled, in this case 0, the byte sent would be 0x10.
36#[repr(C)]
37#[derive(Clone, Copy, Debug, PartialEq)]
38pub struct SequenceId {
39    flag: SequenceFlag,
40    id: u8,
41}
42
43impl SequenceId {
44    /// Creates a new [SequenceId].
45    pub const fn new() -> Self {
46        Self {
47            flag: SequenceFlag::new(),
48            id: 0,
49        }
50    }
51
52    /// Converts a u8 into a [SequenceId].
53    pub const fn from_u8(b: u8) -> Self {
54        let flag = SequenceFlag::from_u8(b >> 7);
55        let id = b & bitmask::SEQUENCE_ID;
56
57        Self { flag, id }
58    }
59
60    /// Creates a [SequenceId] from a [SequenceFlag] and ID.
61    pub const fn from_parts(flag: SequenceFlag, id: u8) -> Self {
62        Self { flag, id }
63    }
64
65    /// Gets the [SequenceFlag].
66    pub fn flag(&self) -> SequenceFlag {
67        self.flag
68    }
69
70    /// Sets the [SequenceFlag].
71    pub fn set_flag(&mut self, flag: SequenceFlag) {
72        self.flag = flag;
73    }
74
75    /// Toggles the value of the [SequenceFlag].
76    pub fn toggle_flag(&mut self) {
77        self.flag = !self.flag;
78    }
79
80    /// Gets the sequence ID.
81    pub fn id(&self) -> u8 {
82        self.id
83    }
84
85    /// Sets the sequence ID.
86    pub fn set_id(&mut self, id: u8) {
87        self.id = id & bitmask::SEQUENCE_ID;
88    }
89
90    /// Increments the sequence ID.
91    ///
92    /// If the ID reaches the maximum (`0x7F`), incrementing resets the value to zero.
93    ///
94    /// This is the behavior described in the documentation.
95    pub fn increment(&mut self) -> u8 {
96        self.id = (self.id + 1) & bitmask::SEQUENCE_ID;
97
98        self.id
99    }
100}
101
102impl_default!(SequenceId);
103
104impl std::ops::Not for SequenceId {
105    type Output = SequenceId;
106
107    fn not(self) -> Self::Output {
108        SequenceId::from_parts(!self.flag(), self.id())
109    }
110}
111
112impl From<u8> for SequenceId {
113    fn from(b: u8) -> Self {
114        Self::from_u8(b)
115    }
116}
117
118impl From<SequenceId> for u8 {
119    fn from(s: SequenceId) -> Self {
120        (u8::from(s.flag) << 7) | (s.id & bitmask::SEQUENCE_ID)
121    }
122}
123
124impl fmt::Display for SequenceId {
125    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126        write!(f, "flag({}): 0x{:02x}", self.flag, self.id)
127    }
128}