use crate::lib_bitfield;
use crate::result::Result;
use super::{ExtCsd, ExtCsdIndex};
lib_bitfield! {
pub ExceptionEventsCtrl(u16): u8 {
pub extended_security_failure: 4;
pub packed_failure: 3;
pub syspool_exhausted: 2;
pub dyncap_needed: 1;
}
}
impl ExceptionEventsCtrl {
pub const MASK: u16 = 0x1e;
pub const DEFAULT: u16 = 0;
pub const fn new() -> Self {
Self(Self::DEFAULT)
}
pub const fn from_bits(val: u16) -> Self {
Self(val & Self::MASK)
}
pub const fn try_from_inner(val: u16) -> Result<Self> {
Ok(Self::from_bits(val))
}
pub const fn into_inner(self) -> u16 {
self.bits()
}
}
impl Default for ExceptionEventsCtrl {
fn default() -> Self {
Self::new()
}
}
impl ExtCsd {
pub const fn exception_events_ctrl(&self) -> Result<ExceptionEventsCtrl> {
let start = self.0[ExtCsdIndex::EXCEPTION_EVENTS_CTRL_START];
let end = self.0[ExtCsdIndex::EXCEPTION_EVENTS_CTRL_END];
ExceptionEventsCtrl::try_from_inner(u16::from_be_bytes([start, end]))
}
pub fn set_exception_events_ctrl(&mut self, val: ExceptionEventsCtrl) {
let [start, end] = val.into_inner().to_be_bytes();
self.0[ExtCsdIndex::EXCEPTION_EVENTS_CTRL_START] = start;
self.0[ExtCsdIndex::EXCEPTION_EVENTS_CTRL_END] = end;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_exception_events_ctrl() {
let mut ext_csd = ExtCsd::new();
(1..=u8::BITS).map(|r| (1u16 << r) - 1).for_each(|raw| {
let status = ExceptionEventsCtrl::from_bits(raw);
assert_eq!(status.bits(), raw & ExceptionEventsCtrl::MASK);
ext_csd.set_exception_events_ctrl(status);
assert_eq!(ext_csd.exception_events_ctrl(), Ok(status));
});
}
}