diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-07-02 16:58:00 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-07-02 16:58:00 +0000 |
| commit | 5137ebab566378705869a1f83d45ecfe54621b4a (patch) | |
| tree | 6c6357516b23b1f846fba198cfe146a405a39321 | |
| parent | 9bdb697cd96d36dd6e42e8680e3f2f7983e35f74 (diff) | |
| parent | c4b88b57812da85b6952300509736fd02a4640fa (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.rs | 7 | ||||
| -rw-r--r-- | embassy-net-wiznet/src/chip/w5100s.rs | 3 | ||||
| -rw-r--r-- | embassy-net-wiznet/src/chip/w5500.rs | 3 | ||||
| -rw-r--r-- | embassy-net-wiznet/src/device.rs | 62 | ||||
| -rw-r--r-- | embassy-net-wiznet/src/lib.rs | 10 | ||||
| -rw-r--r-- | examples/rp/src/bin/ethernet_w5500_multisocket.rs | 3 | ||||
| -rw-r--r-- | examples/rp/src/bin/ethernet_w5500_tcp_client.rs | 3 | ||||
| -rw-r--r-- | examples/rp/src/bin/ethernet_w5500_tcp_server.rs | 3 | ||||
| -rw-r--r-- | examples/rp/src/bin/ethernet_w5500_udp.rs | 3 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/eth_w5500.rs | 4 | ||||
| -rw-r--r-- | tests/rp/src/bin/ethernet_w5100s_perf.rs | 3 |
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; | |||
| 8 | pub(crate) trait SealedChip { | 8 | pub(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 {} | |||
| 11 | impl super::SealedChip for W5100S { | 11 | impl 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 {} | |||
| 15 | impl super::SealedChip for W5500 { | 15 | impl 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 | ||
| 28 | pub 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 | |||
| 40 | impl<SE> From<SE> for InitError<SE> { | ||
| 41 | fn from(e: SE) -> Self { | ||
| 42 | InitError::SpiError(e) | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | impl<SE> core::fmt::Debug for InitError<SE> | ||
| 47 | where | ||
| 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")] | ||
| 61 | impl<SE> defmt::Format for InitError<SE> | ||
| 62 | where | ||
| 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 | |||
| 27 | impl<C: Chip, SPI: SpiDevice> WiznetDevice<C, SPI> { | 75 | impl<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; | |||
| 15 | use embedded_hal_async::spi::SpiDevice; | 15 | use embedded_hal_async::spi::SpiDevice; |
| 16 | 16 | ||
| 17 | use crate::chip::Chip; | 17 | use crate::chip::Chip; |
| 18 | pub use crate::device::InitError; | ||
| 18 | use crate::device::WiznetDevice; | 19 | use 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 |
