net-wiznet: report link up/down on cable plug/unplug.

This commit is contained in:
Dario Nieuwenhuis 2023-10-20 01:29:10 +02:00
parent 035800bfbd
commit 630443a4d6

View File

@ -1,14 +1,14 @@
//! [`embassy-net`](https://crates.io/crates/embassy-net) driver for WIZnet ethernet chips.
#![no_std] #![no_std]
#![feature(async_fn_in_trait)] #![feature(async_fn_in_trait)]
#![doc = include_str!("../README.md")]
pub mod chip; pub mod chip;
mod device; mod device;
use embassy_futures::select::{select, Either}; use embassy_futures::select::{select3, Either3};
use embassy_net_driver_channel as ch; use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::LinkState; use embassy_net_driver_channel::driver::LinkState;
use embassy_time::Timer; use embassy_time::{Duration, Ticker, Timer};
use embedded_hal::digital::OutputPin; use embedded_hal::digital::OutputPin;
use embedded_hal_async::digital::Wait; use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::SpiDevice; use embedded_hal_async::spi::SpiDevice;
@ -49,32 +49,34 @@ pub struct Runner<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> {
impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> { impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> {
pub async fn run(mut self) -> ! { pub async fn run(mut self) -> ! {
let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
let mut tick = Ticker::every(Duration::from_millis(500));
loop { loop {
if self.mac.is_link_up().await { match select3(
state_chan.set_link_state(LinkState::Up); async {
loop { self.int.wait_for_low().await.ok();
match select( rx_chan.rx_buf().await
async { },
self.int.wait_for_low().await.ok(); tx_chan.tx_buf(),
rx_chan.rx_buf().await tick.next(),
}, )
tx_chan.tx_buf(), .await
) {
.await Either3::First(p) => {
{ if let Ok(n) = self.mac.read_frame(p).await {
Either::First(p) => { rx_chan.rx_done(n);
if let Ok(n) = self.mac.read_frame(p).await { }
rx_chan.rx_done(n); }
} Either3::Second(p) => {
} self.mac.write_frame(p).await.ok();
Either::Second(p) => { tx_chan.tx_done();
self.mac.write_frame(p).await.ok(); }
tx_chan.tx_done(); Either3::Third(()) => {
} if self.mac.is_link_up().await {
state_chan.set_link_state(LinkState::Up);
} else {
state_chan.set_link_state(LinkState::Down);
} }
} }
} else {
state_chan.set_link_state(LinkState::Down);
} }
} }
} }