use crate::lib_bitfield;
use super::{ExtCsd, ExtCsdIndex};
lib_bitfield! {
SectorCount: u32,
mask: 0xffff_ffff,
default: 0,
{
count: 31, 0;
}
}
impl SectorCount {
pub const DENSITY: u64 = 512;
#[inline]
pub const fn density(&self) -> u64 {
(self.count() as u64) * Self::DENSITY
}
}
impl ExtCsd {
pub const fn sec_count(&self) -> SectorCount {
let start = ExtCsdIndex::SEC_COUNT_START;
let raw = u32::from_le_bytes([
self.0[start],
self.0[start + 1],
self.0[start + 2],
self.0[start + 3],
]);
SectorCount::from_inner(raw)
}
pub(crate) fn set_sec_count(&mut self, val: SectorCount) {
let start = ExtCsdIndex::SEC_COUNT_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_sec_count() {
let mut ext_csd = ExtCsd::new();
assert_eq!(ext_csd.sec_count(), SectorCount::new());
(0..=u32::BITS)
.map(|r| SectorCount::from_inner(((1u64 << r) - 1) as u32))
.for_each(|sec_count| {
ext_csd.set_sec_count(sec_count);
assert_eq!(ext_csd.sec_count(), sec_count);
assert_eq!(
sec_count.density(),
(sec_count.into_inner() as u64) * SectorCount::DENSITY
);
});
}
}