From 2b3c7e4b2f601fe717fc3130ec5544dfe1e1c4fd Mon Sep 17 00:00:00 2001 From: mwojcik Date: Thu, 10 Mar 2022 15:58:53 +0800 Subject: [PATCH] eth leds: * break led0 from led1 - similar, but not the same settings (led2 not implemented) * fix values, make it compilable * set default behavior (one led for link, other for activity) --- libboard_zynq/src/eth/mod.rs | 1 + libboard_zynq/src/eth/phy/leds.rs | 101 +++++++++++++++++------------- libboard_zynq/src/eth/phy/mod.rs | 58 ++++++++++++++++- 3 files changed, 115 insertions(+), 45 deletions(-) diff --git a/libboard_zynq/src/eth/mod.rs b/libboard_zynq/src/eth/mod.rs index e8e56e4..877b774 100644 --- a/libboard_zynq/src/eth/mod.rs +++ b/libboard_zynq/src/eth/mod.rs @@ -310,6 +310,7 @@ impl Eth { let phy = Phy::find(&mut inner).expect("phy"); phy.reset(&mut inner); phy.restart_autoneg(&mut inner); + phy.set_leds(&mut inner); Eth { rx: (), diff --git a/libboard_zynq/src/eth/phy/leds.rs b/libboard_zynq/src/eth/phy/leds.rs index 596cb63..27813a7 100644 --- a/libboard_zynq/src/eth/phy/leds.rs +++ b/libboard_zynq/src/eth/phy/leds.rs @@ -1,55 +1,58 @@ use bit_field::BitField; -use super::{PhyRegister, Link, LinkDuplex, LinkSpeed}; - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum LedControl { - OnLinkOffNoLink = 0b0000, - OnLinkBlinkActivityOffNoLink = 0b0001, - OnFullDuplexBlinkCollisionOffHalfDuplex = 0b0010, - OnActivityOffNoActivity = 0b0011, - BlinkActivityOffNoActivity = 0b0100, - OnTransmitOffNoTransmit = 0b0101, - On101000LinkOffElse = 0b0110, - On10LinkOffElse = 0b0111, - ForceOff = 0b1000, - ForceOn = 0b1001, - ForceHiZ = 0b1010, - ForceBlink = 0b1011, - //LED[0] only - Mode1 = 0b1100, - Mode2 = 0b1101, - Mode3 = 0b1110, - Mode4 = 0b1111 -} +use super::{PhyRegister, Led0Control, Led1Control}; #[derive(Clone, Copy, Debug)] /// LED Control Register pub struct Leds(pub u16); impl Leds { - pub fn led(led_no: u8) -> LedControl { - match self.0.get_bits((led_no*4)..=(led_no*4+3)) { - 0b0000 => LedControl::OnLinkOffNoLink, - 0b0001 => LedControl::OnLinkBlinkActivityOffNoLink, - 0b0010 => LedControl::OnFullDuplexBlinkCollisionOffHalfDuplex, - 0b0011 => LedControl::OnActivityOffNoActivity, - 0b0100 => LedControl::BlinkActivityOffNoActivity, - 0b0101 => LedControl::OnTransmitOffNoTransmit, - 0b0110 => LedControl::On101000LinkOffElse, - 0b0111 => LedControl::On10LinkOffElse, - 0b1000 => LedControl::ForceOff, - 0b1001 => LedControl::ForceOn, - 0b1010 => LedControl::ForceHiZ, - 0b1011 => LedControl::ForceBlink, - 0b1100 => LedControl::Mode1, - 0b1101 => LedControl::Mode2, - 0b1110 => LedControl::Mode3, - 0b1111 => LedControl::Mode4, + pub fn led0(&self) -> Led0Control { + match self.0.get_bits(0..=3) { + 0b0000 => Led0Control::OnLinkOffNoLink, + 0b0001 => Led0Control::OnLinkBlinkActivityOffNoLink, + 0b0010 => Led0Control::BlinkDependingOnLink, + 0b0011 => Led0Control::OnActivityOffNoActivity, + 0b0100 => Led0Control::BlinkActivityOffNoActivity, + 0b0101 => Led0Control::OnTransmitOffNoTransmit, + 0b0110 => Led0Control::OnCopperLinkOffElse, + 0b0111 => Led0Control::On1000LinkOffElse, + 0b1000 => Led0Control::ForceOff, + 0b1001 => Led0Control::ForceOn, + 0b1010 => Led0Control::ForceHiZ, + 0b1011 => Led0Control::ForceBlink, + 0b1100 => Led0Control::Mode1, + 0b1101 => Led0Control::Mode2, + 0b1110 => Led0Control::Mode3, + 0b1111 => Led0Control::Mode4, + _ => Led0Control::OnLinkOffNoLink, //impossible, but Rust compiler requires it + } + } + pub fn led1(&self) -> Led1Control { + match self.0.get_bits(4..=7) { + 0b0000 => Led1Control::OnReceiveOffNoReceive, + 0b0001 => Led1Control::OnLinkBlinkActivityOffNoLink, + 0b0010 => Led1Control::OnLinkBlinkReceiveOffNoLink, + 0b0011 => Led1Control::OnActivityOffNoActivity, + 0b0100 => Led1Control::BlinkActivityOffNoActivity, + 0b0101 => Led1Control::On100OrFiberOffElse, + 0b0110 => Led1Control::On1001000LinkOffElse, + 0b0111 => Led1Control::On100LinkOffElse, + 0b1000 => Led1Control::ForceOff, + 0b1001 => Led1Control::ForceOn, + 0b1010 => Led1Control::ForceHiZ, + 0b1011 => Led1Control::ForceBlink, + _ => Led1Control::Invalid, //impossible, but Rust compiler requires it } } - pub fn set_led(led_no: u8, setting: LedControl) -> Self { - self.0.set_bits((led_no*4)..=(led_no*4+3), setting as u8) + pub fn set_led0(mut self, setting: Led0Control) -> Self { + self.0.set_bits(0..=3, setting as u16); + self + } + + pub fn set_led1(mut self, setting: Led1Control) -> Self { + self.0.set_bits(4..=7, setting as u16); + self } } @@ -61,4 +64,16 @@ impl PhyRegister for Leds { fn page() -> u8 { 3 } -} \ No newline at end of file +} + +impl From for Leds { + fn from(value: u16) -> Self { + Leds(value) + } +} + +impl Into for Leds { + fn into(self) -> u16 { + self.0 + } +} diff --git a/libboard_zynq/src/eth/phy/mod.rs b/libboard_zynq/src/eth/phy/mod.rs index 16c3d68..b7209be 100644 --- a/libboard_zynq/src/eth/phy/mod.rs +++ b/libboard_zynq/src/eth/phy/mod.rs @@ -6,6 +6,8 @@ mod control; pub use control::Control; mod pssr; pub use pssr::PSSR; +mod leds; +pub use leds::Leds; #[derive(Copy, Clone, Debug, PartialEq)] pub struct Link { @@ -26,6 +28,43 @@ pub enum LinkDuplex { Full, } +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum Led0Control { + OnLinkOffNoLink = 0b0000, + OnLinkBlinkActivityOffNoLink = 0b0001, + BlinkDependingOnLink = 0b0010, + OnActivityOffNoActivity = 0b0011, + BlinkActivityOffNoActivity = 0b0100, + OnTransmitOffNoTransmit = 0b0101, + OnCopperLinkOffElse = 0b0110, + On1000LinkOffElse = 0b0111, + ForceOff = 0b1000, + ForceOn = 0b1001, + ForceHiZ = 0b1010, + ForceBlink = 0b1011, + Mode1 = 0b1100, + Mode2 = 0b1101, + Mode3 = 0b1110, + Mode4 = 0b1111 +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum Led1Control { + OnReceiveOffNoReceive = 0b0000, + OnLinkBlinkActivityOffNoLink = 0b0001, + OnLinkBlinkReceiveOffNoLink = 0b0010, + OnActivityOffNoActivity = 0b0011, + BlinkActivityOffNoActivity = 0b0100, + On100OrFiberOffElse = 0b0101, + On1001000LinkOffElse = 0b0110, + On100LinkOffElse = 0b0111, + ForceOff = 0b1000, + ForceOn = 0b1001, + ForceHiZ = 0b1010, + ForceBlink = 0b1011, + Invalid +} + pub trait PhyAccess { fn read_phy(&mut self, addr: u8, reg: u8) -> u16; fn write_phy(&mut self, addr: u8, reg: u8, data: u16); @@ -87,7 +126,7 @@ impl Phy { PA: PhyAccess, PR: PhyRegister + From, { - pa.write_phy(self.addr, PAGE_REGISTER, PR::page()); + pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into()); pa.read_phy(self.addr, PR::addr()).into() } @@ -97,7 +136,7 @@ impl Phy { PR: PhyRegister + From + Into, F: FnMut(PR) -> PR, { - pa.write_phy(self.addr, PAGE_REGISTER, PR::page()); + pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into()); let reg = pa.read_phy(self.addr, PR::addr()).into(); let reg = f(reg); pa.write_phy(self.addr, PR::addr(), reg.into()) @@ -111,6 +150,14 @@ impl Phy { self.modify_reg(pa, f) } + pub fn modify_leds(&self, pa: &mut PA, f: F) + where + PA: PhyAccess, + F: FnMut(Leds) -> Leds, + { + self.modify_reg(pa, f) + } + pub fn get_control(&self, pa: &mut PA) -> Control { self.read_reg(pa) } @@ -144,4 +191,11 @@ impl Phy { .set_restart_autoneg(true) ); } + + pub fn set_leds(&self, pa: &mut PA) { + self.modify_leds(pa, |leds| + leds.set_led0(Led0Control::OnCopperLinkOffElse) + .set_led1(Led1Control::BlinkActivityOffNoActivity) + ); + } }