From 6effe5c0a9af976d927f1e913e047f4644e7862f Mon Sep 17 00:00:00 2001 From: Michael Watzko Date: Sat, 31 Mar 2018 00:26:11 +0200 Subject: [PATCH] No longer consume SPI --- Cargo.lock | 2 +- src/lib.rs | 123 +++++++++++++++++++++++++++++------------------------ 2 files changed, 69 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6343720..f0381e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,7 +18,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "w5500" -version = "0.1.0" +version = "0.1.2" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "embedded-hal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/lib.rs b/src/lib.rs index 5451f29..18a0a09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,28 +75,27 @@ impl ::core::fmt::Display for MacAddress { } -pub struct W5500 + Sized, O: OutputPin> { - spi: S, - cs: O, +pub struct W5500<'a> { + cs: &'a mut OutputPin, } -impl + Sized, O: OutputPin> W5500 { +impl<'a> W5500<'a> { - pub fn new(spi: S, cs: O) -> Result, E> { + pub fn new>(spi: &mut S, cs: &'a mut OutputPin) -> Result, E> { W5500 { - spi, cs, - }.init() + }.init(spi) } - fn init(mut self) -> Result { - self.reset()?; - self.set_mode(false, false, false, false)?; + fn init>(mut self, spi: &mut S) -> Result { + self.reset(spi)?; + self.set_mode(spi,false, false, false, false)?; Ok(self) } - pub fn reset(&mut self) -> Result<(), E> { + pub fn reset>(&mut self, spi: &mut S) -> Result<(), E> { self.write_to( + spi, Register::CommonRegister(0x00_00_u16), &[ 0b1000_0000, // Mode Register (force reset) @@ -104,7 +103,7 @@ impl + Sized, O: OutputPin> W5500 { ) } - pub fn set_mode(&mut self, wol: bool, ping_block: bool, ppoe: bool, force_arp: bool) -> Result<(), E> { + pub fn set_mode>(&mut self, spi: &mut S, wol: bool, ping_block: bool, ppoe: bool, force_arp: bool) -> Result<(), E> { let mut mode = 0x00; @@ -125,54 +124,61 @@ impl + Sized, O: OutputPin> W5500 { } self.write_to( + spi, Register::CommonRegister(0x00_00_u16), &[mode] ) } - pub fn set_gateway(&mut self, gateway: &IpAddress) -> Result<(), E> { + pub fn set_gateway>(&mut self, spi: &mut S, gateway: &IpAddress) -> Result<(), E> { self.write_to( + spi, Register::CommonRegister(0x00_01_u16), &gateway.address ) } - pub fn set_subnet(&mut self, subnet: &IpAddress) -> Result<(), E> { + pub fn set_subnet>(&mut self, spi: &mut S, subnet: &IpAddress) -> Result<(), E> { self.write_to( + spi, Register::CommonRegister(0x00_05_u16), &subnet.address ) } - pub fn set_mac(&mut self, mac: &MacAddress) -> Result<(), E> { + pub fn set_mac>(&mut self, spi: &mut S, mac: &MacAddress) -> Result<(), E> { self.write_to( + spi, Register::CommonRegister(0x00_09_u16), &mac.address ) } - pub fn get_mac(&mut self) -> Result { + pub fn get_mac>(&mut self, spi: &mut S) -> Result { let mut mac = MacAddress::default(); self.read_from( + spi, Register::CommonRegister(0x00_09_u16), &mut mac.address )?; Ok(mac) } - pub fn set_ip(&mut self, ip: &IpAddress) -> Result<(), E> { + pub fn set_ip>(&mut self, spi: &mut S, ip: &IpAddress) -> Result<(), E> { self.write_to( + spi, Register::CommonRegister(0x00_0F_u16), &ip.address ) } - pub fn send_udp(&mut self, socket: Socket, local_port: u16, host: &IpAddress, host_port: u16, data: &[u8]) -> Result<(), E> { + pub fn send_udp>(&mut self, spi: &mut S, socket: Socket, local_port: u16, host: &IpAddress, host_port: u16, data: &[u8]) -> Result<(), E> { // TODO not always socket 0 // TODO check if in use self.write_to( + spi, socket.register_at(0x00_00), &[ Protocol::UDP as u8, // Socket Mode Register @@ -185,6 +191,7 @@ impl + Sized, O: OutputPin> W5500 { let host_port = u16_to_be_bytes(host_port); self.write_to( + spi, socket.register_at(0x00_04), &[ local_port[0], local_port[1], // local port u16 @@ -201,6 +208,7 @@ impl + Sized, O: OutputPin> W5500 { let data_length = u16_to_be_bytes(data_length); self.write_to( + spi, socket.register_at(0x00_22), &[ 0x00, 0x00, @@ -211,11 +219,13 @@ impl + Sized, O: OutputPin> W5500 { self.write_to( + spi, socket.tx_register_at(0x00_00), &data[..data_length as usize] ); self.write_to( + spi, socket.register_at(0x00_01), &[ 0x20 // SEND @@ -223,12 +233,14 @@ impl + Sized, O: OutputPin> W5500 { ) } - pub fn listen_udp(&mut self, socket: Socket, port: u16) -> Result<(), E> { + pub fn listen_udp>(&mut self, spi: &mut S, socket: Socket, port: u16) -> Result<(), E> { self.write_u16( + spi, socket.register_at(0x00_04), port )?; self.write_to( + spi, socket.register_at(0x00_00), &[ Protocol::UDP as u8, // Socket Mode Register @@ -238,29 +250,30 @@ impl + Sized, O: OutputPin> W5500 { } /// TODO destination buffer has to be as large as the receive buffer or complete read is not guaranteed - pub fn try_receive_udp(&mut self, socket: Socket, destination: &mut [u8]) -> Result, E> { - if self.read_u8(socket.register_at(0x00_2c))? & 0x04 == 0 { + pub fn try_receive_udp>(&mut self, spi: &mut S, socket: Socket, destination: &mut [u8]) -> Result, E> { + if self.read_u8(spi, socket.register_at(0x00_2c))? & 0x04 == 0 { return Ok(None); } let receive_size = loop { - let s0 = self.read_u16(socket.register_at(0x00_26))?; - let s1 = self.read_u16(socket.register_at(0x00_26))?; + let s0 = self.read_u16(spi, socket.register_at(0x00_26))?; + let s1 = self.read_u16(spi, socket.register_at(0x00_26))?; if s0 == s1 { break s0 as usize; } }; if receive_size >= 8 { - let read_pointer = self.read_u16(socket.register_at(0x00_28))?; + let read_pointer = self.read_u16(spi, socket.register_at(0x00_28))?; // |<-- read_pointer read_pointer + received_size -->| // |Destination IP Address | Destination Port | Byte Size of DATA | Actual DATA ... | // | --- 4 Bytes --- | --- 2 Bytes --- | --- 2 Bytes --- | .... | - let ip = self.read_ip(socket.rx_register_at(read_pointer))?; - let port = self.read_u16(socket.rx_register_at(read_pointer+4))?; - let data_length = destination.len().min(self.read_u16(socket.rx_register_at(read_pointer+6))? as usize); + let ip = self.read_ip(spi, socket.rx_register_at(read_pointer))?; + let port = self.read_u16(spi, socket.rx_register_at(read_pointer+4))?; + let data_length = destination.len().min(self.read_u16(spi, socket.rx_register_at(read_pointer+6))? as usize); self.read_from( + spi, socket.rx_register_at(read_pointer+8), &mut destination[..data_length] )?; @@ -269,8 +282,8 @@ impl + Sized, O: OutputPin> W5500 { // self.read_u16(socket.register_at(0x00_10))?; // reset - self.write_u16(socket.register_at(0x00_28), read_pointer + receive_size as u16)?; - self.write_u8(socket.register_at(0x00_01), SocketCommand::Recv as u8)?; + self.write_u16(spi, socket.register_at(0x00_28), read_pointer + receive_size as u16)?; + self.write_u8(spi, socket.register_at(0x00_01), SocketCommand::Recv as u8)?; Ok(Some((ip, port, data_length))) @@ -279,79 +292,79 @@ impl + Sized, O: OutputPin> W5500 { } } - pub fn read_u8(&mut self, register: Register) -> Result { + pub fn read_u8>(&mut self, spi: &mut S, register: Register) -> Result { let mut buffer = [0u8; 1]; - self.read_from(register, &mut buffer)?; + self.read_from(spi, register, &mut buffer)?; Ok(buffer[0]) } - pub fn read_u16(&mut self, register: Register) -> Result { + pub fn read_u16>(&mut self, spi: &mut S, register: Register) -> Result { let mut buffer = [0u8; 2]; - self.read_from(register, &mut buffer)?; + self.read_from(spi, register, &mut buffer)?; Ok(BigEndian::read_u16(&buffer)) } - pub fn read_ip(&mut self, register: Register) -> Result { + pub fn read_ip>(&mut self, spi: &mut S, register: Register) -> Result { let mut ip = IpAddress::default(); - self.read_from(register, &mut ip.address)?; + self.read_from(spi, register, &mut ip.address)?; Ok(ip) } - pub fn read_from(&mut self, register: Register, target: &mut [u8]) -> Result<(), E> { + pub fn read_from>(&mut self, spi: &mut S, register: Register, target: &mut [u8]) -> Result<(), E> { self.chip_select(); let mut request = [0_u8, 0_u8, register.control_byte() | COMMAND_READ | VARIABLE_DATA_LENGTH]; BigEndian::write_u16(&mut request[..2], register.address()); let result = self - .write_bytes(&request) - .and_then(|_| self.read_bytes(target)); + .write_bytes(spi, &request) + .and_then(|_| self.read_bytes(spi, target)); self.chip_deselect(); result } - pub fn write_u8(&mut self, register: Register, value: u8) -> Result<(), E> { - self.write_to(register, &[value]) + pub fn write_u8>(&mut self, spi: &mut S, register: Register, value: u8) -> Result<(), E> { + self.write_to(spi, register, &[value]) } - pub fn write_u16(&mut self, register: Register, value: u16) -> Result<(), E> { + pub fn write_u16>(&mut self, spi: &mut S, register: Register, value: u16) -> Result<(), E> { let mut data = [0u8; 2]; BigEndian::write_u16(&mut data, value); - self.write_to(register, &data) + self.write_to(spi, register, &data) } - pub fn write_to(&mut self, register: Register, data: &[u8]) -> Result<(), E> { + pub fn write_to>(&mut self, spi: &mut S, register: Register, data: &[u8]) -> Result<(), E> { self.chip_select(); let mut request = [0_u8, 0_u8, register.control_byte() | COMMAND_WRITE | VARIABLE_DATA_LENGTH]; BigEndian::write_u16(&mut request[..2], register.address()); let result = self - .write_bytes(&request) - .and_then(|_| self.write_bytes(data)); + .write_bytes(spi, &request) + .and_then(|_| self.write_bytes(spi, data)); self.chip_deselect(); result } - fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<(), E> { + fn read_bytes>(&mut self, spi: &mut S, bytes: &mut [u8]) -> Result<(), E> { for i in 0..bytes.len() { - bytes[i] = self.read()?; + bytes[i] = self.read(spi)?; } Ok(()) } - fn read(&mut self) -> Result { - block!(self.spi.send(0x00))?; - let result = block!(self.spi.read()); + fn read>(&mut self, spi: &mut S) -> Result { + block!(spi.send(0x00))?; + let result = block!(spi.read()); result } - fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), E> { + fn write_bytes>(&mut self, spi: &mut S, bytes: &[u8]) -> Result<(), E> { for b in bytes { - self.write(*b)?; + self.write(spi, *b)?; } Ok(()) } - fn write(&mut self, byte: u8) -> Result<(), E> { - block!(self.spi.send(byte))?; - block!(self.spi.read())?; + fn write>(&mut self, spi: &mut S, byte: u8) -> Result<(), E> { + block!(spi.send(byte))?; + block!(spi.read())?; Ok(()) }