w5500_ll/specifiers.rs
1//! Register specifiers (enumerations).
2
3/// Socket status.
4///
5/// This is used with the [`sn_sr`] method.
6///
7/// [`sn_sr`]: crate::Registers::sn_sr
8#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Hash, Default)]
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10#[repr(u8)]
11pub enum SocketStatus {
12 /// Socket closed, this is the reset state of all sockets.
13 ///
14 /// This state can be set by a [`Disconnect`] or [`Close`] command.
15 ///
16 /// This state will also be set automatically if a timeout occurs.
17 ///
18 /// [`Disconnect`]: SocketCommand::Disconnect
19 /// [`Close`]: SocketCommand::Close
20 #[default]
21 Closed = 0x00,
22 /// The socket is opened in TCP mode.
23 ///
24 /// This state is set when the socket protocol is [`Tcp`], and a [`Open`]
25 /// command is sent.
26 ///
27 /// In this state you can use the [`Listen`] and [`Connect`] commands.
28 ///
29 /// [`Tcp`]: Protocol::Tcp
30 /// [`Open`]: SocketCommand::Open
31 /// [`Listen`]: SocketCommand::Listen
32 /// [`Connect`]: SocketCommand::Connect
33 Init = 0x13,
34 /// The socket is listening, operating as a TCP server.
35 ///
36 /// The socket will wait for a connextion-request (SYN packet) from a
37 /// peer (TCP client).
38 ///
39 /// The state will change to [`Established`] when the connection-request is
40 /// successfully accepted.
41 /// Otherwise the state will change to [`Closed`] after the
42 /// TCP timeout duration set by [`rcr`] and [`rtr`].
43 ///
44 /// [`Established`]: SocketStatus::Established
45 /// [`Closed`]: SocketStatus::Closed
46 /// [`rcr`]: crate::Registers::rcr
47 /// [`rtr`]: crate::Registers::rtr
48 Listen = 0x14,
49 /// Connection request (SYN packet) has been sent to a peer.
50 ///
51 /// This is temporarily displayed between the [`Init`] and [`Established`]
52 /// states, after a [`Connect`] command has been sent.
53 ///
54 /// If the SYN/ACK is received from the peer the state changes to
55 /// [`Established`], otherwise the state changes to [`Closed`] after the TCP
56 /// timeout duration set by [`rcr`] and [`rtr`].
57 ///
58 /// [`Init`]: SocketStatus::Init
59 /// [`Connect`]: SocketCommand::Connect
60 /// [`Established`]: SocketStatus::Established
61 /// [`Closed`]: SocketStatus::Closed
62 /// [`rcr`]: crate::Registers::rcr
63 /// [`rtr`]: crate::Registers::rtr
64 SynSent = 0x15,
65 /// Connection request (SYN packet) has been received from a peer.
66 ///
67 /// If the socket sends the response (SYN/ACK packet) to the peer
68 /// successfully the state changes to [`Established`], otherwise the state
69 /// changes to [`Closed`] after the TCP timeout duration set by [`rcr`] and
70 /// [`rtr`].
71 ///
72 /// [`Established`]: SocketStatus::Established
73 /// [`Closed`]: SocketStatus::Closed
74 /// [`rcr`]: crate::Registers::rcr
75 /// [`rtr`]: crate::Registers::rtr
76 SynRecv = 0x16,
77 /// TCP connection is established.
78 ///
79 /// When operating as a TCP client this state is set after the TCP server
80 /// accepts the SYN packet, which is sent by the client after issuing a
81 /// [`Connect`].
82 ///
83 /// When operating as a TCP server this state is set after a client
84 /// connects when in the [`Listen`] state.
85 ///
86 /// While in this state data can be transferred with the [`Send`] and
87 /// [`Recv`] commands.
88 ///
89 /// [`Connect`]: SocketCommand::Connect
90 /// [`Listen`]: SocketStatus::Listen
91 /// [`Send`]: SocketCommand::Send
92 /// [`Recv`]: SocketCommand::Recv
93 Established = 0x17,
94 /// Temporary status between status transitions.
95 ///
96 /// This indicates the socket is closing.
97 FinWait = 0x18,
98 /// Temporary status between status transitions.
99 ///
100 /// This indicates the socket is closing.
101 Closing = 0x1A,
102 /// Temporary status between status transitions.
103 ///
104 /// This indicates the socket is closing.
105 TimeWait = 0x1B,
106 /// The socket has received the disconnect-request (FIN packet) from the
107 /// connected peer.
108 ///
109 /// This is half-closing status, and data can be transferred.
110 ///
111 /// For full-closing the [`Disconnect`] command is used.
112 ///
113 /// For just-closing the [`Close`] command is used.
114 ///
115 /// [`Disconnect`]: SocketCommand::Disconnect
116 /// [`Close`]: SocketCommand::Close
117 CloseWait = 0x1C,
118 /// Temporary status between status transitions.
119 LastAck = 0x1D,
120 /// Socket is opened in UDP mode.
121 ///
122 /// This state is set when the socket protocol is [`Udp`], and a [`Open`]
123 /// command is sent.
124 ///
125 /// [`Udp`]: Protocol::Udp
126 /// [`Open`]: SocketCommand::Open
127 Udp = 0x22,
128 /// Socket is opened in MACRAW mode.
129 ///
130 /// This is valid only for [socket 0].
131 ///
132 /// This state is set when the socket protocol is [`Macraw`], and a [`Open`]
133 /// command is sent.
134 ///
135 /// [socket 0]: crate::Sn::Sn0
136 /// [`Macraw`]: Protocol::Macraw
137 /// [`Open`]: SocketCommand::Open
138 Macraw = 0x42,
139}
140impl From<SocketStatus> for u8 {
141 fn from(val: SocketStatus) -> u8 {
142 val as u8
143 }
144}
145impl TryFrom<u8> for SocketStatus {
146 type Error = u8;
147 fn try_from(val: u8) -> Result<SocketStatus, u8> {
148 match val {
149 x if x == SocketStatus::Closed as u8 => Ok(SocketStatus::Closed),
150 x if x == SocketStatus::Init as u8 => Ok(SocketStatus::Init),
151 x if x == SocketStatus::Listen as u8 => Ok(SocketStatus::Listen),
152 x if x == SocketStatus::SynSent as u8 => Ok(SocketStatus::SynSent),
153 x if x == SocketStatus::SynRecv as u8 => Ok(SocketStatus::SynRecv),
154 x if x == SocketStatus::Established as u8 => Ok(SocketStatus::Established),
155 x if x == SocketStatus::FinWait as u8 => Ok(SocketStatus::FinWait),
156 x if x == SocketStatus::Closing as u8 => Ok(SocketStatus::Closing),
157 x if x == SocketStatus::TimeWait as u8 => Ok(SocketStatus::TimeWait),
158 x if x == SocketStatus::CloseWait as u8 => Ok(SocketStatus::CloseWait),
159 x if x == SocketStatus::LastAck as u8 => Ok(SocketStatus::LastAck),
160 x if x == SocketStatus::Udp as u8 => Ok(SocketStatus::Udp),
161 x if x == SocketStatus::Macraw as u8 => Ok(SocketStatus::Macraw),
162 _ => Err(val),
163 }
164 }
165}
166
167/// Socket commands.
168///
169/// This is used to set the command for socket n.
170///
171/// After W5500 accepts the command, the [`sn_cr`] register is automatically
172/// cleared to `0x00`.
173/// Even though [`sn_cr`] is cleared to `0x00`, the command
174/// is still being processed.
175/// To check whether the command is completed or not, check
176/// [`sn_ir`] or [`sn_sr`].
177///
178/// [`sn_cr`]: crate::Registers::set_sn_cr
179/// [`sn_ir`]: crate::Registers::sn_ir
180/// [`sn_sr`]: crate::Registers::sn_sr
181#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Hash)]
182#[cfg_attr(feature = "defmt", derive(defmt::Format))]
183#[repr(u8)]
184pub enum SocketCommand {
185 /// The command register clears to this state once a command has been
186 /// accepted.
187 Accepted = 0x00,
188 /// The socket is initialized and opened according to the protocol
189 /// selected in [`sn_mr`].
190 ///
191 /// | [`sn_mr`] | [`sn_sr`] |
192 /// |----------------------|-----------------------------|
193 /// | [`Protocol::Closed`] | - |
194 /// | [`Protocol::Tcp`] | [`SocketStatus::Init`] |
195 /// | [`Protocol::Udp`] | [`SocketStatus::Udp`] |
196 /// | [`Protocol::Macraw`] | [`SocketStatus::Macraw`] |
197 ///
198 /// [`sn_mr`]: crate::Registers::sn_mr
199 /// [`sn_sr`]: crate::Registers::sn_sr
200 Open = 0x01,
201 /// Operate the socket as a TCP server.
202 ///
203 /// This will change the socket state from [`Init`] to [`Listen`],
204 /// and the socket will listen for a
205 /// connection-request (SYN packet) from any TCP client.
206 ///
207 /// When a TCP client connection request is successfully established,
208 /// the socket state changes from [`Listen`] to
209 /// [`Established`] and the [`CON`] socket interrupt is raised.
210 ///
211 /// When a TCP client connection request fails the [`TIMEOUT`] socket
212 /// interrupt is set and the
213 /// socket status changes to [`Closed`].
214 ///
215 /// Only valid in [`Tcp`] mode.
216 ///
217 /// [`Closed`]: SocketStatus::Closed
218 /// [`CON`]: crate::SocketInterrupt::con_raised
219 /// [`Established`]: SocketStatus::Established
220 /// [`Init`]: SocketStatus::Init
221 /// [`Listen`]: SocketStatus::Listen
222 /// [`Tcp`]: Protocol::Tcp
223 /// [`TIMEOUT`]: crate::SocketInterrupt::timeout_raised
224 Listen = 0x02,
225 /// Connect to a TCP server.
226 ///
227 /// A connect-request (SYN packet) is sent to the TCP server configured by
228 /// the IPv4 address and port set with [`set_sn_dest`].
229 ///
230 /// If the connect-request is successful, the socket state changes to
231 /// [`Established`] and the [`CON`] socket interrupt is raised.
232 ///
233 /// The connect-request fails in the following three cases:
234 /// 1. When a ARP<sub>TO</sub> occurs ([`timeout_raised`]) because the
235 /// destination hardware address is not acquired through the
236 /// ARP-process.
237 /// 2. When a SYN/ACK packet is not received within the TCP timeout duration
238 /// set by [`rcr`] and [`rtr`] ([`timeout_raised`]).
239 /// 3. When a RST packet is received instead of a SYN/ACK packet.
240 ///
241 /// In these cases the socket state changes to [`Closed`].
242 ///
243 /// Only valid in [`Tcp`] mode when acting as a TCP client.
244 ///
245 /// [`Closed`]: SocketStatus::Closed
246 /// [`CON`]: crate::SocketInterrupt::con_raised
247 /// [`Established`]: SocketStatus::Established
248 /// [`rcr`]: crate::Registers::rcr
249 /// [`rtr`]: crate::Registers::rtr
250 /// [`set_sn_dest`]: crate::Registers::set_sn_dest
251 /// [`Tcp`]: Protocol::Tcp
252 /// [`timeout_raised`]: crate::SocketInterrupt::timeout_raised
253 Connect = 0x04,
254 /// Start the disconnect process.
255 ///
256 /// * **Active close** it transmits disconnect-request(FIN packet)
257 /// to the connected peer.
258 /// * **Passive close** when FIN packet is received from peer,
259 /// a FIN packet is replied back to the peer.
260 ///
261 /// When the disconnect-process is successful
262 /// (that is, FIN/ACK packet is received successfully),
263 /// the socket state changes to [`Closed`].
264 /// Otherwise, TCP timeout occurs
265 /// ([`timeout_raised`]) and then
266 /// the socket state changes to [`Closed`].
267 ///
268 /// If the [`Close`] command is used instead of
269 /// [`Disconnect`], the socket state is changes to
270 /// [`Closed`] without the disconnect process.
271 ///
272 /// If a RST packet is received from a peer during communication the socket
273 /// status is unconditionally changed to [`Closed`].
274 ///
275 /// Only valid in [`Tcp`] mode.
276 ///
277 /// [`Disconnect`]: SocketCommand::Disconnect
278 /// [`Close`]: SocketCommand::Close
279 /// [`Closed`]: SocketStatus::Closed
280 /// [`Tcp`]: Protocol::Tcp
281 /// [`timeout_raised`]: crate::SocketInterrupt::timeout_raised
282 Disconnect = 0x08,
283 /// Close the socket.
284 ///
285 /// The socket status is changed to [`Closed`].
286 ///
287 /// [`Closed`]: SocketStatus::Closed
288 Close = 0x10,
289 /// Transmits all the data in the socket TX buffer.
290 Send = 0x20,
291 /// The basic operation is same as [`Send`].
292 ///
293 /// Normally [`Send`] transmits data after destination
294 /// hardware address is acquired by the automatic ARP-process
295 /// (Address Resolution Protocol).
296 /// [`SendMac`] transmits data without the automatic
297 /// ARP-process.
298 /// In this case, the destination hardware address is acquired from
299 /// [`sn_dhar`] configured by the host, instead of the ARP
300 /// process.
301 ///
302 /// Only valid in [`Udp`] mode.
303 ///
304 /// [`Send`]: SocketCommand::Send
305 /// [`SendMac`]: SocketCommand::SendMac
306 /// [`Udp`]: Protocol::Udp
307 /// [`sn_dhar`]: crate::Registers::sn_dhar
308 SendMac = 0x21,
309 /// Sends a 1 byte keep-alive packet.
310 ///
311 /// If the peer cannot respond to the keep-alive packet during timeout
312 /// time, the connection is terminated and the timeout interrupt will
313 /// occur ([`timeout_raised`]).
314 ///
315 /// Only valid in [`Tcp`] mode.
316 ///
317 /// [`Tcp`]: Protocol::Tcp
318 /// [`timeout_raised`]: crate::SocketInterrupt::timeout_raised
319 SendKeep = 0x22,
320 /// Completes the processing of the received data in socket RX buffer.
321 ///
322 /// See [`sn_rx_buf`] for an example.
323 ///
324 /// [`sn_rx_buf`]: crate::Registers::sn_rx_buf
325 Recv = 0x40,
326}
327impl From<SocketCommand> for u8 {
328 fn from(val: SocketCommand) -> u8 {
329 val as u8
330 }
331}
332impl TryFrom<u8> for SocketCommand {
333 type Error = u8;
334 fn try_from(val: u8) -> Result<Self, u8> {
335 match val {
336 x if x == Self::Accepted as u8 => Ok(Self::Accepted),
337 x if x == Self::Open as u8 => Ok(Self::Open),
338 x if x == Self::Listen as u8 => Ok(Self::Listen),
339 x if x == Self::Connect as u8 => Ok(Self::Connect),
340 x if x == Self::Disconnect as u8 => Ok(Self::Disconnect),
341 x if x == Self::Close as u8 => Ok(Self::Close),
342 x if x == Self::Send as u8 => Ok(Self::Send),
343 x if x == Self::SendMac as u8 => Ok(Self::SendMac),
344 x if x == Self::SendKeep as u8 => Ok(Self::SendKeep),
345 x if x == Self::Recv as u8 => Ok(Self::Recv),
346 _ => Err(val),
347 }
348 }
349}
350
351/// Socket protocol.
352///
353/// This is used by [`SocketMode::protocol`] method for the [`sn_mr`] register.
354///
355/// [`SocketMode::protocol`]: crate::SocketMode::protocol
356/// [`sn_mr`]: crate::Registers::sn_mr
357#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Hash)]
358#[cfg_attr(feature = "defmt", derive(defmt::Format))]
359#[repr(u8)]
360pub enum Protocol {
361 /// Closed.
362 Closed = 0b0000,
363 /// TCP.
364 Tcp = 0b0001,
365 /// UDP.
366 Udp = 0b0010,
367 /// MACRAW.
368 ///
369 /// MACRAW mode can only be used with [socket 0].
370 ///
371 /// [socket 0]: crate::Sn::Sn0
372 Macraw = 0b0100,
373}
374impl Protocol {
375 /// Convert a raw `u8` to an `Protocol`.
376 ///
377 /// Bit values that do not correspond to a protocol will be returned in the
378 /// `Err` variant of the result.
379 ///
380 /// # Example
381 ///
382 /// ```
383 /// use w5500_ll::Protocol;
384 ///
385 /// assert_eq!(Protocol::from_raw(0b0000), Ok(Protocol::Closed));
386 /// assert_eq!(Protocol::from_raw(0b0001), Ok(Protocol::Tcp));
387 /// assert_eq!(Protocol::from_raw(0b0010), Ok(Protocol::Udp));
388 /// assert_eq!(Protocol::from_raw(0b0100), Ok(Protocol::Macraw));
389 /// assert_eq!(Protocol::from_raw(0b0101), Err(0b0101));
390 /// ```
391 pub const fn from_raw(val: u8) -> Result<Self, u8> {
392 match val {
393 x if x == Protocol::Closed as u8 => Ok(Protocol::Closed),
394 x if x == Protocol::Tcp as u8 => Ok(Protocol::Tcp),
395 x if x == Protocol::Udp as u8 => Ok(Protocol::Udp),
396 x if x == Protocol::Macraw as u8 => Ok(Protocol::Macraw),
397 _ => Err(val),
398 }
399 }
400}
401impl From<Protocol> for u8 {
402 fn from(val: Protocol) -> u8 {
403 val as u8
404 }
405}
406impl Default for Protocol {
407 fn default() -> Self {
408 Self::Closed
409 }
410}
411impl TryFrom<u8> for Protocol {
412 type Error = u8;
413 fn try_from(val: u8) -> Result<Self, u8> {
414 Self::from_raw(val)
415 }
416}
417
418/// PHY operation mode.
419///
420/// This is used by [`PhyCfg::opmdc`] method for the [`phycfgr`] register.
421///
422/// [`PhyCfg::opmdc`]: crate::PhyCfg::opmdc
423/// [`phycfgr`]: crate::Registers::phycfgr
424#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
425#[cfg_attr(feature = "defmt", derive(defmt::Format))]
426#[repr(u8)]
427pub enum OperationMode {
428 /// 10BT half-duplex. Auto-negotiation disabled.
429 HalfDuplex10bt = 0b000,
430 /// 10BT full-duplex. Auto-negotiation disabled.
431 FullDuplex10bt = 0b001,
432 /// 100BT half-duplex. Auto-negotiation disabled.
433 HalfDuplex100bt = 0b010,
434 /// 100BT full-duplex. Auto-negotiation disabled.
435 FullDuplex100bt = 0b011,
436 /// 100BT half-duplex. Auto-negotiation enabled.
437 HalfDuplex100btAuto = 0b100,
438 /// Power down mode.
439 PowerDown = 0b110,
440 /// All capable. Auto-negotiation enabled.
441 Auto = 0b111,
442}
443impl OperationMode {
444 /// Convert a raw `u8` to an `OperationMode`.
445 ///
446 /// Only the first 3 bits of the `u8` value are used.
447 ///
448 /// # Example
449 ///
450 /// ```
451 /// use w5500_ll::OperationMode;
452 ///
453 /// assert_eq!(
454 /// OperationMode::from_raw(0b000),
455 /// OperationMode::HalfDuplex10bt
456 /// );
457 /// assert_eq!(
458 /// OperationMode::from_raw(0b001),
459 /// OperationMode::FullDuplex10bt
460 /// );
461 /// assert_eq!(
462 /// OperationMode::from_raw(0b010),
463 /// OperationMode::HalfDuplex100bt
464 /// );
465 /// assert_eq!(
466 /// OperationMode::from_raw(0b011),
467 /// OperationMode::FullDuplex100bt
468 /// );
469 /// assert_eq!(
470 /// OperationMode::from_raw(0b100),
471 /// OperationMode::HalfDuplex100btAuto
472 /// );
473 /// assert_eq!(OperationMode::from_raw(0b110), OperationMode::PowerDown);
474 /// assert_eq!(OperationMode::from_raw(0b111), OperationMode::Auto);
475 /// ```
476 pub const fn from_raw(val: u8) -> Self {
477 match val & 0b111 {
478 x if x == Self::HalfDuplex10bt as u8 => Self::HalfDuplex10bt,
479 x if x == Self::FullDuplex10bt as u8 => Self::FullDuplex10bt,
480 x if x == Self::HalfDuplex100bt as u8 => Self::HalfDuplex100bt,
481 x if x == Self::FullDuplex100bt as u8 => Self::FullDuplex100bt,
482 x if x == Self::HalfDuplex100btAuto as u8 => Self::HalfDuplex100btAuto,
483 x if x == Self::PowerDown as u8 => Self::PowerDown,
484 // x if x == Self::Auto as u8
485 _ => Self::Auto,
486 }
487 }
488}
489impl From<OperationMode> for u8 {
490 fn from(val: OperationMode) -> u8 {
491 val as u8
492 }
493}
494impl Default for OperationMode {
495 fn default() -> Self {
496 Self::Auto
497 }
498}
499
500/// PHY link status.
501///
502/// This is used by [`PhyCfg::lnk`] method for the [`phycfgr`] register.
503///
504/// [`PhyCfg::lnk`]: crate::PhyCfg::lnk
505/// [`phycfgr`]: crate::Registers::phycfgr
506#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Hash, Default)]
507#[cfg_attr(feature = "defmt", derive(defmt::Format))]
508#[repr(u8)]
509pub enum LinkStatus {
510 /// PHY link down.
511 #[default]
512 Down = 0,
513 /// PHY link up.
514 Up = 1,
515}
516impl From<bool> for LinkStatus {
517 fn from(val: bool) -> LinkStatus {
518 if val {
519 LinkStatus::Up
520 } else {
521 LinkStatus::Down
522 }
523 }
524}
525impl From<LinkStatus> for u8 {
526 fn from(val: LinkStatus) -> u8 {
527 val as u8
528 }
529}
530
531/// PHY speed status.
532///
533/// This is used by [`PhyCfg::spd`] method for the [`phycfgr`] register.
534///
535/// [`PhyCfg::spd`]: crate::PhyCfg::spd
536/// [`phycfgr`]: crate::Registers::phycfgr
537#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Hash, Default)]
538#[cfg_attr(feature = "defmt", derive(defmt::Format))]
539#[repr(u8)]
540pub enum SpeedStatus {
541 /// 10 Mbps.
542 #[default]
543 Mbps10 = 0,
544 /// 100 Mbps.
545 Mbps100 = 1,
546}
547impl From<bool> for SpeedStatus {
548 fn from(val: bool) -> SpeedStatus {
549 if val {
550 SpeedStatus::Mbps100
551 } else {
552 SpeedStatus::Mbps10
553 }
554 }
555}
556impl From<SpeedStatus> for u8 {
557 fn from(val: SpeedStatus) -> u8 {
558 val as u8
559 }
560}
561
562/// PHY duplex status.
563///
564/// This is used by [`PhyCfg::dpx`] method for the [`phycfgr`] register.
565///
566/// [`PhyCfg::dpx`]: crate::PhyCfg::dpx
567/// [`phycfgr`]: crate::Registers::phycfgr
568#[derive(Copy, Clone, Eq, PartialEq, Debug, PartialOrd, Ord, Hash, Default)]
569#[cfg_attr(feature = "defmt", derive(defmt::Format))]
570#[repr(u8)]
571pub enum DuplexStatus {
572 /// Half duplex.
573 #[default]
574 Half = 0,
575 /// Full duplex.
576 Full = 1,
577}
578impl From<bool> for DuplexStatus {
579 fn from(val: bool) -> DuplexStatus {
580 if val {
581 DuplexStatus::Full
582 } else {
583 DuplexStatus::Half
584 }
585 }
586}
587impl From<DuplexStatus> for u8 {
588 fn from(val: DuplexStatus) -> u8 {
589 val as u8
590 }
591}
592
593/// RX and TX buffer sizes.
594///
595/// This is an argument of [`Registers::set_sn_rxbuf_size`] and
596/// [`Registers::set_sn_txbuf_size`].
597///
598/// [`Registers::set_sn_txbuf_size`]: crate::Registers::set_sn_txbuf_size
599/// [`Registers::set_sn_rxbuf_size`]: crate::Registers::set_sn_rxbuf_size
600#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)]
601#[cfg_attr(feature = "defmt", derive(defmt::Format))]
602#[repr(u8)]
603#[allow(clippy::upper_case_acronyms)]
604pub enum BufferSize {
605 /// 0 KiB
606 KB0 = 0,
607 /// 1 KiB
608 KB1 = 1,
609 /// 2 KiB
610 KB2 = 2,
611 /// 4 KiB
612 KB4 = 4,
613 /// 8 KiB
614 KB8 = 8,
615 /// 16 KiB
616 KB16 = 16,
617}
618impl From<BufferSize> for u8 {
619 /// Get the register value from a buffer size.
620 ///
621 /// # Example
622 ///
623 /// ```
624 /// use w5500_ll::BufferSize;
625 ///
626 /// assert_eq!(u8::from(BufferSize::KB0), 0);
627 /// assert_eq!(u8::from(BufferSize::KB1), 1);
628 /// assert_eq!(u8::from(BufferSize::KB2), 2);
629 /// assert_eq!(u8::from(BufferSize::KB4), 4);
630 /// assert_eq!(u8::from(BufferSize::KB8), 8);
631 /// assert_eq!(u8::from(BufferSize::KB16), 16);
632 /// ```
633 fn from(val: BufferSize) -> u8 {
634 val as u8
635 }
636}
637
638impl TryFrom<u8> for BufferSize {
639 type Error = u8;
640
641 /// Get the buffer size given the register value.
642 ///
643 /// # Example
644 ///
645 /// ```
646 /// use w5500_ll::BufferSize;
647 ///
648 /// assert_eq!(BufferSize::try_from(0), Ok(BufferSize::KB0));
649 /// assert_eq!(BufferSize::try_from(1), Ok(BufferSize::KB1));
650 /// assert_eq!(BufferSize::try_from(2), Ok(BufferSize::KB2));
651 /// assert_eq!(BufferSize::try_from(4), Ok(BufferSize::KB4));
652 /// assert_eq!(BufferSize::try_from(8), Ok(BufferSize::KB8));
653 /// assert_eq!(BufferSize::try_from(16), Ok(BufferSize::KB16));
654 /// assert_eq!(BufferSize::try_from(17), Err(17));
655 /// ```
656 fn try_from(val: u8) -> Result<BufferSize, u8> {
657 match val {
658 x if x == BufferSize::KB0 as u8 => Ok(BufferSize::KB0),
659 x if x == BufferSize::KB1 as u8 => Ok(BufferSize::KB1),
660 x if x == BufferSize::KB2 as u8 => Ok(BufferSize::KB2),
661 x if x == BufferSize::KB4 as u8 => Ok(BufferSize::KB4),
662 x if x == BufferSize::KB8 as u8 => Ok(BufferSize::KB8),
663 x if x == BufferSize::KB16 as u8 => Ok(BufferSize::KB16),
664 _ => Err(val),
665 }
666 }
667}
668
669impl Default for BufferSize {
670 /// Default buffer size.
671 ///
672 /// # Example
673 ///
674 /// ```
675 /// use w5500_ll::BufferSize;
676 ///
677 /// assert_eq!(BufferSize::default(), BufferSize::KB2);
678 /// ```
679 fn default() -> Self {
680 BufferSize::KB2
681 }
682}
683
684impl BufferSize {
685 /// Get the buffer size in bytes.
686 ///
687 /// # Example
688 ///
689 /// ```
690 /// use w5500_ll::BufferSize;
691 ///
692 /// assert_eq!(BufferSize::KB0.size_in_bytes(), 0);
693 /// assert_eq!(BufferSize::KB1.size_in_bytes(), 1 * 1024);
694 /// assert_eq!(BufferSize::KB2.size_in_bytes(), 2 * 1024);
695 /// assert_eq!(BufferSize::KB4.size_in_bytes(), 4 * 1024);
696 /// assert_eq!(BufferSize::KB8.size_in_bytes(), 8 * 1024);
697 /// assert_eq!(BufferSize::KB16.size_in_bytes(), 16 * 1024);
698 /// ```
699 pub const fn size_in_bytes(&self) -> usize {
700 match self {
701 BufferSize::KB0 => 0,
702 BufferSize::KB1 => 1024,
703 BufferSize::KB2 => 2048,
704 BufferSize::KB4 => 4096,
705 BufferSize::KB8 => 8192,
706 BufferSize::KB16 => 16384,
707 }
708 }
709}