aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-08-15 17:50:56 +0200
committerDario Nieuwenhuis <[email protected]>2023-08-15 22:52:37 +0200
commit76276c326aaa4fd64a73253a480e2ea22f5ff740 (patch)
tree33a257710366497f68bf2669dacd3ad78516c3d5
parenta436bd068f6059fa073a9f1f246a77e1ce38dd31 (diff)
net-w5500: extract chip-specific stuff to a trait.
-rw-r--r--embassy-net-w5500/src/chip/mod.rs41
-rw-r--r--embassy-net-w5500/src/chip/w5500.rs67
-rw-r--r--embassy-net-w5500/src/device.rs94
-rw-r--r--embassy-net-w5500/src/lib.rs19
-rw-r--r--embassy-net-w5500/src/spi.rs34
-rw-r--r--examples/rp/src/bin/ethernet_w5500_multisocket.rs2
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_client.rs2
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_server.rs2
-rw-r--r--examples/rp/src/bin/ethernet_w5500_udp.rs2
9 files changed, 169 insertions, 94 deletions
diff --git a/embassy-net-w5500/src/chip/mod.rs b/embassy-net-w5500/src/chip/mod.rs
new file mode 100644
index 000000000..b7d550e26
--- /dev/null
+++ b/embassy-net-w5500/src/chip/mod.rs
@@ -0,0 +1,41 @@
1mod w5500;
2pub use w5500::W5500;
3
4pub(crate) mod sealed {
5 use embedded_hal_async::spi::SpiDevice;
6
7 pub trait Chip {
8 type Address;
9
10 const COMMON_MODE: Self::Address;
11 const COMMON_MAC: Self::Address;
12 const COMMON_SOCKET_INTR: Self::Address;
13 const COMMON_PHY_CFG: Self::Address;
14 const SOCKET_MODE: Self::Address;
15 const SOCKET_COMMAND: Self::Address;
16 const SOCKET_RXBUF_SIZE: Self::Address;
17 const SOCKET_TXBUF_SIZE: Self::Address;
18 const SOCKET_TX_FREE_SIZE: Self::Address;
19 const SOCKET_TX_DATA_WRITE_PTR: Self::Address;
20 const SOCKET_RECVD_SIZE: Self::Address;
21 const SOCKET_RX_DATA_READ_PTR: Self::Address;
22 const SOCKET_INTR_MASK: Self::Address;
23 const SOCKET_INTR: Self::Address;
24
25 fn rx_addr(addr: u16) -> Self::Address;
26 fn tx_addr(addr: u16) -> Self::Address;
27
28 async fn bus_read<SPI: SpiDevice>(
29 spi: &mut SPI,
30 address: Self::Address,
31 data: &mut [u8],
32 ) -> Result<(), SPI::Error>;
33 async fn bus_write<SPI: SpiDevice>(
34 spi: &mut SPI,
35 address: Self::Address,
36 data: &[u8],
37 ) -> Result<(), SPI::Error>;
38 }
39}
40
41pub trait Chip: sealed::Chip {}
diff --git a/embassy-net-w5500/src/chip/w5500.rs b/embassy-net-w5500/src/chip/w5500.rs
new file mode 100644
index 000000000..f514e12a7
--- /dev/null
+++ b/embassy-net-w5500/src/chip/w5500.rs
@@ -0,0 +1,67 @@
1use embedded_hal_async::spi::{Operation, SpiDevice};
2
3#[repr(u8)]
4pub enum RegisterBlock {
5 Common = 0x00,
6 Socket0 = 0x01,
7 TxBuf = 0x02,
8 RxBuf = 0x03,
9}
10
11pub enum W5500 {}
12
13impl super::Chip for W5500 {}
14impl super::sealed::Chip for W5500 {
15 type Address = (RegisterBlock, u16);
16
17 const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00);
18 const COMMON_MAC: Self::Address = (RegisterBlock::Common, 0x09);
19 const COMMON_SOCKET_INTR: Self::Address = (RegisterBlock::Common, 0x18);
20 const COMMON_PHY_CFG: Self::Address = (RegisterBlock::Common, 0x2E);
21
22 const SOCKET_MODE: Self::Address = (RegisterBlock::Socket0, 0x00);
23 const SOCKET_COMMAND: Self::Address = (RegisterBlock::Socket0, 0x01);
24 const SOCKET_RXBUF_SIZE: Self::Address = (RegisterBlock::Socket0, 0x1E);
25 const SOCKET_TXBUF_SIZE: Self::Address = (RegisterBlock::Socket0, 0x1F);
26 const SOCKET_TX_FREE_SIZE: Self::Address = (RegisterBlock::Socket0, 0x20);
27 const SOCKET_TX_DATA_WRITE_PTR: Self::Address = (RegisterBlock::Socket0, 0x24);
28 const SOCKET_RECVD_SIZE: Self::Address = (RegisterBlock::Socket0, 0x26);
29 const SOCKET_RX_DATA_READ_PTR: Self::Address = (RegisterBlock::Socket0, 0x28);
30 const SOCKET_INTR_MASK: Self::Address = (RegisterBlock::Socket0, 0x2C);
31 const SOCKET_INTR: Self::Address = (RegisterBlock::Socket0, 0x02);
32
33 fn rx_addr(addr: u16) -> Self::Address {
34 (RegisterBlock::RxBuf, addr)
35 }
36
37 fn tx_addr(addr: u16) -> Self::Address {
38 (RegisterBlock::TxBuf, addr)
39 }
40
41 async fn bus_read<SPI: SpiDevice>(
42 spi: &mut SPI,
43 address: Self::Address,
44 data: &mut [u8],
45 ) -> Result<(), SPI::Error> {
46 let address_phase = address.1.to_be_bytes();
47 let control_phase = [(address.0 as u8) << 3];
48 let operations = &mut [
49 Operation::Write(&address_phase),
50 Operation::Write(&control_phase),
51 Operation::TransferInPlace(data),
52 ];
53 spi.transaction(operations).await
54 }
55
56 async fn bus_write<SPI: SpiDevice>(spi: &mut SPI, address: Self::Address, data: &[u8]) -> Result<(), SPI::Error> {
57 let address_phase = address.1.to_be_bytes();
58 let control_phase = [(address.0 as u8) << 3 | 0b0000_0100];
59 let data_phase = data;
60 let operations = &mut [
61 Operation::Write(&address_phase[..]),
62 Operation::Write(&control_phase),
63 Operation::Write(&data_phase),
64 ];
65 spi.transaction(operations).await
66 }
67}
diff --git a/embassy-net-w5500/src/device.rs b/embassy-net-w5500/src/device.rs
index cf451b334..a6ee8f8f7 100644
--- a/embassy-net-w5500/src/device.rs
+++ b/embassy-net-w5500/src/device.rs
@@ -1,117 +1,107 @@
1use embedded_hal_async::spi::SpiDevice; 1use core::marker::PhantomData;
2
3use crate::spi::{Address, SpiInterface};
4 2
5pub const COMMON_MODE: Address = (RegisterBlock::Common, 0x00); 3use embedded_hal_async::spi::SpiDevice;
6pub const COMMON_MAC: Address = (RegisterBlock::Common, 0x09);
7pub const COMMON_SOCKET_INTR: Address = (RegisterBlock::Common, 0x18);
8pub const COMMON_PHY_CFG: Address = (RegisterBlock::Common, 0x2E);
9 4
10pub const SOCKET_MODE: Address = (RegisterBlock::Socket0, 0x00); 5use crate::chip::Chip;
11pub const SOCKET_COMMAND: Address = (RegisterBlock::Socket0, 0x01);
12pub const SOCKET_RXBUF_SIZE: Address = (RegisterBlock::Socket0, 0x1E);
13pub const SOCKET_TXBUF_SIZE: Address = (RegisterBlock::Socket0, 0x1F);
14pub const SOCKET_TX_FREE_SIZE: Address = (RegisterBlock::Socket0, 0x20);
15pub const SOCKET_TX_DATA_WRITE_PTR: Address = (RegisterBlock::Socket0, 0x24);
16pub const SOCKET_RECVD_SIZE: Address = (RegisterBlock::Socket0, 0x26);
17pub const SOCKET_RX_DATA_READ_PTR: Address = (RegisterBlock::Socket0, 0x28);
18pub const SOCKET_INTR_MASK: Address = (RegisterBlock::Socket0, 0x2C);
19pub const SOCKET_INTR: Address = (RegisterBlock::Socket0, 0x02);
20 6
21#[repr(u8)] 7#[repr(u8)]
22pub enum Command { 8enum Command {
23 Open = 0x01, 9 Open = 0x01,
24 Send = 0x20, 10 Send = 0x20,
25 Receive = 0x40, 11 Receive = 0x40,
26} 12}
27 13
28#[repr(u8)] 14#[repr(u8)]
29pub enum Interrupt { 15enum Interrupt {
30 Receive = 0b00100_u8, 16 Receive = 0b00100_u8,
31} 17}
32 18
33#[repr(u8)]
34pub enum RegisterBlock {
35 Common = 0x00,
36 Socket0 = 0x01,
37 TxBuf = 0x02,
38 RxBuf = 0x03,
39}
40
41/// W5500 in MACRAW mode 19/// W5500 in MACRAW mode
42#[derive(Debug)] 20#[derive(Debug)]
43#[cfg_attr(feature = "defmt", derive(defmt::Format))] 21#[cfg_attr(feature = "defmt", derive(defmt::Format))]
44pub struct W5500<SPI> { 22pub(crate) struct WiznetDevice<C, SPI> {
45 bus: SpiInterface<SPI>, 23 spi: SPI,
24 _phantom: PhantomData<C>,
46} 25}
47 26
48impl<SPI: SpiDevice> W5500<SPI> { 27impl<C: Chip, SPI: SpiDevice> WiznetDevice<C, SPI> {
49 /// Create and initialize the W5500 driver 28 /// Create and initialize the W5500 driver
50 pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result<W5500<SPI>, SPI::Error> { 29 pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result<Self, SPI::Error> {
51 let mut bus = SpiInterface(spi); 30 let mut this = Self {
31 spi,
32 _phantom: PhantomData,
33 };
34
52 // Reset device 35 // Reset device
53 bus.write_frame(COMMON_MODE, &[0x80]).await?; 36 this.bus_write(C::COMMON_MODE, &[0x80]).await?;
54 37
55 // Enable interrupt pin 38 // Enable interrupt pin
56 bus.write_frame(COMMON_SOCKET_INTR, &[0x01]).await?; 39 this.bus_write(C::COMMON_SOCKET_INTR, &[0x01]).await?;
57 // Enable receive interrupt 40 // Enable receive interrupt
58 bus.write_frame(SOCKET_INTR_MASK, &[Interrupt::Receive as u8]).await?; 41 this.bus_write(C::SOCKET_INTR_MASK, &[Interrupt::Receive as u8]).await?;
59 42
60 // Set MAC address 43 // Set MAC address
61 bus.write_frame(COMMON_MAC, &mac_addr).await?; 44 this.bus_write(C::COMMON_MAC, &mac_addr).await?;
62 45
63 // Set the raw socket RX/TX buffer sizes to 16KB 46 // Set the raw socket RX/TX buffer sizes to 16KB
64 bus.write_frame(SOCKET_TXBUF_SIZE, &[16]).await?; 47 this.bus_write(C::SOCKET_TXBUF_SIZE, &[16]).await?;
65 bus.write_frame(SOCKET_RXBUF_SIZE, &[16]).await?; 48 this.bus_write(C::SOCKET_RXBUF_SIZE, &[16]).await?;
66 49
67 // MACRAW mode with MAC filtering. 50 // MACRAW mode with MAC filtering.
68 let mode: u8 = (1 << 2) | (1 << 7); 51 let mode: u8 = (1 << 2) | (1 << 7);
69 bus.write_frame(SOCKET_MODE, &[mode]).await?; 52 this.bus_write(C::SOCKET_MODE, &[mode]).await?;
70 let mut this = Self { bus };
71 this.command(Command::Open).await?; 53 this.command(Command::Open).await?;
72 54
73 Ok(this) 55 Ok(this)
74 } 56 }
75 57
58 async fn bus_read(&mut self, address: C::Address, data: &mut [u8]) -> Result<(), SPI::Error> {
59 C::bus_read(&mut self.spi, address, data).await
60 }
61
62 async fn bus_write(&mut self, address: C::Address, data: &[u8]) -> Result<(), SPI::Error> {
63 C::bus_write(&mut self.spi, address, data).await
64 }
65
76 async fn reset_interrupt(&mut self, code: Interrupt) -> Result<(), SPI::Error> { 66 async fn reset_interrupt(&mut self, code: Interrupt) -> Result<(), SPI::Error> {
77 let data = [code as u8]; 67 let data = [code as u8];
78 self.bus.write_frame(SOCKET_INTR, &data).await 68 self.bus_write(C::SOCKET_INTR, &data).await
79 } 69 }
80 70
81 async fn get_tx_write_ptr(&mut self) -> Result<u16, SPI::Error> { 71 async fn get_tx_write_ptr(&mut self) -> Result<u16, SPI::Error> {
82 let mut data = [0u8; 2]; 72 let mut data = [0u8; 2];
83 self.bus.read_frame(SOCKET_TX_DATA_WRITE_PTR, &mut data).await?; 73 self.bus_read(C::SOCKET_TX_DATA_WRITE_PTR, &mut data).await?;
84 Ok(u16::from_be_bytes(data)) 74 Ok(u16::from_be_bytes(data))
85 } 75 }
86 76
87 async fn set_tx_write_ptr(&mut self, ptr: u16) -> Result<(), SPI::Error> { 77 async fn set_tx_write_ptr(&mut self, ptr: u16) -> Result<(), SPI::Error> {
88 let data = ptr.to_be_bytes(); 78 let data = ptr.to_be_bytes();
89 self.bus.write_frame(SOCKET_TX_DATA_WRITE_PTR, &data).await 79 self.bus_write(C::SOCKET_TX_DATA_WRITE_PTR, &data).await
90 } 80 }
91 81
92 async fn get_rx_read_ptr(&mut self) -> Result<u16, SPI::Error> { 82 async fn get_rx_read_ptr(&mut self) -> Result<u16, SPI::Error> {
93 let mut data = [0u8; 2]; 83 let mut data = [0u8; 2];
94 self.bus.read_frame(SOCKET_RX_DATA_READ_PTR, &mut data).await?; 84 self.bus_read(C::SOCKET_RX_DATA_READ_PTR, &mut data).await?;
95 Ok(u16::from_be_bytes(data)) 85 Ok(u16::from_be_bytes(data))
96 } 86 }
97 87
98 async fn set_rx_read_ptr(&mut self, ptr: u16) -> Result<(), SPI::Error> { 88 async fn set_rx_read_ptr(&mut self, ptr: u16) -> Result<(), SPI::Error> {
99 let data = ptr.to_be_bytes(); 89 let data = ptr.to_be_bytes();
100 self.bus.write_frame(SOCKET_RX_DATA_READ_PTR, &data).await 90 self.bus_write(C::SOCKET_RX_DATA_READ_PTR, &data).await
101 } 91 }
102 92
103 async fn command(&mut self, command: Command) -> Result<(), SPI::Error> { 93 async fn command(&mut self, command: Command) -> Result<(), SPI::Error> {
104 let data = [command as u8]; 94 let data = [command as u8];
105 self.bus.write_frame(SOCKET_COMMAND, &data).await 95 self.bus_write(C::SOCKET_COMMAND, &data).await
106 } 96 }
107 97
108 async fn get_rx_size(&mut self) -> Result<u16, SPI::Error> { 98 async fn get_rx_size(&mut self) -> Result<u16, SPI::Error> {
109 loop { 99 loop {
110 // Wait until two sequential reads are equal 100 // Wait until two sequential reads are equal
111 let mut res0 = [0u8; 2]; 101 let mut res0 = [0u8; 2];
112 self.bus.read_frame(SOCKET_RECVD_SIZE, &mut res0).await?; 102 self.bus_read(C::SOCKET_RECVD_SIZE, &mut res0).await?;
113 let mut res1 = [0u8; 2]; 103 let mut res1 = [0u8; 2];
114 self.bus.read_frame(SOCKET_RECVD_SIZE, &mut res1).await?; 104 self.bus_read(C::SOCKET_RECVD_SIZE, &mut res1).await?;
115 if res0 == res1 { 105 if res0 == res1 {
116 break Ok(u16::from_be_bytes(res0)); 106 break Ok(u16::from_be_bytes(res0));
117 } 107 }
@@ -120,13 +110,13 @@ impl<SPI: SpiDevice> W5500<SPI> {
120 110
121 async fn get_tx_free_size(&mut self) -> Result<u16, SPI::Error> { 111 async fn get_tx_free_size(&mut self) -> Result<u16, SPI::Error> {
122 let mut data = [0; 2]; 112 let mut data = [0; 2];
123 self.bus.read_frame(SOCKET_TX_FREE_SIZE, &mut data).await?; 113 self.bus_read(C::SOCKET_TX_FREE_SIZE, &mut data).await?;
124 Ok(u16::from_be_bytes(data)) 114 Ok(u16::from_be_bytes(data))
125 } 115 }
126 116
127 /// Read bytes from the RX buffer. Returns the number of bytes read. 117 /// Read bytes from the RX buffer. Returns the number of bytes read.
128 async fn read_bytes(&mut self, read_ptr: &mut u16, buffer: &mut [u8]) -> Result<(), SPI::Error> { 118 async fn read_bytes(&mut self, read_ptr: &mut u16, buffer: &mut [u8]) -> Result<(), SPI::Error> {
129 self.bus.read_frame((RegisterBlock::RxBuf, *read_ptr), buffer).await?; 119 self.bus_read(C::rx_addr(*read_ptr), buffer).await?;
130 *read_ptr = (*read_ptr).wrapping_add(buffer.len() as u16); 120 *read_ptr = (*read_ptr).wrapping_add(buffer.len() as u16);
131 121
132 Ok(()) 122 Ok(())
@@ -165,7 +155,7 @@ impl<SPI: SpiDevice> W5500<SPI> {
165 pub async fn write_frame(&mut self, frame: &[u8]) -> Result<usize, SPI::Error> { 155 pub async fn write_frame(&mut self, frame: &[u8]) -> Result<usize, SPI::Error> {
166 while self.get_tx_free_size().await? < frame.len() as u16 {} 156 while self.get_tx_free_size().await? < frame.len() as u16 {}
167 let write_ptr = self.get_tx_write_ptr().await?; 157 let write_ptr = self.get_tx_write_ptr().await?;
168 self.bus.write_frame((RegisterBlock::TxBuf, write_ptr), frame).await?; 158 self.bus_write(C::tx_addr(write_ptr), frame).await?;
169 self.set_tx_write_ptr(write_ptr.wrapping_add(frame.len() as u16)) 159 self.set_tx_write_ptr(write_ptr.wrapping_add(frame.len() as u16))
170 .await?; 160 .await?;
171 self.command(Command::Send).await?; 161 self.command(Command::Send).await?;
@@ -174,7 +164,7 @@ impl<SPI: SpiDevice> W5500<SPI> {
174 164
175 pub async fn is_link_up(&mut self) -> bool { 165 pub async fn is_link_up(&mut self) -> bool {
176 let mut link = [0]; 166 let mut link = [0];
177 self.bus.read_frame(COMMON_PHY_CFG, &mut link).await.ok(); 167 self.bus_read(C::COMMON_PHY_CFG, &mut link).await.ok();
178 link[0] & 1 == 1 168 link[0] & 1 == 1
179 } 169 }
180} 170}
diff --git a/embassy-net-w5500/src/lib.rs b/embassy-net-w5500/src/lib.rs
index 3c54777d8..9b53e9618 100644
--- a/embassy-net-w5500/src/lib.rs
+++ b/embassy-net-w5500/src/lib.rs
@@ -1,8 +1,9 @@
1//! [`embassy-net`](https://crates.io/crates/embassy-net) driver for the WIZnet W5500 ethernet chip. 1//! [`embassy-net`](https://crates.io/crates/embassy-net) driver for the WIZnet W5500 ethernet chip.
2#![no_std] 2#![no_std]
3#![feature(async_fn_in_trait)]
3 4
5pub mod chip;
4mod device; 6mod device;
5mod spi;
6 7
7use embassy_futures::select::{select, Either}; 8use embassy_futures::select::{select, Either};
8use embassy_net_driver_channel as ch; 9use embassy_net_driver_channel as ch;
@@ -12,7 +13,9 @@ use embedded_hal::digital::OutputPin;
12use embedded_hal_async::digital::Wait; 13use embedded_hal_async::digital::Wait;
13use embedded_hal_async::spi::SpiDevice; 14use embedded_hal_async::spi::SpiDevice;
14 15
15use crate::device::W5500; 16use crate::chip::Chip;
17use crate::device::WiznetDevice;
18
16const MTU: usize = 1514; 19const MTU: usize = 1514;
17 20
18/// Type alias for the embassy-net driver for W5500 21/// Type alias for the embassy-net driver for W5500
@@ -35,15 +38,15 @@ impl<const N_RX: usize, const N_TX: usize> State<N_RX, N_TX> {
35/// Background runner for the W5500. 38/// Background runner for the W5500.
36/// 39///
37/// You must call `.run()` in a background task for the W5500 to operate. 40/// You must call `.run()` in a background task for the W5500 to operate.
38pub struct Runner<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> { 41pub struct Runner<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> {
39 mac: W5500<SPI>, 42 mac: WiznetDevice<C, SPI>,
40 ch: ch::Runner<'d, MTU>, 43 ch: ch::Runner<'d, MTU>,
41 int: INT, 44 int: INT,
42 _reset: RST, 45 _reset: RST,
43} 46}
44 47
45/// You must call this in a background task for the W5500 to operate. 48/// You must call this in a background task for the W5500 to operate.
46impl<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, SPI, INT, RST> { 49impl<'d, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, C, SPI, INT, RST> {
47 pub async fn run(mut self) -> ! { 50 pub async fn run(mut self) -> ! {
48 let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); 51 let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
49 loop { 52 loop {
@@ -78,13 +81,13 @@ impl<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, SPI, INT, RST> {
78} 81}
79 82
80/// Obtain a driver for using the W5500 with [`embassy-net`](https://crates.io/crates/embassy-net). 83/// Obtain a driver for using the W5500 with [`embassy-net`](https://crates.io/crates/embassy-net).
81pub async fn new<'a, const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait, RST: OutputPin>( 84pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevice, INT: Wait, RST: OutputPin>(
82 mac_addr: [u8; 6], 85 mac_addr: [u8; 6],
83 state: &'a mut State<N_RX, N_TX>, 86 state: &'a mut State<N_RX, N_TX>,
84 spi_dev: SPI, 87 spi_dev: SPI,
85 int: INT, 88 int: INT,
86 mut reset: RST, 89 mut reset: RST,
87) -> (Device<'a>, Runner<'a, SPI, INT, RST>) { 90) -> (Device<'a>, Runner<'a, C, SPI, INT, RST>) {
88 // Reset the W5500. 91 // Reset the W5500.
89 reset.set_low().ok(); 92 reset.set_low().ok();
90 // Ensure the reset is registered. 93 // Ensure the reset is registered.
@@ -93,7 +96,7 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT:
93 // Wait for the W5500 to achieve PLL lock. 96 // Wait for the W5500 to achieve PLL lock.
94 Timer::after(Duration::from_millis(2)).await; 97 Timer::after(Duration::from_millis(2)).await;
95 98
96 let mac = W5500::new(spi_dev, mac_addr).await.unwrap(); 99 let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap();
97 100
98 let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr)); 101 let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr));
99 ( 102 (
diff --git a/embassy-net-w5500/src/spi.rs b/embassy-net-w5500/src/spi.rs
deleted file mode 100644
index 316c6521e..000000000
--- a/embassy-net-w5500/src/spi.rs
+++ /dev/null
@@ -1,34 +0,0 @@
1use embedded_hal_async::spi::{Operation, SpiDevice};
2
3use crate::device::RegisterBlock;
4
5pub type Address = (RegisterBlock, u16);
6
7#[derive(Debug)]
8#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9pub struct SpiInterface<SPI>(pub SPI);
10
11impl<SPI: SpiDevice> SpiInterface<SPI> {
12 pub async fn read_frame(&mut self, address: Address, data: &mut [u8]) -> Result<(), SPI::Error> {
13 let address_phase = address.1.to_be_bytes();
14 let control_phase = [(address.0 as u8) << 3];
15 let operations = &mut [
16 Operation::Write(&address_phase),
17 Operation::Write(&control_phase),
18 Operation::TransferInPlace(data),
19 ];
20 self.0.transaction(operations).await
21 }
22
23 pub async fn write_frame(&mut self, address: Address, data: &[u8]) -> Result<(), SPI::Error> {
24 let address_phase = address.1.to_be_bytes();
25 let control_phase = [(address.0 as u8) << 3 | 0b0000_0100];
26 let data_phase = data;
27 let operations = &mut [
28 Operation::Write(&address_phase[..]),
29 Operation::Write(&control_phase),
30 Operation::Write(&data_phase),
31 ];
32 self.0.transaction(operations).await
33 }
34}
diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
index 9f800d0d9..3677f3cd6 100644
--- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs
+++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
@@ -10,6 +10,7 @@ use defmt::*;
10use embassy_executor::Spawner; 10use embassy_executor::Spawner;
11use embassy_futures::yield_now; 11use embassy_futures::yield_now;
12use embassy_net::{Stack, StackResources}; 12use embassy_net::{Stack, StackResources};
13use embassy_net_w5500::chip::W5500;
13use embassy_net_w5500::*; 14use embassy_net_w5500::*;
14use embassy_rp::clocks::RoscRng; 15use embassy_rp::clocks::RoscRng;
15use embassy_rp::gpio::{Input, Level, Output, Pull}; 16use embassy_rp::gpio::{Input, Level, Output, Pull};
@@ -26,6 +27,7 @@ use {defmt_rtt as _, panic_probe as _};
26async fn ethernet_task( 27async fn ethernet_task(
27 runner: Runner< 28 runner: Runner<
28 'static, 29 'static,
30 W5500,
29 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>,
30 Input<'static, PIN_21>, 32 Input<'static, PIN_21>,
31 Output<'static, PIN_20>, 33 Output<'static, PIN_20>,
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
index fee84b613..b78a09779 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
@@ -12,6 +12,7 @@ use defmt::*;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_futures::yield_now; 13use embassy_futures::yield_now;
14use embassy_net::{Stack, StackResources}; 14use embassy_net::{Stack, StackResources};
15use embassy_net_w5500::chip::W5500;
15use embassy_net_w5500::*; 16use embassy_net_w5500::*;
16use embassy_rp::clocks::RoscRng; 17use embassy_rp::clocks::RoscRng;
17use embassy_rp::gpio::{Input, Level, Output, Pull}; 18use embassy_rp::gpio::{Input, Level, Output, Pull};
@@ -28,6 +29,7 @@ use {defmt_rtt as _, panic_probe as _};
28async fn ethernet_task( 29async fn ethernet_task(
29 runner: Runner< 30 runner: Runner<
30 'static, 31 'static,
32 W5500,
31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 33 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>,
32 Input<'static, PIN_21>, 34 Input<'static, PIN_21>,
33 Output<'static, PIN_20>, 35 Output<'static, PIN_20>,
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
index 024574267..34f054d9a 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
@@ -11,6 +11,7 @@ use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_futures::yield_now; 12use embassy_futures::yield_now;
13use embassy_net::{Stack, StackResources}; 13use embassy_net::{Stack, StackResources};
14use embassy_net_w5500::chip::W5500;
14use embassy_net_w5500::*; 15use embassy_net_w5500::*;
15use embassy_rp::clocks::RoscRng; 16use embassy_rp::clocks::RoscRng;
16use embassy_rp::gpio::{Input, Level, Output, Pull}; 17use embassy_rp::gpio::{Input, Level, Output, Pull};
@@ -26,6 +27,7 @@ use {defmt_rtt as _, panic_probe as _};
26async fn ethernet_task( 27async fn ethernet_task(
27 runner: Runner< 28 runner: Runner<
28 'static, 29 'static,
30 W5500,
29 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 31 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>,
30 Input<'static, PIN_21>, 32 Input<'static, PIN_21>,
31 Output<'static, PIN_20>, 33 Output<'static, PIN_20>,
diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs
index 038432b17..8f38e453e 100644
--- a/examples/rp/src/bin/ethernet_w5500_udp.rs
+++ b/examples/rp/src/bin/ethernet_w5500_udp.rs
@@ -11,6 +11,7 @@ use embassy_executor::Spawner;
11use embassy_futures::yield_now; 11use embassy_futures::yield_now;
12use embassy_net::udp::{PacketMetadata, UdpSocket}; 12use embassy_net::udp::{PacketMetadata, UdpSocket};
13use embassy_net::{Stack, StackResources}; 13use embassy_net::{Stack, StackResources};
14use embassy_net_w5500::chip::W5500;
14use embassy_net_w5500::*; 15use embassy_net_w5500::*;
15use embassy_rp::clocks::RoscRng; 16use embassy_rp::clocks::RoscRng;
16use embassy_rp::gpio::{Input, Level, Output, Pull}; 17use embassy_rp::gpio::{Input, Level, Output, Pull};
@@ -25,6 +26,7 @@ use {defmt_rtt as _, panic_probe as _};
25async fn ethernet_task( 26async fn ethernet_task(
26 runner: Runner< 27 runner: Runner<
27 'static, 28 'static,
29 W5500,
28 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, 30 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>,
29 Input<'static, PIN_21>, 31 Input<'static, PIN_21>,
30 Output<'static, PIN_20>, 32 Output<'static, PIN_20>,