forked from M-Labs/zynq-rs
1
0
Fork 0

zynq: replace unnecessary slcr::unlocked with new

This commit is contained in:
Astro 2019-10-31 20:47:05 +01:00
parent 54e4b9281f
commit 6bee1f44f4
4 changed files with 309 additions and 320 deletions

View File

@ -99,30 +99,29 @@ impl CpuClocks {
.nth(0) .nth(0)
.expect("PLL_FDIV_LOCK_PARAM") .expect("PLL_FDIV_LOCK_PARAM")
.1.clone(); .1.clone();
slcr::RegisterBlock::unlocked(|regs| { let slcr = slcr::RegisterBlock::new();
regs.ddr_pll_ctrl.modify(|_, w| w slcr.ddr_pll_ctrl.modify(|_, w| w
.pll_pwrdwn(false) .pll_pwrdwn(false)
.pll_bypass_force(true) .pll_bypass_force(true)
.pll_fdiv(fdiv) .pll_fdiv(fdiv)
); );
regs.ddr_pll_cfg.write( slcr.ddr_pll_cfg.write(
slcr::PllCfg::zeroed() slcr::PllCfg::zeroed()
.pll_res(pll_res) .pll_res(pll_res)
.pll_cp(pll_cp) .pll_cp(pll_cp)
.lock_cnt(lock_cnt) .lock_cnt(lock_cnt)
); );
regs.ddr_pll_ctrl.modify(|_, w| w slcr.ddr_pll_ctrl.modify(|_, w| w
.pll_reset(true) .pll_reset(true)
); );
regs.ddr_pll_ctrl.modify(|_, w| w slcr.ddr_pll_ctrl.modify(|_, w| w
.pll_reset(false) .pll_reset(false)
); );
while ! regs.pll_status.read().ddr_pll_lock() {} while ! slcr.pll_status.read().ddr_pll_lock() {}
regs.ddr_pll_ctrl.modify(|_, w| w slcr.ddr_pll_ctrl.modify(|_, w| w
.pll_bypass_force(false) .pll_bypass_force(false)
.pll_bypass_qual(false) .pll_bypass_qual(false)
); );
});
} }
} }

View File

@ -42,15 +42,14 @@ impl DdrRam {
let ddr3x_clk_divisor = ((clocks.ddr - 1) / DDR_FREQ + 1).min(255) as u8; let ddr3x_clk_divisor = ((clocks.ddr - 1) / DDR_FREQ + 1).min(255) as u8;
let ddr2x_clk_divisor = 3 * ddr3x_clk_divisor / 2; let ddr2x_clk_divisor = 3 * ddr3x_clk_divisor / 2;
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
slcr.ddr_clk_ctrl.write( slcr.ddr_clk_ctrl.write(
slcr::DdrClkCtrl::zeroed() slcr::DdrClkCtrl::zeroed()
.ddr_2xclkact(true) .ddr_2xclkact(true)
.ddr_3xclkact(true) .ddr_3xclkact(true)
.ddr_2xclk_divisor(ddr2x_clk_divisor) .ddr_2xclk_divisor(ddr2x_clk_divisor)
.ddr_3xclk_divisor(ddr3x_clk_divisor) .ddr_3xclk_divisor(ddr3x_clk_divisor)
); );
});
clocks clocks
} }
@ -62,101 +61,99 @@ impl DdrRam {
let divisor1 = 1 + (clocks.ddr / DCI_FREQ / u32::from(divisor0)) let divisor1 = 1 + (clocks.ddr / DCI_FREQ / u32::from(divisor0))
.max(1).min(63) as u8; .max(1).min(63) as u8;
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
// Step 1. // Step 1.
slcr.dci_clk_ctrl.write( slcr.dci_clk_ctrl.write(
slcr::DciClkCtrl::zeroed() slcr::DciClkCtrl::zeroed()
.clkact(true) .clkact(true)
.divisor0(divisor0) .divisor0(divisor0)
.divisor1(divisor1) .divisor1(divisor1)
); );
// Step 2.a. // Step 2.a.
slcr.ddriob_dci_ctrl.modify(|_, w| slcr.ddriob_dci_ctrl.modify(|_, w|
w.reset(false) w.reset(false)
); );
slcr.ddriob_dci_ctrl.modify(|_, w| slcr.ddriob_dci_ctrl.modify(|_, w|
w.reset(true) w.reset(true)
); );
// Step 3.b. for DDR3/DDR3L // Step 3.b. for DDR3/DDR3L
slcr.ddriob_dci_ctrl.modify(|_, w| slcr.ddriob_dci_ctrl.modify(|_, w|
w.nref_opt1(0) w.nref_opt1(0)
.nref_opt2(0) .nref_opt2(0)
.nref_opt4(1) .nref_opt4(1)
.pref_opt1(0) .pref_opt1(0)
.pref_opt2(0) .pref_opt2(0)
); );
// Step 2.c. // Step 2.c.
slcr.ddriob_dci_ctrl.modify(|_, w| slcr.ddriob_dci_ctrl.modify(|_, w|
w.update_control(false) w.update_control(false)
); );
// Step 2.d. // Step 2.d.
slcr.ddriob_dci_ctrl.modify(|_, w| slcr.ddriob_dci_ctrl.modify(|_, w|
w.enable(true) w.enable(true)
); );
// Step 2.e. // Step 2.e.
while ! slcr.ddriob_dci_status.read().done() {} while ! slcr.ddriob_dci_status.read().done() {}
});
} }
/// Zynq-7000 AP SoC Technical Reference Manual: /// Zynq-7000 AP SoC Technical Reference Manual:
/// 10.6.3 DDR IOB Configuration /// 10.6.3 DDR IOB Configuration
fn configure_iob() { fn configure_iob() {
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
let addr_config = slcr::DdriobConfig::zeroed() let addr_config = slcr::DdriobConfig::zeroed()
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
slcr.ddriob_addr0.write(addr_config.clone()); slcr.ddriob_addr0.write(addr_config.clone());
slcr.ddriob_addr1.write(addr_config); slcr.ddriob_addr1.write(addr_config);
let data_config = slcr::DdriobConfig::zeroed() let data_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::VrefDifferential) .inp_type(slcr::DdriobInputType::VrefDifferential)
.term_en(true) .term_en(true)
.dci_type(slcr::DdriobDciType::Termination) .dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
slcr.ddriob_data0.write(data_config.clone()); slcr.ddriob_data0.write(data_config.clone());
slcr.ddriob_data1.write(data_config); slcr.ddriob_data1.write(data_config);
let diff_config = slcr::DdriobConfig::zeroed() let diff_config = slcr::DdriobConfig::zeroed()
.inp_type(slcr::DdriobInputType::Differential) .inp_type(slcr::DdriobInputType::Differential)
.term_en(true) .term_en(true)
.dci_type(slcr::DdriobDciType::Termination) .dci_type(slcr::DdriobDciType::Termination)
.output_en(slcr::DdriobOutputEn::Obuf); .output_en(slcr::DdriobOutputEn::Obuf);
slcr.ddriob_diff0.write(diff_config.clone()); slcr.ddriob_diff0.write(diff_config.clone());
slcr.ddriob_diff1.write(diff_config); slcr.ddriob_diff1.write(diff_config);
slcr.ddriob_clock.write( slcr.ddriob_clock.write(
slcr::DdriobConfig::zeroed() slcr::DdriobConfig::zeroed()
.output_en(slcr::DdriobOutputEn::Obuf) .output_en(slcr::DdriobOutputEn::Obuf)
); );
unsafe { unsafe {
// Not documented in Technical Reference Manual // Not documented in Technical Reference Manual
slcr.ddriob_drive_slew_addr.write(0x0018C61C); slcr.ddriob_drive_slew_addr.write(0x0018C61C);
slcr.ddriob_drive_slew_data.write(0x00F9861C); slcr.ddriob_drive_slew_data.write(0x00F9861C);
slcr.ddriob_drive_slew_diff.write(0x00F9861C); slcr.ddriob_drive_slew_diff.write(0x00F9861C);
slcr.ddriob_drive_slew_clock.write(0x00F9861C); slcr.ddriob_drive_slew_clock.write(0x00F9861C);
} }
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
let vref_sel = slcr::DdriobVrefSel::Vref0_75V; let vref_sel = slcr::DdriobVrefSel::Vref0_75V;
#[cfg(feature = "target_cora_z7_10")] #[cfg(feature = "target_cora_z7_10")]
let vref_sel = slcr::DdriobVrefSel::Vref0_675V; let vref_sel = slcr::DdriobVrefSel::Vref0_675V;
// // Enable internal V[REF] // // Enable internal V[REF]
// slcr.ddriob_ddr_ctrl.modify(|_, w| w // slcr.ddriob_ddr_ctrl.modify(|_, w| w
// .vref_ext_en_lower(false) // .vref_ext_en_lower(false)
// .vref_ext_en_upper(false) // .vref_ext_en_upper(false)
// .vref_sel(vref_sel) // .vref_sel(vref_sel)
// .vref_int_en(true) // .vref_int_en(true)
// ); // );
// Enable external V[REF] // Enable external V[REF]
slcr.ddriob_ddr_ctrl.modify(|_, w| w slcr.ddriob_ddr_ctrl.modify(|_, w| w
.vref_ext_en_lower(true) .vref_ext_en_lower(true)
.vref_ext_en_upper(true) .vref_ext_en_upper(true)
.vref_sel(vref_sel) .vref_sel(vref_sel)
.vref_int_en(false) .vref_int_en(false)
); );
});
} }
/// Reset DDR controller /// Reset DDR controller

