forked from M-Labs/zynq-rs
libboard_zynq: eth phy for Marvell 88E1518
* add support for LED control registers * support for registers on different pages
This commit is contained in:
parent
43e0440911
commit
84d6d391ce
@ -82,6 +82,10 @@ impl PhyRegister for Control {
|
|||||||
fn addr() -> u8 {
|
fn addr() -> u8 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for Control {
|
impl From<u16> for Control {
|
||||||
|
64
libboard_zynq/src/eth/phy/leds.rs
Normal file
64
libboard_zynq/src/eth/phy/leds.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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 set_led(led_no: u8, setting: LedControl) -> Self {
|
||||||
|
self.0.set_bits((led_no*4)..=(led_no*4+3), setting as u8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PhyRegister for Leds {
|
||||||
|
fn addr() -> u8 {
|
||||||
|
0x10
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,7 @@ pub trait PhyAccess {
|
|||||||
|
|
||||||
pub trait PhyRegister {
|
pub trait PhyRegister {
|
||||||
fn addr() -> u8;
|
fn addr() -> u8;
|
||||||
|
fn page() -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +46,8 @@ const OUI_MARVELL: u32 = 0x005043;
|
|||||||
const OUI_REALTEK: u32 = 0x000732;
|
const OUI_REALTEK: u32 = 0x000732;
|
||||||
const OUI_LANTIQ : u32 = 0x355969;
|
const OUI_LANTIQ : u32 = 0x355969;
|
||||||
|
|
||||||
|
const PAGE_REGISTER: u8 = 0x16;
|
||||||
|
|
||||||
impl Phy {
|
impl Phy {
|
||||||
/// Probe all addresses on MDIO for a known PHY
|
/// Probe all addresses on MDIO for a known PHY
|
||||||
pub fn find<PA: PhyAccess>(pa: &mut PA) -> Option<Phy> {
|
pub fn find<PA: PhyAccess>(pa: &mut PA) -> Option<Phy> {
|
||||||
@ -84,6 +87,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.read_phy(self.addr, PR::addr()).into()
|
pa.read_phy(self.addr, PR::addr()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +97,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());
|
||||||
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())
|
||||||
|
@ -43,6 +43,10 @@ impl PhyRegister for PSSR {
|
|||||||
fn addr() -> u8 {
|
fn addr() -> u8 {
|
||||||
0x11
|
0x11
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for PSSR {
|
impl From<u16> for PSSR {
|
||||||
|
@ -100,6 +100,10 @@ impl PhyRegister for Status {
|
|||||||
fn addr() -> u8 {
|
fn addr() -> u8 {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn page() -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u16> for Status {
|
impl From<u16> for Status {
|
||||||
|
Loading…
Reference in New Issue
Block a user