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}