#![allow(clippy::missing_safety_doc)]
#![allow(clippy::identity_op)]
#![allow(clippy::unnecessary_cast)]
#![allow(clippy::erasing_op)]
#[doc = "Hardware semaphore (HSEM). 32 lock channels with PID/CID-keyed write-lock and read-lock acquisition, batch unlock by key, and per-channel interrupt on remote unlock."]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Hsem {
ptr: *mut u8,
}
unsafe impl Send for Hsem {}
unsafe impl Sync for Hsem {}
impl Hsem {
#[inline(always)]
pub const unsafe fn from_ptr(ptr: *mut ()) -> Self {
Self { ptr: ptr as _ }
}
#[inline(always)]
pub const fn as_ptr(&self) -> *mut () {
self.ptr as _
}
#[doc = "Lock channel register (write-lock / 2-step acquisition)."]
#[inline(always)]
pub const fn rx(self, n: usize) -> crate::common::Reg<regs::Lock, crate::common::RW> {
assert!(n < 32usize);
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0usize + n * 4usize) as _) }
}
#[doc = "Read-lock channel register (read-lock / 1-step acquisition). Same field layout as RX but read-only."]
#[inline(always)]
pub const fn rlrx(self, n: usize) -> crate::common::Reg<regs::Lock, crate::common::R> {
assert!(n < 32usize);
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0100usize + n * 4usize) as _) }
}
#[doc = "Lock status register. Bit n indicates whether channel n is currently locked."]
#[inline(always)]
pub const fn lse(self) -> crate::common::Reg<regs::Chbits, crate::common::R> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0200usize) as _) }
}
#[doc = "Batch unlock register. Writing the unlock key together with match PID/CID and masks unlocks all channels matching the rule."]
#[inline(always)]
pub const fn clr(self) -> crate::common::Reg<regs::Clr, crate::common::W> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0208usize) as _) }
}
#[doc = "Unlock key and auto-clear control register."]
#[inline(always)]
pub const fn key(self) -> crate::common::Reg<regs::Key, crate::common::RW> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x020cusize) as _) }
}
#[doc = "Per-channel interrupt enable register (hart-private). Bit n enables interrupt when channel n is unlocked by the other hart."]
#[inline(always)]
pub const fn ier(self) -> crate::common::Reg<regs::Chbits, crate::common::RW> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0300usize) as _) }
}
#[doc = "Per-channel interrupt status register (hart-private). Bit n is set when channel n is unlocked by the other hart. Write 1 to clear."]
#[inline(always)]
pub const fn isr(self) -> crate::common::Reg<regs::Chbits, crate::common::RW> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0308usize) as _) }
}
#[doc = "Per-channel interrupt mask status register (hart-private). Read-only AND of IER and ISR — bit n set means channel n is currently raising an interrupt."]
#[inline(always)]
pub const fn ism(self) -> crate::common::Reg<regs::Chbits, crate::common::R> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0310usize) as _) }
}
#[doc = "Lock status mask register (hart-private). Bit n indicates channel n is locked by THIS hart."]
#[inline(always)]
pub const fn lsm(self) -> crate::common::Reg<regs::Chbits, crate::common::R> {
unsafe { crate::common::Reg::from_ptr(self.ptr.add(0x0318usize) as _) }
}
}
pub mod regs {
#[doc = "32-bit per-channel bitmap (used by LSE / IER / ISR / ISM / LSM). Bit n maps to HSEM channel n."]
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Chbits(pub u32);
impl Chbits {
#[doc = "Per-channel flag."]
#[inline(always)]
pub const fn ch(&self, n: usize) -> bool {
assert!(n < 32usize);
let offs = 0usize + n * 1usize;
let val = (self.0 >> offs) & 0x01;
val != 0
}
#[doc = "Per-channel flag."]
#[inline(always)]
pub fn set_ch(&mut self, n: usize, val: bool) {
assert!(n < 32usize);
let offs = 0usize + n * 1usize;
self.0 = (self.0 & !(0x01 << offs)) | (((val as u32) & 0x01) << offs);
}
}
impl Default for Chbits {
#[inline(always)]
fn default() -> Chbits {
Chbits(0)
}
}
#[doc = "Batch unlock register."]
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Clr(pub u32);
impl Clr {
#[doc = "PID value to match against each locked channel's PID for batch unlock."]
#[inline(always)]
pub const fn match_pid(&self) -> u8 {
let val = (self.0 >> 0usize) & 0xff;
val as u8
}
#[doc = "PID value to match against each locked channel's PID for batch unlock."]
#[inline(always)]
pub fn set_match_pid(&mut self, val: u8) {
self.0 = (self.0 & !(0xff << 0usize)) | (((val as u32) & 0xff) << 0usize);
}
#[doc = "CID value to match against each locked channel's CID for batch unlock."]
#[inline(always)]
pub const fn match_cid(&self) -> u8 {
let val = (self.0 >> 8usize) & 0x03;
val as u8
}
#[doc = "CID value to match against each locked channel's CID for batch unlock."]
#[inline(always)]
pub fn set_match_cid(&mut self, val: u8) {
self.0 = (self.0 & !(0x03 << 8usize)) | (((val as u32) & 0x03) << 8usize);
}
#[doc = "1=mask PID match (unlock regardless of PID); 0=require PID equality."]
#[inline(always)]
pub const fn pid_mask(&self) -> bool {
let val = (self.0 >> 12usize) & 0x01;
val != 0
}
#[doc = "1=mask PID match (unlock regardless of PID); 0=require PID equality."]
#[inline(always)]
pub fn set_pid_mask(&mut self, val: bool) {
self.0 = (self.0 & !(0x01 << 12usize)) | (((val as u32) & 0x01) << 12usize);
}
#[doc = "1=mask CID match (unlock regardless of CID); 0=require CID equality."]
#[inline(always)]
pub const fn cid_mask(&self) -> bool {
let val = (self.0 >> 13usize) & 0x01;
val != 0
}
#[doc = "1=mask CID match (unlock regardless of CID); 0=require CID equality."]
#[inline(always)]
pub fn set_cid_mask(&mut self, val: bool) {
self.0 = (self.0 & !(0x01 << 13usize)) | (((val as u32) & 0x01) << 13usize);
}
#[doc = "Unlock key. Must equal HSEM_KEY.KEY_VALUE (default 0x5AA5) for the write to take effect."]
#[inline(always)]
pub const fn clr_key(&self) -> u16 {
let val = (self.0 >> 16usize) & 0xffff;
val as u16
}
#[doc = "Unlock key. Must equal HSEM_KEY.KEY_VALUE (default 0x5AA5) for the write to take effect."]
#[inline(always)]
pub fn set_clr_key(&mut self, val: u16) {
self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize);
}
}
impl Default for Clr {
#[inline(always)]
fn default() -> Clr {
Clr(0)
}
}
#[doc = "Unlock key and auto-clear control register."]
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Key(pub u32);
impl Key {
#[doc = "When set, a 1-step lock failure auto-clears the corresponding interrupt status bit."]
#[inline(always)]
pub const fn auto_1step_clr(&self) -> bool {
let val = (self.0 >> 0usize) & 0x01;
val != 0
}
#[doc = "When set, a 1-step lock failure auto-clears the corresponding interrupt status bit."]
#[inline(always)]
pub fn set_auto_1step_clr(&mut self, val: bool) {
self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize);
}
#[doc = "When set, a 2-step lock failure auto-clears the corresponding interrupt status bit."]
#[inline(always)]
pub const fn auto_2step_clr(&self) -> bool {
let val = (self.0 >> 1usize) & 0x01;
val != 0
}
#[doc = "When set, a 2-step lock failure auto-clears the corresponding interrupt status bit."]
#[inline(always)]
pub fn set_auto_2step_clr(&mut self, val: bool) {
self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize);
}
#[doc = "Unlock key value used for batch-unlock matching (read-only, default 0x5AA5)."]
#[inline(always)]
pub const fn key_value(&self) -> u16 {
let val = (self.0 >> 16usize) & 0xffff;
val as u16
}
#[doc = "Unlock key value used for batch-unlock matching (read-only, default 0x5AA5)."]
#[inline(always)]
pub fn set_key_value(&mut self, val: u16) {
self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize);
}
}
impl Default for Key {
#[inline(always)]
fn default() -> Key {
Key(0)
}
}
#[doc = "Lock channel register layout used by RX (RW) and RLRX (RO)."]
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Lock(pub u32);
impl Lock {
#[doc = "Process ID. Reset/release value is 0; on write-lock takes the bus write data."]
#[inline(always)]
pub const fn pid(&self) -> u8 {
let val = (self.0 >> 0usize) & 0xff;
val as u8
}
#[doc = "Process ID. Reset/release value is 0; on write-lock takes the bus write data."]
#[inline(always)]
pub fn set_pid(&mut self, val: u8) {
self.0 = (self.0 & !(0xff << 0usize)) | (((val as u32) & 0xff) << 0usize);
}
#[doc = "Core ID of the hart that locked the channel. 0=hart 0 (V3F), 1=hart 1 (V5F)."]
#[inline(always)]
pub const fn cid(&self) -> u8 {
let val = (self.0 >> 8usize) & 0x03;
val as u8
}
#[doc = "Core ID of the hart that locked the channel. 0=hart 0 (V3F), 1=hart 1 (V5F)."]
#[inline(always)]
pub fn set_cid(&mut self, val: u8) {
self.0 = (self.0 & !(0x03 << 8usize)) | (((val as u32) & 0x03) << 8usize);
}
#[doc = "Channel lock state. 1=locked, 0=idle."]
#[inline(always)]
pub const fn lock(&self) -> bool {
let val = (self.0 >> 31usize) & 0x01;
val != 0
}
#[doc = "Channel lock state. 1=locked, 0=idle."]
#[inline(always)]
pub fn set_lock(&mut self, val: bool) {
self.0 = (self.0 & !(0x01 << 31usize)) | (((val as u32) & 0x01) << 31usize);
}
}
impl Default for Lock {
#[inline(always)]
fn default() -> Lock {
Lock(0)
}
}
}