use crate::register::csd::v2::taac::{AccessTimeUnit, AccessTimeValue};
use crate::response::End;
use super::*;
#[test]
fn test_valid_default() {
let raw_bytes = CsdV3::DEFAULT;
let raw_crc = raw_bytes[15] >> 1;
let crc = Crc7::calculate(&raw_bytes[..15]);
assert_eq!(crc.bits(), raw_crc);
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_crc(), raw_crc as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_csd() {
let exp = CsdStructure::V3;
let raw = exp.into_raw();
let mut raw_bytes = CsdV3::DEFAULT;
raw_bytes[0] = raw << 6;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_csd_structure(), raw as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.csd_structure(), Ok(exp));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_taac() {
let unit = AccessTimeUnit::Ms1;
let value = AccessTimeValue::Value10;
let mut raw_bytes = CsdV3::DEFAULT;
let raw_unit = unit.into_raw();
let raw_value = value.into_raw();
let exp_taac = TimeAsyncAccessCycles::new();
let raw_taac = exp_taac.bits();
raw_bytes[1] = raw_taac;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_taac(), raw_taac as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.taac(), Ok(exp_taac));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_nsac() {
let raw_nsac = 0;
let mut raw_bytes = CsdV3::DEFAULT;
let exp_nsac = NsAccessCycles::from_bits(raw_nsac);
raw_bytes[2] = raw_nsac;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_nsac(), raw_nsac as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.nsac(), Ok(exp_nsac));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_tran_speed() {
use crate::register::csd::tran_speed::{TransferRateUnit, TransferTimeValue};
[
TransferTimeValue::Value10,
TransferTimeValue::Value12,
TransferTimeValue::Value13,
TransferTimeValue::Value15,
TransferTimeValue::Value20,
TransferTimeValue::Value25,
TransferTimeValue::Value30,
TransferTimeValue::Value35,
TransferTimeValue::Value40,
TransferTimeValue::Value45,
TransferTimeValue::Value50,
TransferTimeValue::Value55,
TransferTimeValue::Value60,
TransferTimeValue::Value70,
TransferTimeValue::Value80,
]
.into_iter()
.for_each(|time_value| {
[
TransferRateUnit::Kbits100,
TransferRateUnit::Mbits1,
TransferRateUnit::Mbits10,
TransferRateUnit::Mbits100,
]
.into_iter()
.for_each(|rate_unit| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_tran_speed = TransferSpeed::from_parts(rate_unit, time_value);
raw_bytes[3] = exp_tran_speed.bits();
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_tran_speed(), exp_tran_speed.bits() as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.tran_speed(), Ok(exp_tran_speed));
assert_eq!(exp_csd.crc(), crc);
});
});
}
#[test]
fn test_valid_ccc() {
(0..=CardCommandClass::MASK).for_each(|raw_ccc| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_ccc = CardCommandClass::from_bits(raw_ccc);
raw_bytes[4] = (raw_ccc >> 4) as u8;
raw_bytes[5] = (raw_bytes[5] & !0xf0) | ((raw_ccc & 0xf) << 4) as u8;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_ccc(), raw_ccc as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.ccc(), exp_ccc);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_read_bl_len() {
let exp_read_bl_len = BlockLength::Bytes512;
let mut raw_bytes = CsdV3::DEFAULT;
let raw_read_bl_len = exp_read_bl_len.into_raw();
raw_bytes[5] = (raw_bytes[5] & !0xf) | raw_read_bl_len;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_read_bl_len(), raw_read_bl_len as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.read_bl_len(), Ok(exp_read_bl_len));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_read_bl_partial() {
(0..=1).for_each(|raw_read_bl_partial| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_read_bl_partial = ReadBlockPartial::from_inner(raw_read_bl_partial != 0);
raw_bytes[6] = (raw_bytes[6] & !0x80) | (raw_read_bl_partial << 7);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_read_bl_partial(), exp_read_bl_partial.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.read_bl_partial(), exp_read_bl_partial);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_write_blk_misalign() {
(0..=1).for_each(|raw_write_blk_misalign| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_write_blk_misalign = WriteBlockMisalign::from_inner(raw_write_blk_misalign != 0);
raw_bytes[6] = (raw_bytes[6] & !0x40) | (raw_write_blk_misalign << 6);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(
exp_csd.raw_write_blk_misalign(),
exp_write_blk_misalign.into()
);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.write_blk_misalign(), exp_write_blk_misalign);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_read_blk_misalign() {
(0..=1).for_each(|raw_read_blk_misalign| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_read_blk_misalign = ReadBlockMisalign::from_inner(raw_read_blk_misalign != 0);
raw_bytes[6] = (raw_bytes[6] & !0x20) | (raw_read_blk_misalign << 5);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(
exp_csd.raw_read_blk_misalign(),
exp_read_blk_misalign.into()
);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.read_blk_misalign(), exp_read_blk_misalign);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_dsr_imp() {
(0..=1).for_each(|raw_dsr_imp| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_dsr_imp = DsrImplemented::from_inner(raw_dsr_imp != 0);
raw_bytes[6] = (raw_bytes[6] & !0x10) | (raw_dsr_imp << 4);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_dsr_imp(), exp_dsr_imp.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.dsr_imp(), exp_dsr_imp);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_c_size() {
(1..=28).for_each(|raw_idx| {
let raw_c_size = (1 << raw_idx) - 1;
let mut raw_bytes = CsdV3::DEFAULT;
let exp_c_size = CapacitySize::from_inner(raw_c_size);
raw_bytes[6] = (raw_bytes[6] & !0xf) | (((raw_c_size & 0xf00_0000) >> 24) as u8);
raw_bytes[7] = ((raw_c_size & 0xff_0000) >> 16) as u8;
raw_bytes[8] = ((raw_c_size & 0xff00) >> 8) as u8;
raw_bytes[9] = (raw_c_size & 0xff) as u8;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_c_size(), exp_c_size.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.c_size(), exp_c_size);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_erase_blk_en() {
(0..=1).for_each(|raw_erase_blk_en| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_erase_blk_en = EraseBlockEnable::from_inner(raw_erase_blk_en != 0);
raw_bytes[10] = (raw_bytes[10] & !0x40) | (raw_erase_blk_en << 6);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_erase_blk_en(), exp_erase_blk_en.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.erase_blk_en(), exp_erase_blk_en);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_sector_size() {
let raw_sector_size = 0x7f;
let mut raw_bytes = CsdV3::DEFAULT;
let exp_sector_size = SectorSize::from_inner(raw_sector_size);
raw_bytes[10] = (raw_bytes[10] & !0x3f) | (raw_sector_size >> 1);
raw_bytes[11] = (raw_bytes[11] & !0x80) | ((raw_sector_size & 0x1) << 7);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(
exp_csd.raw_sector_size(),
exp_sector_size.into_inner() as u32
);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.sector_size(), Ok(exp_sector_size));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_wp_grp_size() {
(0..=0x7f).for_each(|raw_wp_grp_size| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_wp_grp_size = WriteProtectGroupSize::from_inner(raw_wp_grp_size);
raw_bytes[11] = (raw_bytes[11] & !0x7f) | raw_wp_grp_size;
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(
exp_csd.raw_wp_grp_size(),
exp_wp_grp_size.into_inner() as u32
);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.wp_grp_size(), exp_wp_grp_size);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_wp_grp_enable() {
(0..=1).for_each(|raw_wp_grp_enable| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_wp_grp_enable = WriteProtectGroupEnable::from_inner(raw_wp_grp_enable != 0);
raw_bytes[12] = (raw_bytes[12] & !0x80) | (raw_wp_grp_enable << 7);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_wp_grp_enable(), exp_wp_grp_enable.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.wp_grp_enable(), exp_wp_grp_enable);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_r2w_factor() {
let exp_r2w_factor = WriteSpeedFactor::Multiple4;
let mut raw_bytes = CsdV3::DEFAULT;
let raw_r2w_factor = exp_r2w_factor.into_raw();
raw_bytes[12] = (raw_bytes[12] & !0x1c) | (raw_r2w_factor << 2);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_r2w_factor(), raw_r2w_factor as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.r2w_factor(), Ok(exp_r2w_factor));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_write_bl_len() {
let exp_write_bl_len = BlockLength::Bytes512;
let mut raw_bytes = CsdV3::DEFAULT;
let raw_write_bl_len = exp_write_bl_len.into_raw();
raw_bytes[12] = (raw_bytes[12] & !0x3) | (raw_write_bl_len >> 2);
raw_bytes[13] = (raw_bytes[13] & !0xc0) | (raw_write_bl_len << 6);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_write_bl_len(), raw_write_bl_len as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.write_bl_len(), Ok(exp_write_bl_len));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_write_bl_partial() {
(0..=1).for_each(|raw_write_bl_partial| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_write_bl_partial = WriteBlockPartial::from_inner(raw_write_bl_partial != 0);
raw_bytes[13] = (raw_bytes[13] & !0x20) | (raw_write_bl_partial << 5);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_write_bl_partial(), exp_write_bl_partial.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.write_bl_partial(), exp_write_bl_partial);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_file_format_grp() {
(0..=1).for_each(|raw_file_format_grp| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_file_format_grp = FileFormatGroup::from_inner(raw_file_format_grp != 0);
raw_bytes[14] = (raw_bytes[14] & !0x80) | (raw_file_format_grp << 7);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_file_format_grp(), exp_file_format_grp.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.file_format_grp(), exp_file_format_grp);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_copy() {
(0..=1).for_each(|raw_copy| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_copy = Copied::from_inner(raw_copy != 0);
raw_bytes[14] = (raw_bytes[14] & !0x40) | (raw_copy << 6);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_copy(), exp_copy.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.copy(), exp_copy);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_perm_write_protect() {
(0..=1).for_each(|raw_perm_write_protect| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_perm_write_protect = PermanentWriteProtect::from_inner(raw_perm_write_protect != 0);
raw_bytes[14] = (raw_bytes[14] & !0x20) | (raw_perm_write_protect << 5);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(
exp_csd.raw_perm_write_protect(),
exp_perm_write_protect.into()
);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.perm_write_protect(), exp_perm_write_protect);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_tmp_write_protect() {
(0..=1).for_each(|raw_tmp_write_protect| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_tmp_write_protect = TemporaryWriteProtect::from_inner(raw_tmp_write_protect != 0);
raw_bytes[14] = (raw_bytes[14] & !0x10) | (raw_tmp_write_protect << 4);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(
exp_csd.raw_tmp_write_protect(),
exp_tmp_write_protect.into()
);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.tmp_write_protect(), exp_tmp_write_protect);
assert_eq!(exp_csd.crc(), crc);
});
}
#[test]
fn test_valid_file_format() {
let exp_file_format = FileFormat::HardDisk;
let mut raw_bytes = CsdV3::DEFAULT;
let raw_file_format = exp_file_format.into_raw();
raw_bytes[14] = (raw_bytes[14] & !0x0c) | (raw_file_format << 2);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_file_format(), raw_file_format as u32);
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.file_format(), Ok(exp_file_format));
assert_eq!(exp_csd.crc(), crc);
}
#[test]
fn test_valid_wp_upc() {
(0..=1).for_each(|raw_wp_upc| {
let mut raw_bytes = CsdV3::DEFAULT;
let exp_wp_upc = WriteProtectUntilPowerCycle::from_inner(raw_wp_upc != 0);
raw_bytes[14] = (raw_bytes[14] & !0x02) | (raw_wp_upc << 1);
let crc = Crc7::calculate(&raw_bytes[..15]);
raw_bytes[15] = End::from_crc(crc).bits();
let exp_csd = CsdV3(raw_bytes);
assert_eq!(exp_csd.raw_wp_upc(), exp_wp_upc.into());
assert_eq!(CsdV3::try_from_bytes(raw_bytes.as_ref()), Ok(exp_csd));
assert_eq!(exp_csd.wp_upc(), exp_wp_upc);
assert_eq!(exp_csd.crc(), crc);
});
}