Update doc and links
This commit is contained in:
parent
0785534c1c
commit
02ae928a51
1 changed files with 66 additions and 32 deletions
98
src/lib.rs
98
src/lib.rs
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue