use crate::std::{self, fmt};
use crate::{bool_enum, impl_default};
pub mod bitmask {
pub const SEQUENCE_ID: u8 = 0x7f;
}
bool_enum!(
SequenceFlag,
r"
Each time the master sends a new packet to a device it alternates the sequence flag. If a
device receives a packet with the same sequence flag as the last one, it does not execute
the command but simply repeats its last reply. In a reply packet the address and sequence
flag match the command packet.
"
);
impl SequenceFlag {
pub const fn new() -> Self {
Self::Unset
}
}
impl_default!(SequenceFlag);
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SequenceId {
flag: SequenceFlag,
id: u8,
}
impl SequenceId {
pub const fn new() -> Self {
Self {
flag: SequenceFlag::new(),
id: 0,
}
}
pub const fn from_u8(b: u8) -> Self {
let flag = SequenceFlag::from_u8(b >> 7);
let id = b & bitmask::SEQUENCE_ID;
Self { flag, id }
}
pub const fn from_parts(flag: SequenceFlag, id: u8) -> Self {
Self { flag, id }
}
pub fn flag(&self) -> SequenceFlag {
self.flag
}
pub fn set_flag(&mut self, flag: SequenceFlag) {
self.flag = flag;
}
pub fn toggle_flag(&mut self) {
self.flag = !self.flag;
}
pub fn id(&self) -> u8 {
self.id
}
pub fn set_id(&mut self, id: u8) {
self.id = id & bitmask::SEQUENCE_ID;
}
pub fn increment(&mut self) -> u8 {
self.id = (self.id + 1) & bitmask::SEQUENCE_ID;
self.id
}
}
impl_default!(SequenceId);
impl std::ops::Not for SequenceId {
type Output = SequenceId;
fn not(self) -> Self::Output {
SequenceId::from_parts(!self.flag(), self.id())
}
}
impl From<u8> for SequenceId {
fn from(b: u8) -> Self {
Self::from_u8(b)
}
}
impl From<SequenceId> for u8 {
fn from(s: SequenceId) -> Self {
(u8::from(s.flag) << 7) | (s.id & bitmask::SEQUENCE_ID)
}
}
impl fmt::Display for SequenceId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "flag({}): 0x{:02x}", self.flag, self.id)
}
}