diff --git a/src/slcr.rs b/src/slcr.rs index 2dcbb051..4d814c12 100644 --- a/src/slcr.rs +++ b/src/slcr.rs @@ -1,5 +1,6 @@ -#[allow(unused)] +///! Register definitions for System Level Control +use volatile_register::{RO, WO, RW}; use crate::{register, register_bit, register_bits, register_at, regs::RegisterW, regs::RegisterRW}; pub enum PllSource { @@ -8,45 +9,228 @@ pub enum PllSource { DdrPll = 0b11, } -pub fn with_slcr R, R>(mut f: F) -> R { - unsafe { SlcrUnlock::new() }.unlock(); - let r = f(); - unsafe { SlcrLock::new() }.lock(); - r +#[repr(C)] +pub struct RegisterBlock { + pub scl: RW, + pub slcr_lock: SlcrLock, + pub slcr_unlock: SlcrUnlock, + pub slcr_locksta: RO, + reserved0: [u32; 60], + pub arm_pll_ctrl: RW, + pub ddr_pll_ctrl: RW, + pub io_pll_ctrl: RW, + pub pll_status: RO, + pub arm_pll_cfg: RW, + pub ddr_pll_cfg: RW, + pub io_pll_cfg: RW, + reserved1: [u32; 1], + pub arm_clk_ctrl: RW, + pub ddr_clk_ctrl: RW, + pub dci_clk_ctrl: RW, + pub aper_clk_ctrl: AperClkCtrl, + pub usb0_clk_ctrl: RW, + pub usb1_clk_ctrl: RW, + pub gem0_rclk_ctrl: RW, + pub gem1_rclk_ctrl: RW, + pub gem0_clk_ctrl: RW, + pub gem1_clk_ctrl: RW, + pub smc_clk_ctrl: RW, + pub lqspi_clk_ctrl: RW, + pub sdio_clk_ctrl: RW, + pub uart_clk_ctrl: UartClkCtrl, + pub spi_clk_ctrl: RW, + pub can_clk_ctrl: RW, + pub can_mioclk_ctrl: RW, + pub dbg_clk_ctrl: RW, + pub pcap_clk_ctrl: RW, + pub topsw_clk_ctrl: RW, + pub fpga0_clk_ctrl: RW, + pub fpga0_thr_ctrl: RW, + pub fpga0_thr_cnt: RW, + pub fpga0_thr_sta: RO, + pub fpga1_clk_ctrl: RW, + pub fpga1_thr_ctrl: RW, + pub fpga1_thr_cnt: RW, + pub fpga1_thr_sta: RO, + pub fpga2_clk_ctrl: RW, + pub fpga2_thr_ctrl: RW, + pub fpga2_thr_cnt: RW, + pub fpga2_thr_sta: RO, + pub fpga3_clk_ctrl: RW, + pub fpga3_thr_ctrl: RW, + pub fpga3_thr_cnt: RW, + pub fpga3_thr_sta: RO, + reserved2: [u32; 5], + pub clk_621_true: RW, + reserved3: [u32; 14], + pub pss_rst_ctrl: RW, + pub ddr_rst_ctrl: RW, + pub topsw_rst_ctrl: RW, + pub dmac_rst_ctrl: RW, + pub usb_rst_ctrl: RW, + pub gem_rst_ctrl: RW, + pub sdio_rst_ctrl: RW, + pub spi_rst_ctrl: RW, + pub can_rst_ctrl: RW, + pub i2c_rst_ctrl: RW, + pub uart_rst_ctrl: UartRstCtrl, + pub gpio_rst_ctrl: RW, + pub lqspi_rst_ctrl: RW, + pub smc_rst_ctrl: RW, + pub ocm_rst_ctrl: RW, + reserved4: [u32; 1], + pub fpga_rst_ctrl: RW, + pub a9_cpu_rst_ctrl: RW, + reserved5: [u32; 1], + pub rs_awdt_ctrl: RW, + reserved6: [u32; 2], + pub reboot_status: RW, + pub boot_mode: RW, + reserved7: [u32; 40], + pub apu_ctrl: RW, + pub wdt_clk_sel: RW, + reserved8: [u32; 78], + pub tz_dma_ns: RW, + pub tz_dma_irq_ns: RW, + pub tz_dma_periph_ns: RW, + reserved9: [u32; 57], + pub pss_idcode: RW, + reserved10: [u32; 51], + pub ddr_urgent: RW, + reserved11: [u32; 2], + pub ddr_cal_start: RW, + reserved12: [u32; 1], + pub ddr_ref_start: RW, + pub ddr_cmd_sta: RW, + pub ddr_urgent_sel: RW, + pub ddr_dfi_status: RW, + reserved13: [u32; 55], + pub mio_pin_00: RW, + pub mio_pin_01: RW, + pub mio_pin_02: RW, + pub mio_pin_03: RW, + pub mio_pin_04: RW, + pub mio_pin_05: RW, + pub mio_pin_06: RW, + pub mio_pin_07: RW, + pub mio_pin_08: RW, + pub mio_pin_09: RW, + pub mio_pin_10: RW, + pub mio_pin_11: RW, + pub mio_pin_12: RW, + pub mio_pin_13: RW, + pub mio_pin_14: RW, + pub mio_pin_15: RW, + pub mio_pin_16: RW, + pub mio_pin_17: RW, + pub mio_pin_18: RW, + pub mio_pin_19: RW, + pub mio_pin_20: RW, + pub mio_pin_21: RW, + pub mio_pin_22: RW, + pub mio_pin_23: RW, + pub mio_pin_24: RW, + pub mio_pin_25: RW, + pub mio_pin_26: RW, + pub mio_pin_27: RW, + pub mio_pin_28: RW, + pub mio_pin_29: RW, + pub mio_pin_30: RW, + pub mio_pin_31: RW, + pub mio_pin_32: RW, + pub mio_pin_33: RW, + pub mio_pin_34: RW, + pub mio_pin_35: RW, + pub mio_pin_36: RW, + pub mio_pin_37: RW, + pub mio_pin_38: RW, + pub mio_pin_39: RW, + pub mio_pin_40: RW, + pub mio_pin_41: RW, + pub mio_pin_42: RW, + pub mio_pin_43: RW, + pub mio_pin_44: RW, + pub mio_pin_45: RW, + pub mio_pin_46: RW, + pub mio_pin_47: RW, + pub mio_pin_48: MioPin48, + pub mio_pin_49: MioPin49, + pub mio_pin_50: RW, + pub mio_pin_51: RW, + pub mio_pin_52: RW, + pub mio_pin_53: RW, + reserved14: [u32; 11], + pub mio_loopback: RW, + reserved15: [u32; 1], + pub mio_mst_tri0: RW, + pub mio_mst_tri1: RW, + reserved16: [u32; 7], + pub sd0_wp_cd_sel: RW, + pub sd1_wp_cd_sel: RW, + reserved17: [u32; 50], + pub lvl_shftr_en: RW, + reserved18: [u32; 3], + pub ocm_cfg: RW, + reserved19: [u32; 123], + pub gpiob_ctrl: RW, + pub gpiob_cfg_cmos18: RW, + pub gpiob_cfg_cmos25: RW, + pub gpiob_cfg_cmos33: RW, + reserved20: [u32; 1], + pub gpiob_cfg_hstl: RW, + pub gpiob_drvr_bias_ctrl: RW, + reserved21: [u32; 9], + pub ddriob_addr1: RW, + pub ddriob_data0: RW, + pub ddriob_data1: RW, + pub ddriob_diff0: RW, + pub ddriob_diff1: RW, + pub ddriob_clock: RW, + pub w_addr: RW, + pub w_data: RW, + pub w_diff: RW, + pub w_clock: RW, + pub ddriob_ddr_ctrl: RW, + pub ddriob_dci_ctrl: RW, + pub ddriob_dci_status: RW, +} +register_at!(RegisterBlock, 0xF8000000, new); + +impl RegisterBlock { + pub fn unlocked R, R>(mut f: F) -> R { + let self_ = Self::new(); + self_.slcr_unlock.unlock(); + let r = f(&self_); + self_.slcr_lock.lock(); + r + } } register!(slcr_lock, SlcrLock, WO, u32); register_bits!(slcr_lock, lock_key, u16, 0, 15); -register_at!(SlcrLock, 0xF8000004, new); impl SlcrLock { pub fn lock(&self) { - unsafe { - self.write( - Self::zeroed() - .lock_key(0x767B) - ); - } + self.write( + Self::zeroed() + .lock_key(0x767B) + ); } } register!(slcr_unlock, SlcrUnlock, WO, u32); register_bits!(slcr_unlock, unlock_key, u16, 0, 15); -register_at!(SlcrUnlock, 0xF8000008, new); impl SlcrUnlock { pub fn unlock(&self) { - unsafe { - self.write( - Self::zeroed() - .unlock_key(0xDF0D) - ); - } + self.write( + Self::zeroed() + .unlock_key(0xDF0D) + ); } } register!(aper_clk_ctrl, AperClkCtrl, RW, u32); register_bit!(aper_clk_ctrl, uart1_cpu_1xclkact, 21); register_bit!(aper_clk_ctrl, uart0_cpu_1xclkact, 20); -register_at!(AperClkCtrl, 0xF800012C, new); impl AperClkCtrl { pub fn enable_uart0(&self) { self.modify(|_, w| w.uart0_cpu_1xclkact(true)); @@ -117,3 +301,29 @@ impl UartRstCtrl { ); } } + +/// Used for MioPin*.io_type +pub enum IoBufferType { + Lvcmos18 = 0b001, + Lvcmos25 = 0b010, + Lvcmos33 = 0b011, + Hstl = 0b100, +} + +macro_rules! mio_pin_register { + ($mod_name: ident, $struct_name: ident) => ( + register!($mod_name, $struct_name, RW, u32); + register_bit!($mod_name, disable_rcvr, 13); + register_bit!($mod_name, pullup, 12); + register_bits!($mod_name, io_type, u8, 9, 11); + register_bit!($mod_name, speed, 8); + register_bits!($mod_name, l3_sel, u8, 5, 7); + register_bits!($mod_name, l2_sel, u8, 3, 4); + register_bit!($mod_name, l1_sel, 2); + register_bit!($mod_name, l0_sel, 1); + register_bit!($mod_name, tri_enable, 0); + ); +} + +mio_pin_register!(mio_pin_48, MioPin48); +mio_pin_register!(mio_pin_49, MioPin49); diff --git a/src/uart/mod.rs b/src/uart/mod.rs index 93f0d9ed..64206f54 100644 --- a/src/uart/mod.rs +++ b/src/uart/mod.rs @@ -4,6 +4,7 @@ use core::fmt; use volatile_register::RW; use crate::regs::*; +use crate::slcr; mod regs; mod baud_rate_gen; @@ -18,24 +19,28 @@ pub struct Uart { impl Uart { pub fn uart1(baudrate: u32) -> Self { - super::slcr::with_slcr(|| { - let uart_rst_ctrl = super::slcr::UartRstCtrl::new(); - uart_rst_ctrl.reset_uart1(); + slcr::RegisterBlock::unlocked(|slcr| { + slcr.uart_rst_ctrl.reset_uart1(); // Route UART 1 RxD/TxD Signals to MIO Pins - unsafe { - // TX pin - let mio_pin_48 = &*(0xF80007C0 as *const RW); - mio_pin_48.write(0x0000_12E0); - // RX pin - let mio_pin_49 = &*(0xF80007C4 as *const RW); - mio_pin_49.write(0x0000_12E1); - } + // TX pin + slcr.mio_pin_48.write( + slcr::MioPin48::zeroed() + .l3_sel(0b111) + .io_type(0b001) + .pullup(true) + ); + // RX pin + slcr.mio_pin_49.write( + slcr::MioPin49::zeroed() + .tri_enable(true) + .l3_sel(0b111) + .io_type(0b001) + .pullup(true) + ); - let aper_clk_ctrl = super::slcr::AperClkCtrl::new(); - aper_clk_ctrl.enable_uart1(); - let uart_clk_ctrl = super::slcr::UartClkCtrl::new(); - uart_clk_ctrl.enable_uart1(); + slcr.aper_clk_ctrl.enable_uart1(); + slcr.uart_clk_ctrl.enable_uart1(); }); let self_ = Uart { regs: regs::RegisterBlock::uart1(),