use heterob::{bit_numbering::Lsb, P13};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Status<const T: char> {
pub reserved: u8,
pub interrupt_status: bool,
pub capabilities_list: bool,
pub is_66mhz_capable: bool,
pub user_definable_features: bool,
pub fast_back_to_back_capable: bool,
pub master_data_parity_error: bool,
pub devsel_timing: DevselTiming,
pub signaled_target_abort: bool,
pub received_target_abort: bool,
pub received_master_abort: bool,
pub system_error: bool,
pub detected_parity_error: bool,
}
impl<const T: char> From<u16> for Status<T> {
fn from(word: u16) -> Self {
let Lsb((
reserved,
interrupt_status,
capabilities_list,
is_66mhz_capable,
user_definable_features,
fast_back_to_back_capable,
master_data_parity_error,
devsel_timing,
signaled_target_abort,
received_target_abort,
received_master_abort,
system_error,
detected_parity_error,
)) = P13::<_, 3, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1>(word).into();
Self {
reserved,
interrupt_status,
capabilities_list,
is_66mhz_capable,
user_definable_features,
fast_back_to_back_capable,
master_data_parity_error,
devsel_timing: From::<u8>::from(devsel_timing),
signaled_target_abort,
received_target_abort,
received_master_abort,
system_error,
detected_parity_error,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DevselTiming {
Fast,
Medium,
Slow,
Undefined,
}
impl From<u8> for DevselTiming {
fn from(byte: u8) -> Self {
match byte {
0b00 => Self::Fast,
0b01 => Self::Medium,
0b10 => Self::Slow,
0b11 => Self::Undefined,
_ => unreachable!(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn from_word() {
let result: Status<'P'> = 0xAAAA.into();
let sample = Status {
reserved: 0b010,
interrupt_status: true,
capabilities_list: false,
is_66mhz_capable: true,
user_definable_features: false,
fast_back_to_back_capable: true,
master_data_parity_error: false,
devsel_timing: DevselTiming::Medium,
signaled_target_abort: true,
received_target_abort: false,
received_master_abort: true,
system_error: false,
detected_parity_error: true,
};
assert_eq!(sample, result);
}
}