aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-wiznet
diff options
context:
space:
mode:
authorJosh Junon <[email protected]>2024-06-29 01:17:27 +0200
committerJosh Junon <[email protected]>2024-06-30 23:56:17 +0200
commitc4b88b57812da85b6952300509736fd02a4640fa (patch)
treef7e34e26b4dd23986661e7a73a6d240c527a9c6d /embassy-net-wiznet
parent26e660722cca9151e5a9331c328421145509ab20 (diff)
wiznet: add version check to initialization sequence
Diffstat (limited to 'embassy-net-wiznet')
-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
5 files changed, 80 insertions, 5 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}