View File

@ -25,132 +25,131 @@ pub struct Eth<'r, RX, TX> {
impl<'r> Eth<'r, (), ()> { impl<'r> Eth<'r, (), ()> {
pub fn default(macaddr: [u8; 6]) -> Self { pub fn default(macaddr: [u8; 6]) -> Self {
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
// Manual example: 0x0000_1280 // Manual example: 0x0000_1280
// MDIO // MDIO
slcr.mio_pin_53.write( slcr.mio_pin_53.write(
slcr::MioPin53::zeroed() slcr::MioPin53::zeroed()
.l3_sel(0b100) .l3_sel(0b100)
.io_type(slcr::IoBufferType::Lvcmos18) .io_type(slcr::IoBufferType::Lvcmos18)
.pullup(true) .pullup(true)
); );
// MDC // MDC
slcr.mio_pin_52.write( slcr.mio_pin_52.write(
slcr::MioPin52::zeroed() slcr::MioPin52::zeroed()
.l3_sel(0b100) .l3_sel(0b100)
.io_type(slcr::IoBufferType::Lvcmos18) .io_type(slcr::IoBufferType::Lvcmos18)
.pullup(true) .pullup(true)
); );
// Manual example: 0x0000_3902 // Manual example: 0x0000_3902
// TX_CLK // TX_CLK
slcr.mio_pin_16.write( slcr.mio_pin_16.write(
slcr::MioPin16::zeroed() slcr::MioPin16::zeroed()
.l0_sel(true) .l0_sel(true)
.speed(true) .speed(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
.disable_rcvr(true) .disable_rcvr(true)
); );
// TX_CTRL // TX_CTRL
slcr.mio_pin_21.write( slcr.mio_pin_21.write(
slcr::MioPin21::zeroed() slcr::MioPin21::zeroed()
.l0_sel(true) .l0_sel(true)
.speed(true) .speed(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
.disable_rcvr(true) .disable_rcvr(true)
); );
// TXD3 // TXD3
slcr.mio_pin_20.write( slcr.mio_pin_20.write(
slcr::MioPin20::zeroed() slcr::MioPin20::zeroed()
.l0_sel(true) .l0_sel(true)
.speed(true) .speed(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
.disable_rcvr(true) .disable_rcvr(true)
); );
// TXD2 // TXD2
slcr.mio_pin_19.write( slcr.mio_pin_19.write(
slcr::MioPin19::zeroed() slcr::MioPin19::zeroed()
.l0_sel(true) .l0_sel(true)
.speed(true) .speed(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
.disable_rcvr(true) .disable_rcvr(true)
); );
// TXD1 // TXD1
slcr.mio_pin_18.write( slcr.mio_pin_18.write(
slcr::MioPin18::zeroed() slcr::MioPin18::zeroed()
.l0_sel(true) .l0_sel(true)
.speed(true) .speed(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
.disable_rcvr(true) .disable_rcvr(true)
); );
// TXD0 // TXD0
slcr.mio_pin_17.write( slcr.mio_pin_17.write(
slcr::MioPin17::zeroed() slcr::MioPin17::zeroed()
.l0_sel(true) .l0_sel(true)
.speed(true) .speed(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
.disable_rcvr(true) .disable_rcvr(true)
); );
// Manual example: 0x0000_1903 // Manual example: 0x0000_1903
// RX_CLK // RX_CLK
slcr.mio_pin_22.write( slcr.mio_pin_22.write(
slcr::MioPin22::zeroed() slcr::MioPin22::zeroed()
.tri_enable(true) .tri_enable(true)
.l0_sel(true) .l0_sel(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
); );
// RX_CTRL // RX_CTRL
slcr.mio_pin_27.write( slcr.mio_pin_27.write(
slcr::MioPin27::zeroed() slcr::MioPin27::zeroed()
.tri_enable(true) .tri_enable(true)
.l0_sel(true) .l0_sel(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
); );
// RXD3 // RXD3
slcr.mio_pin_26.write( slcr.mio_pin_26.write(
slcr::MioPin26::zeroed() slcr::MioPin26::zeroed()
.tri_enable(true) .tri_enable(true)
.l0_sel(true) .l0_sel(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
); );
// RXD2 // RXD2
slcr.mio_pin_25.write( slcr.mio_pin_25.write(
slcr::MioPin25::zeroed() slcr::MioPin25::zeroed()
.tri_enable(true) .tri_enable(true)
.l0_sel(true) .l0_sel(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
); );
// RXD1 // RXD1
slcr.mio_pin_24.write( slcr.mio_pin_24.write(
slcr::MioPin24::zeroed() slcr::MioPin24::zeroed()
.tri_enable(true) .tri_enable(true)
.l0_sel(true) .l0_sel(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
); );
// RXD0 // RXD0
slcr.mio_pin_23.write( slcr.mio_pin_23.write(
slcr::MioPin23::zeroed() slcr::MioPin23::zeroed()
.tri_enable(true) .tri_enable(true)
.l0_sel(true) .l0_sel(true)
.io_type(slcr::IoBufferType::Hstl) .io_type(slcr::IoBufferType::Hstl)
.pullup(true) .pullup(true)
); );
// VREF internal generator // VREF internal generator
slcr.gpiob_ctrl.write( slcr.gpiob_ctrl.write(
slcr::GpiobCtrl::zeroed() slcr::GpiobCtrl::zeroed()
.vref_en(true) .vref_en(true)
); );
});
Self::gem0(macaddr) Self::gem0(macaddr)
} }
@ -196,23 +195,22 @@ impl<'r, RX, TX> Eth<'r, RX, TX> {
let d0 = (io_pll / tx_clock).min(63); let d0 = (io_pll / tx_clock).min(63);
let d1 = (io_pll / tx_clock / d0).min(63); let d1 = (io_pll / tx_clock / d0).min(63);
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
slcr.gem0_clk_ctrl.write( slcr.gem0_clk_ctrl.write(
// 0x0050_0801: 8, 5: 100 Mb/s // 0x0050_0801: 8, 5: 100 Mb/s
// ...: 8, 1: 1000 Mb/s // ...: 8, 1: 1000 Mb/s
slcr::GemClkCtrl::zeroed() slcr::GemClkCtrl::zeroed()
.clkact(true) .clkact(true)
.srcsel(slcr::PllSource::IoPll) .srcsel(slcr::PllSource::IoPll)
.divisor(d0 as u8) .divisor(d0 as u8)
.divisor1(d1 as u8) .divisor1(d1 as u8)
); );
// Enable gem0 recv clock // Enable gem0 recv clock
slcr.gem0_rclk_ctrl.write( slcr.gem0_rclk_ctrl.write(
// 0x0000_0801 // 0x0000_0801
slcr::RclkCtrl::zeroed() slcr::RclkCtrl::zeroed()
.clkact(true) .clkact(true)
); );
});
} }
pub fn setup_gem1_clock(tx_clock: u32) { pub fn setup_gem1_clock(tx_clock: u32) {
@ -220,21 +218,20 @@ impl<'r, RX, TX> Eth<'r, RX, TX> {
let d0 = (io_pll / tx_clock).min(63); let d0 = (io_pll / tx_clock).min(63);
let d1 = (io_pll / tx_clock / d0).min(63); let d1 = (io_pll / tx_clock / d0).min(63);
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
slcr.gem1_clk_ctrl.write( slcr.gem1_clk_ctrl.write(
slcr::GemClkCtrl::zeroed() slcr::GemClkCtrl::zeroed()
.clkact(true) .clkact(true)
.srcsel(slcr::PllSource::IoPll) .srcsel(slcr::PllSource::IoPll)
.divisor(d0 as u8) .divisor(d0 as u8)
.divisor1(d1 as u8) .divisor1(d1 as u8)
); );
// Enable gem1 recv clock // Enable gem1 recv clock
slcr.gem1_rclk_ctrl.write( slcr.gem1_rclk_ctrl.write(
// 0x0000_0801 // 0x0000_0801
slcr::RclkCtrl::zeroed() slcr::RclkCtrl::zeroed()
.clkact(true) .clkact(true)
); );
});
} }
pub fn start_rx<'rx>(self, rx_list: &'rx mut [rx::DescEntry], rx_buffers: &'rx mut [[u8; MTU]]) -> Eth<'r, rx::DescList<'rx>, TX> { pub fn start_rx<'rx>(self, rx_list: &'rx mut [rx::DescEntry], rx_buffers: &'rx mut [[u8; MTU]]) -> Eth<'r, rx::DescList<'rx>, TX> {

View File

@ -14,56 +14,53 @@ pub struct Uart {
impl Uart { impl Uart {
#[cfg(feature = "target_zc706")] #[cfg(feature = "target_zc706")]
pub fn serial(baudrate: u32) -> Self { pub fn serial(baudrate: u32) -> Self {
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
// Route UART 1 RxD/TxD Signals to MIO Pins // Route UART 1 RxD/TxD Signals to MIO Pins
// TX pin // TX pin
slcr.mio_pin_48.write( slcr.mio_pin_48.write(
slcr::MioPin48::zeroed() slcr::MioPin48::zeroed()
.l3_sel(0b111) .l3_sel(0b111)
.io_type(slcr::IoBufferType::Lvcmos18) .io_type(slcr::IoBufferType::Lvcmos18)
.pullup(true) .pullup(true)
); );
// RX pin // RX pin
slcr.mio_pin_49.write( slcr.mio_pin_49.write(
slcr::MioPin49::zeroed() slcr::MioPin49::zeroed()
.tri_enable(true) .tri_enable(true)
.l3_sel(0b111) .l3_sel(0b111)
.io_type(slcr::IoBufferType::Lvcmos18) .io_type(slcr::IoBufferType::Lvcmos18)
.pullup(true) .pullup(true)
); );
});
Self::uart1(baudrate) Self::uart1(baudrate)
} }
#[cfg(feature = "target_cora_z7_10")] #[cfg(feature = "target_cora_z7_10")]
pub fn serial(baudrate: u32) -> Self { pub fn serial(baudrate: u32) -> Self {
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
// Route UART 0 RxD/TxD Signals to MIO Pins // Route UART 0 RxD/TxD Signals to MIO Pins
// TX pin // TX pin
slcr.mio_pin_15.write( slcr.mio_pin_15.write(
slcr::MioPin15::zeroed() slcr::MioPin15::zeroed()
.l3_sel(0b111) .l3_sel(0b111)
.io_type(slcr::IoBufferType::Lvcmos33) .io_type(slcr::IoBufferType::Lvcmos33)
.pullup(true) .pullup(true)
); );
// RX pin // RX pin
slcr.mio_pin_14.write( slcr.mio_pin_14.write(
slcr::MioPin14::zeroed() slcr::MioPin14::zeroed()
.tri_enable(true) .tri_enable(true)
.l3_sel(0b111) .l3_sel(0b111)
.io_type(slcr::IoBufferType::Lvcmos33) .io_type(slcr::IoBufferType::Lvcmos33)
.pullup(true) .pullup(true)
); );
});
Self::uart0(baudrate) Self::uart0(baudrate)
} }
pub fn uart0(baudrate: u32) -> Self { pub fn uart0(baudrate: u32) -> Self {
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
slcr.uart_rst_ctrl.reset_uart0(); slcr.uart_rst_ctrl.reset_uart0();
slcr.aper_clk_ctrl.enable_uart0(); slcr.aper_clk_ctrl.enable_uart0();
slcr.uart_clk_ctrl.enable_uart0(); slcr.uart_clk_ctrl.enable_uart0();
});
let mut self_ = Uart { let mut self_ = Uart {
regs: regs::RegisterBlock::uart0(), regs: regs::RegisterBlock::uart0(),
}; };
@ -72,11 +69,10 @@ impl Uart {
} }
pub fn uart1(baudrate: u32) -> Self { pub fn uart1(baudrate: u32) -> Self {
slcr::RegisterBlock::unlocked(|slcr| { let slcr = slcr::RegisterBlock::new();
slcr.uart_rst_ctrl.reset_uart1(); slcr.uart_rst_ctrl.reset_uart1();
slcr.aper_clk_ctrl.enable_uart1(); slcr.aper_clk_ctrl.enable_uart1();
slcr.uart_clk_ctrl.enable_uart1(); slcr.uart_clk_ctrl.enable_uart1();
});
let mut self_ = Uart { let mut self_ = Uart {
regs: regs::RegisterBlock::uart1(), regs: regs::RegisterBlock::uart1(),
}; };