zynq7000_hal/slcr.rs
1//! # System Level Control Register (SLCR) module
2use zynq7000::slcr::MmioSlcr;
3
4pub const LOCK_KEY: u32 = 0x767B;
5pub const UNLOCK_KEY: u32 = 0xDF0D;
6
7pub struct Slcr(zynq7000::slcr::MmioSlcr<'static>);
8
9impl Slcr {
10 /// Modify the SLCR register.
11 ///
12 /// # Safety
13 ///
14 /// This method unsafely steals the SLCR MMIO block and then calls a user provided function
15 /// with the [SLCR MMIO][MmioSlcr] block as an input argument. It is the user's responsibility
16 /// that the SLCR is not used concurrently in a way which leads to data races.
17 pub unsafe fn with<F: FnOnce(&mut MmioSlcr<'static>)>(f: F) {
18 let mut slcr = unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() };
19 slcr.write_unlock(UNLOCK_KEY);
20 f(&mut slcr);
21 slcr.write_lock(LOCK_KEY);
22 }
23
24 /// Create a new SLCR peripheral wrapper.
25 pub fn new(slcr: zynq7000::slcr::MmioSlcr<'static>) -> Self {
26 Self(slcr)
27 }
28
29 /// Unsafely create a new SLCR peripheral wrapper.
30 ///
31 /// # Safety
32 ///
33 /// This allows to create an arbitrary number of SLCR peripheral wrappers. It is the user's
34 /// responsibility that these wrappers are not used concurrently in a way which leads to
35 /// data races.
36 pub unsafe fn steal() -> Self {
37 Self::new(unsafe { zynq7000::slcr::Slcr::new_mmio_fixed() })
38 }
39
40 /// Returns a mutable reference to the SLCR MMIO block.
41 ///
42 /// The MMIO block will not be unlocked. However, the registers can still be read.
43 pub fn regs(&self) -> &MmioSlcr<'static> {
44 &self.0
45 }
46
47 /// Modify the SLCR register.
48 ///
49 /// This method unlocks the SLCR registers and then calls a user provided function
50 /// with the [SLCR MMIO][MmioSlcr] block as an input argument. This allows the user
51 /// to safely modify the SLCR registers. The SLCR will be locked afte the operation.
52 pub fn modify<F: FnMut(&mut MmioSlcr)>(&mut self, mut f: F) {
53 self.0.write_unlock(UNLOCK_KEY);
54 f(&mut self.0);
55 self.0.write_lock(LOCK_KEY);
56 }
57
58 /// Manually unlock the SLCR registers.
59 pub fn unlock(&mut self) {
60 self.0.write_unlock(UNLOCK_KEY);
61 }
62
63 /// Manually lock the SLCR registers.
64 pub fn lock(&mut self) {
65 self.0.write_lock(LOCK_KEY);
66 }
67}