use anyhow::{bail, Result};
use bitflags::bitflags;
use num_enum::IntoPrimitive;
use serde::{Deserialize, Serialize};
use crate::with_unknown;
with_unknown! {
pub enum DifLcCtrlState: u32 {
Raw = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateRaw ,
TestUnlocked0 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked0 ,
TestLocked0 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked0 ,
TestUnlocked1 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked1 ,
TestLocked1 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked1 ,
TestUnlocked2 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked2 ,
TestLocked2 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked2 ,
TestUnlocked3 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked3 ,
TestLocked3 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked3 ,
TestUnlocked4 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked4 ,
TestLocked4 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked4 ,
TestUnlocked5 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked5 ,
TestLocked5 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked5 ,
TestUnlocked6 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked6 ,
TestLocked6 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestLocked6 ,
TestUnlocked7 = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateTestUnlocked7 ,
Dev = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateDev ,
Prod = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateProd ,
ProdEnd = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateProdEnd ,
Rma = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateRma ,
Scrap = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateScrap ,
PostTransition = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStatePostTransition ,
Escalate = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateEscalate ,
StateInvalid = bindgen::dif::dif_lc_ctrl_state_kDifLcCtrlStateInvalid ,
}
}
pub struct DifLcCtrlTransCheck {
pub valid: bool,
pub token: bool,
}
impl DifLcCtrlState {
pub fn from_redundant_encoding(encoding: u32) -> Result<Self> {
let base_encoding = encoding & 0x1fu32;
if base_encoding > u32::from(DifLcCtrlState::StateInvalid) {
bail!("Invalid life cycle state value.");
}
Ok(DifLcCtrlState(encoding & 0x1fu32))
}
pub fn redundant_encoding(&self) -> u32 {
let value: u32 = self.0;
assert_eq!(value & 0b11111, value);
(0..6).fold(0u32, |acc, _| (acc << 5) | value)
}
pub fn lc_state_to_str(self) -> &'static str {
match self {
DifLcCtrlState::Raw => "raw",
DifLcCtrlState::TestUnlocked0 => "test_unlocked0",
DifLcCtrlState::TestLocked0 => "test_locked0",
DifLcCtrlState::TestUnlocked1 => "test_unlocked1",
DifLcCtrlState::TestLocked1 => "test_locked1",
DifLcCtrlState::TestUnlocked2 => "test_unlocked2",
DifLcCtrlState::TestLocked2 => "test_locked2",
DifLcCtrlState::TestUnlocked3 => "test_unlocked3",
DifLcCtrlState::TestLocked3 => "test_locked3",
DifLcCtrlState::TestUnlocked4 => "test_unlocked4",
DifLcCtrlState::TestLocked4 => "test_locked4",
DifLcCtrlState::TestUnlocked5 => "test_unlocked5",
DifLcCtrlState::TestLocked5 => "test_locked5",
DifLcCtrlState::TestUnlocked6 => "test_unlocked6",
DifLcCtrlState::TestLocked6 => "test_locked6",
DifLcCtrlState::TestUnlocked7 => "test_unlocked7",
DifLcCtrlState::Dev => "dev",
DifLcCtrlState::Prod => "prod",
DifLcCtrlState::ProdEnd => "prod_end",
DifLcCtrlState::Rma => "rma",
DifLcCtrlState::Scrap => "scrap",
DifLcCtrlState::PostTransition => "post_transition",
DifLcCtrlState::Escalate => "escalate",
_ => "invalid",
}
}
pub fn parse_lc_state_str(lc_state_str: &str) -> Result<Self> {
match lc_state_str {
"raw" => Ok(DifLcCtrlState::Raw),
"test_unlocked0" => Ok(DifLcCtrlState::TestUnlocked0),
"test_locked0" => Ok(DifLcCtrlState::TestLocked0),
"test_unlocked1" => Ok(DifLcCtrlState::TestUnlocked1),
"test_locked1" => Ok(DifLcCtrlState::TestLocked1),
"test_unlocked2" => Ok(DifLcCtrlState::TestUnlocked2),
"test_locked2" => Ok(DifLcCtrlState::TestLocked2),
"test_unlocked3" => Ok(DifLcCtrlState::TestUnlocked3),
"test_locked3" => Ok(DifLcCtrlState::TestLocked3),
"test_unlocked4" => Ok(DifLcCtrlState::TestUnlocked4),
"test_locked4" => Ok(DifLcCtrlState::TestLocked4),
"test_unlocked5" => Ok(DifLcCtrlState::TestUnlocked5),
"test_locked5" => Ok(DifLcCtrlState::TestLocked5),
"test_unlocked6" => Ok(DifLcCtrlState::TestUnlocked6),
"test_locked6" => Ok(DifLcCtrlState::TestLocked6),
"test_unlocked7" => Ok(DifLcCtrlState::TestUnlocked7),
"dev" => Ok(DifLcCtrlState::Dev),
"prod" => Ok(DifLcCtrlState::Prod),
"prod_end" => Ok(DifLcCtrlState::ProdEnd),
"rma" => Ok(DifLcCtrlState::Rma),
"scrap" => Ok(DifLcCtrlState::Scrap),
"post_transition" => Ok(DifLcCtrlState::PostTransition),
"escalate" => Ok(DifLcCtrlState::Escalate),
_ => Ok(DifLcCtrlState::StateInvalid),
}
}
pub fn check_transition(self, target: DifLcCtrlState) -> DifLcCtrlTransCheck {
match (self, target) {
(DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked0)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked1)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked2)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked3)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked4)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked5)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::Raw, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked1)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked2)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked3)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked4)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked5)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked2)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked3)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked4)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked5)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked3)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked4)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked5)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked4)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked5)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::TestUnlocked5)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked5, DifLcCtrlState::TestUnlocked6)
| (DifLcCtrlState::TestLocked5, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked5, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked5, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked5, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::TestLocked6, DifLcCtrlState::TestUnlocked7)
| (DifLcCtrlState::TestLocked6, DifLcCtrlState::Dev)
| (DifLcCtrlState::TestLocked6, DifLcCtrlState::Prod)
| (DifLcCtrlState::TestLocked6, DifLcCtrlState::ProdEnd)
| (DifLcCtrlState::Dev, DifLcCtrlState::Rma)
| (DifLcCtrlState::Prod, DifLcCtrlState::Rma) => DifLcCtrlTransCheck {
valid: true,
token: true,
},
(DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Rma)
| (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Rma)
| (DifLcCtrlState::Raw, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked7, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked0, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked1, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked2, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked3, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked4, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked5, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestLocked6, DifLcCtrlState::Scrap)
| (DifLcCtrlState::Dev, DifLcCtrlState::Scrap)
| (DifLcCtrlState::Prod, DifLcCtrlState::Scrap)
| (DifLcCtrlState::ProdEnd, DifLcCtrlState::Scrap)
| (DifLcCtrlState::Rma, DifLcCtrlState::Scrap)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked0)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked1)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked2)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked3)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked4)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked5)
| (DifLcCtrlState::TestUnlocked0, DifLcCtrlState::TestLocked6)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked1)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked2)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked3)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked4)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked5)
| (DifLcCtrlState::TestUnlocked1, DifLcCtrlState::TestLocked6)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked2)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked3)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked4)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked5)
| (DifLcCtrlState::TestUnlocked2, DifLcCtrlState::TestLocked6)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked3)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked4)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked5)
| (DifLcCtrlState::TestUnlocked3, DifLcCtrlState::TestLocked6)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::TestLocked4)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::TestLocked5)
| (DifLcCtrlState::TestUnlocked4, DifLcCtrlState::TestLocked6)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::TestLocked5)
| (DifLcCtrlState::TestUnlocked5, DifLcCtrlState::TestLocked6)
| (DifLcCtrlState::TestUnlocked6, DifLcCtrlState::TestLocked6) => DifLcCtrlTransCheck {
valid: true,
token: false,
},
_ => DifLcCtrlTransCheck {
valid: false,
token: false,
},
}
}
}
#[derive(Copy, Clone)]
pub struct DifLcCtrlToken(bindgen::dif::dif_lc_ctrl_token);
impl From<[u8; 16]> for DifLcCtrlToken {
fn from(bytes: [u8; 16]) -> Self {
DifLcCtrlToken(bindgen::dif::dif_lc_ctrl_token { data: bytes })
}
}
impl From<Vec<u8>> for DifLcCtrlToken {
fn from(vector: Vec<u8>) -> Self {
let bytes: [u8; 16] = vector.try_into().unwrap();
DifLcCtrlToken::from(bytes)
}
}
impl From<[u32; 4]> for DifLcCtrlToken {
fn from(words: [u32; 4]) -> Self {
let bytes: [u8; 16] = words
.iter()
.flat_map(|v| v.to_le_bytes())
.collect::<Vec<u8>>()
.try_into()
.unwrap();
DifLcCtrlToken::from(bytes)
}
}
impl From<Vec<u32>> for DifLcCtrlToken {
fn from(vector: Vec<u32>) -> Self {
let bytes: [u8; 16] = vector
.iter()
.flat_map(|v| v.to_le_bytes())
.collect::<Vec<u8>>()
.try_into()
.unwrap();
DifLcCtrlToken::from(bytes)
}
}
impl DifLcCtrlToken {
pub fn into_register_values(self) -> [u32; 4] {
let mut out_words = [0u32; 4];
let bytes = self.0.data;
bytes
.chunks_exact(std::mem::size_of::<u32>())
.map(|chunk| u32::from_le_bytes(chunk.try_into().unwrap()))
.zip(&mut out_words)
.for_each(|(word, out)| *out = word);
out_words
}
pub fn is_zero(self) -> bool {
self.0.data == [0; 16]
}
}
#[derive(IntoPrimitive, Clone, Debug, strum::EnumString)]
#[strum(serialize_all = "snake_case")]
#[repr(u32)]
pub enum LcCtrlReg {
AlertTest = bindgen::dif::LC_CTRL_ALERT_TEST_REG_OFFSET,
Status = bindgen::dif::LC_CTRL_STATUS_REG_OFFSET,
ClaimTransitionIf = bindgen::dif::LC_CTRL_CLAIM_TRANSITION_IF_REG_OFFSET,
TransitionRegwen = bindgen::dif::LC_CTRL_TRANSITION_REGWEN_REG_OFFSET,
TransitionCmd = bindgen::dif::LC_CTRL_TRANSITION_CMD_REG_OFFSET,
TransitionCtrl = bindgen::dif::LC_CTRL_TRANSITION_CTRL_REG_OFFSET,
TransitionToken0 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_0_REG_OFFSET,
TransitionToken1 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_1_REG_OFFSET,
TransitionToken2 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_2_REG_OFFSET,
TransitionToken3 = bindgen::dif::LC_CTRL_TRANSITION_TOKEN_3_REG_OFFSET,
TransitionTarget = bindgen::dif::LC_CTRL_TRANSITION_TARGET_REG_OFFSET,
OtpVendorTestCtrl = bindgen::dif::LC_CTRL_OTP_VENDOR_TEST_CTRL_REG_OFFSET,
OtpVendorTestStatus = bindgen::dif::LC_CTRL_OTP_VENDOR_TEST_STATUS_REG_OFFSET,
LcState = bindgen::dif::LC_CTRL_LC_STATE_REG_OFFSET,
LcTransitionCnt = bindgen::dif::LC_CTRL_LC_TRANSITION_CNT_REG_OFFSET,
LcIdState = bindgen::dif::LC_CTRL_LC_ID_STATE_REG_OFFSET,
HwRevision0 = bindgen::dif::LC_CTRL_HW_REVISION0_REG_OFFSET,
HwRevision1 = bindgen::dif::LC_CTRL_HW_REVISION1_REG_OFFSET,
DeviceId0 = bindgen::dif::LC_CTRL_DEVICE_ID_0_REG_OFFSET,
DeviceId1 = bindgen::dif::LC_CTRL_DEVICE_ID_1_REG_OFFSET,
DeviceId2 = bindgen::dif::LC_CTRL_DEVICE_ID_2_REG_OFFSET,
DeviceId3 = bindgen::dif::LC_CTRL_DEVICE_ID_3_REG_OFFSET,
DeviceId4 = bindgen::dif::LC_CTRL_DEVICE_ID_4_REG_OFFSET,
DeviceId5 = bindgen::dif::LC_CTRL_DEVICE_ID_5_REG_OFFSET,
DeviceId6 = bindgen::dif::LC_CTRL_DEVICE_ID_6_REG_OFFSET,
DeviceId7 = bindgen::dif::LC_CTRL_DEVICE_ID_7_REG_OFFSET,
ManufState0 = bindgen::dif::LC_CTRL_MANUF_STATE_0_REG_OFFSET,
ManufState1 = bindgen::dif::LC_CTRL_MANUF_STATE_1_REG_OFFSET,
ManufState2 = bindgen::dif::LC_CTRL_MANUF_STATE_2_REG_OFFSET,
ManufState3 = bindgen::dif::LC_CTRL_MANUF_STATE_3_REG_OFFSET,
ManufState4 = bindgen::dif::LC_CTRL_MANUF_STATE_4_REG_OFFSET,
ManufState5 = bindgen::dif::LC_CTRL_MANUF_STATE_5_REG_OFFSET,
ManufState6 = bindgen::dif::LC_CTRL_MANUF_STATE_6_REG_OFFSET,
ManufState7 = bindgen::dif::LC_CTRL_MANUF_STATE_7_REG_OFFSET,
}
impl LcCtrlReg {
pub fn byte_offset(&self) -> u32 {
self.clone().into()
}
pub fn word_offset(&self) -> u32 {
const BYTES_PER_WORD: u32 = std::mem::size_of::<u32>() as u32;
assert_eq!(self.byte_offset() % BYTES_PER_WORD, 0);
self.byte_offset() / BYTES_PER_WORD
}
}
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
#[serde(transparent)]
pub struct LcCtrlStatus: u32 {
const INITIALIZED = 0b1 << bindgen::dif::LC_CTRL_STATUS_INITIALIZED_BIT;
const READY = 0b1 << bindgen::dif::LC_CTRL_STATUS_READY_BIT;
const EXT_CLOCK_SWITCHED = 0b1 << bindgen::dif::LC_CTRL_STATUS_EXT_CLOCK_SWITCHED_BIT;
const TRANSITION_SUCCESSFUL = 0b1 << bindgen::dif::LC_CTRL_STATUS_TRANSITION_SUCCESSFUL_BIT;
const TRANSITION_COUNT_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_TRANSITION_COUNT_ERROR_BIT;
const TRANSITION_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_TRANSITION_ERROR_BIT;
const TOKEN_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_TOKEN_ERROR_BIT;
const FLASH_RMA_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_FLASH_RMA_ERROR_BIT;
const OTP_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_OTP_ERROR_BIT;
const STATE_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_STATE_ERROR_BIT;
const BUS_INTEG_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_BUS_INTEG_ERROR_BIT;
const OTP_PARTITION_ERROR = 0b1 << bindgen::dif::LC_CTRL_STATUS_OTP_PARTITION_ERROR_BIT;
const ERRORS =
Self::TRANSITION_COUNT_ERROR.bits() |
Self::TRANSITION_ERROR.bits() |
Self::TOKEN_ERROR.bits() |
Self::FLASH_RMA_ERROR.bits() |
Self::OTP_ERROR.bits() |
Self::STATE_ERROR.bits() |
Self::BUS_INTEG_ERROR.bits() |
Self::OTP_PARTITION_ERROR.bits();
}
}
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LcCtrlTransitionRegwen: u32 {
const TRANSITION_REGWEN = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_REGWEN_TRANSITION_REGWEN_BIT;
}
}
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LcCtrlTransitionCmd: u32 {
const START = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_CMD_START_BIT;
}
}
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LcCtrlTransitionCtrl: u32 {
const EXT_CLOCK_EN = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_CTRL_EXT_CLOCK_EN_BIT;
const VOLATILE_RAW_UNLOCK = 0b1 << bindgen::dif::LC_CTRL_TRANSITION_CTRL_VOLATILE_RAW_UNLOCK_BIT;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn lc_ctrl_state_redundant_encoding_zero() {
assert_eq!(u32::from(DifLcCtrlState::Raw), 0);
assert_eq!(DifLcCtrlState::Raw.redundant_encoding(), 0);
}
#[test]
fn lc_ctrl_state_redundant_encoding_nonzero() {
assert_ne!(
u32::from(DifLcCtrlState::Rma),
DifLcCtrlState::Rma.redundant_encoding()
);
assert_eq!(DifLcCtrlState::Rma.redundant_encoding(), 0x2739ce73);
}
#[test]
fn lc_ctrl_token() {
let token_bytes: [u8; 16] = [
0x01, 0x02, 0x03, 0x04, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34, ];
let token = DifLcCtrlToken::from(token_bytes);
let words: [u32; 4] = token.into_register_values();
assert_eq!(words, [0x04030201, 0x14131211, 0x24232221, 0x34333231]);
}
#[test]
fn lc_ctrl_register_offsets() {
let offset = bindgen::dif::LC_CTRL_LC_STATE_REG_OFFSET;
assert_eq!(LcCtrlReg::LcState.byte_offset(), offset);
assert_eq!(LcCtrlReg::LcState.word_offset(), offset / 4);
}
#[test]
fn lc_status_bits() {
assert_eq!(LcCtrlStatus::empty(), LcCtrlStatus::from_bits_truncate(0));
assert_eq!(
LcCtrlStatus::INITIALIZED,
LcCtrlStatus::from_bits_truncate(1)
);
assert_eq!(
LcCtrlStatus::INITIALIZED | LcCtrlStatus::READY,
LcCtrlStatus::from_bits_truncate(3)
);
let ready = LcCtrlStatus::INITIALIZED | LcCtrlStatus::READY;
assert!(ready.contains(LcCtrlStatus::READY));
assert!(!ready.contains(LcCtrlStatus::TRANSITION_SUCCESSFUL));
}
}