diff --git a/libboard_zynq_us/src/slcr/common.rs b/libboard_zynq_us/src/slcr/common.rs new file mode 100644 index 0000000..7a7ce5f --- /dev/null +++ b/libboard_zynq_us/src/slcr/common.rs @@ -0,0 +1,25 @@ +///! Type definitions for re-use across SLCR blocks + +use libregister::{register, register_bit, register_bits}; + +register!(wprot, WProt, RW, u32); +register_bit!(wprot, active, 0); + +register!(pll_ctrl, PllCtrl, RW, u32); +register_bits!(pll_ctrl, pll_post_src, u8, 24, 26); +register_bits!(pll_ctrl, pll_pre_src, u8, 20, 22); +register_bit!(pll_ctrl, pll_div2, 16); +register_bits!(pll_ctrl, pll_fdiv, u8, 8, 14); +register_bit!(pll_ctrl, pll_bypass_force, 3); +register_bit!(pll_ctrl, pll_reset, 0); + +register!(pll_cfg, PllCfg, RW, u32); +register_bits!(pll_cfg, lock_dly, u8, 25, 31); +register_bits!(pll_cfg, lock_cnt, u16, 13, 22); +register_bits!(pll_cfg, lfhf, u8, 10, 11); +register_bits!(pll_cfg, pll_cp, u8, 5, 8); +register_bits!(pll_cfg, pll_res, u8, 0, 3); + +register!(pll_frac_cfg, PllFracCfg, RW, u32); +register_bit!(pll_frac_cfg, enabled, 31); +register_bits!(pll_frac_cfg, data, u16, 0, 15); diff --git a/libboard_zynq_us/src/slcr/crf_apb.rs b/libboard_zynq_us/src/slcr/crf_apb.rs index c20ff5f..03a7b39 100644 --- a/libboard_zynq_us/src/slcr/crf_apb.rs +++ b/libboard_zynq_us/src/slcr/crf_apb.rs @@ -4,8 +4,11 @@ use volatile_register::{RO, RW, WO}; use libregister::{ register, register_at, register_bit, register_bits, + RegisterW, }; +use super::common::{WProt, PllCfg, PllCtrl, PllFracCfg}; + #[repr(C)] pub struct RegisterBlock { // CRF_APB @@ -14,7 +17,7 @@ pub struct RegisterBlock { pub ir_mask: RO, pub ir_enable: WO, pub ir_disable: WO, - pub crf_wprot: RW, + pub crf_wprot: WProt, pub apu_pll_ctrl: PllCtrl, pub apu_pll_cfg: PllCfg, pub apu_pll_frac_cfg: PllFracCfg, @@ -56,24 +59,16 @@ pub struct RegisterBlock { } register_at!(RegisterBlock, 0xFD1A_0000, crf_apb); -register!(pll_ctrl, PllCtrl, RW, u32); -register_bits!(pll_ctrl, post_src, u8, 24, 26); -register_bits!(pll_ctrl, pre_src, u8, 20, 22); -register_bit!(pll_ctrl, div2, 16); -register_bits!(pll_ctrl, fbdiv, u8, 8, 14); -register_bit!(pll_ctrl, bypass, 3); -register_bit!(pll_ctrl, reset, 0); +impl RegisterBlock { + pub fn unlocked R, R>(mut f: F) -> R { + let mut self_ = Self::crf_apb(); + self_.crf_wprot.write(WProt::zeroed().active(false)); + let r = f(&mut self_); + self_.crf_wprot.write(WProt::zeroed().active(true)); + r + } +} -register!(pll_cfg, PllCfg, RW, u32); -register_bits!(pll_cfg, lock_dly, u8, 25, 31); -register_bits!(pll_cfg, lock_cnt, u16, 13, 22); -register_bits!(pll_cfg, lfhf, u8, 10, 11); -register_bits!(pll_cfg, cp, u8, 5, 8); -register_bits!(pll_cfg, res, u8, 0, 3); - -register!(pll_frac_cfg, PllFracCfg, RW, u32); -register_bit!(pll_frac_cfg, enabled, 31); -register_bits!(pll_frac_cfg, data, u16, 0, 15); register!(pll_status, PllStatus, RO, u32); register_bit!(pll_status, video_pll_stable, 5); diff --git a/libboard_zynq_us/src/slcr/mod.rs b/libboard_zynq_us/src/slcr/mod.rs index 1a1c2bb..beae39e 100644 --- a/libboard_zynq_us/src/slcr/mod.rs +++ b/libboard_zynq_us/src/slcr/mod.rs @@ -1,4 +1,5 @@ ///! Register definitions for UltraScale+ System Level Control +pub mod common; pub mod crf_apb; // APU // FPD_SLCR