eth: add drivers for init, polling & sending data
This commit is contained in:
parent
771f2813f7
commit
ee0ed8ebe7
|
@ -373,6 +373,7 @@ dependencies = [
|
||||||
"cortex-m-rt",
|
"cortex-m-rt",
|
||||||
"cortex-m-semihosting 0.5.0",
|
"cortex-m-semihosting 0.5.0",
|
||||||
"fugit",
|
"fugit",
|
||||||
|
"ieee802_3_miim",
|
||||||
"log",
|
"log",
|
||||||
"miniconf",
|
"miniconf",
|
||||||
"nb 1.1.0",
|
"nb 1.1.0",
|
||||||
|
|
|
@ -23,7 +23,8 @@ bare-metal = "1"
|
||||||
nb = "1"
|
nb = "1"
|
||||||
cortex-m-log = { version = "0.7.0", features = ["log-integration", "semihosting"] }
|
cortex-m-log = { version = "0.7.0", features = ["log-integration", "semihosting"] }
|
||||||
stm32f4xx-hal = { version = "0.14.0", features = ["rt", "stm32f407", "usb_fs"] }
|
stm32f4xx-hal = { version = "0.14.0", features = ["rt", "stm32f407", "usb_fs"] }
|
||||||
stm32-eth = { version = "0.5.2", features = ["stm32f407"] }
|
stm32-eth = { version = "0.5.2", features = ["stm32f407", "smoltcp-phy", "smoltcp"] }
|
||||||
|
ieee802_3_miim = "0.8.0"
|
||||||
smoltcp = { version = "0.10.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log", "medium-ethernet"] }
|
smoltcp = { version = "0.10.0", default-features = false, features = ["proto-ipv4", "socket-tcp", "log", "medium-ethernet"] }
|
||||||
uom = { version = "0.30", default-features = false, features = ["autoconvert", "si", "f64", "use_serde"] }
|
uom = { version = "0.30", default-features = false, features = ["autoconvert", "si", "f64", "use_serde"] }
|
||||||
num-traits = { version = "0.2.15", default-features = false, features = ["libm"] }
|
num-traits = { version = "0.2.15", default-features = false, features = ["libm"] }
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# echo-client.py
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
|
#192, 168, 1, 132
|
||||||
|
HOST = "192.168.1.132" # The server's hostname or IP address
|
||||||
|
PORT = 1337 # The port used by the server
|
||||||
|
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
s.connect((HOST, PORT))
|
||||||
|
s.sendall(b"Hello, world")
|
||||||
|
data = s.recv(1024)
|
||||||
|
|
||||||
|
print(f"Received {data!r}")
|
|
@ -1,9 +1,12 @@
|
||||||
use super::{gpio, sys_timer, usb};
|
use super::{gpio, sys_timer, usb};
|
||||||
use crate::device::flash_store::{self, FlashStore};
|
use crate::device::flash_store::{self, FlashStore};
|
||||||
|
use crate::device::sys_timer::sleep;
|
||||||
use crate::laser_diode::ld_ctrl::{*};
|
use crate::laser_diode::ld_ctrl::{*};
|
||||||
use crate::laser_diode::laser_diode::LdDrive;
|
use crate::laser_diode::laser_diode::LdDrive;
|
||||||
use crate::thermostat::max1968::MAX1968;
|
use crate::thermostat::max1968::MAX1968;
|
||||||
use crate::thermostat::thermostat::Thermostat;
|
use crate::thermostat::thermostat::Thermostat;
|
||||||
|
use crate::net::net::ServerHandle;
|
||||||
|
use stm32_eth;
|
||||||
use fugit::ExtU32;
|
use fugit::ExtU32;
|
||||||
use log::info;
|
use log::info;
|
||||||
use stm32f4xx_hal::{
|
use stm32f4xx_hal::{
|
||||||
|
@ -41,7 +44,7 @@ pub fn bootup(
|
||||||
|
|
||||||
sys_timer::setup(core_perif.SYST, clocks);
|
sys_timer::setup(core_perif.SYST, clocks);
|
||||||
|
|
||||||
let (_eth_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) = gpio::setup(
|
let (eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy) = gpio::setup(
|
||||||
clocks,
|
clocks,
|
||||||
perif.TIM4,
|
perif.TIM4,
|
||||||
perif.GPIOA,
|
perif.GPIOA,
|
||||||
|
@ -59,8 +62,21 @@ pub fn bootup(
|
||||||
|
|
||||||
usb::State::setup(usb);
|
usb::State::setup(usb);
|
||||||
|
|
||||||
let current_source = LdCtrl::new(current_source_phy);
|
let ethernet_parts_in = stm32_eth::PartsIn {
|
||||||
|
dma: perif.ETHERNET_DMA,
|
||||||
|
mac: perif.ETHERNET_MAC,
|
||||||
|
mmc: perif.ETHERNET_MMC,
|
||||||
|
ptp: perif.ETHERNET_PTP,
|
||||||
|
};
|
||||||
|
|
||||||
|
sleep(1000);
|
||||||
|
|
||||||
|
info!("Setting up ETH");
|
||||||
|
ServerHandle::new(eth_pins, eth_mgmt_pins, ethernet_parts_in, clocks);
|
||||||
|
info!("Setting finish setting up ETH");
|
||||||
|
|
||||||
|
let current_source = LdCtrl::new(current_source_phy);
|
||||||
|
info!("Setting up Laser");
|
||||||
let mut laser = LdDrive::new(current_source, perif.ADC2, pd_mon_phy);
|
let mut laser = LdDrive::new(current_source, perif.ADC2, pd_mon_phy);
|
||||||
laser.setup();
|
laser.setup();
|
||||||
laser.ld_open();
|
laser.ld_open();
|
||||||
|
@ -69,6 +85,7 @@ pub fn bootup(
|
||||||
laser.set_pd_i_limit(ElectricCurrent::new::<milliampere>(2.5));
|
laser.set_pd_i_limit(ElectricCurrent::new::<milliampere>(2.5));
|
||||||
laser.power_up();
|
laser.power_up();
|
||||||
|
|
||||||
|
info!("Setting up TEC");
|
||||||
let tec_driver = MAX1968::new(max1968_phy, perif.ADC1);
|
let tec_driver = MAX1968::new(max1968_phy, perif.ADC1);
|
||||||
|
|
||||||
let mut thermostat = Thermostat::new(tec_driver, ad7172_phy);
|
let mut thermostat = Thermostat::new(tec_driver, ad7172_phy);
|
||||||
|
|
|
@ -4,9 +4,10 @@ use crate::laser_diode::ld_pwr_exc_protector::LdPwrExcProtectorPhy;
|
||||||
use crate::thermostat::ad5680;
|
use crate::thermostat::ad5680;
|
||||||
use crate::thermostat::max1968::{self, MAX1968PinSet, MAX1968Phy, PWM_FREQ_KHZ};
|
use crate::thermostat::max1968::{self, MAX1968PinSet, MAX1968Phy, PWM_FREQ_KHZ};
|
||||||
use crate::thermostat::ad7172;
|
use crate::thermostat::ad7172;
|
||||||
|
use crate::net::net::EthernetMgmtPins;
|
||||||
use stm32_eth::EthPins;
|
use stm32_eth::EthPins;
|
||||||
use stm32f4xx_hal::{
|
use stm32f4xx_hal::{
|
||||||
gpio::{gpioa::*, gpiob::*, gpioc::*, GpioExt, Input},
|
gpio::{gpioa::*, gpiob::*, gpioc::*, GpioExt, Input, Speed},
|
||||||
otg_fs::USB,
|
otg_fs::USB,
|
||||||
pac::{
|
pac::{
|
||||||
GPIOA, GPIOB, GPIOC, GPIOD, GPIOG, OTG_FS_DEVICE, OTG_FS_GLOBAL, OTG_FS_PWRCLK, SPI1, SPI2, SPI3,
|
GPIOA, GPIOB, GPIOC, GPIOD, GPIOG, OTG_FS_DEVICE, OTG_FS_GLOBAL, OTG_FS_PWRCLK, SPI1, SPI2, SPI3,
|
||||||
|
@ -36,6 +37,7 @@ pub fn setup(
|
||||||
otg_fs_pwrclk: OTG_FS_PWRCLK,
|
otg_fs_pwrclk: OTG_FS_PWRCLK,
|
||||||
) -> (
|
) -> (
|
||||||
EthernetPins,
|
EthernetPins,
|
||||||
|
EthernetMgmtPins,
|
||||||
USB,
|
USB,
|
||||||
LdCtrlPhy<ld_ctrl::Channel0>,
|
LdCtrlPhy<ld_ctrl::Channel0>,
|
||||||
ad7172::AdcPhy,
|
ad7172::AdcPhy,
|
||||||
|
@ -67,6 +69,13 @@ pub fn setup(
|
||||||
rx_d1: gpioc.pc5,
|
rx_d1: gpioc.pc5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut eth_mgmt_pins = EthernetMgmtPins {
|
||||||
|
mdio: gpioa.pa2.into_alternate::<11>(),
|
||||||
|
mdc: gpioc.pc1.into_alternate::<11>(),
|
||||||
|
};
|
||||||
|
eth_mgmt_pins.mdio.set_speed(Speed::VeryHigh);
|
||||||
|
eth_mgmt_pins.mdc.set_speed(Speed::VeryHigh);
|
||||||
|
|
||||||
let current_source_phy = LdCtrlPhy {
|
let current_source_phy = LdCtrlPhy {
|
||||||
dac: max5719::Dac::new(Spi::new(
|
dac: max5719::Dac::new(Spi::new(
|
||||||
spi2,
|
spi2,
|
||||||
|
@ -137,5 +146,5 @@ pub fn setup(
|
||||||
gpioa.pa15.into_push_pull_output(),
|
gpioa.pa15.into_push_pull_output(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
(eth_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy)
|
(eth_pins, eth_mgmt_pins, usb, current_source_phy, ad7172_phy, max1968_phy, pd_mon_phy)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ mod device;
|
||||||
mod laser_diode;
|
mod laser_diode;
|
||||||
mod thermostat;
|
mod thermostat;
|
||||||
mod pid;
|
mod pid;
|
||||||
|
mod net;
|
||||||
|
|
||||||
use device::{boot::bootup, log_setup, sys_timer};
|
use device::{boot::bootup, log_setup, sys_timer};
|
||||||
use uom::fmt::DisplayStyle::Abbreviation;
|
use uom::fmt::DisplayStyle::Abbreviation;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod net;
|
|
@ -0,0 +1,289 @@
|
||||||
|
use crate::device::sys_timer;
|
||||||
|
use log::{debug, info, warn};
|
||||||
|
use smoltcp::{
|
||||||
|
iface::{
|
||||||
|
self, Interface, SocketHandle, SocketSet, SocketStorage
|
||||||
|
},
|
||||||
|
socket::tcp::{State, SocketBuffer, Socket},
|
||||||
|
wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address, Ipv4Cidr},
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
use stm32_eth::{
|
||||||
|
Parts, EthPins, PartsIn,
|
||||||
|
dma::{
|
||||||
|
TxRingEntry, RxRingEntry, EthernetDMA
|
||||||
|
}};
|
||||||
|
use stm32f4xx_hal::{
|
||||||
|
gpio::{gpioa::*, gpiob::*, gpioc::*, Alternate, Input},
|
||||||
|
rcc::Clocks,
|
||||||
|
interrupt,
|
||||||
|
};
|
||||||
|
|
||||||
|
const IPV4_ADDR: (u8, u8, u8, u8) = (192, 168, 1, 132);
|
||||||
|
const IP_INIT: IpCidr = IpCidr::Ipv4(Ipv4Cidr::new(
|
||||||
|
Ipv4Address::new(IPV4_ADDR.0, IPV4_ADDR.1, IPV4_ADDR.2, IPV4_ADDR.3),
|
||||||
|
24,
|
||||||
|
));
|
||||||
|
const ADDRESS: (IpAddress, u16) = (
|
||||||
|
IpAddress::Ipv4(Ipv4Address::new(
|
||||||
|
IPV4_ADDR.0,
|
||||||
|
IPV4_ADDR.1,
|
||||||
|
IPV4_ADDR.2,
|
||||||
|
IPV4_ADDR.3,
|
||||||
|
)),
|
||||||
|
1337,
|
||||||
|
);
|
||||||
|
const MAC: [u8; 6] = [0x02, 0x5f, 0x25, 0x37, 0x93, 0x0e];
|
||||||
|
|
||||||
|
pub struct ServerHandle {
|
||||||
|
socket_handle: SocketHandle,
|
||||||
|
socket_set: SocketSet<'static>,
|
||||||
|
iface: EthInterface,
|
||||||
|
dma: EthernetDMA<'static, 'static>,
|
||||||
|
}
|
||||||
|
pub type EthernetPins =
|
||||||
|
EthPins<PA1<Input>, PA7<Input>, PB11<Input>, PB12<Input>, PB13<Input>, PC4<Input>, PC5<Input>>;
|
||||||
|
pub struct EthernetMgmtPins {
|
||||||
|
pub mdio: PA2<Alternate<11>>,
|
||||||
|
pub mdc: PC1<Alternate<11>>,
|
||||||
|
}
|
||||||
|
pub type EthInterface = Interface;
|
||||||
|
|
||||||
|
static mut RX_RING: Option<[RxRingEntry; 8]> = None;
|
||||||
|
static mut TX_RING: Option<[TxRingEntry; 2]> = None;
|
||||||
|
static mut SOCKET_STORAGE: Option<[SocketStorage<'static>; 1]> = None;
|
||||||
|
|
||||||
|
static mut TCP_SOCKET_STORAGE : Option<TcpSocketStorage> = None;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct TcpSocketStorage {
|
||||||
|
rx_storage: [u8; 2048],
|
||||||
|
tx_storage: [u8; 2048],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TcpSocketStorage {
|
||||||
|
const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
rx_storage: [0; 2048],
|
||||||
|
tx_storage: [0; 2048],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn now_fn() -> smoltcp::time::Instant {
|
||||||
|
Instant::from_millis(i64::from(sys_timer::now()))
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut SERVER_HANDLE : Option<ServerHandle> = None;
|
||||||
|
|
||||||
|
impl ServerHandle {
|
||||||
|
pub fn new (eth_pins: EthernetPins,
|
||||||
|
eth_mgmt_pins: EthernetMgmtPins,
|
||||||
|
ethernet_parts_in: PartsIn,
|
||||||
|
clocks: Clocks,
|
||||||
|
) {
|
||||||
|
let rx_ring = unsafe { RX_RING.get_or_insert(Default::default()) };
|
||||||
|
let tx_ring = unsafe { TX_RING.get_or_insert(Default::default()) };
|
||||||
|
let tcp_socket_storage = unsafe { TCP_SOCKET_STORAGE.get_or_insert(TcpSocketStorage::new()) };
|
||||||
|
let socket_storage = unsafe { SOCKET_STORAGE.get_or_insert([SocketStorage::EMPTY; 1]) };
|
||||||
|
|
||||||
|
let Parts {
|
||||||
|
mut dma,
|
||||||
|
mac,
|
||||||
|
#[cfg(feature = "ptp")]
|
||||||
|
..
|
||||||
|
} = stm32_eth::new_with_mii(
|
||||||
|
ethernet_parts_in,
|
||||||
|
&mut rx_ring[..],
|
||||||
|
&mut tx_ring[..],
|
||||||
|
clocks,
|
||||||
|
eth_pins,
|
||||||
|
eth_mgmt_pins.mdio,
|
||||||
|
eth_mgmt_pins.mdc
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut routes = smoltcp::iface::Routes::new();
|
||||||
|
routes
|
||||||
|
.add_default_ipv4_route(Ipv4Address::new(192, 168, 1, 1))
|
||||||
|
.ok();
|
||||||
|
dma.enable_interrupt();
|
||||||
|
|
||||||
|
let rx_buffer = SocketBuffer::new(&mut tcp_socket_storage.rx_storage[..]);
|
||||||
|
let tx_buffer = SocketBuffer::new(&mut tcp_socket_storage.tx_storage[..]);
|
||||||
|
let socket = Socket::new(rx_buffer, tx_buffer);
|
||||||
|
|
||||||
|
let config = iface::Config::new(EthernetAddress::from_bytes(&MAC).into());
|
||||||
|
let mut iface = Interface::new(config, &mut &mut dma, smoltcp::time::Instant::ZERO);
|
||||||
|
iface.set_hardware_addr(EthernetAddress(MAC).into());
|
||||||
|
|
||||||
|
iface.update_ip_addrs(|addr| {
|
||||||
|
addr.push(IP_INIT).unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut sockets = SocketSet::new(&mut socket_storage[..]);
|
||||||
|
let tcp_handle = sockets.add(socket);
|
||||||
|
let socket = sockets.get_mut::<Socket>(tcp_handle);
|
||||||
|
socket.listen(ADDRESS).ok();
|
||||||
|
iface.poll(Instant::from_millis(i64::from(sys_timer::now())), &mut &mut dma, &mut sockets);
|
||||||
|
|
||||||
|
let server = ServerHandle {
|
||||||
|
socket_handle: tcp_handle,
|
||||||
|
socket_set: sockets,
|
||||||
|
iface: iface,
|
||||||
|
dma: dma,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(mut phy) = EthernetPhy::from_miim(mac, 0) {
|
||||||
|
info!(
|
||||||
|
"Resetting PHY as an extra step. Type: {}",
|
||||||
|
phy.ident_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
phy.phy_init();
|
||||||
|
} else {
|
||||||
|
info!("Not resetting unsupported PHY.");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
SERVER_HANDLE = Some(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn poll(&mut self, buffer: &mut [u8]) {
|
||||||
|
self.iface.poll(now_fn(), &mut &mut self.dma, &mut self.socket_set);
|
||||||
|
let socket = self.socket_set.get_mut::<Socket>(self.socket_handle);
|
||||||
|
|
||||||
|
if let Ok(recv_bytes) = socket.recv_slice(buffer) {
|
||||||
|
if recv_bytes > 0 {
|
||||||
|
socket.send_slice(&buffer[..recv_bytes]).ok();
|
||||||
|
info!("Echoed {} bytes.", recv_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !socket.is_listening() && !socket.is_open() || socket.state() == State::CloseWait {
|
||||||
|
socket.abort();
|
||||||
|
socket.listen(ADDRESS).ok();
|
||||||
|
warn!("Disconnected... Reopening listening socket.");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.iface.poll(now_fn(), &mut &mut self.dma, &mut self.socket_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use ieee802_3_miim::{
|
||||||
|
phy::{
|
||||||
|
lan87xxa::{LAN8720A, LAN8742A},
|
||||||
|
BarePhy, KSZ8081R,
|
||||||
|
},
|
||||||
|
Miim, Pause, Phy,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An ethernet PHY
|
||||||
|
pub enum EthernetPhy<M: Miim> {
|
||||||
|
/// LAN8720A
|
||||||
|
LAN8720A(LAN8720A<M>),
|
||||||
|
/// LAN8742A
|
||||||
|
LAN8742A(LAN8742A<M>),
|
||||||
|
/// KSZ8081R
|
||||||
|
KSZ8081R(KSZ8081R<M>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Miim> Phy<M> for EthernetPhy<M> {
|
||||||
|
fn best_supported_advertisement(&self) -> ieee802_3_miim::AutoNegotiationAdvertisement {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_miim(&mut self) -> &mut M {
|
||||||
|
match self {
|
||||||
|
EthernetPhy::LAN8720A(phy) => phy.get_miim(),
|
||||||
|
EthernetPhy::LAN8742A(phy) => phy.get_miim(),
|
||||||
|
EthernetPhy::KSZ8081R(phy) => phy.get_miim(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_phy_addr(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
EthernetPhy::LAN8720A(phy) => phy.get_phy_addr(),
|
||||||
|
EthernetPhy::LAN8742A(phy) => phy.get_phy_addr(),
|
||||||
|
EthernetPhy::KSZ8081R(phy) => phy.get_phy_addr(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Miim> EthernetPhy<M> {
|
||||||
|
/// Attempt to create one of the known PHYs from the given
|
||||||
|
/// MIIM.
|
||||||
|
///
|
||||||
|
/// Returns an error if the PHY does not support the extended register
|
||||||
|
/// set, or if the PHY's identifier does not correspond to a known PHY.
|
||||||
|
pub fn from_miim(miim: M, phy_addr: u8) -> Result<Self, M> {
|
||||||
|
let mut bare = BarePhy::new(miim, phy_addr, Pause::NoPause);
|
||||||
|
let phy_ident = if let Some(id) = bare.phy_ident() {
|
||||||
|
id.raw_u32()
|
||||||
|
} else {
|
||||||
|
return Err(bare.release());
|
||||||
|
};
|
||||||
|
let miim = bare.release();
|
||||||
|
match phy_ident & 0xFFFFFFF0 {
|
||||||
|
0x0007C0F0 => Ok(Self::LAN8720A(LAN8720A::new(miim, phy_addr))),
|
||||||
|
0x0007C130 => Ok(Self::LAN8742A(LAN8742A::new(miim, phy_addr))),
|
||||||
|
0x00221560 => Ok(Self::KSZ8081R(KSZ8081R::new(miim, phy_addr))),
|
||||||
|
_ => Err(miim),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a string describing the type of PHY
|
||||||
|
pub const fn ident_string(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
EthernetPhy::LAN8720A(_) => "LAN8720A",
|
||||||
|
EthernetPhy::LAN8742A(_) => "LAN8742A",
|
||||||
|
EthernetPhy::KSZ8081R(_) => "KSZ8081R",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Initialize the PHY
|
||||||
|
pub fn phy_init(&mut self) {
|
||||||
|
match self {
|
||||||
|
EthernetPhy::LAN8720A(phy) => phy.phy_init(),
|
||||||
|
EthernetPhy::LAN8742A(phy) => phy.phy_init(),
|
||||||
|
EthernetPhy::KSZ8081R(phy) => {
|
||||||
|
phy.set_autonegotiation_advertisement(phy.best_supported_advertisement());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn speed(&mut self) -> Option<ieee802_3_miim::phy::PhySpeed> {
|
||||||
|
match self {
|
||||||
|
EthernetPhy::LAN8720A(phy) => phy.link_speed(),
|
||||||
|
EthernetPhy::LAN8742A(phy) => phy.link_speed(),
|
||||||
|
EthernetPhy::KSZ8081R(phy) => phy.link_speed(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn release(self) -> M {
|
||||||
|
match self {
|
||||||
|
EthernetPhy::LAN8720A(phy) => phy.release(),
|
||||||
|
EthernetPhy::LAN8742A(phy) => phy.release(),
|
||||||
|
EthernetPhy::KSZ8081R(phy) => phy.release(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Potentially wake up from `wfi()`, set the interrupt pending flag,
|
||||||
|
/// clear interrupt flags.
|
||||||
|
#[interrupt]
|
||||||
|
fn ETH() {
|
||||||
|
let interrupt_reason = stm32_eth::eth_interrupt_handler();
|
||||||
|
debug!("Ethernet Interrupt{:?}", interrupt_reason);
|
||||||
|
unsafe{
|
||||||
|
if let Some(ref mut server_handle ) = SERVER_HANDLE {
|
||||||
|
let mut data : [u8; 512] = [0u8; 512];
|
||||||
|
server_handle.poll(&mut data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic!("Interrupt is called before init");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue