Update doc and links

This commit is contained in:
Michael Watzko 2020-06-10 17:19:34 +02:00
commit 02ae928a51

View file

@ -20,7 +20,8 @@ const FIXED_DATA_LENGTH_2_BYTES: u8 = 0b_10;
#[allow(unused)] #[allow(unused)]
const FIXED_DATA_LENGTH_4_BYTES: u8 = 0b_11; const FIXED_DATA_LENGTH_4_BYTES: u8 = 0b_11;
/// IP Address struct. Represents an IP address as a u8 array of length 4. Can be instantiated with `IpAddress::new` /// IP Address struct. Represents an IP address as a u8 array of length 4.
/// Can be instantiated with [`IpAddress::new`]
#[derive(Copy, Clone, PartialOrd, PartialEq, Default, Debug)] #[derive(Copy, Clone, PartialOrd, PartialEq, Default, Debug)]
pub struct IpAddress { pub struct IpAddress {
pub address: [u8; 4], pub address: [u8; 4],
@ -46,7 +47,8 @@ impl ::core::fmt::Display for IpAddress {
} }
} }
/// MAC address struct. Represents a MAC address as a u8 array of length 6. Can be instantiated with `MacAddress::new` /// MAC address struct. Represents a MAC address as a u8 array of length 6.
/// Can be instantiated with [`MacAddress::new`]
#[derive(Copy, Clone, PartialOrd, PartialEq, Default, Debug)] #[derive(Copy, Clone, PartialOrd, PartialEq, Default, Debug)]
pub struct MacAddress { pub struct MacAddress {
pub address: [u8; 6], pub address: [u8; 6],
@ -77,22 +79,23 @@ impl ::core::fmt::Display for MacAddress {
} }
} }
/// Error enum that represents the union between SPI hardware errors and digital IO pin errors. Returned as an Error /// Error enum that represents the union between SPI hardware errors and digital IO pin errors.
/// type by many W5500 that talk to the chip /// Returned as an Error type by many [`ActiveW5500`] operations that talk to the chip
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub enum TransferError<SpiError, ChipSelectError> { pub enum TransferError<SpiError, ChipSelectError> {
SpiError(SpiError), SpiError(SpiError),
ChipSelectError(ChipSelectError), ChipSelectError(ChipSelectError),
} }
/// Settings for wake on LAN. Allows the W5500 to optionally emit an interrupt upon receiving a packet /// Settings for wake on LAN. Allows the W5500 to optionally emit an interrupt upon receiving a
/// WOL magic packet.
#[derive(Copy, Clone, PartialOrd, PartialEq)] #[derive(Copy, Clone, PartialOrd, PartialEq)]
pub enum OnWakeOnLan { pub enum OnWakeOnLan {
InvokeInterrupt, InvokeInterrupt,
Ignore, Ignore,
} }
/// Settings for ping. Allows the W5500 to respond to or ignore network ping requests /// Settings for ping. Allows the W5500 to respond to or ignore network ping requests.
#[derive(Copy, Clone, PartialOrd, PartialEq)] #[derive(Copy, Clone, PartialOrd, PartialEq)]
pub enum OnPingRequest { pub enum OnPingRequest {
Respond, Respond,
@ -113,17 +116,21 @@ pub enum ArpResponses {
DropAfterUse, DropAfterUse,
} }
/// Represents a socket that has not yet been initialized for a particular protocol /// Represents a [`Socket`] that has not yet been initialized for a particular protocol
pub struct UninitializedSocket(Socket); pub struct UninitializedSocket(Socket);
/// Represents a socket that has been initialized to use the UDP protocol /// Represents a [`Socket`] that has been initialized to use the UDP protocol
pub struct UdpSocket(Socket); pub struct UdpSocket(Socket);
/// The first level of instantiating communication with the W5500. It can not communicate by itself, but calling /// The first level of instantiating communication with the W5500 device. This type is not used
/// `activate` will return an `ActiveW5500` which can. /// for communication, but to keep track of the state of the device. Calling [`W5500::activate`]
/// will return an [`ActiveW5500`] which can be used to communicate with the device. This
/// allows the SPI-Bus to be used for other devices while not being activated without loosing
/// the state.
pub struct W5500<ChipSelect: OutputPin> { pub struct W5500<ChipSelect: OutputPin> {
chip_select: ChipSelect, chip_select: ChipSelect,
sockets: u8, // each bit represents whether the corresponding socket is available for take /// each bit represents whether the corresponding socket is available for take
sockets: u8,
} }
impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<ChipSelect> { impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<ChipSelect> {
@ -134,7 +141,8 @@ impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<Chip
} }
} }
/// Primary method for instantiating. Briefly activates the W5500, and sets it up with the specified configuration /// Creates a new instance and initializes the device accordingly to the parameters.
/// To do so, it briefly activates the [`W5500`], to set it up with the specified configuration.
pub fn with_initialisation<Spi: FullDuplex<u8>>( pub fn with_initialisation<Spi: FullDuplex<u8>>(
chip_select: ChipSelect, chip_select: ChipSelect,
spi: &mut Spi, spi: &mut Spi,
@ -147,6 +155,8 @@ impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<Chip
{ {
let mut w5500_active = w5500.activate(spi)?; let mut w5500_active = w5500.activate(spi)?;
unsafe { unsafe {
// this is safe, since the w5500 instance hast just been created and no sockets
// are given away or were initialized
w5500_active.reset()?; w5500_active.reset()?;
} }
w5500_active.update_operation_mode(wol, ping, mode, arp)?; w5500_active.update_operation_mode(wol, ping, mode, arp)?;
@ -154,7 +164,7 @@ impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<Chip
Ok(w5500) Ok(w5500)
} }
/// Returns the requested socket if it is not already used. /// Returns the requested socket if it is not already taken.
pub fn take_socket(&mut self, socket: Socket) -> Option<UninitializedSocket> { pub fn take_socket(&mut self, socket: Socket) -> Option<UninitializedSocket> {
let mask = 0x01 << socket.number(); let mask = 0x01 << socket.number();
if self.sockets & mask == mask { if self.sockets & mask == mask {
@ -165,7 +175,8 @@ impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<Chip
} }
} }
/// Creates a new `ActiveW5500` with the provided `FullDuplex` implementation /// Returns a [`ActiveW5500`] which can be used to modify the device and to communicate
/// with other ethernet devices within the connected LAN.
pub fn activate<'a, 'b, Spi: FullDuplex<u8>>( pub fn activate<'a, 'b, Spi: FullDuplex<u8>>(
&'a mut self, &'a mut self,
spi: &'b mut Spi, spi: &'b mut Spi,
@ -175,7 +186,11 @@ impl<ChipSelectError, ChipSelect: OutputPin<Error = ChipSelectError>> W5500<Chip
} }
} }
/// Struct that can communicate with the W5500 chip, configuring it and reading/writing to the registers on a low level /// This - by concept meant to be a temporary - instance allows to directly communicate with
/// the w5500 device. The reference to the [`W5500`] provides the chip-select [`OutputPin`]
/// as well as its current state. The given SPI interface is borrowed for as long as this
/// instance lives to communicate with the W5500 chip. Drop this instance to re-use the
/// SPI bus for communication with another device.
pub struct ActiveW5500<'a, 'b, ChipSelect: OutputPin, Spi: FullDuplex<u8>>( pub struct ActiveW5500<'a, 'b, ChipSelect: OutputPin, Spi: FullDuplex<u8>>(
&'a mut W5500<ChipSelect>, &'a mut W5500<ChipSelect>,
&'b mut Spi, &'b mut Spi,
@ -188,12 +203,12 @@ impl<
Spi: FullDuplex<u8, Error = SpiError>, Spi: FullDuplex<u8, Error = SpiError>,
> ActiveW5500<'_, '_, ChipSelect, Spi> > ActiveW5500<'_, '_, ChipSelect, Spi>
{ {
/// Returns the requested socket if it is not already used /// Returns the requested socket if it is not already taken. See [`W5500::take_socket`]
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)
} }
/// Set up basic configuration of the W5500 chip /// Set up the basic configuration of the W5500 chip
pub fn update_operation_mode( pub fn update_operation_mode(
&mut self, &mut self,
wol: OnWakeOnLan, wol: OnWakeOnLan,
@ -222,7 +237,7 @@ impl<
self.write_to(Register::CommonRegister(0x00_00_u16), &[value]) self.write_to(Register::CommonRegister(0x00_00_u16), &[value])
} }
/// Sets the IP address of the network gateway (router) /// Sets the IP address of the network gateway (your router's address)
pub fn set_gateway( pub fn set_gateway(
&mut self, &mut self,
gateway: IpAddress, gateway: IpAddress,
@ -230,7 +245,7 @@ impl<
self.write_to(Register::CommonRegister(0x00_01_u16), &gateway.address) self.write_to(Register::CommonRegister(0x00_01_u16), &gateway.address)
} }
/// Sets the subnet on the network /// Sets the subnet on the network (for example 255.255.255.0 for /24 subnets)
pub fn set_subnet( pub fn set_subnet(
&mut self, &mut self,
subnet: IpAddress, subnet: IpAddress,
@ -238,7 +253,20 @@ impl<
self.write_to(Register::CommonRegister(0x00_05_u16), &subnet.address) self.write_to(Register::CommonRegister(0x00_05_u16), &subnet.address)
} }
/// Sets the MAC address of the W5500 device on the network /// Sets the MAC address of the W5500 device on the network.
/// Consider using freely available private/locally administered mac addresses that match the
/// following hex pattern:
///
/// ```code
/// x2-xx-xx-xx-xx-xx
/// x6-xx-xx-xx-xx-xx
/// xA-xx-xx-xx-xx-xx
/// xE-xx-xx-xx-xx-xx
/// ```
///
/// "Universally administered and locally administered addresses are distinguished by setting
/// the second-least-significant bit of the first octet of the address" [Wikipedia](https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local)
///
pub fn set_mac( pub fn set_mac(
&mut self, &mut self,
mac: MacAddress, mac: MacAddress,
@ -246,7 +274,8 @@ impl<
self.write_to(Register::CommonRegister(0x00_09_u16), &mac.address) self.write_to(Register::CommonRegister(0x00_09_u16), &mac.address)
} }
/// Sets the IP address of the W5500 device on network. Must be within the range permitted by the gateway /// Sets the IP address of the W5500 device. Must be within the range and permitted by the
/// gateway or the device will not be accessible.
pub fn set_ip( pub fn set_ip(
&mut self, &mut self,
ip: IpAddress, ip: IpAddress,
@ -254,7 +283,7 @@ impl<
self.write_to(Register::CommonRegister(0x00_0F_u16), &ip.address) self.write_to(Register::CommonRegister(0x00_0F_u16), &ip.address)
} }
/// Reads 4 bytesfrom any register location and returns the value as an IP address /// Reads the 4 bytes from any ip register and returns the value as an [`IpAddress`]
pub fn read_ip( pub fn read_ip(
&mut self, &mut self,
register: Register, register: Register,
@ -303,7 +332,7 @@ impl<
self.write_to(socket.at(SocketRegister::Interrupt), &[interrupt as u8]) self.write_to(socket.at(SocketRegister::Interrupt), &[interrupt as u8])
} }
/// Reads one byte from any register address as a u8 /// Reads one byte from the given [`Register`] as a u8
fn read_u8( fn read_u8(
&mut self, &mut self,
register: Register, register: Register,
@ -313,7 +342,7 @@ impl<
Ok(buffer[0]) Ok(buffer[0])
} }
/// Reads two bytes from any register address and returns as a u16 /// Reads two bytes from the given [`Register`] as a u16
fn read_u16( fn read_u16(
&mut self, &mut self,
register: Register, register: Register,
@ -323,7 +352,7 @@ impl<
Ok(BigEndian::read_u16(&buffer)) Ok(BigEndian::read_u16(&buffer))
} }
/// Reads enough bytes from any register address to fill the `target` u8 slice /// Reads enough bytes from the given [`Register`] address onward to fill the `target` u8 slice
fn read_from( fn read_from(
&mut self, &mut self,
register: Register, register: Register,
@ -357,13 +386,15 @@ impl<
Ok(()) Ok(())
} }
/// Reads a single byte over SPI by writing a zero and reading the response /// Reads a single byte over SPI
fn read(&mut self) -> Result<u8, SpiError> { fn read(&mut self) -> Result<u8, SpiError> {
// SPI is in read/write sync, for every byte one wants to read, a byte needs
// to be written
block!(self.1.send(0x00))?; block!(self.1.send(0x00))?;
block!(self.1.read()) block!(self.1.read())
} }
/// Write a single u8 byte to any register address /// Write a single u8 byte to the given [`Register`]
fn write_u8( fn write_u8(
&mut self, &mut self,
register: Register, register: Register,
@ -372,7 +403,7 @@ impl<
self.write_to(register, &[value]) self.write_to(register, &[value])
} }
/// Write a u16 as two bytes o any register address /// Write a u16 as two bytes o the given [`Register`]
fn write_u16( fn write_u16(
&mut self, &mut self,
register: Register, register: Register,
@ -383,7 +414,7 @@ impl<
self.write_to(register, &data) self.write_to(register, &data)
} }
/// Write a slice of u8 bytes to any register address /// Write a slice of u8 bytes to the given [`Register`]
fn write_to( fn write_to(
&mut self, &mut self,
register: Register, register: Register,
@ -420,6 +451,8 @@ impl<
/// Write a single byte over SPI /// Write a single byte over SPI
fn write(&mut self, byte: u8) -> Result<(), SpiError> { fn write(&mut self, byte: u8) -> Result<(), SpiError> {
block!(self.1.send(byte))?; block!(self.1.send(byte))?;
// SPI is in read/write sync, for every byte one wants to write, a byte needs
// to be read
block!(self.1.read())?; block!(self.1.read())?;
Ok(()) Ok(())
} }
@ -468,7 +501,7 @@ impl<ChipSelect: OutputPin, Spi: FullDuplex<u8>> IntoUdpSocket<UninitializedSock
} }
} }
/// UDP trait that can send and receive UDP packets /// UDP trait that defines send and receive methods for UDP packets
pub trait Udp { pub trait Udp {
type Error; type Error;
@ -490,7 +523,8 @@ impl<ChipSelect: OutputPin, Spi: FullDuplex<u8>> Udp
{ {
type Error = TransferError<Spi::Error, ChipSelect::Error>; type Error = TransferError<Spi::Error, ChipSelect::Error>;
/// Returns a UDP packet if one is available. Will return `None` if no UDP packets are in the socket's buffer /// Returns a UDP packet if one is available. Will return `None` if no UDP packets are in the
/// socket's buffer
fn receive( fn receive(
&mut self, &mut self,
destination: &mut [u8], destination: &mut [u8],
@ -542,7 +576,7 @@ impl<ChipSelect: OutputPin, Spi: FullDuplex<u8>> Udp
} }
} }
/// Sends a UDP packet to the specified IP and port, and blocks until it is sent /// Sends a UDP packet to the specified IP and port, and blocks until it is fully sent
fn blocking_send( fn blocking_send(
&mut self, &mut self,
host: &IpAddress, host: &IpAddress,