forked from M-Labs/zynq-rs
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)
This commit is contained in:
parent
84d6d391ce
commit
2b3c7e4b2f
|
@ -310,6 +310,7 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
|
||||||
let phy = Phy::find(&mut inner).expect("phy");
|
let phy = Phy::find(&mut inner).expect("phy");
|
||||||
phy.reset(&mut inner);
|
phy.reset(&mut inner);
|
||||||
phy.restart_autoneg(&mut inner);
|
phy.restart_autoneg(&mut inner);
|
||||||
|
phy.set_leds(&mut inner);
|
||||||
|
|
||||||
Eth {
|
Eth {
|
||||||
rx: (),
|
rx: (),
|
||||||
|
|
|
@ -1,55 +1,58 @@
|
||||||
use bit_field::BitField;
|
use bit_field::BitField;
|
||||||
use super::{PhyRegister, Link, LinkDuplex, LinkSpeed};
|
use super::{PhyRegister, Led0Control, Led1Control};
|
||||||
|
|
||||||
#[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
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
/// LED Control Register
|
/// LED Control Register
|
||||||
pub struct Leds(pub u16);
|
pub struct Leds(pub u16);
|
||||||
|
|
||||||
impl Leds {
|
impl Leds {
|
||||||
pub fn led(led_no: u8) -> LedControl {
|
pub fn led0(&self) -> Led0Control {
|
||||||
match self.0.get_bits((led_no*4)..=(led_no*4+3)) {
|
match self.0.get_bits(0..=3) {
|
||||||
0b0000 => LedControl::OnLinkOffNoLink,
|
0b0000 => Led0Control::OnLinkOffNoLink,
|
||||||
0b0001 => LedControl::OnLinkBlinkActivityOffNoLink,
|
0b0001 => Led0Control::OnLinkBlinkActivityOffNoLink,
|
||||||
0b0010 => LedControl::OnFullDuplexBlinkCollisionOffHalfDuplex,
|
0b0010 => Led0Control::BlinkDependingOnLink,
|
||||||
0b0011 => LedControl::OnActivityOffNoActivity,
|
0b0011 => Led0Control::OnActivityOffNoActivity,
|
||||||
0b0100 => LedControl::BlinkActivityOffNoActivity,
|
0b0100 => Led0Control::BlinkActivityOffNoActivity,
|
||||||
0b0101 => LedControl::OnTransmitOffNoTransmit,
|
0b0101 => Led0Control::OnTransmitOffNoTransmit,
|
||||||
0b0110 => LedControl::On101000LinkOffElse,
|
0b0110 => Led0Control::OnCopperLinkOffElse,
|
||||||
0b0111 => LedControl::On10LinkOffElse,
|
0b0111 => Led0Control::On1000LinkOffElse,
|
||||||
0b1000 => LedControl::ForceOff,
|
0b1000 => Led0Control::ForceOff,
|
||||||
0b1001 => LedControl::ForceOn,
|
0b1001 => Led0Control::ForceOn,
|
||||||
0b1010 => LedControl::ForceHiZ,
|
0b1010 => Led0Control::ForceHiZ,
|
||||||
0b1011 => LedControl::ForceBlink,
|
0b1011 => Led0Control::ForceBlink,
|
||||||
0b1100 => LedControl::Mode1,
|
0b1100 => Led0Control::Mode1,
|
||||||
0b1101 => LedControl::Mode2,
|
0b1101 => Led0Control::Mode2,
|
||||||
0b1110 => LedControl::Mode3,
|
0b1110 => Led0Control::Mode3,
|
||||||
0b1111 => LedControl::Mode4,
|
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 {
|
pub fn set_led0(mut self, setting: Led0Control) -> Self {
|
||||||
self.0.set_bits((led_no*4)..=(led_no*4+3), setting as u8)
|
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 {
|
fn page() -> u8 {
|
||||||
3
|
3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<u16> for Leds {
|
||||||
|
fn from(value: u16) -> Self {
|
||||||
|
Leds(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<u16> for Leds {
|
||||||
|
fn into(self) -> u16 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ mod control;
|
||||||
pub use control::Control;
|
pub use control::Control;
|
||||||
mod pssr;
|
mod pssr;
|
||||||
pub use pssr::PSSR;
|
pub use pssr::PSSR;
|
||||||
|
mod leds;
|
||||||
|
pub use leds::Leds;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub struct Link {
|
pub struct Link {
|
||||||
|
@ -26,6 +28,43 @@ pub enum LinkDuplex {
|
||||||
Full,
|
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 {
|
pub trait PhyAccess {
|
||||||
fn read_phy(&mut self, addr: u8, reg: u8) -> u16;
|
fn read_phy(&mut self, addr: u8, reg: u8) -> u16;
|
||||||
fn write_phy(&mut self, addr: u8, reg: u8, data: u16);
|
fn write_phy(&mut self, addr: u8, reg: u8, data: u16);
|
||||||
|
@ -87,7 +126,7 @@ impl Phy {
|
||||||
PA: PhyAccess,
|
PA: PhyAccess,
|
||||||
PR: PhyRegister + From<u16>,
|
PR: PhyRegister + From<u16>,
|
||||||
{
|
{
|
||||||
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()
|
pa.read_phy(self.addr, PR::addr()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +136,7 @@ impl Phy {
|
||||||
PR: PhyRegister + From<u16> + Into<u16>,
|
PR: PhyRegister + From<u16> + Into<u16>,
|
||||||
F: FnMut(PR) -> PR,
|
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 = pa.read_phy(self.addr, PR::addr()).into();
|
||||||
let reg = f(reg);
|
let reg = f(reg);
|
||||||
pa.write_phy(self.addr, PR::addr(), reg.into())
|
pa.write_phy(self.addr, PR::addr(), reg.into())
|
||||||
|
@ -111,6 +150,14 @@ impl Phy {
|
||||||
self.modify_reg(pa, f)
|
self.modify_reg(pa, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn modify_leds<PA, F>(&self, pa: &mut PA, f: F)
|
||||||
|
where
|
||||||
|
PA: PhyAccess,
|
||||||
|
F: FnMut(Leds) -> Leds,
|
||||||
|
{
|
||||||
|
self.modify_reg(pa, f)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_control<PA: PhyAccess>(&self, pa: &mut PA) -> Control {
|
pub fn get_control<PA: PhyAccess>(&self, pa: &mut PA) -> Control {
|
||||||
self.read_reg(pa)
|
self.read_reg(pa)
|
||||||
}
|
}
|
||||||
|
@ -144,4 +191,11 @@ impl Phy {
|
||||||
.set_restart_autoneg(true)
|
.set_restart_autoneg(true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_leds<PA: PhyAccess>(&self, pa: &mut PA) {
|
||||||
|
self.modify_leds(pa, |leds|
|
||||||
|
leds.set_led0(Led0Control::OnCopperLinkOffElse)
|
||||||
|
.set_led1(Led1Control::BlinkActivityOffNoActivity)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue