diff --git a/experiments/Cargo.toml b/experiments/Cargo.toml index afa0a64..d5c0916 100644 --- a/experiments/Cargo.toml +++ b/experiments/Cargo.toml @@ -15,6 +15,9 @@ default = ["target_zc706"] [dependencies] log = "0.4" embedded-hal = "0.2" +volatile-register = "0.2" +bit_field = "0.10" +nb = "0.1" libregister = { path = "../libregister" } libcortex_a9 = { path = "../libcortex_a9" } libboard_zynq = { path = "../libboard_zynq" } diff --git a/experiments/src/main.rs b/experiments/src/main.rs index a75aa83..ededc48 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -25,6 +25,7 @@ use libboard_zynq::{ wire::{EthernetAddress, IpAddress, IpCidr}, }, time::Milliseconds, + slcr }; #[cfg(feature = "target_zc706")] use libboard_zynq::print; @@ -37,13 +38,19 @@ use libcortex_a9::{ spin_lock_yield, notify_spin_lock, asm, interrupt_handler }; -use libregister::{RegisterR, RegisterW}; +use libregister::{RegisterR, RegisterW, RegisterRW}; use libsupport_zynq::{ boot, ram, }; use log::{info, warn}; use core::sync::atomic::{AtomicBool, Ordering}; +use libregister::{ + register, register_at, + register_bit, register_bits +}; +use embedded_hal::timer::CountDown; + const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; static mut CORE1_REQ: (Sender, Receiver) = sync_channel!(usize, 10); @@ -84,6 +91,23 @@ pub fn restart_core1() { } } +// MIO[53:32] +register!(gpio_direction, GPIODirection, RW, u32); +register_at!(GPIODirection, 0xE000A244, new); +register_bit!(gpio_direction, phy_rst_n, 15); + +// MIO[53:32] +register!(gpio_output_enable, GPIOOutputEnable, RW, u32); +register_at!(GPIOOutputEnable, 0xE000A248, new); +register_bit!(gpio_output_enable, phy_rst_n, 15); + +// MIO[47:32] +register!(gpio_output_mask, GPIOOutputMask, RW, u32); +register_at!(GPIOOutputMask, 0xE000A008, new); +register_bit!(gpio_output_mask, phy_rst_n, 15); +register_bits!(gpio_output_mask, mask, u16, 16, 31); + + #[no_mangle] pub fn main_core0() { // zynq::clocks::CpuClocks::enable_io(1_250_000_000); @@ -183,6 +207,42 @@ pub fn main_core0() { println!(""); } + info!("resetting PHY -RST3"); + slcr::RegisterBlock::unlocked(|slcr| { + slcr.mio_pin_47.write( + slcr::MioPin47::zeroed() + .l3_sel(0b000) + .io_type(slcr::IoBufferType::Lvcmos18) + .disable_rcvr(true) + ); + slcr.gpio_rst_ctrl.reset_gpio(); + }); + let dir = GPIODirection::new(); + let oe = GPIOOutputEnable::new(); + let mask = GPIOOutputMask::new(); + mask.modify(|_, w| { + w.mask(0xffff & !(1 << 15)) + }); + dir.modify(|_, w| { + w.phy_rst_n(true) + }); + oe.modify(|_, w| { + w.phy_rst_n(true) + }); + + mask.modify(|_, w| { + w.phy_rst_n(false) + }); + let mut countdown: zynq::timer::global::CountDown = timer.countdown(); + countdown.start(Milliseconds(500)); + nb::block!(countdown.wait()).unwrap(); + mask.modify(|_, w| { + w.phy_rst_n(true) + }); + countdown.start(Milliseconds(500)); + nb::block!(countdown.wait()).unwrap(); + + let eth = zynq::eth::Eth::eth0(HWADDR.clone()); println!("Eth on");