sdmmc-core 0.5.0

SD/MMC core data structures and algorithms
Documentation
use crate::result::{Error, Result};
use crate::{lib_bitfield, lib_enum};

use super::{ExtCsd, ExtCsdIndex};

mod attribute;

pub use attribute::*;

lib_bitfield! {
    /// Represents the `EXTENDED_PARTITION_ATTRIBUTE` for all general purpose partitions.
    ExtendedPartitionsAttribute: u16,
    mask: 0xffff,
    default: 0x0,
    {
        /// Extended partition attribute for general purpose partition 4.
        ext4: Attribute, 15, 12;
        /// Extended partition attribute for general purpose partition 3.
        ext3: Attribute, 11, 8;
        /// Extended partition attribute for general purpose partition 2.
        ext2: Attribute, 7, 4;
        /// Extended partition attribute for general purpose partition 1.
        ext1: Attribute, 3, 0;
    }
}

impl ExtCsd {
    /// Gets the `EXT_PARTITIONS_ATTRIBUTE` field of the [ExtCsd] register.
    pub const fn ext_partitions_attribute(&self) -> Result<ExtendedPartitionsAttribute> {
        let start = self.0[ExtCsdIndex::EXTENDED_PARTITIONS_ATTRIBUTE_START];
        let end = self.0[ExtCsdIndex::EXTENDED_PARTITIONS_ATTRIBUTE_END];

        ExtendedPartitionsAttribute::try_from_inner(u16::from_be_bytes([start, end]))
    }

    /// Sets the `EXT_PARTITIONS_ATTRIBUTE` field of the [ExtCsd] register.
    pub fn set_ext_partitions_attribute(&mut self, val: ExtendedPartitionsAttribute) {
        let [start, end] = val.into_inner().to_be_bytes();

        self.0[ExtCsdIndex::EXTENDED_PARTITIONS_ATTRIBUTE_START] = start;
        self.0[ExtCsdIndex::EXTENDED_PARTITIONS_ATTRIBUTE_END] = end;
    }
}

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

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

        [
            Attribute::None,
            Attribute::SystemCode,
            Attribute::NonPersistent,
        ]
        .into_iter()
        .for_each(|ext_part| {
            (1..=4).for_each(|idx| {
                let mut ext_parts = ExtendedPartitionsAttribute::new();

                match idx {
                    1 => ext_parts.set_ext1(ext_part),
                    2 => ext_parts.set_ext2(ext_part),
                    3 => ext_parts.set_ext3(ext_part),
                    _ => ext_parts.set_ext4(ext_part),
                }

                ext_csd.set_ext_partitions_attribute(ext_parts);
                assert_eq!(ext_csd.ext_partitions_attribute(), Ok(ext_parts));
            });
        });
    }
}