use super::ocotp;
impl ocotp::Ocotp {
#[inline(always)]
pub(crate) fn read_fuse_data(&self) -> u32 {
crate::ral::read_reg!(crate::ral::ocotp, self.ocotp, READ_FUSE_DATA0)
}
#[inline(always)]
pub(crate) fn check_end_fuse_read(&mut self) -> Result<(), ocotp::Error> {
if crate::ral::read_reg!(crate::ral::ocotp, self.ocotp, OUT_STATUS, DED == 1) {
crate::ral::write_reg!(crate::ral::ocotp, self.ocotp, OUT_STATUS_SET, DED: 1);
return Err(ocotp::Error::DedRead);
}
Ok(())
}
#[inline(always)]
pub(crate) fn check_end_fuse_write(&mut self) -> Result<(), ocotp::Error> {
let (progfail, locked) =
crate::ral::read_reg!(crate::ral::ocotp, self.ocotp, OUT_STATUS, PROGFAIL, LOCKED);
crate::ral::write_reg!(crate::ral::ocotp, self.ocotp, OUT_STATUS_SET, PROGFAIL: progfail, LOCKED: locked);
if 0 != progfail {
return Err(ocotp::Error::Programming);
}
if 0 != locked {
return Err(ocotp::Error::LockedRegionAccess);
}
Ok(())
}
pub fn has_read_sec(&self) -> bool {
crate::ral::read_reg!(crate::ral::ocotp, self.ocotp, OUT_STATUS, SEC == 1)
}
pub fn clear_read_sec(&self) {
crate::ral::write_reg!(crate::ral::ocotp, self.ocotp, OUT_STATUS_SET, SEC: 1);
}
pub(crate) const FUSE_ADDRESS_OFFSET: u16 = 0x800;
}
#[cfg(test)]
mod tests {
use super::ocotp::FuseAddress;
#[test]
fn fuse_address_from_rm_example() {
let fuse = FuseAddress::new(0x960).unwrap();
assert_eq!(fuse.raw(), 0x16);
}
#[test]
fn fuse_address_from_min_fuse() {
let fuse = FuseAddress::new(0x840).unwrap();
assert_eq!(fuse.raw(), 4);
}
#[test]
fn fuse_address_from_max_fuse() {
let fuse = FuseAddress::new(0x1800).unwrap();
assert_eq!(fuse.raw(), 0x100);
}
}