w5500_ll/
spi.rs

1//! Helpers and functions relating to W5500 SPI transfers.
2
3/// SPI Access Modes.
4#[repr(u8)]
5#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
6#[cfg_attr(feature = "defmt", derive(defmt::Format))]
7pub enum AccessMode {
8    /// Read access.
9    Read = 0,
10    /// Write access.
11    Write = 1,
12}
13
14impl From<AccessMode> for u8 {
15    fn from(val: AccessMode) -> Self {
16        val as u8
17    }
18}
19
20/// SPI header length.
21pub const HEADER_LEN: usize = 3;
22
23/// Helper to create a variable data length SPI header.
24///
25/// # Example
26///
27/// SPI header to read the VERSIONR register in variable data length mode.
28///
29/// ```
30/// use w5500_ll::{spi, Reg, COMMON_BLOCK_OFFSET};
31///
32/// let hdr = spi::vdm_header(
33///     Reg::VERSIONR.addr(),
34///     COMMON_BLOCK_OFFSET,
35///     spi::AccessMode::Read,
36/// );
37/// assert_eq!(hdr, [0x00, 0x39, 0x00]);
38/// ```
39#[inline]
40pub const fn vdm_header(addr: u16, block: u8, mode: AccessMode) -> [u8; HEADER_LEN] {
41    [
42        (addr >> 8) as u8,
43        addr as u8,
44        (block << 3) | ((mode as u8) << 2),
45    ]
46}
47
48/// Helper to create a 1 byte fixed data length SPI header.
49///
50/// # Example
51///
52/// SPI header to read the VERSIONR register in fixed data length mode.
53///
54/// ```
55/// use w5500_ll::{spi, Reg, COMMON_BLOCK_OFFSET};
56///
57/// let hdr = spi::fdm_header_1b(
58///     Reg::VERSIONR.addr(),
59///     COMMON_BLOCK_OFFSET,
60///     spi::AccessMode::Read,
61/// );
62/// assert_eq!(hdr, [0x00, 0x39, 0x01]);
63/// ```
64pub const fn fdm_header_1b(addr: u16, block: u8, mode: AccessMode) -> [u8; HEADER_LEN] {
65    [
66        (addr >> 8) as u8,
67        addr as u8,
68        (block << 3) | ((mode as u8) << 2) | 0b01,
69    ]
70}
71
72/// Helper to create a 2 byte fixed data length SPI header.
73///
74/// # Example
75///
76/// SPI header to read the UPORTR register in fixed data length mode.
77///
78/// ```
79/// use w5500_ll::{spi, Reg, COMMON_BLOCK_OFFSET};
80///
81/// let hdr = spi::fdm_header_2b(
82///     Reg::UPORTR0.addr(),
83///     COMMON_BLOCK_OFFSET,
84///     spi::AccessMode::Read,
85/// );
86/// assert_eq!(hdr, [0x00, 0x2C, 0x02]);
87/// ```
88pub const fn fdm_header_2b(addr: u16, block: u8, mode: AccessMode) -> [u8; HEADER_LEN] {
89    [
90        (addr >> 8) as u8,
91        addr as u8,
92        (block << 3) | ((mode as u8) << 2) | 0b10,
93    ]
94}
95
96/// Helper to create a 4 byte fixed data length SPI header.
97///
98/// # Example
99///
100/// SPI header to read the UIPR register in fixed data length mode.
101///
102/// ```
103/// use w5500_ll::{spi, Reg, COMMON_BLOCK_OFFSET};
104///
105/// let hdr = spi::fdm_header_4b(
106///     Reg::UIPR0.addr(),
107///     COMMON_BLOCK_OFFSET,
108///     spi::AccessMode::Read,
109/// );
110/// assert_eq!(hdr, [0x00, 0x28, 0x03]);
111/// ```
112pub const fn fdm_header_4b(addr: u16, block: u8, mode: AccessMode) -> [u8; HEADER_LEN] {
113    [
114        (addr >> 8) as u8,
115        addr as u8,
116        (block << 3) | ((mode as u8) << 2) | 0b11,
117    ]
118}