diff options
| author | Josh Junon <[email protected]> | 2024-06-29 01:17:27 +0200 |
|---|---|---|
| committer | Josh Junon <[email protected]> | 2024-06-30 23:56:17 +0200 |
| commit | c4b88b57812da85b6952300509736fd02a4640fa (patch) | |
| tree | f7e34e26b4dd23986661e7a73a6d240c527a9c6d /embassy-net-wiznet | |
| parent | 26e660722cca9151e5a9331c328421145509ab20 (diff) | |
wiznet: add version check to initialization sequence
Diffstat (limited to 'embassy-net-wiznet')
| -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 |
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; | |||
| 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 | } |
