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 mode;
mod strobe;

pub use mode::*;
pub use strobe::*;

lib_bitfield! {
    /// Represents the `BUS_WIDTH` field of the [ExtCsd] register.
    BusWidth: u8,
    mask: 0x8f,
    default: 0,
    {
        /// Indicates the support for the `Enhanced Strobe` mode.
        enhanced_strobe: EnhancedStrobe, 7;
        /// Indicates the bus mode (width and rate).
        bus_mode_selection: BusModeSelection, 3, 0;
    }
}

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

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

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

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

        assert_eq!(ext_csd.bus_width(), Ok(BusWidth::new()));

        (0..=u8::MAX).for_each(|raw_bus| {
            // set a potentially invalid BusWidth
            ext_csd.set_bus_width(BusWidth(raw_bus));

            match BusWidth::try_from_inner(raw_bus) {
                Ok(bus) => assert_eq!(ext_csd.bus_width(), Ok(bus)),
                Err(err) => assert_eq!(ext_csd.bus_width(), Err(err)),
            }
        });
    }
}