add support for PHY_RST GPIO #104
|
@ -13,6 +13,9 @@ mod regs;
|
||||||
pub mod rx;
|
pub mod rx;
|
||||||
pub mod tx;
|
pub mod tx;
|
||||||
|
|
||||||
|
use super::time::Milliseconds;
|
||||||
|
use embedded_hal::timer::CountDown;
|
||||||
|
|
||||||
/// Size of all the buffers
|
/// Size of all the buffers
|
||||||
pub const MTU: usize = 1536;
|
pub const MTU: usize = 1536;
|
||||||
/// Maximum MDC clock
|
/// Maximum MDC clock
|
||||||
|
@ -300,11 +303,18 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
|
||||||
fn gem_common(macaddr: [u8; 6]) -> Self {
|
fn gem_common(macaddr: [u8; 6]) -> Self {
|
||||||
GEM::setup_clock(TX_1000);
|
GEM::setup_clock(TX_1000);
|
||||||
|
|
||||||
|
#[cfg(feature="target_kasli_soc")]
|
||||||
|
{
|
||||||
|
let mut eth_reset_pin = PhyRst::rst_pin();
|
||||||
|
eth_reset_pin.reset();
|
||||||
|
}
|
||||||
|
|
||||||
let mut inner = EthInner {
|
let mut inner = EthInner {
|
||||||
gem: PhantomData,
|
gem: PhantomData,
|
||||||
link: None,
|
link: None,
|
||||||
};
|
};
|
||||||
inner.init();
|
inner.init();
|
||||||
|
|
||||||
inner.configure(macaddr);
|
inner.configure(macaddr);
|
||||||
|
|
||||||
let phy = Phy::find(&mut inner).expect("phy");
|
let phy = Phy::find(&mut inner).expect("phy");
|
||||||
|
@ -482,6 +492,70 @@ impl<'a, GEM: Gem> smoltcp::phy::Device<'a> for &mut Eth<GEM, rx::DescList, tx::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PhyRst {
|
||||||
|
regs: regs::GpioRegisterBlock,
|
||||||
|
count_down: super::timer::global::CountDown<Milliseconds>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PhyRst {
|
||||||
|
pub fn rst_pin() -> Self {
|
||||||
|
slcr::RegisterBlock::unlocked(|slcr| {
|
||||||
|
// Hardware Reset for PHY
|
||||||
|
slcr.mio_pin_47.write(
|
||||||
|
slcr::MioPin47::zeroed()
|
||||||
|
.l3_sel(0b000)
|
||||||
|
.io_type(slcr::IoBufferType::Lvcmos18)
|
||||||
|
.pullup(true)
|
||||||
|
.disable_rcvr(true)
|
||||||
|
);
|
||||||
|
slcr.gpio_rst_ctrl.reset_gpio();
|
||||||
|
});
|
||||||
|
Self::eth_reset_common(0xFFFF - 0x8000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delay_ms(&mut self, ms: u64) {
|
||||||
|
self.count_down.start(Milliseconds(ms));
|
||||||
|
nb::block!(self.count_down.wait()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eth_reset_common(gpio_output_mask: u16) -> Self {
|
||||||
|
let self_ = Self {
|
||||||
|
regs: regs::GpioRegisterBlock::regs(),
|
||||||
|
count_down: unsafe { super::timer::GlobalTimer::get() }.countdown(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup GPIO output mask
|
||||||
|
self_.regs.gpio_output_mask.modify(|_, w| {
|
||||||
|
w.mask(gpio_output_mask)
|
||||||
|
});
|
||||||
|
|
||||||
|
self_.regs.gpio_direction.modify(|_, w| {
|
||||||
|
w.phy_rst(true)
|
||||||
|
});
|
||||||
|
|
||||||
|
self_
|
||||||
|
}
|
||||||
|
|
||||||
|
fn oe(&mut self, oe: bool) {
|
||||||
|
self.regs.gpio_output_enable.modify(|_, w| {
|
||||||
|
w.phy_rst(oe)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggle(&mut self, o: bool) {
|
||||||
|
self.regs.gpio_output_mask.modify(|_, w| {
|
||||||
|
w.phy_rst(o)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.toggle(false); // drive phy_rst (active LOW) pin low
|
||||||
|
self.oe(true); // enable pin's output
|
||||||
|
self.delay_ms(10);
|
||||||
|
self.toggle(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct EthInner<GEM: Gem> {
|
struct EthInner<GEM: Gem> {
|
||||||
gem: PhantomData<GEM>,
|
gem: PhantomData<GEM>,
|
||||||
|
|
|
@ -110,6 +110,49 @@ pub struct RegisterBlock {
|
||||||
pub design_cfg5: RO<u32>,
|
pub design_cfg5: RO<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GpioRegisterBlock {
|
||||||
|
pub gpio_output_mask: &'static mut OutputMask,
|
||||||
|
pub gpio_direction: &'static mut Direction,
|
||||||
|
pub gpio_output_enable: &'static mut OutputEnable,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GpioRegisterBlock {
|
||||||
|
pub fn regs() -> Self {
|
||||||
|
Self {
|
||||||
|
gpio_output_mask: OutputMask::new(),
|
||||||
|
gpio_direction: Direction::new(),
|
||||||
|
gpio_output_enable: OutputEnable::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register!(gpio_output_mask,
|
||||||
|
/// MASK_DATA_1_SW:
|
||||||
|
/// Maskable output data for MIO[47:32]
|
||||||
|
OutputMask, RW, u32);
|
||||||
|
register_at!(OutputMask, 0xE000A008, new);
|
||||||
|
register_bit!(gpio_output_mask,
|
||||||
|
/// Output for PHY_RST (MIO[47])
|
||||||
|
phy_rst, 15);
|
||||||
|
register_bits!(gpio_output_mask,
|
||||||
|
mask, u16, 16, 31);
|
||||||
|
register!(gpio_direction,
|
||||||
|
/// DIRM_1:
|
||||||
|
/// Direction mode for MIO[53:32]; 0/1 = in/out
|
||||||
|
Direction, RW, u32);
|
||||||
|
register_at!(Direction, 0xE000A244, new);
|
||||||
|
register_bit!(gpio_direction,
|
||||||
|
/// Direction for PHY_RST
|
||||||
|
phy_rst, 15);
|
||||||
|
register!(gpio_output_enable,
|
||||||
|
/// OEN_1:
|
||||||
|
/// Output enable for MIO[53:32]
|
||||||
|
OutputEnable, RW, u32);
|
||||||
|
register_at!(OutputEnable, 0xE000A248, new);
|
||||||
|
register_bit!(gpio_output_enable,
|
||||||
|
/// Output enable for PHY_RST
|
||||||
|
phy_rst, 15);
|
||||||
|
|
||||||
register_at!(RegisterBlock, 0xE000B000, gem0);
|
register_at!(RegisterBlock, 0xE000B000, gem0);
|
||||||
register_at!(RegisterBlock, 0xE000C000, gem1);
|
register_at!(RegisterBlock, 0xE000C000, gem1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue