sdmmc-core 0.5.0

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

use super::{ExtCsd, ExtCsdIndex};

lib_bitfield! {
    /// Represents the `FIRMWARE_VERSION` field of the [ExtCsd] register.
    FirmwareVersion: u64,
    mask: 0xffff_ffff_ffff_ffff,
    default: 0,
    {
        /// Represents the firmware version.
        firmware_version: 63, 0;
    }
}

impl ExtCsd {
    /// Gets the `FIRMWARE_VERSION` field of the [ExtCsd] register.
    pub const fn firmware_version(&self) -> FirmwareVersion {
        let start = ExtCsdIndex::FIRMWARE_VERSION_START;

        FirmwareVersion::from_inner(u64::from_le_bytes([
            self.0[start],
            self.0[start + 1],
            self.0[start + 2],
            self.0[start + 3],
            self.0[start + 4],
            self.0[start + 5],
            self.0[start + 6],
            self.0[start + 7],
        ]))
    }

    /// Sets the `FIRMWARE_VERSION` field of the [ExtCsd] register.
    pub(crate) fn set_firmware_version(&mut self, val: FirmwareVersion) {
        let start = ExtCsdIndex::FIRMWARE_VERSION_START;
        let [s0, s1, s2, s3, s4, s5, s6, s7] = val.into_inner().to_le_bytes();

        self.0[start] = s0;
        self.0[start + 1] = s1;
        self.0[start + 2] = s2;
        self.0[start + 3] = s3;
        self.0[start + 4] = s4;
        self.0[start + 5] = s5;
        self.0[start + 6] = s6;
        self.0[start + 7] = s7;
    }
}

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

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

        assert_eq!(ext_csd.firmware_version(), FirmwareVersion::new());

        (0..=u64::BITS)
            .map(|r| FirmwareVersion::from_inner(((1u128 << r) - 1) as u64))
            .for_each(|version| {
                ext_csd.set_firmware_version(version);
                assert_eq!(ext_csd.firmware_version(), version);
            });
    }
}