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 `FFU_ARG` field of the [ExtCsd] register.
    FfuArg: u32,
    mask: 0xffff_ffff,
    default: 0,
    {
        /// Represents the argument the host should use for read/write commands in FFU mode.
        arg: 31, 0;
    }
}

impl ExtCsd {
    /// Gets the `FFU_ARG` field of the [ExtCsd] register.
    pub const fn ffu_arg(&self) -> FfuArg {
        let start = ExtCsdIndex::FFU_ARG_START;

        FfuArg::from_inner(u32::from_le_bytes([
            self.0[start],
            self.0[start + 1],
            self.0[start + 2],
            self.0[start + 3],
        ]))
    }

    /// Gets the `FFU_ARG` field of the [ExtCsd] register.
    pub(crate) fn set_ffu_arg(&mut self, val: FfuArg) {
        let start = ExtCsdIndex::FFU_ARG_START;
        let [s0, s1, s2, s3] = 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;
    }
}

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

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

        assert_eq!(ext_csd.ffu_arg(), FfuArg::new());

        (1..=u32::BITS)
            .map(|r| FfuArg::from_inner(((1u64 << r) - 1) as u32))
            .for_each(|arg| {
                ext_csd.set_ffu_arg(arg);
                assert_eq!(ext_csd.ffu_arg(), arg);
            });
    }
}