aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-07-02 16:58:00 +0000
committerGitHub <[email protected]>2024-07-02 16:58:00 +0000
commit5137ebab566378705869a1f83d45ecfe54621b4a (patch)
tree6c6357516b23b1f846fba198cfe146a405a39321
parent9bdb697cd96d36dd6e42e8680e3f2f7983e35f74 (diff)
parentc4b88b57812da85b6952300509736fd02a4640fa (diff)
Merge pull request #3132 from oro-os/wiznet-version-check
wiznet: add version check to initialization sequence
-rw-r--r--embassy-net-wiznet/src/chip/mod.rs7
-rw-r--r--embassy-net-wiznet/src/chip/w5100s.rs3
-rw-r--r--embassy-net-wiznet/src/chip/w5500.rs3
-rw-r--r--embassy-net-wiznet/src/device.rs62
-rw-r--r--embassy-net-wiznet/src/lib.rs10
-rw-r--r--examples/rp/src/bin/ethernet_w5500_multisocket.rs3
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_client.rs3
-rw-r--r--examples/rp/src/bin/ethernet_w5500_tcp_server.rs3
-rw-r--r--examples/rp/src/bin/ethernet_w5500_udp.rs3
-rw-r--r--examples/stm32f4/src/bin/eth_w5500.rs4
-rw-r--r--tests/rp/src/bin/ethernet_w5100s_perf.rs3
11 files changed, 93 insertions, 11 deletions
diff --git a/embassy-net-wiznet/src/chip/mod.rs b/embassy-net-wiznet/src/chip/mod.rs
index e1f963d95..2e7a9ed6c 100644
--- a/embassy-net-wiznet/src/chip/mod.rs
+++ b/embassy-net-wiznet/src/chip/mod.rs
@@ -8,10 +8,17 @@ pub use w5100s::W5100S;
8pub(crate) trait SealedChip { 8pub(crate) trait SealedChip {
9 type Address; 9 type Address;
10 10
11 /// The version of the chip as reported by the VERSIONR register.
12 /// This is used to verify that the chip is supported by the driver,
13 /// and that SPI communication is working.
14 const CHIP_VERSION: u8;
15
11 const COMMON_MODE: Self::Address; 16 const COMMON_MODE: Self::Address;
12 const COMMON_MAC: Self::Address; 17 const COMMON_MAC: Self::Address;
13 const COMMON_SOCKET_INTR: Self::Address; 18 const COMMON_SOCKET_INTR: Self::Address;
14 const COMMON_PHY_CFG: Self::Address; 19 const COMMON_PHY_CFG: Self::Address;
20 const COMMON_VERSION: Self::Address;
21
15 const SOCKET_MODE: Self::Address; 22 const SOCKET_MODE: Self::Address;
16 const SOCKET_COMMAND: Self::Address; 23 const SOCKET_COMMAND: Self::Address;
17 const SOCKET_RXBUF_SIZE: Self::Address; 24 const SOCKET_RXBUF_SIZE: Self::Address;
diff --git a/embassy-net-wiznet/src/chip/w5100s.rs b/embassy-net-wiznet/src/chip/w5100s.rs
index 23ce3ed83..4c4b7ab16 100644
--- a/embassy-net-wiznet/src/chip/w5100s.rs
+++ b/embassy-net-wiznet/src/chip/w5100s.rs
@@ -11,10 +11,13 @@ impl super::Chip for W5100S {}
11impl super::SealedChip for W5100S { 11impl super::SealedChip for W5100S {
12 type Address = u16; 12 type Address = u16;
13 13
14 const CHIP_VERSION: u8 = 0x51;
15
14 const COMMON_MODE: Self::Address = 0x00; 16 const COMMON_MODE: Self::Address = 0x00;
15 const COMMON_MAC: Self::Address = 0x09; 17 const COMMON_MAC: Self::Address = 0x09;
16 const COMMON_SOCKET_INTR: Self::Address = 0x16; 18 const COMMON_SOCKET_INTR: Self::Address = 0x16;
17 const COMMON_PHY_CFG: Self::Address = 0x3c; 19 const COMMON_PHY_CFG: Self::Address = 0x3c;
20 const COMMON_VERSION: Self::Address = 0x80;
18 21
19 const SOCKET_MODE: Self::Address = SOCKET_BASE + 0x00; 22 const SOCKET_MODE: Self::Address = SOCKET_BASE + 0x00;
20 const SOCKET_COMMAND: Self::Address = SOCKET_BASE + 0x01; 23 const SOCKET_COMMAND: Self::Address = SOCKET_BASE + 0x01;
diff --git a/embassy-net-wiznet/src/chip/w5500.rs b/embassy-net-wiznet/src/chip/w5500.rs
index 12e610ea2..5cfcb94e4 100644
--- a/embassy-net-wiznet/src/chip/w5500.rs
+++ b/embassy-net-wiznet/src/chip/w5500.rs
@@ -15,10 +15,13 @@ impl super::Chip for W5500 {}
15impl super::SealedChip for W5500 { 15impl super::SealedChip for W5500 {
16 type Address = (RegisterBlock, u16); 16 type Address = (RegisterBlock, u16);
17 17
18 const CHIP_VERSION: u8 = 0x04;
19
18 const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00); 20 const COMMON_MODE: Self::Address = (RegisterBlock::Common, 0x00);
19 const COMMON_MAC: Self::Address = (RegisterBlock::Common, 0x09); 21 const COMMON_MAC: Self::Address = (RegisterBlock::Common, 0x09);
20 const COMMON_SOCKET_INTR: Self::Address = (RegisterBlock::Common, 0x18); 22 const COMMON_SOCKET_INTR: Self::Address = (RegisterBlock::Common, 0x18);
21 const COMMON_PHY_CFG: Self::Address = (RegisterBlock::Common, 0x2E); 23 const COMMON_PHY_CFG: Self::Address = (RegisterBlock::Common, 0x2E);
24 const COMMON_VERSION: Self::Address = (RegisterBlock::Common, 0x39);
22 25
23 const SOCKET_MODE: Self::Address = (RegisterBlock::Socket0, 0x00); 26 const SOCKET_MODE: Self::Address = (RegisterBlock::Socket0, 0x00);
24 const SOCKET_COMMAND: Self::Address = (RegisterBlock::Socket0, 0x01); 27 const SOCKET_COMMAND: Self::Address = (RegisterBlock::Socket0, 0x01);
diff --git a/embassy-net-wiznet/src/device.rs b/embassy-net-wiznet/src/device.rs
index 43f9512a3..d2b6bb0c3 100644
--- a/embassy-net-wiznet/src/device.rs
+++ b/embassy-net-wiznet/src/device.rs
@@ -24,9 +24,57 @@ pub(crate) struct WiznetDevice<C, SPI> {
24 _phantom: PhantomData<C>, 24 _phantom: PhantomData<C>,
25} 25}
26 26
27/// Error type when initializing a new Wiznet device
28pub enum InitError<SE> {
29 /// Error occurred when sending or receiving SPI data
30 SpiError(SE),
31 /// The chip returned a version that isn't expected or supported
32 InvalidChipVersion {
33 /// The version that is supported
34 expected: u8,
35 /// The version that was returned by the chip
36 actual: u8,
37 },
38}
39
40impl<SE> From<SE> for InitError<SE> {
41 fn from(e: SE) -> Self {
42 InitError::SpiError(e)
43 }
44}
45
46impl<SE> core::fmt::Debug for InitError<SE>
47where
48 SE: core::fmt::Debug,
49{
50 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51 match self {
52 InitError::SpiError(e) => write!(f, "SpiError({:?})", e),
53 InitError::InvalidChipVersion { expected, actual } => {
54 write!(f, "InvalidChipVersion {{ expected: {}, actual: {} }}", expected, actual)
55 }
56 }
57 }
58}
59
60#[cfg(feature = "defmt")]
61impl<SE> defmt::Format for InitError<SE>
62where
63 SE: defmt::Format,
64{
65 fn format(&self, f: defmt::Formatter) {
66 match self {
67 InitError::SpiError(e) => defmt::write!(f, "SpiError({})", e),
68 InitError::InvalidChipVersion { expected, actual } => {
69 defmt::write!(f, "InvalidChipVersion {{ expected: {}, actual: {} }}", expected, actual)
70 }
71 }
72 }
73}
74
27impl<C: Chip, SPI: SpiDevice> WiznetDevice<C, SPI> { 75impl<C: Chip, SPI: SpiDevice> WiznetDevice<C, SPI> {
28 /// Create and initialize the driver 76 /// Create and initialize the driver
29 pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result<Self, SPI::Error> { 77 pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result<Self, InitError<SPI::Error>> {
30 let mut this = Self { 78 let mut this = Self {
31 spi, 79 spi,
32 _phantom: PhantomData, 80 _phantom: PhantomData,
@@ -35,6 +83,18 @@ impl<C: Chip, SPI: SpiDevice> WiznetDevice<C, SPI> {
35 // Reset device 83 // Reset device
36 this.bus_write(C::COMMON_MODE, &[0x80]).await?; 84 this.bus_write(C::COMMON_MODE, &[0x80]).await?;
37 85
86 // Check the version of the chip
87 let mut version = [0];
88 this.bus_read(C::COMMON_VERSION, &mut version).await?;
89 if version[0] != C::CHIP_VERSION {
90 #[cfg(feature = "defmt")]
91 defmt::error!("invalid chip version: {} (expected {})", version[0], C::CHIP_VERSION);
92 return Err(InitError::InvalidChipVersion {
93 actual: version[0],
94 expected: C::CHIP_VERSION,
95 });
96 }
97
38 // Enable interrupt pin 98 // Enable interrupt pin
39 this.bus_write(C::COMMON_SOCKET_INTR, &[0x01]).await?; 99 this.bus_write(C::COMMON_SOCKET_INTR, &[0x01]).await?;
40 // Enable receive interrupt 100 // Enable receive interrupt
diff --git a/embassy-net-wiznet/src/lib.rs b/embassy-net-wiznet/src/lib.rs
index 90102196a..3fbd4c741 100644
--- a/embassy-net-wiznet/src/lib.rs
+++ b/embassy-net-wiznet/src/lib.rs
@@ -15,6 +15,7 @@ use embedded_hal_async::digital::Wait;
15use embedded_hal_async::spi::SpiDevice; 15use embedded_hal_async::spi::SpiDevice;
16 16
17use crate::chip::Chip; 17use crate::chip::Chip;
18pub use crate::device::InitError;
18use crate::device::WiznetDevice; 19use crate::device::WiznetDevice;
19 20
20// If you change this update the docs of State 21// If you change this update the docs of State
@@ -105,7 +106,7 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi
105 spi_dev: SPI, 106 spi_dev: SPI,
106 int: INT, 107 int: INT,
107 mut reset: RST, 108 mut reset: RST,
108) -> (Device<'a>, Runner<'a, C, SPI, INT, RST>) { 109) -> Result<(Device<'a>, Runner<'a, C, SPI, INT, RST>), InitError<SPI::Error>> {
109 // Reset the chip. 110 // Reset the chip.
110 reset.set_low().ok(); 111 reset.set_low().ok();
111 // Ensure the reset is registered. 112 // Ensure the reset is registered.
@@ -116,10 +117,11 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi
116 // Slowest is w5100s which is 100ms, so let's just wait that. 117 // Slowest is w5100s which is 100ms, so let's just wait that.
117 Timer::after_millis(100).await; 118 Timer::after_millis(100).await;
118 119
119 let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap(); 120 let mac = WiznetDevice::new(spi_dev, mac_addr).await?;
120 121
121 let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr)); 122 let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr));
122 ( 123
124 Ok((
123 device, 125 device,
124 Runner { 126 Runner {
125 ch: runner, 127 ch: runner,
@@ -127,5 +129,5 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi
127 int, 129 int,
128 _reset: reset, 130 _reset: reset,
129 }, 131 },
130 ) 132 ))
131} 133}
diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
index bd52cadca..def26b53d 100644
--- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs
+++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs
@@ -63,7 +63,8 @@ async fn main(spawner: Spawner) {
63 w5500_int, 63 w5500_int,
64 w5500_reset, 64 w5500_reset,
65 ) 65 )
66 .await; 66 .await
67 .unwrap();
67 unwrap!(spawner.spawn(ethernet_task(runner))); 68 unwrap!(spawner.spawn(ethernet_task(runner)));
68 69
69 // Generate random seed 70 // Generate random seed
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
index 3e4fbd2e6..6c4a78361 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs
@@ -66,7 +66,8 @@ async fn main(spawner: Spawner) {
66 w5500_int, 66 w5500_int,
67 w5500_reset, 67 w5500_reset,
68 ) 68 )
69 .await; 69 .await
70 .unwrap();
70 unwrap!(spawner.spawn(ethernet_task(runner))); 71 unwrap!(spawner.spawn(ethernet_task(runner)));
71 72
72 // Generate random seed 73 // Generate random seed
diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
index 5532851f3..30a3a7463 100644
--- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
+++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs
@@ -65,7 +65,8 @@ async fn main(spawner: Spawner) {
65 w5500_int, 65 w5500_int,
66 w5500_reset, 66 w5500_reset,
67 ) 67 )
68 .await; 68 .await
69 .unwrap();
69 unwrap!(spawner.spawn(ethernet_task(runner))); 70 unwrap!(spawner.spawn(ethernet_task(runner)));
70 71
71 // Generate random seed 72 // Generate random seed
diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs
index adb1d8941..1613ed887 100644
--- a/examples/rp/src/bin/ethernet_w5500_udp.rs
+++ b/examples/rp/src/bin/ethernet_w5500_udp.rs
@@ -63,7 +63,8 @@ async fn main(spawner: Spawner) {
63 w5500_int, 63 w5500_int,
64 w5500_reset, 64 w5500_reset,
65 ) 65 )
66 .await; 66 .await
67 .unwrap();
67 unwrap!(spawner.spawn(ethernet_task(runner))); 68 unwrap!(spawner.spawn(ethernet_task(runner)));
68 69
69 // Generate random seed 70 // Generate random seed
diff --git a/examples/stm32f4/src/bin/eth_w5500.rs b/examples/stm32f4/src/bin/eth_w5500.rs
index c51111110..3c770a873 100644
--- a/examples/stm32f4/src/bin/eth_w5500.rs
+++ b/examples/stm32f4/src/bin/eth_w5500.rs
@@ -80,7 +80,9 @@ async fn main(spawner: Spawner) -> ! {
80 let mac_addr = [0x02, 234, 3, 4, 82, 231]; 80 let mac_addr = [0x02, 234, 3, 4, 82, 231];
81 static STATE: StaticCell<State<2, 2>> = StaticCell::new(); 81 static STATE: StaticCell<State<2, 2>> = StaticCell::new();
82 let state = STATE.init(State::<2, 2>::new()); 82 let state = STATE.init(State::<2, 2>::new());
83 let (device, runner) = embassy_net_wiznet::new(mac_addr, state, spi, w5500_int, w5500_reset).await; 83 let (device, runner) = embassy_net_wiznet::new(mac_addr, state, spi, w5500_int, w5500_reset)
84 .await
85 .unwrap();
84 unwrap!(spawner.spawn(ethernet_task(runner))); 86 unwrap!(spawner.spawn(ethernet_task(runner)));
85 87
86 let config = embassy_net::Config::dhcpv4(Default::default()); 88 let config = embassy_net::Config::dhcpv4(Default::default());
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs
index 5d5547773..4b04571bd 100644
--- a/tests/rp/src/bin/ethernet_w5100s_perf.rs
+++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs
@@ -59,7 +59,8 @@ async fn main(spawner: Spawner) {
59 w5500_int, 59 w5500_int,
60 w5500_reset, 60 w5500_reset,
61 ) 61 )
62 .await; 62 .await
63 .unwrap();
63 unwrap!(spawner.spawn(ethernet_task(runner))); 64 unwrap!(spawner.spawn(ethernet_task(runner)));
64 65
65 // Generate random seed 66 // Generate random seed