diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-08-15 17:20:41 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-08-15 22:52:37 +0200 |
| commit | a436bd068f6059fa073a9f1f246a77e1ce38dd31 (patch) | |
| tree | 2291de0aa03c0831c5a255c4588803fd236a0e44 | |
| parent | c367b84ee53b9d7a31f442f962c939f822aadb0d (diff) | |
net-w5500: inline socket into device.
| -rw-r--r-- | embassy-net-w5500/src/device.rs | 124 | ||||
| -rw-r--r-- | embassy-net-w5500/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-net-w5500/src/socket.rs | 78 |
3 files changed, 99 insertions, 104 deletions
diff --git a/embassy-net-w5500/src/device.rs b/embassy-net-w5500/src/device.rs index 1793baaa3..cf451b334 100644 --- a/embassy-net-w5500/src/device.rs +++ b/embassy-net-w5500/src/device.rs | |||
| @@ -1,12 +1,34 @@ | |||
| 1 | use embedded_hal_async::spi::SpiDevice; | 1 | use embedded_hal_async::spi::SpiDevice; |
| 2 | 2 | ||
| 3 | use crate::socket; | ||
| 4 | use crate::spi::{Address, SpiInterface}; | 3 | use crate::spi::{Address, SpiInterface}; |
| 5 | 4 | ||
| 6 | pub const MODE: Address = (RegisterBlock::Common, 0x00); | 5 | pub const COMMON_MODE: Address = (RegisterBlock::Common, 0x00); |
| 7 | pub const MAC: Address = (RegisterBlock::Common, 0x09); | 6 | pub const COMMON_MAC: Address = (RegisterBlock::Common, 0x09); |
| 8 | pub const SOCKET_INTR: Address = (RegisterBlock::Common, 0x18); | 7 | pub const COMMON_SOCKET_INTR: Address = (RegisterBlock::Common, 0x18); |
| 9 | pub const PHY_CFG: Address = (RegisterBlock::Common, 0x2E); | 8 | pub const COMMON_PHY_CFG: Address = (RegisterBlock::Common, 0x2E); |
| 9 | |||
| 10 | pub const SOCKET_MODE: Address = (RegisterBlock::Socket0, 0x00); | ||
| 11 | pub const SOCKET_COMMAND: Address = (RegisterBlock::Socket0, 0x01); | ||
| 12 | pub const SOCKET_RXBUF_SIZE: Address = (RegisterBlock::Socket0, 0x1E); | ||
| 13 | pub const SOCKET_TXBUF_SIZE: Address = (RegisterBlock::Socket0, 0x1F); | ||
| 14 | pub const SOCKET_TX_FREE_SIZE: Address = (RegisterBlock::Socket0, 0x20); | ||
| 15 | pub const SOCKET_TX_DATA_WRITE_PTR: Address = (RegisterBlock::Socket0, 0x24); | ||
| 16 | pub const SOCKET_RECVD_SIZE: Address = (RegisterBlock::Socket0, 0x26); | ||
| 17 | pub const SOCKET_RX_DATA_READ_PTR: Address = (RegisterBlock::Socket0, 0x28); | ||
| 18 | pub const SOCKET_INTR_MASK: Address = (RegisterBlock::Socket0, 0x2C); | ||
| 19 | pub const SOCKET_INTR: Address = (RegisterBlock::Socket0, 0x02); | ||
| 20 | |||
| 21 | #[repr(u8)] | ||
| 22 | pub enum Command { | ||
| 23 | Open = 0x01, | ||
| 24 | Send = 0x20, | ||
| 25 | Receive = 0x40, | ||
| 26 | } | ||
| 27 | |||
| 28 | #[repr(u8)] | ||
| 29 | pub enum Interrupt { | ||
| 30 | Receive = 0b00100_u8, | ||
| 31 | } | ||
| 10 | 32 | ||
| 11 | #[repr(u8)] | 33 | #[repr(u8)] |
| 12 | pub enum RegisterBlock { | 34 | pub enum RegisterBlock { |
| @@ -28,27 +50,78 @@ impl<SPI: SpiDevice> W5500<SPI> { | |||
| 28 | pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result<W5500<SPI>, SPI::Error> { | 50 | pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result<W5500<SPI>, SPI::Error> { |
| 29 | let mut bus = SpiInterface(spi); | 51 | let mut bus = SpiInterface(spi); |
| 30 | // Reset device | 52 | // Reset device |
| 31 | bus.write_frame(MODE, &[0x80]).await?; | 53 | bus.write_frame(COMMON_MODE, &[0x80]).await?; |
| 32 | 54 | ||
| 33 | // Enable interrupt pin | 55 | // Enable interrupt pin |
| 34 | bus.write_frame(SOCKET_INTR, &[0x01]).await?; | 56 | bus.write_frame(COMMON_SOCKET_INTR, &[0x01]).await?; |
| 35 | // Enable receive interrupt | 57 | // Enable receive interrupt |
| 36 | bus.write_frame(socket::SOCKET_INTR_MASK, &[socket::Interrupt::Receive as u8]) | 58 | bus.write_frame(SOCKET_INTR_MASK, &[Interrupt::Receive as u8]).await?; |
| 37 | .await?; | ||
| 38 | 59 | ||
| 39 | // Set MAC address | 60 | // Set MAC address |
| 40 | bus.write_frame(MAC, &mac_addr).await?; | 61 | bus.write_frame(COMMON_MAC, &mac_addr).await?; |
| 41 | 62 | ||
| 42 | // Set the raw socket RX/TX buffer sizes to 16KB | 63 | // Set the raw socket RX/TX buffer sizes to 16KB |
| 43 | bus.write_frame(socket::TXBUF_SIZE, &[16]).await?; | 64 | bus.write_frame(SOCKET_TXBUF_SIZE, &[16]).await?; |
| 44 | bus.write_frame(socket::RXBUF_SIZE, &[16]).await?; | 65 | bus.write_frame(SOCKET_RXBUF_SIZE, &[16]).await?; |
| 45 | 66 | ||
| 46 | // MACRAW mode with MAC filtering. | 67 | // MACRAW mode with MAC filtering. |
| 47 | let mode: u8 = (1 << 2) | (1 << 7); | 68 | let mode: u8 = (1 << 2) | (1 << 7); |
| 48 | bus.write_frame(socket::MODE, &[mode]).await?; | 69 | bus.write_frame(SOCKET_MODE, &[mode]).await?; |
| 49 | socket::command(&mut bus, socket::Command::Open).await?; | 70 | let mut this = Self { bus }; |
| 71 | this.command(Command::Open).await?; | ||
| 72 | |||
| 73 | Ok(this) | ||
| 74 | } | ||
| 75 | |||
| 76 | async fn reset_interrupt(&mut self, code: Interrupt) -> Result<(), SPI::Error> { | ||
| 77 | let data = [code as u8]; | ||
| 78 | self.bus.write_frame(SOCKET_INTR, &data).await | ||
| 79 | } | ||
| 80 | |||
| 81 | async fn get_tx_write_ptr(&mut self) -> Result<u16, SPI::Error> { | ||
| 82 | let mut data = [0u8; 2]; | ||
| 83 | self.bus.read_frame(SOCKET_TX_DATA_WRITE_PTR, &mut data).await?; | ||
| 84 | Ok(u16::from_be_bytes(data)) | ||
| 85 | } | ||
| 50 | 86 | ||
| 51 | Ok(Self { bus }) | 87 | async fn set_tx_write_ptr(&mut self, ptr: u16) -> Result<(), SPI::Error> { |
| 88 | let data = ptr.to_be_bytes(); | ||
| 89 | self.bus.write_frame(SOCKET_TX_DATA_WRITE_PTR, &data).await | ||
| 90 | } | ||
| 91 | |||
| 92 | async fn get_rx_read_ptr(&mut self) -> Result<u16, SPI::Error> { | ||
| 93 | let mut data = [0u8; 2]; | ||
| 94 | self.bus.read_frame(SOCKET_RX_DATA_READ_PTR, &mut data).await?; | ||
| 95 | Ok(u16::from_be_bytes(data)) | ||
| 96 | } | ||
| 97 | |||
| 98 | async fn set_rx_read_ptr(&mut self, ptr: u16) -> Result<(), SPI::Error> { | ||
| 99 | let data = ptr.to_be_bytes(); | ||
| 100 | self.bus.write_frame(SOCKET_RX_DATA_READ_PTR, &data).await | ||
| 101 | } | ||
| 102 | |||
| 103 | async fn command(&mut self, command: Command) -> Result<(), SPI::Error> { | ||
| 104 | let data = [command as u8]; | ||
| 105 | self.bus.write_frame(SOCKET_COMMAND, &data).await | ||
| 106 | } | ||
| 107 | |||
| 108 | async fn get_rx_size(&mut self) -> Result<u16, SPI::Error> { | ||
| 109 | loop { | ||
| 110 | // Wait until two sequential reads are equal | ||
| 111 | let mut res0 = [0u8; 2]; | ||
| 112 | self.bus.read_frame(SOCKET_RECVD_SIZE, &mut res0).await?; | ||
| 113 | let mut res1 = [0u8; 2]; | ||
| 114 | self.bus.read_frame(SOCKET_RECVD_SIZE, &mut res1).await?; | ||
| 115 | if res0 == res1 { | ||
| 116 | break Ok(u16::from_be_bytes(res0)); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | async fn get_tx_free_size(&mut self) -> Result<u16, SPI::Error> { | ||
| 122 | let mut data = [0; 2]; | ||
| 123 | self.bus.read_frame(SOCKET_TX_FREE_SIZE, &mut data).await?; | ||
| 124 | Ok(u16::from_be_bytes(data)) | ||
| 52 | } | 125 | } |
| 53 | 126 | ||
| 54 | /// Read bytes from the RX buffer. Returns the number of bytes read. | 127 | /// Read bytes from the RX buffer. Returns the number of bytes read. |
| @@ -61,14 +134,14 @@ impl<SPI: SpiDevice> W5500<SPI> { | |||
| 61 | 134 | ||
| 62 | /// Read an ethernet frame from the device. Returns the number of bytes read. | 135 | /// Read an ethernet frame from the device. Returns the number of bytes read. |
| 63 | pub async fn read_frame(&mut self, frame: &mut [u8]) -> Result<usize, SPI::Error> { | 136 | pub async fn read_frame(&mut self, frame: &mut [u8]) -> Result<usize, SPI::Error> { |
| 64 | let rx_size = socket::get_rx_size(&mut self.bus).await? as usize; | 137 | let rx_size = self.get_rx_size().await? as usize; |
| 65 | if rx_size == 0 { | 138 | if rx_size == 0 { |
| 66 | return Ok(0); | 139 | return Ok(0); |
| 67 | } | 140 | } |
| 68 | 141 | ||
| 69 | socket::reset_interrupt(&mut self.bus, socket::Interrupt::Receive).await?; | 142 | self.reset_interrupt(Interrupt::Receive).await?; |
| 70 | 143 | ||
| 71 | let mut read_ptr = socket::get_rx_read_ptr(&mut self.bus).await?; | 144 | let mut read_ptr = self.get_rx_read_ptr().await?; |
| 72 | 145 | ||
| 73 | // First two bytes gives the size of the received ethernet frame | 146 | // First two bytes gives the size of the received ethernet frame |
| 74 | let expected_frame_size: usize = { | 147 | let expected_frame_size: usize = { |
| @@ -82,25 +155,26 @@ impl<SPI: SpiDevice> W5500<SPI> { | |||
| 82 | .await?; | 155 | .await?; |
| 83 | 156 | ||
| 84 | // Register RX as completed | 157 | // Register RX as completed |
| 85 | socket::set_rx_read_ptr(&mut self.bus, read_ptr).await?; | 158 | self.set_rx_read_ptr(read_ptr).await?; |
| 86 | socket::command(&mut self.bus, socket::Command::Receive).await?; | 159 | self.command(Command::Receive).await?; |
| 87 | 160 | ||
| 88 | Ok(expected_frame_size) | 161 | Ok(expected_frame_size) |
| 89 | } | 162 | } |
| 90 | 163 | ||
| 91 | /// Write an ethernet frame to the device. Returns number of bytes written | 164 | /// Write an ethernet frame to the device. Returns number of bytes written |
| 92 | pub async fn write_frame(&mut self, frame: &[u8]) -> Result<usize, SPI::Error> { | 165 | pub async fn write_frame(&mut self, frame: &[u8]) -> Result<usize, SPI::Error> { |
| 93 | while socket::get_tx_free_size(&mut self.bus).await? < frame.len() as u16 {} | 166 | while self.get_tx_free_size().await? < frame.len() as u16 {} |
| 94 | let write_ptr = socket::get_tx_write_ptr(&mut self.bus).await?; | 167 | let write_ptr = self.get_tx_write_ptr().await?; |
| 95 | self.bus.write_frame((RegisterBlock::TxBuf, write_ptr), frame).await?; | 168 | self.bus.write_frame((RegisterBlock::TxBuf, write_ptr), frame).await?; |
| 96 | socket::set_tx_write_ptr(&mut self.bus, write_ptr.wrapping_add(frame.len() as u16)).await?; | 169 | self.set_tx_write_ptr(write_ptr.wrapping_add(frame.len() as u16)) |
| 97 | socket::command(&mut self.bus, socket::Command::Send).await?; | 170 | .await?; |
| 171 | self.command(Command::Send).await?; | ||
| 98 | Ok(frame.len()) | 172 | Ok(frame.len()) |
| 99 | } | 173 | } |
| 100 | 174 | ||
| 101 | pub async fn is_link_up(&mut self) -> bool { | 175 | pub async fn is_link_up(&mut self) -> bool { |
| 102 | let mut link = [0]; | 176 | let mut link = [0]; |
| 103 | self.bus.read_frame(PHY_CFG, &mut link).await.ok(); | 177 | self.bus.read_frame(COMMON_PHY_CFG, &mut link).await.ok(); |
| 104 | link[0] & 1 == 1 | 178 | link[0] & 1 == 1 |
| 105 | } | 179 | } |
| 106 | } | 180 | } |
diff --git a/embassy-net-w5500/src/lib.rs b/embassy-net-w5500/src/lib.rs index 52494b443..3c54777d8 100644 --- a/embassy-net-w5500/src/lib.rs +++ b/embassy-net-w5500/src/lib.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | 3 | ||
| 4 | mod device; | 4 | mod device; |
| 5 | mod socket; | ||
| 6 | mod spi; | 5 | mod spi; |
| 7 | 6 | ||
| 8 | use embassy_futures::select::{select, Either}; | 7 | use embassy_futures::select::{select, Either}; |
diff --git a/embassy-net-w5500/src/socket.rs b/embassy-net-w5500/src/socket.rs deleted file mode 100644 index 1c96cca1f..000000000 --- a/embassy-net-w5500/src/socket.rs +++ /dev/null | |||
| @@ -1,78 +0,0 @@ | |||
| 1 | use embedded_hal_async::spi::SpiDevice; | ||
| 2 | |||
| 3 | use crate::device::RegisterBlock; | ||
| 4 | use crate::spi::{Address, SpiInterface}; | ||
| 5 | |||
| 6 | pub const MODE: Address = (RegisterBlock::Socket0, 0x00); | ||
| 7 | pub const COMMAND: Address = (RegisterBlock::Socket0, 0x01); | ||
| 8 | pub const RXBUF_SIZE: Address = (RegisterBlock::Socket0, 0x1E); | ||
| 9 | pub const TXBUF_SIZE: Address = (RegisterBlock::Socket0, 0x1F); | ||
| 10 | pub const TX_FREE_SIZE: Address = (RegisterBlock::Socket0, 0x20); | ||
| 11 | pub const TX_DATA_WRITE_PTR: Address = (RegisterBlock::Socket0, 0x24); | ||
| 12 | pub const RECVD_SIZE: Address = (RegisterBlock::Socket0, 0x26); | ||
| 13 | pub const RX_DATA_READ_PTR: Address = (RegisterBlock::Socket0, 0x28); | ||
| 14 | pub const SOCKET_INTR_MASK: Address = (RegisterBlock::Socket0, 0x2C); | ||
| 15 | pub const INTR: Address = (RegisterBlock::Socket0, 0x02); | ||
| 16 | |||
| 17 | #[repr(u8)] | ||
| 18 | pub enum Command { | ||
| 19 | Open = 0x01, | ||
| 20 | Send = 0x20, | ||
| 21 | Receive = 0x40, | ||
| 22 | } | ||
| 23 | |||
| 24 | #[repr(u8)] | ||
| 25 | pub enum Interrupt { | ||
| 26 | Receive = 0b00100_u8, | ||
| 27 | } | ||
| 28 | |||
| 29 | pub async fn reset_interrupt<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>, code: Interrupt) -> Result<(), SPI::Error> { | ||
| 30 | let data = [code as u8]; | ||
| 31 | bus.write_frame(INTR, &data).await | ||
| 32 | } | ||
| 33 | |||
| 34 | pub async fn get_tx_write_ptr<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>) -> Result<u16, SPI::Error> { | ||
| 35 | let mut data = [0u8; 2]; | ||
| 36 | bus.read_frame(TX_DATA_WRITE_PTR, &mut data).await?; | ||
| 37 | Ok(u16::from_be_bytes(data)) | ||
| 38 | } | ||
| 39 | |||
| 40 | pub async fn set_tx_write_ptr<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>, ptr: u16) -> Result<(), SPI::Error> { | ||
| 41 | let data = ptr.to_be_bytes(); | ||
| 42 | bus.write_frame(TX_DATA_WRITE_PTR, &data).await | ||
| 43 | } | ||
| 44 | |||
| 45 | pub async fn get_rx_read_ptr<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>) -> Result<u16, SPI::Error> { | ||
| 46 | let mut data = [0u8; 2]; | ||
| 47 | bus.read_frame(RX_DATA_READ_PTR, &mut data).await?; | ||
| 48 | Ok(u16::from_be_bytes(data)) | ||
| 49 | } | ||
| 50 | |||
| 51 | pub async fn set_rx_read_ptr<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>, ptr: u16) -> Result<(), SPI::Error> { | ||
| 52 | let data = ptr.to_be_bytes(); | ||
| 53 | bus.write_frame(RX_DATA_READ_PTR, &data).await | ||
| 54 | } | ||
| 55 | |||
| 56 | pub async fn command<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>, command: Command) -> Result<(), SPI::Error> { | ||
| 57 | let data = [command as u8]; | ||
| 58 | bus.write_frame(COMMAND, &data).await | ||
| 59 | } | ||
| 60 | |||
| 61 | pub async fn get_rx_size<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>) -> Result<u16, SPI::Error> { | ||
| 62 | loop { | ||
| 63 | // Wait until two sequential reads are equal | ||
| 64 | let mut res0 = [0u8; 2]; | ||
| 65 | bus.read_frame(RECVD_SIZE, &mut res0).await?; | ||
| 66 | let mut res1 = [0u8; 2]; | ||
| 67 | bus.read_frame(RECVD_SIZE, &mut res1).await?; | ||
| 68 | if res0 == res1 { | ||
| 69 | break Ok(u16::from_be_bytes(res0)); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | pub async fn get_tx_free_size<SPI: SpiDevice>(bus: &mut SpiInterface<SPI>) -> Result<u16, SPI::Error> { | ||
| 75 | let mut data = [0; 2]; | ||
| 76 | bus.read_frame(TX_FREE_SIZE, &mut data).await?; | ||
| 77 | Ok(u16::from_be_bytes(data)) | ||
| 78 | } | ||
