sdmmc-core 0.5.0

SD/MMC core data structures and algorithms
Documentation
use crate::lib_bitfield;
use crate::result::Result;

use super::{ExtCsd, ExtCsdIndex};

mod period;
mod unit;

pub use period::*;
pub use unit::*;

lib_bitfield! {
    /// Represents the `PERIODIC_WAKEUP` field of the [ExtCsd] register.
    PeriodicWakeup: u8,
    mask: 0xff,
    default: 0,
    {
        /// Represents the time unit for the wakeup period.
        wakeup_unit: WakeupUnit, 7, 5;
        /// Represents the time value for the wakeup period.
        wakeup_period: WakeupPeriod, 4, 0;
    }
}

impl ExtCsd {
    /// Gets the `PERIODIC_WAKEUP` field of the [ExtCsd] register.
    pub const fn periodic_wakeup(&self) -> Result<PeriodicWakeup> {
        PeriodicWakeup::try_from_inner(self.0[ExtCsdIndex::PeriodicWakeup.into_inner()])
    }

    /// Sets the `PERIODIC_WAKEUP` field of the [ExtCsd] register.
    pub fn set_periodic_wakeup(&mut self, val: PeriodicWakeup) {
        self.0[ExtCsdIndex::PeriodicWakeup.into_inner()] = val.into_inner();
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_periodic_wakeup() {
        let mut ext_csd = ExtCsd::new();

        assert_eq!(ext_csd.periodic_wakeup(), Ok(PeriodicWakeup::new()));

        (0..=WakeupPeriod::MASK)
            .map(WakeupPeriod::from_inner)
            .for_each(|period| {
                [
                    WakeupUnit::Infinity,
                    WakeupUnit::Months,
                    WakeupUnit::Weeks,
                    WakeupUnit::Days,
                    WakeupUnit::Hours,
                    WakeupUnit::Minutes,
                ]
                .into_iter()
                .for_each(|unit| {
                    let mut exp_wakeup = PeriodicWakeup::new();

                    exp_wakeup.set_wakeup_unit(unit);
                    exp_wakeup.set_wakeup_period(period);

                    assert_eq!(exp_wakeup.wakeup_unit(), Ok(unit));
                    assert_eq!(exp_wakeup.wakeup_period(), Ok(period));

                    ext_csd.set_periodic_wakeup(exp_wakeup);
                    assert_eq!(ext_csd.periodic_wakeup(), Ok(exp_wakeup));
                });
            });
    }
}