embassy_net_wiznet/
lib.rs1#![no_std]
2#![allow(async_fn_in_trait)]
3#![doc = include_str!("../README.md")]
4#![warn(missing_docs)]
5
6pub mod chip;
7mod device;
8
9use embassy_futures::select::{select3, Either3};
10use embassy_net_driver_channel as ch;
11use embassy_net_driver_channel::driver::LinkState;
12use embassy_time::{Duration, Ticker, Timer};
13use embedded_hal::digital::OutputPin;
14use embedded_hal_async::digital::Wait;
15use embedded_hal_async::spi::SpiDevice;
16
17use crate::chip::Chip;
18pub use crate::device::InitError;
19use crate::device::WiznetDevice;
20
21const MTU: usize = 1514;
23
24pub type Device<'d> = embassy_net_driver_channel::Device<'d, MTU>;
26
27pub struct State<const N_RX: usize, const N_TX: usize> {
38 ch_state: ch::State<MTU, N_RX, N_TX>,
39}
40
41impl<const N_RX: usize, const N_TX: usize> State<N_RX, N_TX> {
42 pub const fn new() -> Self {
44 Self {
45 ch_state: ch::State::new(),
46 }
47 }
48}
49
50pub struct Runner<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> {
54 mac: WiznetDevice<C, SPI>,
55 ch: ch::Runner<'d, MTU>,
56 int: INT,
57 _reset: RST,
58}
59
60impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> {
62 pub async fn run(mut self) -> ! {
64 let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
65 let mut tick = Ticker::every(Duration::from_millis(500));
66 loop {
67 match select3(
68 async {
69 self.int.wait_for_low().await.ok();
70 rx_chan.rx_buf().await
71 },
72 tx_chan.tx_buf(),
73 tick.next(),
74 )
75 .await
76 {
77 Either3::First(p) => {
78 if let Ok(n) = self.mac.read_frame(p).await {
79 rx_chan.rx_done(n);
80 }
81 }
82 Either3::Second(p) => {
83 self.mac.write_frame(p).await.ok();
84 tx_chan.tx_done();
85 }
86 Either3::Third(()) => {
87 if self.mac.is_link_up().await {
88 state_chan.set_link_state(LinkState::Up);
89 } else {
90 state_chan.set_link_state(LinkState::Down);
91 }
92 }
93 }
94 }
95 }
96}
97
98pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin>(
104 mac_addr: [u8; 6],
105 state: &'a mut State<N_RX, N_TX>,
106 spi_dev: SPI,
107 int: INT,
108 mut reset: RST,
109) -> Result<(Device<'a>, Runner<'a, C, SPI, INT, RST>), InitError<SPI::Error>> {
110 reset.set_low().ok();
112 Timer::after_millis(1).await;
114 reset.set_high().ok();
115
116 Timer::after_millis(100).await;
119
120 let mac = WiznetDevice::new(spi_dev, mac_addr).await?;
121
122 let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr));
123
124 Ok((
125 device,
126 Runner {
127 ch: runner,
128 mac,
129 int,
130 _reset: reset,
131 },
132 ))
133}