diff --git a/experiments/src/main.rs b/experiments/src/main.rs index a75aa83..05e1f06 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -183,6 +183,20 @@ pub fn main_core0() { println!(""); } + #[cfg(feature = "target_kasli_soc")] + { + let mut err_cdwn = timer.countdown(); + let mut err_state = true; + let mut led = zynq::error_led::ErrorLED::error_led(); + task::spawn( async move { + loop { + led.toggle(err_state); + err_state = !err_state; + delay(&mut err_cdwn, Milliseconds(1000)).await; + } + }); + } + let eth = zynq::eth::Eth::eth0(HWADDR.clone()); println!("Eth on"); diff --git a/libboard_zynq/src/error_led.rs b/libboard_zynq/src/error_led.rs new file mode 100644 index 0000000..933c82a --- /dev/null +++ b/libboard_zynq/src/error_led.rs @@ -0,0 +1,116 @@ +use libregister::{RegisterRW, RegisterW}; +use libregister::{register, register_at, register_bit, register_bits}; +use super::slcr; + +pub struct ErrorLED { + regs: RegisterBlock, +} + +impl ErrorLED { + #[cfg(feature = "target_kasli_soc")] + pub fn error_led() -> Self { + slcr::RegisterBlock::unlocked(|slcr| { + // Error LED at MIO pin 37 + slcr.mio_pin_37.write( + slcr::MioPin37::zeroed() + .l3_sel(0b000) + .io_type(slcr::IoBufferType::Lvcmos25) + .pullup(true) + .disable_rcvr(true) + ); + // reset + slcr.gpio_rst_ctrl.reset_gpio(); + }); + + Self::error_led_common(0xFFFF - 0x0080) + } + + fn error_led_common(gpio_output_mask: u16) -> Self { + // Setup register block + let self_ = Self { + regs: RegisterBlock::error_led(), + }; + + // Setup GPIO output mask + self_.regs.gpio_output_mask.modify(|_, w| { + w.mask(gpio_output_mask) + }); + + self_.regs.gpio_direction.modify(|_, w| { + w.lederr(true) + }); + + self_ + } + + fn led_oe(&mut self, oe: bool) { + self.regs.gpio_output_enable.modify(|_, w| { + w.lederr(oe) + }) + } + + fn led_o(&mut self, o: bool) { + self.regs.gpio_output_mask.modify(|_, w| { + w.lederr_o(o) + }) + } + + pub fn toggle(&mut self, state: bool) { + self.led_o(state); + self.led_oe(state); + } +} + + +pub struct RegisterBlock { + pub gpio_output_mask: &'static mut GPIOOutputMask, + pub gpio_direction: &'static mut GPIODirection, + pub gpio_output_enable: &'static mut GPIOOutputEnable, +} + +impl RegisterBlock { + pub fn error_led() -> Self { + Self { + gpio_output_mask: GPIOOutputMask::new(), + gpio_direction: GPIODirection::new(), + gpio_output_enable: GPIOOutputEnable::new() + } + } +} + +register!(gpio_output_mask, + /// MASK_DATA_1_LSW: + /// Maskable output data for MIO[47:32] + GPIOOutputMask, RW, u32); +#[cfg(feature = "target_kasli_soc")] +register_at!(GPIOOutputMask, 0xE000A008, new); +#[cfg(feature = "target_kasli_soc")] +register_bit!(gpio_output_mask, + /// Output for LED_ERR (MIO[37]) + lederr_o, 5); +#[cfg(feature = "target_kasli_soc")] +register_bits!(gpio_output_mask, + mask, u16, 16, 31); + +register!(gpio_direction, + /// DIRM_1: + /// Direction mode for MIO[53:32]; 0/1 = in/out + GPIODirection, RW, u32); +#[cfg(feature = "target_kasli_soc")] +register_at!(GPIODirection, 0xE000A244, new); +#[cfg(feature = "target_kasli_soc")] +register_bit!(gpio_direction, + /// Direction for LED_ERR + lederr, 5); + +register!(gpio_output_enable, + /// OEN_1: + /// Output enable for MIO[53:32] + GPIOOutputEnable, RW, u32); +#[cfg(feature = "target_kasli_soc")] +register_at!(GPIOOutputEnable, 0xE000A248, new); +#[cfg(feature = "target_kasli_soc")] +register_bit!(gpio_output_enable, + /// Output enable for LED_ERR + lederr, 5); + \ No newline at end of file diff --git a/libboard_zynq/src/lib.rs b/libboard_zynq/src/lib.rs index 1f8251d..14c6e99 100644 --- a/libboard_zynq/src/lib.rs +++ b/libboard_zynq/src/lib.rs @@ -23,3 +23,5 @@ pub mod sdio; pub mod i2c; pub mod logger; pub mod ps7_init; +#[cfg(feature="target_kasli_soc")] +pub mod error_led; diff --git a/libsupport_zynq/src/panic.rs b/libsupport_zynq/src/panic.rs index 5b0b536..0f9d142 100644 --- a/libsupport_zynq/src/panic.rs +++ b/libsupport_zynq/src/panic.rs @@ -1,4 +1,6 @@ use libboard_zynq::{print, println}; +#[cfg(feature = "target_kasli_soc")] +use libboard_zynq::error_led::ErrorLED; #[panic_handler] fn panic(info: &core::panic::PanicInfo) -> ! { @@ -13,6 +15,10 @@ fn panic(info: &core::panic::PanicInfo) -> ! { } else { println!(""); } - + #[cfg(feature = "target_kasli_soc")] + { + let mut err_led = ErrorLED::error_led(); + err_led.toggle(true); + } loop {} }