Updated all dependencies, replaced deprecated v1 OutputPin

This commit is contained in:
Jonah Dahlquist 2019-07-30 20:25:18 -05:00
commit 1d88a91e88
3 changed files with 168 additions and 61 deletions

20
Cargo.lock generated
View file

@ -2,21 +2,21 @@
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.2.6" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "embedded-hal" name = "embedded-hal"
version = "0.2.1" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "nb" name = "nb"
version = "0.1.1" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -28,13 +28,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "w5500" name = "w5500"
version = "0.2.1" version = "0.2.1"
dependencies = [ dependencies = [
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"embedded-hal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[metadata] [metadata]
"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum embedded-hal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "26944677e4934eb5fb4025501dc0d6cdbcf6bfabd6200fcfee2e7e8eef8c0362" "checksum embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b"
"checksum nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "69f380b5fe9fab8c0d7a6a99cda23e2cc0463bedb2cbc3aada0813b98496ecdc" "checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

View file

@ -10,6 +10,6 @@ license = "MIT OR Apache-2.0"
readme = "README.md" readme = "README.md"
[dependencies] [dependencies]
byteorder = { version = "1.2.1", default-features = false } byteorder = { version = "1.3.2", default-features = false }
embedded-hal = "0.2.1" embedded-hal = "0.2.3"
nb = "0.1.1" nb = "0.1.2"

View file

@ -7,7 +7,7 @@ extern crate embedded_hal as hal;
#[macro_use(block)] #[macro_use(block)]
extern crate nb; extern crate nb;
use hal::digital::OutputPin; use hal::digital::v2::OutputPin;
use hal::spi::FullDuplex; use hal::spi::FullDuplex;
use byteorder::BigEndian; use byteorder::BigEndian;
@ -72,6 +72,12 @@ impl ::core::fmt::Display for MacAddress {
} }
} }
#[derive(Copy, Clone, Debug)]
pub enum TransferError<SpiError, ChipSelectError> {
SpiError(SpiError),
ChipSelectError(ChipSelectError),
}
#[derive(Copy, Clone, PartialOrd, PartialEq)] #[derive(Copy, Clone, PartialOrd, PartialEq)]
pub enum OnWakeOnLan { pub enum OnWakeOnLan {
InvokeInterrupt, InvokeInterrupt,
@ -101,12 +107,14 @@ pub enum ArpResponses {
pub struct UninitializedSocket(Socket); pub struct UninitializedSocket(Socket);
pub struct UdpSocket(Socket); pub struct UdpSocket(Socket);
pub struct W5500<'a, ChipSelect: OutputPin> { pub struct W5500<'a, ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> {
chip_select: &'a mut ChipSelect, chip_select: &'a mut ChipSelect,
sockets: u8, // each bit represents whether the corresponding socket is available for take sockets: u8, // each bit represents whether the corresponding socket is available for take
} }
impl<'b, 'a: 'b, ChipSelect: OutputPin> W5500<'a, ChipSelect> { impl<'b, 'a: 'b, ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>>
W5500<'a, ChipSelectError, ChipSelect>
{
fn new(chip_select: &'a mut ChipSelect) -> Self { fn new(chip_select: &'a mut ChipSelect) -> Self {
W5500 { W5500 {
chip_select, chip_select,
@ -121,7 +129,7 @@ impl<'b, 'a: 'b, ChipSelect: OutputPin> W5500<'a, ChipSelect> {
ping: OnPingRequest, ping: OnPingRequest,
mode: ConnectionType, mode: ConnectionType,
arp: ArpResponses, arp: ArpResponses,
) -> Result<Self, E> { ) -> Result<Self, TransferError<E, ChipSelectError>> {
let mut w5500 = Self::new(chip_select); let mut w5500 = Self::new(chip_select);
{ {
let mut w5500_active = w5500.activate(spi)?; let mut w5500_active = w5500.activate(spi)?;
@ -146,14 +154,31 @@ impl<'b, 'a: 'b, ChipSelect: OutputPin> W5500<'a, ChipSelect> {
pub fn activate<'c, E, Spi: FullDuplex<u8, Error = E>>( pub fn activate<'c, E, Spi: FullDuplex<u8, Error = E>>(
&'b mut self, &'b mut self,
spi: &'c mut Spi, spi: &'c mut Spi,
) -> Result<ActiveW5500<'b, 'a, 'c, E, ChipSelect, Spi>, E> { ) -> Result<
ActiveW5500<'b, 'a, 'c, E, ChipSelectError, ChipSelect, Spi>,
TransferError<E, ChipSelectError>,
> {
Ok(ActiveW5500(self, spi)) Ok(ActiveW5500(self, spi))
} }
} }
pub struct ActiveW5500<'a, 'b: 'a, 'c, E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>>(&'a mut W5500<'b, ChipSelect>, &'c mut Spi); pub struct ActiveW5500<
'a,
'b: 'a,
'c,
SpiError,
ChipSelectError,
ChipSelect: OutputPin<Error = ChipSelectError>,
Spi: FullDuplex<u8, Error = SpiError>,
>(&'a mut W5500<'b, ChipSelectError, ChipSelect>, &'c mut Spi);
impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> ActiveW5500<'_, '_, '_, E, ChipSelect, Spi> { impl<
SpiError,
ChipSelectError,
ChipSelect: OutputPin<Error = ChipSelectError>,
Spi: FullDuplex<u8, Error = SpiError>,
> ActiveW5500<'_, '_, '_, SpiError, ChipSelectError, ChipSelect, Spi>
{
pub fn take_socket(&mut self, socket: Socket) -> Option<UninitializedSocket> { pub fn take_socket(&mut self, socket: Socket) -> Option<UninitializedSocket> {
self.0.take_socket(socket) self.0.take_socket(socket)
} }
@ -164,7 +189,7 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> ActiveW5500<'_, '
ping: OnPingRequest, ping: OnPingRequest,
mode: ConnectionType, mode: ConnectionType,
arp: ArpResponses, arp: ArpResponses,
) -> Result<(), E> { ) -> Result<(), TransferError<SpiError, ChipSelectError>> {
let mut value = 0x00; let mut value = 0x00;
if let OnWakeOnLan::InvokeInterrupt = wol { if let OnWakeOnLan::InvokeInterrupt = wol {
@ -186,23 +211,38 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> ActiveW5500<'_, '
self.write_to(Register::CommonRegister(0x00_00_u16), &[value]) self.write_to(Register::CommonRegister(0x00_00_u16), &[value])
} }
pub fn set_gateway(&mut self, gateway: IpAddress) -> Result<(), E> { pub fn set_gateway(
&mut self,
gateway: IpAddress,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to(Register::CommonRegister(0x00_01_u16), &gateway.address) self.write_to(Register::CommonRegister(0x00_01_u16), &gateway.address)
} }
pub fn set_subnet(&mut self, subnet: IpAddress) -> Result<(), E> { pub fn set_subnet(
&mut self,
subnet: IpAddress,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to(Register::CommonRegister(0x00_05_u16), &subnet.address) self.write_to(Register::CommonRegister(0x00_05_u16), &subnet.address)
} }
pub fn set_mac(&mut self, mac: MacAddress) -> Result<(), E> { pub fn set_mac(
&mut self,
mac: MacAddress,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to(Register::CommonRegister(0x00_09_u16), &mac.address) self.write_to(Register::CommonRegister(0x00_09_u16), &mac.address)
} }
pub fn set_ip(&mut self, ip: IpAddress) -> Result<(), E> { pub fn set_ip(
&mut self,
ip: IpAddress,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to(Register::CommonRegister(0x00_0F_u16), &ip.address) self.write_to(Register::CommonRegister(0x00_0F_u16), &ip.address)
} }
pub fn read_ip(&mut self, register: Register) -> Result<IpAddress, E> { pub fn read_ip(
&mut self,
register: Register,
) -> Result<IpAddress, TransferError<SpiError, ChipSelectError>> {
let mut ip = IpAddress::default(); let mut ip = IpAddress::default();
self.read_from(register, &mut ip.address)?; self.read_from(register, &mut ip.address)?;
Ok(ip) Ok(ip)
@ -211,7 +251,7 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> ActiveW5500<'_, '
/// This is unsafe because it cannot set taken sockets back to be uninitialized /// This is unsafe because it cannot set taken sockets back to be uninitialized
/// It assumes, none of the old sockets will used anymore. Otherwise that socket /// It assumes, none of the old sockets will used anymore. Otherwise that socket
/// will have undefined behavior. /// will have undefined behavior.
pub unsafe fn reset(&mut self) -> Result<(), E> { pub unsafe fn reset(&mut self) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to( self.write_to(
Register::CommonRegister(0x00_00_u16), Register::CommonRegister(0x00_00_u16),
&[ &[
@ -222,108 +262,160 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> ActiveW5500<'_, '
Ok(()) Ok(())
} }
fn is_interrupt_set(&mut self, socket: Socket, interrupt: Interrupt) -> Result<bool, E> { fn is_interrupt_set(
&mut self,
socket: Socket,
interrupt: Interrupt,
) -> Result<bool, TransferError<SpiError, ChipSelectError>> {
let mut state = [0u8; 1]; let mut state = [0u8; 1];
self.read_from(socket.at(SocketRegister::Interrupt), &mut state)?; self.read_from(socket.at(SocketRegister::Interrupt), &mut state)?;
Ok(state[0] & interrupt as u8 != 0) Ok(state[0] & interrupt as u8 != 0)
} }
pub fn reset_interrupt(&mut self, socket: Socket, interrupt: Interrupt) -> Result<(), E> { pub fn reset_interrupt(
&mut self,
socket: Socket,
interrupt: Interrupt,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to(socket.at(SocketRegister::Interrupt), &[interrupt as u8]) self.write_to(socket.at(SocketRegister::Interrupt), &[interrupt as u8])
} }
fn read_u8(&mut self, register: Register) -> Result<u8, E> { fn read_u8(
&mut self,
register: Register,
) -> Result<u8, TransferError<SpiError, ChipSelectError>> {
let mut buffer = [0u8; 1]; let mut buffer = [0u8; 1];
self.read_from(register, &mut buffer)?; self.read_from(register, &mut buffer)?;
Ok(buffer[0]) Ok(buffer[0])
} }
fn read_u16(&mut self, register: Register) -> Result<u16, E> { fn read_u16(
&mut self,
register: Register,
) -> Result<u16, TransferError<SpiError, ChipSelectError>> {
let mut buffer = [0u8; 2]; let mut buffer = [0u8; 2];
self.read_from(register, &mut buffer)?; self.read_from(register, &mut buffer)?;
Ok(BigEndian::read_u16(&buffer)) Ok(BigEndian::read_u16(&buffer))
} }
fn read_from(&mut self, register: Register, target: &mut [u8]) -> Result<(), E> { fn read_from(
self.chip_select(); &mut self,
register: Register,
target: &mut [u8],
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.chip_select()
.map_err(|error| -> TransferError<SpiError, ChipSelectError> {
TransferError::ChipSelectError(error)
});
let mut request = [ let mut request = [
0_u8, 0_u8,
0_u8, 0_u8,
register.control_byte() | COMMAND_READ | VARIABLE_DATA_LENGTH, register.control_byte() | COMMAND_READ | VARIABLE_DATA_LENGTH,
]; ];
BigEndian::write_u16(&mut request[..2], register.address()); BigEndian::write_u16(&mut request[..2], register.address());
let result = self.write_bytes(&request) let result = self
.write_bytes(&request)
.and_then(|_| self.read_bytes(target)); .and_then(|_| self.read_bytes(target));
self.chip_deselect(); self.chip_deselect()
result .map_err(|error| -> TransferError<SpiError, ChipSelectError> {
TransferError::ChipSelectError(error)
});
result.map_err(|error| TransferError::SpiError(error))
} }
fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<(), E> { fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<(), SpiError> {
for byte in bytes { for byte in bytes {
*byte = self.read()?; *byte = self.read()?;
} }
Ok(()) Ok(())
} }
fn read(&mut self) -> Result<u8, E> { fn read(&mut self) -> Result<u8, SpiError> {
block!(self.1.send(0x00))?; block!(self.1.send(0x00))?;
block!(self.1.read()) block!(self.1.read())
} }
fn write_u8(&mut self, register: Register, value: u8) -> Result<(), E> { fn write_u8(
&mut self,
register: Register,
value: u8,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.write_to(register, &[value]) self.write_to(register, &[value])
} }
fn write_u16(&mut self, register: Register, value: u16) -> Result<(), E> { fn write_u16(
&mut self,
register: Register,
value: u16,
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
let mut data = [0u8; 2]; let mut data = [0u8; 2];
BigEndian::write_u16(&mut data, value); BigEndian::write_u16(&mut data, value);
self.write_to(register, &data) self.write_to(register, &data)
} }
fn write_to(&mut self, register: Register, data: &[u8]) -> Result<(), E> { fn write_to(
self.chip_select(); &mut self,
register: Register,
data: &[u8],
) -> Result<(), TransferError<SpiError, ChipSelectError>> {
self.chip_select()
.map_err(|error| -> TransferError<SpiError, ChipSelectError> {
TransferError::ChipSelectError(error)
});
let mut request = [ let mut request = [
0_u8, 0_u8,
0_u8, 0_u8,
register.control_byte() | COMMAND_WRITE | VARIABLE_DATA_LENGTH, register.control_byte() | COMMAND_WRITE | VARIABLE_DATA_LENGTH,
]; ];
BigEndian::write_u16(&mut request[..2], register.address()); BigEndian::write_u16(&mut request[..2], register.address());
let result = self.write_bytes(&request) let result = self
.write_bytes(&request)
.and_then(|_| self.write_bytes(data)); .and_then(|_| self.write_bytes(data));
self.chip_deselect(); self.chip_deselect()
result .map_err(|error| -> TransferError<SpiError, ChipSelectError> {
TransferError::ChipSelectError(error)
});
result.map_err(|error| TransferError::SpiError(error))
} }
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), E> { fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SpiError> {
for b in bytes { for b in bytes {
self.write(*b)?; self.write(*b)?;
} }
Ok(()) Ok(())
} }
fn write(&mut self, byte: u8) -> Result<(), E> { fn write(&mut self, byte: u8) -> Result<(), SpiError> {
block!(self.1.send(byte))?; block!(self.1.send(byte))?;
block!(self.1.read())?; block!(self.1.read())?;
Ok(()) Ok(())
} }
fn chip_select(&mut self) { fn chip_select(&mut self) -> Result<(), ChipSelectError> {
self.0.chip_select.set_low() self.0.chip_select.set_low()
} }
fn chip_deselect(&mut self) { fn chip_deselect(&mut self) -> Result<(), ChipSelectError> {
self.0.chip_select.set_high() self.0.chip_select.set_high()
} }
} }
pub trait IntoUdpSocket<E> { pub trait IntoUdpSocket<SpiError> {
fn try_into_udp_server_socket(self, port: u16) -> Result<UdpSocket, E> fn try_into_udp_server_socket(self, port: u16) -> Result<UdpSocket, SpiError>
where where
Self: Sized; Self: Sized;
} }
impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> IntoUdpSocket<UninitializedSocket> impl<
for (&mut ActiveW5500<'_, '_, '_, E, ChipSelect, Spi>, UninitializedSocket) SpiError,
ChipSelectError,
ChipSelect: OutputPin<Error = ChipSelectError>,
Spi: FullDuplex<u8, Error = SpiError>,
> IntoUdpSocket<UninitializedSocket>
for (
&mut ActiveW5500<'_, '_, '_, SpiError, ChipSelectError, ChipSelect, Spi>,
UninitializedSocket,
)
{ {
fn try_into_udp_server_socket(self, port: u16) -> Result<UdpSocket, UninitializedSocket> { fn try_into_udp_server_socket(self, port: u16) -> Result<UdpSocket, UninitializedSocket> {
let socket = (self.1).0; let socket = (self.1).0;
@ -341,22 +433,38 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> IntoUdpSocket<Uni
)?; )?;
Ok(UdpSocket(socket)) Ok(UdpSocket(socket))
})() })()
.map_err(|_: E| UninitializedSocket(socket)) .map_err(|_: TransferError<SpiError, ChipSelectError>| UninitializedSocket(socket))
} }
} }
pub trait Udp<E> { pub trait Udp<SpiError, ChipSelectError> {
fn receive(&mut self, target_buffer: &mut [u8]) -> Result<Option<(IpAddress, u16, usize)>, E>; fn receive(
&mut self,
target_buffer: &mut [u8],
) -> Result<Option<(IpAddress, u16, usize)>, TransferError<SpiError, ChipSelectError>>;
fn blocking_send( fn blocking_send(
&mut self, &mut self,
host: &IpAddress, host: &IpAddress,
host_port: u16, host_port: u16,
data: &[u8], data: &[u8],
) -> Result<(), E>; ) -> Result<(), TransferError<SpiError, ChipSelectError>>;
} }
impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> Udp<E> for (&mut ActiveW5500<'_, '_, '_, E, ChipSelect, Spi>, &UdpSocket) { impl<
fn receive(&mut self, destination: &mut [u8]) -> Result<Option<(IpAddress, u16, usize)>, E> { SpiError,
ChipSelectError,
ChipSelect: OutputPin<Error = ChipSelectError>,
Spi: FullDuplex<u8, Error = SpiError>,
> Udp<SpiError, ChipSelectError>
for (
&mut ActiveW5500<'_, '_, '_, SpiError, ChipSelectError, ChipSelect, Spi>,
&UdpSocket,
)
{
fn receive(
&mut self,
destination: &mut [u8],
) -> Result<Option<(IpAddress, u16, usize)>, TransferError<SpiError, ChipSelectError>> {
let (w5500, UdpSocket(socket)) = self; let (w5500, UdpSocket(socket)) = self;
if w5500.read_u8(socket.at(SocketRegister::InterruptMask))? & 0x04 == 0 { if w5500.read_u8(socket.at(SocketRegister::InterruptMask))? & 0x04 == 0 {
@ -412,7 +520,7 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> Udp<E> for (&mut
host: &IpAddress, host: &IpAddress,
host_port: u16, host_port: u16,
data: &[u8], data: &[u8],
) -> Result<(), E> { ) -> Result<(), TransferError<SpiError, ChipSelectError>> {
let (w5500, UdpSocket(socket)) = self; let (w5500, UdpSocket(socket)) = self;
{ {
@ -486,7 +594,6 @@ impl<E, ChipSelect: OutputPin, Spi: FullDuplex<u8, Error = E>> Udp<E> for (&mut
} }
} }
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
pub enum SocketRegister { pub enum SocketRegister {