w5500_ll/aio.rs
1//! Asynchronous W5500 traits.
2use crate::{
3 BufferSize, Eui48Addr, Interrupt, Ipv4Addr, Mode, PhyCfg, Reg, RxPtrs, Sn, SnReg, SocketAddrV4,
4 SocketCommand, SocketInterrupt, SocketInterruptMask, SocketMode, SocketStatus, TxPtrs,
5 COMMON_BLOCK_OFFSET,
6};
7
8/// Asynchronous register IO.
9pub trait Registers {
10 /// Register accessor error type.
11 type Error;
12
13 /// Read from the W5500 asynchronously.
14 ///
15 /// # Arguments
16 ///
17 /// * `addr` - Starting address of the memory being read.
18 /// * `block` - W5500 block select bits
19 /// * `data` - Buffer to read data into. The number of bytes read is equal
20 /// to the length of this buffer.
21 async fn read(&mut self, addr: u16, block: u8, data: &mut [u8]) -> Result<(), Self::Error>;
22
23 /// Write to the W5500 asynchronously.
24 ///
25 /// # Arguments
26 ///
27 /// * `addr` - Starting address of the memory being written.
28 /// * `block` - W5500 block select bits
29 /// * `data` - Buffer of data to write. The number of bytes written is equal
30 /// to the length of this buffer.
31 async fn write(&mut self, addr: u16, block: u8, data: &[u8]) -> Result<(), Self::Error>;
32
33 /// Get the mode register.
34 ///
35 /// # Example
36 ///
37 /// ```
38 /// # #[tokio::main(flavor = "current_thread")]
39 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
40 /// # let spi = ehm::eh1::spi::Mock::new(&[
41 /// # ehm::eh1::spi::Transaction::transaction_start(),
42 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, 0x00]),
43 /// # ehm::eh1::spi::Transaction::read(0),
44 /// # ehm::eh1::spi::Transaction::transaction_end(),
45 /// # ]);
46 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Mode};
47 ///
48 /// let mut w5500 = W5500::new(spi);
49 /// let mode: Mode = w5500.mr().await?;
50 /// assert_eq!(mode, Mode::default());
51 /// # w5500.free().done(); Ok(()) }
52 /// ```
53 async fn mr(&mut self) -> Result<Mode, Self::Error> {
54 let mut reg: [u8; 1] = [0];
55 self.read(Reg::MR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
56 .await
57 .map(|_| Mode::from(reg[0]))
58 }
59
60 /// Set the mode register.
61 ///
62 /// # Example
63 ///
64 /// ```
65 /// # #[tokio::main(flavor = "current_thread")]
66 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
67 /// # let spi = ehm::eh1::spi::Mock::new(&[
68 /// # ehm::eh1::spi::Transaction::transaction_start(),
69 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, 0x04]),
70 /// # ehm::eh1::spi::Transaction::write(w5500_ll::Mode::WOL_MASK),
71 /// # ehm::eh1::spi::Transaction::transaction_end(),
72 /// # ]);
73 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Mode};
74 ///
75 /// const MODE: Mode = Mode::DEFAULT.enable_wol();
76 /// let mut w5500 = W5500::new(spi);
77 /// w5500.set_mr(MODE).await?;
78 /// # w5500.free().done(); Ok(()) }
79 /// ```
80 async fn set_mr(&mut self, mode: Mode) -> Result<(), Self::Error> {
81 self.write(Reg::MR.addr(), COMMON_BLOCK_OFFSET, &[mode.into()])
82 .await
83 }
84
85 /// Get the gateway IP address.
86 ///
87 /// # Example
88 ///
89 /// ```
90 /// # #[tokio::main(flavor = "current_thread")]
91 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
92 /// # let spi = ehm::eh1::spi::Mock::new(&[
93 /// # ehm::eh1::spi::Transaction::transaction_start(),
94 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x00]),
95 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0]),
96 /// # ehm::eh1::spi::Transaction::transaction_end(),
97 /// # ]);
98 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
99 ///
100 /// let mut w5500 = W5500::new(spi);
101 /// let gar = w5500.gar().await?;
102 /// assert_eq!(gar, Ipv4Addr::UNSPECIFIED);
103 /// # w5500.free().done(); Ok(()) }
104 /// ```
105 async fn gar(&mut self) -> Result<Ipv4Addr, Self::Error> {
106 let mut gar: [u8; 4] = [0; 4];
107 self.read(Reg::GAR0.addr(), COMMON_BLOCK_OFFSET, &mut gar)
108 .await?;
109 Ok::<Ipv4Addr, Self::Error>(gar.into())
110 }
111
112 /// Set the gateway IP address.
113 ///
114 /// # Example
115 ///
116 /// ```
117 /// # #[tokio::main(flavor = "current_thread")]
118 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
119 /// # let spi = ehm::eh1::spi::Mock::new(&[
120 /// # ehm::eh1::spi::Transaction::transaction_start(),
121 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x04]),
122 /// # ehm::eh1::spi::Transaction::write_vec(vec![192, 168, 0, 1]),
123 /// # ehm::eh1::spi::Transaction::transaction_end(),
124 /// # ]);
125 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
126 ///
127 /// let mut w5500 = W5500::new(spi);
128 /// w5500.set_gar(&Ipv4Addr::new(192, 168, 0, 1)).await?;
129 /// # w5500.free().done(); Ok(()) }
130 /// ```
131 async fn set_gar(&mut self, gar: &Ipv4Addr) -> Result<(), Self::Error> {
132 self.write(Reg::GAR0.addr(), COMMON_BLOCK_OFFSET, &gar.octets())
133 .await
134 }
135
136 /// Get the subnet mask.
137 ///
138 /// # Example
139 ///
140 /// ```
141 /// # #[tokio::main(flavor = "current_thread")]
142 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
143 /// # let spi = ehm::eh1::spi::Mock::new(&[
144 /// # ehm::eh1::spi::Transaction::transaction_start(),
145 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x05, 0x00]),
146 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0]),
147 /// # ehm::eh1::spi::Transaction::transaction_end(),
148 /// # ]);
149 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
150 ///
151 /// let mut w5500 = W5500::new(spi);
152 /// let subr = w5500.subr().await?;
153 /// assert_eq!(subr, Ipv4Addr::UNSPECIFIED);
154 /// # w5500.free().done(); Ok(()) }
155 /// ```
156 async fn subr(&mut self) -> Result<Ipv4Addr, Self::Error> {
157 let mut subr: [u8; 4] = [0; 4];
158 self.read(Reg::SUBR0.addr(), COMMON_BLOCK_OFFSET, &mut subr)
159 .await?;
160 Ok::<Ipv4Addr, Self::Error>(subr.into())
161 }
162
163 /// Set the subnet mask.
164 ///
165 /// # Example
166 ///
167 /// ```
168 /// # #[tokio::main(flavor = "current_thread")]
169 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
170 /// # let spi = ehm::eh1::spi::Mock::new(&[
171 /// # ehm::eh1::spi::Transaction::transaction_start(),
172 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x05, 0x04]),
173 /// # ehm::eh1::spi::Transaction::write_vec(vec![255, 255, 255, 0]),
174 /// # ehm::eh1::spi::Transaction::transaction_end(),
175 /// # ]);
176 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
177 ///
178 /// let mut w5500 = W5500::new(spi);
179 /// w5500.set_subr(&Ipv4Addr::new(255, 255, 255, 0)).await?;
180 /// # w5500.free().done(); Ok(()) }
181 /// ```
182 async fn set_subr(&mut self, subr: &Ipv4Addr) -> Result<(), Self::Error> {
183 self.write(Reg::SUBR0.addr(), COMMON_BLOCK_OFFSET, &subr.octets())
184 .await
185 }
186
187 /// Get the source hardware address.
188 ///
189 /// # Example
190 ///
191 /// ```
192 /// # #[tokio::main(flavor = "current_thread")]
193 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
194 /// # let spi = ehm::eh1::spi::Mock::new(&[
195 /// # ehm::eh1::spi::Transaction::transaction_start(),
196 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x09, 0x00]),
197 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0, 0, 0]),
198 /// # ehm::eh1::spi::Transaction::transaction_end(),
199 /// # ]);
200 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Eui48Addr};
201 ///
202 /// let mut w5500 = W5500::new(spi);
203 /// let shar = w5500.shar().await?;
204 /// assert_eq!(shar, Eui48Addr::UNSPECIFIED);
205 /// # w5500.free().done(); Ok(()) }
206 /// ```
207 async fn shar(&mut self) -> Result<Eui48Addr, Self::Error> {
208 let mut shar = Eui48Addr::UNSPECIFIED;
209 self.read(Reg::SHAR0.addr(), COMMON_BLOCK_OFFSET, &mut shar.octets)
210 .await?;
211 Ok::<Eui48Addr, Self::Error>(shar)
212 }
213
214 /// Set the source hardware address.
215 ///
216 /// # Example
217 ///
218 /// ```
219 /// # #[tokio::main(flavor = "current_thread")]
220 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
221 /// # let spi = ehm::eh1::spi::Mock::new(&[
222 /// # ehm::eh1::spi::Transaction::transaction_start(),
223 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x09, 0x04]),
224 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34, 0, 0, 0, 0]),
225 /// # ehm::eh1::spi::Transaction::transaction_end(),
226 /// # ]);
227 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Eui48Addr};
228 ///
229 /// let mut w5500 = W5500::new(spi);
230 /// w5500
231 /// .set_shar(&Eui48Addr::new(0x12, 0x34, 0x00, 0x00, 0x00, 0x00))
232 /// .await?;
233 /// # w5500.free().done(); Ok(()) }
234 /// ```
235 async fn set_shar(&mut self, shar: &Eui48Addr) -> Result<(), Self::Error> {
236 self.write(Reg::SHAR0.addr(), COMMON_BLOCK_OFFSET, &shar.octets)
237 .await
238 }
239
240 /// Get the source (client) IP address.
241 ///
242 /// # Example
243 ///
244 /// ```
245 /// # #[tokio::main(flavor = "current_thread")]
246 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
247 /// # let spi = ehm::eh1::spi::Mock::new(&[
248 /// # ehm::eh1::spi::Transaction::transaction_start(),
249 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x0F, 0x00]),
250 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0]),
251 /// # ehm::eh1::spi::Transaction::transaction_end(),
252 /// # ]);
253 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
254 ///
255 /// let mut w5500 = W5500::new(spi);
256 /// let sipr = w5500.sipr().await?;
257 /// assert_eq!(sipr, Ipv4Addr::UNSPECIFIED);
258 /// # w5500.free().done(); Ok(()) }
259 /// ```
260 async fn sipr(&mut self) -> Result<Ipv4Addr, Self::Error> {
261 let mut sipr: [u8; 4] = [0; 4];
262 self.read(Reg::SIPR0.addr(), COMMON_BLOCK_OFFSET, &mut sipr)
263 .await?;
264 Ok::<Ipv4Addr, Self::Error>(sipr.into())
265 }
266
267 /// Set the source (client) IP address.
268 ///
269 /// # Example
270 ///
271 /// ```
272 /// # #[tokio::main(flavor = "current_thread")]
273 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
274 /// # let spi = ehm::eh1::spi::Mock::new(&[
275 /// # ehm::eh1::spi::Transaction::transaction_start(),
276 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x0F, 0x04]),
277 /// # ehm::eh1::spi::Transaction::write_vec(vec![192, 168, 0, 150]),
278 /// # ehm::eh1::spi::Transaction::transaction_end(),
279 /// # ]);
280 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
281 ///
282 /// let mut w5500 = W5500::new(spi);
283 /// w5500.set_sipr(&Ipv4Addr::new(192, 168, 0, 150)).await?;
284 /// # w5500.free().done(); Ok(()) }
285 /// ```
286 async fn set_sipr(&mut self, sipr: &Ipv4Addr) -> Result<(), Self::Error> {
287 self.write(Reg::SIPR0.addr(), COMMON_BLOCK_OFFSET, &sipr.octets())
288 .await
289 }
290
291 /// Get the interrupt low level time.
292 ///
293 /// INTLEVEL configures the assert wait time (I<sub>AWT</sub>).
294 ///
295 /// When the next interrupt occurs, the interrupt in (INTn) will assert
296 /// to low after INTLEVEL time.
297 ///
298 /// The equation is:
299 ///
300 /// I<sub>AWT</sub> = (INTLEVEL + 1) * PLL<sub>CLK</sub> * 4
301 ///
302 /// When INTLEVEL > 0.
303 ///
304 /// You might want to take a look at the data sheet, there is a handy
305 /// timing diagram there.
306 ///
307 /// # Example
308 ///
309 /// ```
310 /// # #[tokio::main(flavor = "current_thread")]
311 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
312 /// # let spi = ehm::eh1::spi::Mock::new(&[
313 /// # ehm::eh1::spi::Transaction::transaction_start(),
314 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x13, 0x00]),
315 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
316 /// # ehm::eh1::spi::Transaction::transaction_end(),
317 /// # ]);
318 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
319 ///
320 /// let mut w5500 = W5500::new(spi);
321 /// let intlevel: u16 = w5500.intlevel().await?;
322 /// assert_eq!(intlevel, 0x00);
323 /// # w5500.free().done(); Ok(()) }
324 /// ```
325 async fn intlevel(&mut self) -> Result<u16, Self::Error> {
326 let mut buf: [u8; 2] = [0; 2];
327 self.read(Reg::INTLEVEL0.addr(), COMMON_BLOCK_OFFSET, &mut buf)
328 .await?;
329 Ok::<u16, Self::Error>(u16::from_be_bytes(buf))
330 }
331
332 /// Set the interrupt low level time.
333 ///
334 /// See [`Registers::intlevel`] for more information.
335 ///
336 /// # Example
337 ///
338 /// ```
339 /// # #[tokio::main(flavor = "current_thread")]
340 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
341 /// # let spi = ehm::eh1::spi::Mock::new(&[
342 /// # ehm::eh1::spi::Transaction::transaction_start(),
343 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x13, 0x04]),
344 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34]),
345 /// # ehm::eh1::spi::Transaction::transaction_end(),
346 /// # ]);
347 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
348 ///
349 /// let mut w5500 = W5500::new(spi);
350 /// w5500.set_intlevel(0x1234).await?;
351 /// # w5500.free().done(); Ok(()) }
352 /// ```
353 async fn set_intlevel(&mut self, intlevel: u16) -> Result<(), Self::Error> {
354 self.write(
355 Reg::INTLEVEL0.addr(),
356 COMMON_BLOCK_OFFSET,
357 &intlevel.to_be_bytes(),
358 )
359 .await
360 }
361
362 /// Get the interrupt status.
363 ///
364 /// `1` indicates the interrupt is raised.
365 ///
366 /// # Example
367 ///
368 /// ```
369 /// # #[tokio::main(flavor = "current_thread")]
370 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
371 /// # let spi = ehm::eh1::spi::Mock::new(&[
372 /// # ehm::eh1::spi::Transaction::transaction_start(),
373 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x15, 0x00]),
374 /// # ehm::eh1::spi::Transaction::read(0),
375 /// # ehm::eh1::spi::Transaction::transaction_end(),
376 /// # ]);
377 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Interrupt};
378 ///
379 /// let mut w5500 = W5500::new(spi);
380 /// let ir: Interrupt = w5500.ir().await?;
381 /// assert_eq!(ir, Interrupt::default());
382 /// # w5500.free().done(); Ok(()) }
383 /// ```
384 async fn ir(&mut self) -> Result<Interrupt, Self::Error> {
385 let mut reg: [u8; 1] = [0];
386 self.read(Reg::IR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
387 .await?;
388 Ok::<Interrupt, Self::Error>(Interrupt::from(reg[0]))
389 }
390
391 /// Set the interrupt status.
392 ///
393 /// Setting an interrupt bit to `1` will clear the interrupt.
394 ///
395 /// # Example
396 ///
397 /// ```
398 /// # #[tokio::main(flavor = "current_thread")]
399 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
400 /// # let spi = ehm::eh1::spi::Mock::new(&[
401 /// # ehm::eh1::spi::Transaction::transaction_start(),
402 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x15, 0x00]),
403 /// # ehm::eh1::spi::Transaction::read(0),
404 /// # ehm::eh1::spi::Transaction::transaction_end(),
405 /// # ehm::eh1::spi::Transaction::transaction_start(),
406 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x15, 0x04]),
407 /// # ehm::eh1::spi::Transaction::write(0),
408 /// # ehm::eh1::spi::Transaction::transaction_end(),
409 /// # ]);
410 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Interrupt};
411 ///
412 /// let mut w5500 = W5500::new(spi);
413 /// let ir: Interrupt = w5500.ir().await?;
414 /// w5500.set_ir(ir).await?;
415 /// # w5500.free().done(); Ok(()) }
416 /// ```
417 async fn set_ir(&mut self, interrupt: Interrupt) -> Result<(), Self::Error> {
418 self.write(Reg::IR.addr(), COMMON_BLOCK_OFFSET, &[interrupt.into()])
419 .await
420 }
421
422 /// Get the interrupt mask.
423 ///
424 /// `0` indicates the interrupt is masked.
425 ///
426 /// # Example
427 ///
428 /// ```
429 /// # #[tokio::main(flavor = "current_thread")]
430 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
431 /// # let spi = ehm::eh1::spi::Mock::new(&[
432 /// # ehm::eh1::spi::Transaction::transaction_start(),
433 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x16, 0x00]),
434 /// # ehm::eh1::spi::Transaction::read(0),
435 /// # ehm::eh1::spi::Transaction::transaction_end(),
436 /// # ]);
437 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Interrupt};
438 ///
439 /// let mut w5500 = W5500::new(spi);
440 /// let imr: Interrupt = w5500.imr().await?;
441 /// assert_eq!(imr, Interrupt::default());
442 /// # w5500.free().done(); Ok(()) }
443 /// ```
444 async fn imr(&mut self) -> Result<Interrupt, Self::Error> {
445 let mut reg: [u8; 1] = [0];
446 self.read(Reg::IMR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
447 .await?;
448 Ok::<Interrupt, Self::Error>(Interrupt::from(reg[0]))
449 }
450
451 /// Set the interrupt mask.
452 ///
453 /// Setting an interrupt bit to `1` will mask the interrupt.
454 /// When a bit of IMR is `1` and the corresponding interrupt is `1` an
455 /// interrupt will be issued.
456 /// If a bit of IMR is `0`, and interrupt will not be issued even if the
457 /// corresponding IR bit is `1`.
458 ///
459 /// # Example
460 ///
461 /// ```
462 /// # #[tokio::main(flavor = "current_thread")]
463 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
464 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Interrupt};
465 /// # let spi = ehm::eh1::spi::Mock::new(&[
466 /// # ehm::eh1::spi::Transaction::transaction_start(),
467 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x16, 0x04]),
468 /// # ehm::eh1::spi::Transaction::write_vec(vec![Interrupt::MP_MASK]),
469 /// # ehm::eh1::spi::Transaction::transaction_end(),
470 /// # ]);
471 ///
472 /// // enable the magic packet interrupt
473 /// const IMR: Interrupt = Interrupt::DEFAULT.set_mp();
474 ///
475 /// let mut w5500 = W5500::new(spi);
476 /// w5500.set_imr(IMR).await?;
477 /// # w5500.free().done(); Ok(()) }
478 /// ```
479 async fn set_imr(&mut self, mask: Interrupt) -> Result<(), Self::Error> {
480 self.write(Reg::IMR.addr(), COMMON_BLOCK_OFFSET, &[mask.into()])
481 .await
482 }
483
484 /// Get the socket interrupt status.
485 ///
486 /// SIMR indicates the interrupt status of all sockets.
487 /// Each bit of SIR will be `1` until [`sn_ir`] is cleared.
488 /// If [`sn_ir`] is not equal to `0x00` the n<sub>th</sub>
489 /// bit of `sir` is `1` and the INTn pin is asserted until SIR is `0x00`.
490 ///
491 /// # Example
492 ///
493 /// ```
494 /// # #[tokio::main(flavor = "current_thread")]
495 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
496 /// # let spi = ehm::eh1::spi::Mock::new(&[
497 /// # ehm::eh1::spi::Transaction::transaction_start(),
498 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x17, 0x00]),
499 /// # ehm::eh1::spi::Transaction::read(0),
500 /// # ehm::eh1::spi::Transaction::transaction_end(),
501 /// # ]);
502 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, SOCKETS};
503 ///
504 /// let mut w5500 = W5500::new(spi);
505 /// let sir = w5500.sir().await?;
506 /// // clear all socket interrupts
507 /// for socket in SOCKETS.iter() {
508 /// if 1 << (*socket as u8) & sir != 0 {
509 /// let sn_ir = w5500.sn_ir(*socket).await?;
510 /// w5500.set_sn_ir(*socket, sn_ir.into()).await?;
511 /// }
512 /// }
513 /// # w5500.free().done(); Ok(()) }
514 /// ```
515 ///
516 /// [`sn_ir`]: Registers::sn_ir
517 async fn sir(&mut self) -> Result<u8, Self::Error> {
518 let mut reg: [u8; 1] = [0];
519 self.read(Reg::SIR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
520 .await?;
521 Ok::<u8, Self::Error>(reg[0])
522 }
523
524 /// Get the socket interrupt mask.
525 ///
526 /// Each bit of SIMR corresponds to each bit of [`Registers::sir`].
527 /// When a bit of SIMR is `1` and the corresponding bit of SIR is `1`
528 /// and interrupt will be issued.
529 /// If a bit of SIMR is `0` an interrupt will be not issued even if the
530 /// corresponding bit of SIR is `1`.
531 ///
532 /// # Example
533 ///
534 /// ```
535 /// # #[tokio::main(flavor = "current_thread")]
536 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
537 /// # let spi = ehm::eh1::spi::Mock::new(&[
538 /// # ehm::eh1::spi::Transaction::transaction_start(),
539 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x18, 0x00]),
540 /// # ehm::eh1::spi::Transaction::read(0),
541 /// # ehm::eh1::spi::Transaction::transaction_end(),
542 /// # ]);
543 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
544 ///
545 /// let mut w5500 = W5500::new(spi);
546 /// let simr: u8 = w5500.simr().await?;
547 /// # w5500.free().done(); Ok(()) }
548 /// ```
549 async fn simr(&mut self) -> Result<u8, Self::Error> {
550 let mut reg: [u8; 1] = [0];
551 self.read(Reg::SIMR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
552 .await?;
553 Ok::<u8, Self::Error>(reg[0])
554 }
555
556 /// Set the socket interrupt mask.
557 ///
558 /// See [`Registers::simr`] for more information.
559 ///
560 /// # Example
561 ///
562 /// ```
563 /// # #[tokio::main(flavor = "current_thread")]
564 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
565 /// # let spi = ehm::eh1::spi::Mock::new(&[
566 /// # ehm::eh1::spi::Transaction::transaction_start(),
567 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x18, 0x04]),
568 /// # ehm::eh1::spi::Transaction::write(0xFF),
569 /// # ehm::eh1::spi::Transaction::transaction_end(),
570 /// # ]);
571 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
572 ///
573 /// let mut w5500 = W5500::new(spi);
574 /// // enable all socket interrupts
575 /// w5500.set_simr(0xFF).await?;
576 /// # w5500.free().done(); Ok(()) }
577 /// ```
578 async fn set_simr(&mut self, simr: u8) -> Result<(), Self::Error> {
579 self.write(Reg::SIMR.addr(), COMMON_BLOCK_OFFSET, &[simr])
580 .await
581 }
582
583 /// Get the retry time.
584 ///
585 /// RTR configures the re-transmission timeout period.
586 /// The unit of timeout period is 100 us and the default of RTR is `0x07D0`
587 /// or `2000`.
588 /// And so the default timeout period is 200 ms (100 us X 2000).
589 /// During the time configured by RTR, the W5500 waits for the peer response
590 /// to the packet that is transmitted by Sn_CR (CONNECT, DISCON, CLOSE,
591 /// SEND, SEND_MAC, SEND_KEEP command).
592 /// If the peer does not respond within the RTR time, the W5500 re-transmits
593 /// the packet or issues a timeout.
594 ///
595 /// # Example
596 ///
597 /// ```
598 /// # #[tokio::main(flavor = "current_thread")]
599 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
600 /// # let spi = ehm::eh1::spi::Mock::new(&[
601 /// # ehm::eh1::spi::Transaction::transaction_start(),
602 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x19, 0x00]),
603 /// # ehm::eh1::spi::Transaction::read_vec(vec![0x07, 0xD0]),
604 /// # ehm::eh1::spi::Transaction::transaction_end(),
605 /// # ]);
606 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
607 ///
608 /// let mut w5500 = W5500::new(spi);
609 /// let rtr: u16 = w5500.rtr().await?;
610 /// assert_eq!(rtr, 0x07D0);
611 /// # w5500.free().done(); Ok(()) }
612 /// ```
613 async fn rtr(&mut self) -> Result<u16, Self::Error> {
614 let mut buf: [u8; 2] = [0; 2];
615 self.read(Reg::RTR0.addr(), COMMON_BLOCK_OFFSET, &mut buf)
616 .await?;
617 Ok::<u16, Self::Error>(u16::from_be_bytes(buf))
618 }
619
620 /// Set the retry time.
621 ///
622 /// See [`Registers::rtr`] for more information.
623 ///
624 /// # Example
625 ///
626 /// ```
627 /// # #[tokio::main(flavor = "current_thread")]
628 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
629 /// # let spi = ehm::eh1::spi::Mock::new(&[
630 /// # ehm::eh1::spi::Transaction::transaction_start(),
631 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x19, 0x04]),
632 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34]),
633 /// # ehm::eh1::spi::Transaction::transaction_end(),
634 /// # ]);
635 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
636 ///
637 /// let mut w5500 = W5500::new(spi);
638 /// w5500.set_rtr(0x1234).await?;
639 /// # w5500.free().done(); Ok(()) }
640 /// ```
641 async fn set_rtr(&mut self, rtr: u16) -> Result<(), Self::Error> {
642 self.write(Reg::RTR0.addr(), COMMON_BLOCK_OFFSET, &rtr.to_be_bytes())
643 .await
644 }
645
646 /// Get the retry count.
647 ///
648 /// RCR configured the number of re-transmission attempts.
649 /// When the number of re-transmission equals RCR + 1 the socket timeout
650 /// interrupt is raised.
651 ///
652 /// There is a LOT more information in the data sheet,
653 /// including some equations that would be very annoying to input.
654 ///
655 /// # Example
656 ///
657 /// ```
658 /// # #[tokio::main(flavor = "current_thread")]
659 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
660 /// # let spi = ehm::eh1::spi::Mock::new(&[
661 /// # ehm::eh1::spi::Transaction::transaction_start(),
662 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1B, 0x00]),
663 /// # ehm::eh1::spi::Transaction::read(0x08),
664 /// # ehm::eh1::spi::Transaction::transaction_end(),
665 /// # ]);
666 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
667 ///
668 /// let mut w5500 = W5500::new(spi);
669 /// let rcr: u8 = w5500.rcr().await?;
670 /// # w5500.free().done(); Ok(()) }
671 /// ```
672 async fn rcr(&mut self) -> Result<u8, Self::Error> {
673 let mut reg: [u8; 1] = [0];
674 self.read(Reg::RCR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
675 .await?;
676 Ok::<u8, Self::Error>(reg[0])
677 }
678
679 /// Set the retry count.
680 ///
681 /// See [`Registers::rcr`] for more information.
682 ///
683 /// # Example
684 ///
685 /// ```
686 /// # #[tokio::main(flavor = "current_thread")]
687 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
688 /// # let spi = ehm::eh1::spi::Mock::new(&[
689 /// # ehm::eh1::spi::Transaction::transaction_start(),
690 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1B, 0x04]),
691 /// # ehm::eh1::spi::Transaction::write(0x0A),
692 /// # ehm::eh1::spi::Transaction::transaction_end(),
693 /// # ]);
694 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
695 ///
696 /// let mut w5500 = W5500::new(spi);
697 /// w5500.set_rcr(0x0A).await?;
698 /// # w5500.free().done(); Ok(()) }
699 /// ```
700 async fn set_rcr(&mut self, rcr: u8) -> Result<(), Self::Error> {
701 self.write(Reg::RCR.addr(), COMMON_BLOCK_OFFSET, &[rcr])
702 .await
703 }
704
705 /// Get the PPP link control protocol request timer.
706 ///
707 /// PTIMER configures the time for sending LCP echo request.
708 ///
709 /// The unit of time is 25 milliseconds, for a register value of 200 the
710 /// timer is 5 seconds.
711 ///
712 /// # Example
713 ///
714 /// ```
715 /// # #[tokio::main(flavor = "current_thread")]
716 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
717 /// # let spi = ehm::eh1::spi::Mock::new(&[
718 /// # ehm::eh1::spi::Transaction::transaction_start(),
719 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1C, 0x00]),
720 /// # ehm::eh1::spi::Transaction::read(0x08),
721 /// # ehm::eh1::spi::Transaction::transaction_end(),
722 /// # ]);
723 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
724 ///
725 /// let mut w5500 = W5500::new(spi);
726 /// let ptimer: u8 = w5500.ptimer().await?;
727 /// # w5500.free().done(); Ok(()) }
728 /// ```
729 async fn ptimer(&mut self) -> Result<u8, Self::Error> {
730 let mut reg: [u8; 1] = [0];
731 self.read(Reg::PTIMER.addr(), COMMON_BLOCK_OFFSET, &mut reg)
732 .await?;
733 Ok::<u8, Self::Error>(reg[0])
734 }
735
736 /// Set the PPP link control protocol request timer.
737 ///
738 /// See [`Registers::ptimer`] for more information.
739 ///
740 /// # Example
741 ///
742 /// ```
743 /// # #[tokio::main(flavor = "current_thread")]
744 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
745 /// # let spi = ehm::eh1::spi::Mock::new(&[
746 /// # ehm::eh1::spi::Transaction::transaction_start(),
747 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1C, 0x04]),
748 /// # ehm::eh1::spi::Transaction::write(0xC8),
749 /// # ehm::eh1::spi::Transaction::transaction_end(),
750 /// # ]);
751 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
752 ///
753 /// let mut w5500 = W5500::new(spi);
754 /// w5500.set_ptimer(200).await?;
755 /// # w5500.free().done(); Ok(()) }
756 /// ```
757 async fn set_ptimer(&mut self, ptimer: u8) -> Result<(), Self::Error> {
758 self.write(Reg::PTIMER.addr(), COMMON_BLOCK_OFFSET, &[ptimer])
759 .await
760 }
761
762 /// Get the PPP link control protocol magic number.
763 ///
764 /// PMAGIC configures the 4 byte magic number used in the LCP echo request.
765 /// For a register value of `0x01` the magic number is `0x01010101`.
766 ///
767 /// # Example
768 ///
769 /// ```
770 /// # #[tokio::main(flavor = "current_thread")]
771 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
772 /// # let spi = ehm::eh1::spi::Mock::new(&[
773 /// # ehm::eh1::spi::Transaction::transaction_start(),
774 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1D, 0x00]),
775 /// # ehm::eh1::spi::Transaction::read(0x08),
776 /// # ehm::eh1::spi::Transaction::transaction_end(),
777 /// # ]);
778 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
779 ///
780 /// let mut w5500 = W5500::new(spi);
781 /// let pmagic: u8 = w5500.pmagic().await?;
782 /// # w5500.free().done(); Ok(()) }
783 /// ```
784 async fn pmagic(&mut self) -> Result<u8, Self::Error> {
785 let mut reg: [u8; 1] = [0];
786 self.read(Reg::PMAGIC.addr(), COMMON_BLOCK_OFFSET, &mut reg)
787 .await?;
788 Ok::<u8, Self::Error>(reg[0])
789 }
790
791 /// Set the PPP link control protocol magic number.
792 ///
793 /// See [`Registers::pmagic`] for more information.
794 ///
795 /// # Example
796 ///
797 /// ```
798 /// # #[tokio::main(flavor = "current_thread")]
799 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
800 /// # let spi = ehm::eh1::spi::Mock::new(&[
801 /// # ehm::eh1::spi::Transaction::transaction_start(),
802 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1D, 0x04]),
803 /// # ehm::eh1::spi::Transaction::write(0x01),
804 /// # ehm::eh1::spi::Transaction::transaction_end(),
805 /// # ]);
806 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
807 ///
808 /// let mut w5500 = W5500::new(spi);
809 /// w5500.set_pmagic(0x01).await?;
810 /// # w5500.free().done(); Ok(()) }
811 /// ```
812 async fn set_pmagic(&mut self, pmagic: u8) -> Result<(), Self::Error> {
813 self.write(Reg::PMAGIC.addr(), COMMON_BLOCK_OFFSET, &[pmagic])
814 .await
815 }
816
817 /// Get the destination hardware address in PPPoE mode.
818 ///
819 /// # Example
820 ///
821 /// ```
822 /// # #[tokio::main(flavor = "current_thread")]
823 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
824 /// # let spi = ehm::eh1::spi::Mock::new(&[
825 /// # ehm::eh1::spi::Transaction::transaction_start(),
826 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1E, 0x00]),
827 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0, 0, 0]),
828 /// # ehm::eh1::spi::Transaction::transaction_end(),
829 /// # ]);
830 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Eui48Addr};
831 ///
832 /// let mut w5500 = W5500::new(spi);
833 /// let phar = w5500.phar().await?;
834 /// assert_eq!(phar, Eui48Addr::UNSPECIFIED);
835 /// # w5500.free().done(); Ok(()) }
836 /// ```
837 async fn phar(&mut self) -> Result<Eui48Addr, Self::Error> {
838 let mut phar = Eui48Addr::UNSPECIFIED;
839 self.read(Reg::PHAR0.addr(), COMMON_BLOCK_OFFSET, &mut phar.octets)
840 .await?;
841 Ok::<Eui48Addr, Self::Error>(phar)
842 }
843
844 /// Set the destination hardware address in PPPoE mode.
845 ///
846 /// # Example
847 ///
848 /// ```
849 /// # #[tokio::main(flavor = "current_thread")]
850 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
851 /// # let spi = ehm::eh1::spi::Mock::new(&[
852 /// # ehm::eh1::spi::Transaction::transaction_start(),
853 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1E, 0x04]),
854 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34, 0, 0, 0, 0]),
855 /// # ehm::eh1::spi::Transaction::transaction_end(),
856 /// # ]);
857 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Eui48Addr};
858 ///
859 /// let mut w5500 = W5500::new(spi);
860 /// w5500
861 /// .set_phar(&Eui48Addr::new(0x12, 0x34, 0x00, 0x00, 0x00, 0x00))
862 /// .await?;
863 /// # w5500.free().done(); Ok(()) }
864 /// ```
865 async fn set_phar(&mut self, phar: &Eui48Addr) -> Result<(), Self::Error> {
866 self.write(Reg::PHAR0.addr(), COMMON_BLOCK_OFFSET, &phar.octets)
867 .await
868 }
869
870 /// Get the session ID in PPPoE mode.
871 ///
872 /// PSID should be written to the PPPoE server session ID acquired in the
873 /// PPPoE connection process.
874 ///
875 /// # Example
876 ///
877 /// ```
878 /// # #[tokio::main(flavor = "current_thread")]
879 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
880 /// # let spi = ehm::eh1::spi::Mock::new(&[
881 /// # ehm::eh1::spi::Transaction::transaction_start(),
882 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x24, 0x00]),
883 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
884 /// # ehm::eh1::spi::Transaction::transaction_end(),
885 /// # ]);
886 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
887 ///
888 /// let mut w5500 = W5500::new(spi);
889 /// let psid: u16 = w5500.psid().await?;
890 /// assert_eq!(psid, 0x0000);
891 /// # w5500.free().done(); Ok(()) }
892 /// ```
893 async fn psid(&mut self) -> Result<u16, Self::Error> {
894 let mut buf: [u8; 2] = [0; 2];
895 self.read(Reg::PSID0.addr(), COMMON_BLOCK_OFFSET, &mut buf)
896 .await?;
897 Ok::<u16, Self::Error>(u16::from_be_bytes(buf))
898 }
899
900 /// Set the session ID in PPPoE mode.
901 ///
902 /// See [`Registers::psid`] for more information.
903 ///
904 /// # Example
905 ///
906 /// ```
907 /// # #[tokio::main(flavor = "current_thread")]
908 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
909 /// # let spi = ehm::eh1::spi::Mock::new(&[
910 /// # ehm::eh1::spi::Transaction::transaction_start(),
911 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x24, 0x04]),
912 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34]),
913 /// # ehm::eh1::spi::Transaction::transaction_end(),
914 /// # ]);
915 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
916 ///
917 /// let mut w5500 = W5500::new(spi);
918 /// w5500.set_psid(0x1234).await?;
919 /// # w5500.free().done(); Ok(()) }
920 /// ```
921 async fn set_psid(&mut self, psid: u16) -> Result<(), Self::Error> {
922 self.write(Reg::PSID0.addr(), COMMON_BLOCK_OFFSET, &psid.to_be_bytes())
923 .await
924 }
925
926 /// Get the maximum receive unit in PPPoE mode.
927 ///
928 /// PMRU configures the maximum receive unit of PPPoE.
929 ///
930 /// # Example
931 ///
932 /// ```
933 /// # #[tokio::main(flavor = "current_thread")]
934 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
935 /// # let spi = ehm::eh1::spi::Mock::new(&[
936 /// # ehm::eh1::spi::Transaction::transaction_start(),
937 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x26, 0x00]),
938 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
939 /// # ehm::eh1::spi::Transaction::transaction_end(),
940 /// # ]);
941 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
942 ///
943 /// let mut w5500 = W5500::new(spi);
944 /// let pmru: u16 = w5500.pmru().await?;
945 /// assert_eq!(pmru, 0x0000);
946 /// # w5500.free().done(); Ok(()) }
947 /// ```
948 async fn pmru(&mut self) -> Result<u16, Self::Error> {
949 let mut buf: [u8; 2] = [0; 2];
950 self.read(Reg::PMRU0.addr(), COMMON_BLOCK_OFFSET, &mut buf)
951 .await?;
952 Ok::<u16, Self::Error>(u16::from_be_bytes(buf))
953 }
954
955 /// Set the maximum receive unit in PPPoE mode.
956 ///
957 /// See [`Registers::pmru`] for more information.
958 ///
959 /// # Example
960 ///
961 /// ```
962 /// # #[tokio::main(flavor = "current_thread")]
963 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
964 /// # let spi = ehm::eh1::spi::Mock::new(&[
965 /// # ehm::eh1::spi::Transaction::transaction_start(),
966 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x26, 0x04]),
967 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34]),
968 /// # ehm::eh1::spi::Transaction::transaction_end(),
969 /// # ]);
970 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
971 ///
972 /// let mut w5500 = W5500::new(spi);
973 /// w5500.set_pmru(0x1234).await?;
974 /// # w5500.free().done(); Ok(()) }
975 /// ```
976 async fn set_pmru(&mut self, pmru: u16) -> Result<(), Self::Error> {
977 self.write(Reg::PMRU0.addr(), COMMON_BLOCK_OFFSET, &pmru.to_be_bytes())
978 .await
979 }
980
981 /// Get the unreachable IP address.
982 ///
983 /// This awkward wording is taken directly from the data-sheet:
984 ///
985 /// W5500 receives an ICMP packet (destination port unreachable)
986 /// when data is sent to a port number which socket is not open and
987 /// the UNREACH bit of [`Registers::ir`] becomes `1` and UIPR and UPORTR
988 /// indicates the destination IP address and port number respectively.
989 ///
990 /// # Example
991 ///
992 /// ```
993 /// # #[tokio::main(flavor = "current_thread")]
994 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
995 /// # let spi = ehm::eh1::spi::Mock::new(&[
996 /// # ehm::eh1::spi::Transaction::transaction_start(),
997 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x28, 0x00]),
998 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0]),
999 /// # ehm::eh1::spi::Transaction::transaction_end(),
1000 /// # ]);
1001 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr};
1002 ///
1003 /// let mut w5500 = W5500::new(spi);
1004 /// let uipr = w5500.uipr().await?;
1005 /// assert_eq!(uipr, Ipv4Addr::UNSPECIFIED);
1006 /// # w5500.free().done(); Ok(()) }
1007 /// ```
1008 async fn uipr(&mut self) -> Result<Ipv4Addr, Self::Error> {
1009 let mut uipr: [u8; 4] = [0; 4];
1010 self.read(Reg::UIPR0.addr(), COMMON_BLOCK_OFFSET, &mut uipr)
1011 .await?;
1012 Ok::<Ipv4Addr, Self::Error>(uipr.into())
1013 }
1014
1015 /// Get the unreachable port.
1016 ///
1017 /// See [`Registers::uipr`] for more information.
1018 ///
1019 /// # Example
1020 ///
1021 /// ```
1022 /// # #[tokio::main(flavor = "current_thread")]
1023 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1024 /// # let spi = ehm::eh1::spi::Mock::new(&[
1025 /// # ehm::eh1::spi::Transaction::transaction_start(),
1026 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2C, 0x00]),
1027 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
1028 /// # ehm::eh1::spi::Transaction::transaction_end(),
1029 /// # ]);
1030 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
1031 ///
1032 /// let mut w5500 = W5500::new(spi);
1033 /// let uportr = w5500.uportr().await?;
1034 /// # w5500.free().done(); Ok(()) }
1035 /// ```
1036 async fn uportr(&mut self) -> Result<u16, Self::Error> {
1037 let mut buf: [u8; 2] = [0; 2];
1038 self.read(Reg::UPORTR0.addr(), COMMON_BLOCK_OFFSET, &mut buf)
1039 .await?;
1040 Ok::<u16, Self::Error>(u16::from_be_bytes(buf))
1041 }
1042
1043 /// Get the PHY configuration.
1044 ///
1045 /// # Example
1046 ///
1047 /// ```
1048 /// # #[tokio::main(flavor = "current_thread")]
1049 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1050 /// # let spi = ehm::eh1::spi::Mock::new(&[
1051 /// # ehm::eh1::spi::Transaction::transaction_start(),
1052 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2E, 0x00]),
1053 /// # ehm::eh1::spi::Transaction::read(0b10111000),
1054 /// # ehm::eh1::spi::Transaction::transaction_end(),
1055 /// # ]);
1056 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, PhyCfg};
1057 ///
1058 /// let mut w5500 = W5500::new(spi);
1059 /// let phy_cfg: PhyCfg = w5500.phycfgr().await?;
1060 /// assert_eq!(phy_cfg, PhyCfg::default());
1061 /// # w5500.free().done(); Ok(()) }
1062 /// ```
1063 async fn phycfgr(&mut self) -> Result<PhyCfg, Self::Error> {
1064 let mut reg: [u8; 1] = [0];
1065 self.read(Reg::PHYCFGR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
1066 .await?;
1067 Ok::<PhyCfg, Self::Error>(PhyCfg::from(reg[0]))
1068 }
1069
1070 /// Set the PHY configuration.
1071 ///
1072 /// # Example
1073 ///
1074 /// ```
1075 /// # #[tokio::main(flavor = "current_thread")]
1076 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1077 /// # let spi = ehm::eh1::spi::Mock::new(&[
1078 /// # ehm::eh1::spi::Transaction::transaction_start(),
1079 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2E, 0x04]),
1080 /// # ehm::eh1::spi::Transaction::write(0b11111000),
1081 /// # ehm::eh1::spi::Transaction::transaction_end(),
1082 /// # ]);
1083 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, OperationMode, PhyCfg};
1084 ///
1085 /// const PHY_CFG: PhyCfg = PhyCfg::DEFAULT.set_opmdc(OperationMode::Auto);
1086 /// let mut w5500 = W5500::new(spi);
1087 /// w5500.set_phycfgr(PHY_CFG).await?;
1088 /// # w5500.free().done(); Ok(()) }
1089 /// ```
1090 async fn set_phycfgr(&mut self, phycfg: PhyCfg) -> Result<(), Self::Error> {
1091 self.write(Reg::PHYCFGR.addr(), COMMON_BLOCK_OFFSET, &[phycfg.into()])
1092 .await
1093 }
1094
1095 /// Get the version.
1096 ///
1097 /// The value returned is always `0x04`.
1098 ///
1099 /// This register is extremely useful as a sanity check to ensure SPI
1100 /// communications are working with the W5500.
1101 ///
1102 /// # Example
1103 ///
1104 /// ```
1105 /// # #[tokio::main(flavor = "current_thread")]
1106 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1107 /// # let spi = ehm::eh1::spi::Mock::new(&[
1108 /// # ehm::eh1::spi::Transaction::transaction_start(),
1109 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x39, 0x00]),
1110 /// # ehm::eh1::spi::Transaction::read(0x04),
1111 /// # ehm::eh1::spi::Transaction::transaction_end(),
1112 /// # ]);
1113 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500};
1114 ///
1115 /// let mut w5500 = W5500::new(spi);
1116 /// let version = w5500.version().await?;
1117 /// assert_eq!(version, 0x04);
1118 /// # w5500.free().done(); Ok(()) }
1119 /// ```
1120 async fn version(&mut self) -> Result<u8, Self::Error> {
1121 let mut reg: [u8; 1] = [0];
1122 self.read(Reg::VERSIONR.addr(), COMMON_BLOCK_OFFSET, &mut reg)
1123 .await?;
1124 Ok::<u8, Self::Error>(reg[0])
1125 }
1126
1127 /// Get the socket mode.
1128 ///
1129 /// # Example
1130 ///
1131 /// ```
1132 /// # #[tokio::main(flavor = "current_thread")]
1133 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1134 /// # let spi = ehm::eh1::spi::Mock::new(&[
1135 /// # ehm::eh1::spi::Transaction::transaction_start(),
1136 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, 0x08]),
1137 /// # ehm::eh1::spi::Transaction::read(0),
1138 /// # ehm::eh1::spi::Transaction::transaction_end(),
1139 /// # ]);
1140 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketMode};
1141 ///
1142 /// let mut w5500 = W5500::new(spi);
1143 /// let socket_mode = w5500.sn_mr(Sn::Sn0).await?;
1144 /// assert_eq!(socket_mode, SocketMode::default());
1145 /// # w5500.free().done(); Ok(()) }
1146 /// ```
1147 async fn sn_mr(&mut self, sn: Sn) -> Result<SocketMode, Self::Error> {
1148 let mut reg: [u8; 1] = [0];
1149 self.read(SnReg::MR.addr(), sn.block(), &mut reg).await?;
1150 Ok::<SocketMode, Self::Error>(SocketMode::from(reg[0]))
1151 }
1152
1153 /// Set the socket mode.
1154 ///
1155 /// # Example
1156 ///
1157 /// ```
1158 /// # #[tokio::main(flavor = "current_thread")]
1159 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1160 /// # let spi = ehm::eh1::spi::Mock::new(&[
1161 /// # ehm::eh1::spi::Transaction::transaction_start(),
1162 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, 0x08 | 0x04]),
1163 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x01]),
1164 /// # ehm::eh1::spi::Transaction::transaction_end(),
1165 /// # ]);
1166 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Protocol, Sn, SocketMode};
1167 ///
1168 /// const SOCKET_MODE: SocketMode = SocketMode::DEFAULT.set_protocol(Protocol::Tcp);
1169 /// let mut w5500 = W5500::new(spi);
1170 /// w5500.set_sn_mr(Sn::Sn0, SOCKET_MODE).await?;
1171 /// # w5500.free().done(); Ok(()) }
1172 /// ```
1173 async fn set_sn_mr(&mut self, sn: Sn, mode: SocketMode) -> Result<(), Self::Error> {
1174 self.write(SnReg::MR.addr(), sn.block(), &[mode.into()])
1175 .await
1176 }
1177
1178 /// Get the socket command.
1179 ///
1180 /// The only use for reading this register is to check if a socket command
1181 /// has been accepted.
1182 ///
1183 /// # Example
1184 ///
1185 /// ```
1186 /// # #[tokio::main(flavor = "current_thread")]
1187 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1188 /// # let spi = ehm::eh1::spi::Mock::new(&[
1189 /// # ehm::eh1::spi::Transaction::transaction_start(),
1190 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x08 | 0x04]),
1191 /// # ehm::eh1::spi::Transaction::write(0x01),
1192 /// # ehm::eh1::spi::Transaction::transaction_end(),
1193 /// # ehm::eh1::spi::Transaction::transaction_start(),
1194 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x08]),
1195 /// # ehm::eh1::spi::Transaction::read(1),
1196 /// # ehm::eh1::spi::Transaction::transaction_end(),
1197 /// # ehm::eh1::spi::Transaction::transaction_start(),
1198 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x08]),
1199 /// # ehm::eh1::spi::Transaction::read(0),
1200 /// # ehm::eh1::spi::Transaction::transaction_end(),
1201 /// # ]);
1202 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketCommand};
1203 ///
1204 /// let mut w5500 = W5500::new(spi);
1205 /// w5500.set_sn_cr(Sn::Sn0, SocketCommand::Open).await?;
1206 /// while w5500.sn_cr(Sn::Sn0).await? != SocketCommand::Accepted.into() {}
1207 /// # w5500.free().done(); Ok(()) }
1208 /// ```
1209 async fn sn_cr(&mut self, sn: Sn) -> Result<u8, Self::Error> {
1210 let mut reg: [u8; 1] = [0];
1211 self.read(SnReg::CR.addr(), sn.block(), &mut reg).await?;
1212 Ok::<u8, Self::Error>(reg[0])
1213 }
1214
1215 /// Set the socket command.
1216 ///
1217 /// # Example
1218 ///
1219 /// ```
1220 /// # #[tokio::main(flavor = "current_thread")]
1221 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1222 /// # let spi = ehm::eh1::spi::Mock::new(&[
1223 /// # ehm::eh1::spi::Transaction::transaction_start(),
1224 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x08 | 0x04]),
1225 /// # ehm::eh1::spi::Transaction::write(0x01),
1226 /// # ehm::eh1::spi::Transaction::transaction_end(),
1227 /// # ]);
1228 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketCommand};
1229 ///
1230 /// let mut w5500 = W5500::new(spi);
1231 /// w5500.set_sn_cr(Sn::Sn0, SocketCommand::Open).await?;
1232 /// # w5500.free().done(); Ok(()) }
1233 /// ```
1234 async fn set_sn_cr(&mut self, sn: Sn, cmd: SocketCommand) -> Result<(), Self::Error> {
1235 self.write(SnReg::CR.addr(), sn.block(), &[cmd.into()])
1236 .await
1237 }
1238
1239 /// Get the socket interrupt status.
1240 ///
1241 /// # Example
1242 ///
1243 /// ```
1244 /// # #[tokio::main(flavor = "current_thread")]
1245 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1246 /// # let spi = ehm::eh1::spi::Mock::new(&[
1247 /// # ehm::eh1::spi::Transaction::transaction_start(),
1248 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x02, 0x08]),
1249 /// # ehm::eh1::spi::Transaction::read(0),
1250 /// # ehm::eh1::spi::Transaction::transaction_end(),
1251 /// # ]);
1252 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1253 ///
1254 /// let mut w5500 = W5500::new(spi);
1255 /// let socket_interrupts = w5500.sn_ir(Sn::Sn0).await?;
1256 /// # w5500.free().done(); Ok(()) }
1257 /// ```
1258 async fn sn_ir(&mut self, sn: Sn) -> Result<SocketInterrupt, Self::Error> {
1259 let mut reg: [u8; 1] = [0];
1260 self.read(SnReg::IR.addr(), sn.block(), &mut reg).await?;
1261 Ok::<SocketInterrupt, Self::Error>(SocketInterrupt::from(reg[0]))
1262 }
1263
1264 /// Set the socket interrupt status.
1265 ///
1266 /// This is a write 1 to clear register.
1267 ///
1268 /// # Examples
1269 ///
1270 /// Clearing all raised interrupts.
1271 ///
1272 /// ```
1273 /// # #[tokio::main(flavor = "current_thread")]
1274 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1275 /// # let spi = ehm::eh1::spi::Mock::new(&[
1276 /// # ehm::eh1::spi::Transaction::transaction_start(),
1277 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x02, 0x08]),
1278 /// # ehm::eh1::spi::Transaction::read(0),
1279 /// # ehm::eh1::spi::Transaction::transaction_end(),
1280 /// # ehm::eh1::spi::Transaction::transaction_start(),
1281 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x02, 0x08 | 0x04]),
1282 /// # ehm::eh1::spi::Transaction::write(0),
1283 /// # ehm::eh1::spi::Transaction::transaction_end(),
1284 /// # ]);
1285 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketInterrupt};
1286 ///
1287 /// let mut w5500 = W5500::new(spi);
1288 /// let socket_interrupts: SocketInterrupt = w5500.sn_ir(Sn::Sn0).await?;
1289 /// w5500.set_sn_ir(Sn::Sn0, socket_interrupts.into()).await?;
1290 /// # w5500.free().done(); Ok(()) }
1291 /// ```
1292 ///
1293 /// Clearing only the SENDOK interrupt.
1294 ///
1295 /// ```
1296 /// # #[tokio::main(flavor = "current_thread")]
1297 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1298 /// # let spi = ehm::eh1::spi::Mock::new(&[
1299 /// # ehm::eh1::spi::Transaction::transaction_start(),
1300 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x02, 0x08 | 0x04]),
1301 /// # ehm::eh1::spi::Transaction::write(SocketInterrupt::SENDOK_MASK),
1302 /// # ehm::eh1::spi::Transaction::transaction_end(),
1303 /// # ]);
1304 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketInterrupt};
1305 ///
1306 /// let mut w5500 = W5500::new(spi);
1307 /// w5500
1308 /// .set_sn_ir(Sn::Sn0, SocketInterrupt::SENDOK_MASK)
1309 /// .await?;
1310 /// # w5500.free().done(); Ok(()) }
1311 /// ```
1312 async fn set_sn_ir(&mut self, sn: Sn, sn_ir: u8) -> Result<(), Self::Error> {
1313 // todo: not consistent with synchronous version
1314 // https://github.com/rust-lang/rust/issues/65442
1315 self.write(SnReg::IR.addr(), sn.block(), &[sn_ir]).await
1316 }
1317
1318 /// Get the socket status.
1319 ///
1320 /// **Note:** This method returns a nested [`core::result::Result`].
1321 ///
1322 /// The outermost `Result` is for handling bus errors, similar to most of
1323 /// the other methods in this trait.
1324 ///
1325 /// The innermost `Result<SocketStatus, u8>` is the result of a `u8` to
1326 /// [`SocketStatus`] conversion because not every value of `u8` corresponds
1327 /// to a valid [`SocketStatus`].
1328 /// * `u8` values that have a corresponding [`SocketStatus`] will be
1329 /// converted and returned in the [`Ok`] variant of the inner `Result`.
1330 /// * `u8` values that do not corresponding [`SocketStatus`] will have the
1331 /// raw `u8` byte returned in the [`Err`] variant of the inner `Result`.
1332 ///
1333 /// # Example
1334 ///
1335 /// ```
1336 /// # #[tokio::main(flavor = "current_thread")]
1337 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1338 /// # let spi = ehm::eh1::spi::Mock::new(&[
1339 /// # ehm::eh1::spi::Transaction::transaction_start(),
1340 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x03, 0x08]),
1341 /// # ehm::eh1::spi::Transaction::read(0),
1342 /// # ehm::eh1::spi::Transaction::transaction_end(),
1343 /// # ]);
1344 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketStatus};
1345 ///
1346 /// let mut w5500 = W5500::new(spi);
1347 /// let sn_sr = w5500.sn_sr(Sn::Sn0).await?;
1348 /// assert_eq!(sn_sr, Ok(SocketStatus::Closed));
1349 /// # w5500.free().done(); Ok(()) }
1350 /// ```
1351 ///
1352 /// [`Ok`]: https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok
1353 /// [`Err`]: https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err
1354 async fn sn_sr(&mut self, sn: Sn) -> Result<Result<SocketStatus, u8>, Self::Error> {
1355 let mut reg: [u8; 1] = [0];
1356 self.read(SnReg::SR.addr(), sn.block(), &mut reg).await?;
1357 Ok::<Result<SocketStatus, u8>, Self::Error>(SocketStatus::try_from(reg[0]))
1358 }
1359
1360 /// Get the socket source port.
1361 ///
1362 /// This is only valid in TCP/UDP mode.
1363 /// This should be set before sending the OPEN command.
1364 ///
1365 /// # Example
1366 ///
1367 /// ```
1368 /// # #[tokio::main(flavor = "current_thread")]
1369 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1370 /// # let spi = ehm::eh1::spi::Mock::new(&[
1371 /// # ehm::eh1::spi::Transaction::transaction_start(),
1372 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x04, 0x08]),
1373 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
1374 /// # ehm::eh1::spi::Transaction::transaction_end(),
1375 /// # ]);
1376 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketMode};
1377 ///
1378 /// let mut w5500 = W5500::new(spi);
1379 /// let socket_port: u16 = w5500.sn_port(Sn::Sn0).await?;
1380 /// # w5500.free().done(); Ok(()) }
1381 /// ```
1382 async fn sn_port(&mut self, sn: Sn) -> Result<u16, Self::Error> {
1383 let mut reg: [u8; 2] = [0; 2];
1384 self.read(SnReg::PORT0.addr(), sn.block(), &mut reg).await?;
1385 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
1386 }
1387
1388 /// Set the socket source port.
1389 ///
1390 /// See [`Registers::sn_port`] for more information.
1391 ///
1392 /// # Example
1393 ///
1394 /// ```
1395 /// # #[tokio::main(flavor = "current_thread")]
1396 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1397 /// # let spi = ehm::eh1::spi::Mock::new(&[
1398 /// # ehm::eh1::spi::Transaction::transaction_start(),
1399 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x04, 0x08 | 0x04]),
1400 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 68]),
1401 /// # ehm::eh1::spi::Transaction::transaction_end(),
1402 /// # ]);
1403 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1404 ///
1405 /// let mut w5500 = W5500::new(spi);
1406 /// w5500.set_sn_port(Sn::Sn0, 68).await?;
1407 /// # w5500.free().done(); Ok(()) }
1408 /// ```
1409 async fn set_sn_port(&mut self, sn: Sn, port: u16) -> Result<(), Self::Error> {
1410 self.write(SnReg::PORT0.addr(), sn.block(), &u16::to_be_bytes(port))
1411 .await
1412 }
1413
1414 /// Get the socket destination hardware address.
1415 ///
1416 /// Sn_DHAR configures the destination hardware address of Socket n when
1417 /// using SEND_MAC command in UDP mode or it indicates that it is acquired
1418 /// in ARP-process by CONNECT/SEND command.
1419 ///
1420 /// # Example
1421 ///
1422 /// ```
1423 /// # #[tokio::main(flavor = "current_thread")]
1424 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1425 /// # let spi = ehm::eh1::spi::Mock::new(&[
1426 /// # ehm::eh1::spi::Transaction::transaction_start(),
1427 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x06, 0x08]),
1428 /// # ehm::eh1::spi::Transaction::read_vec(vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]),
1429 /// # ehm::eh1::spi::Transaction::transaction_end(),
1430 /// # ]);
1431 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1432 ///
1433 /// let mut w5500 = W5500::new(spi);
1434 /// let dhar = w5500.sn_dhar(Sn::Sn0).await?;
1435 /// # w5500.free().done(); Ok(()) }
1436 /// ```
1437 async fn sn_dhar(&mut self, sn: Sn) -> Result<Eui48Addr, Self::Error> {
1438 let mut dhar: Eui48Addr = Eui48Addr::UNSPECIFIED;
1439 self.read(SnReg::DHAR0.addr(), sn.block(), &mut dhar.octets)
1440 .await?;
1441 Ok::<Eui48Addr, Self::Error>(dhar)
1442 }
1443
1444 /// Set the socket destination hardware address.
1445 ///
1446 /// See [`Registers::sn_dhar`] for more information.
1447 ///
1448 /// # Example
1449 ///
1450 /// ```
1451 /// # #[tokio::main(flavor = "current_thread")]
1452 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1453 /// # let spi = ehm::eh1::spi::Mock::new(&[
1454 /// # ehm::eh1::spi::Transaction::transaction_start(),
1455 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x06, 0x08 | 0x04]),
1456 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34, 0x00, 0x00, 0x00, 0x00]),
1457 /// # ehm::eh1::spi::Transaction::transaction_end(),
1458 /// # ]);
1459 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Eui48Addr, Sn};
1460 ///
1461 /// let dhar = Eui48Addr::new(0x12, 0x34, 0x00, 0x00, 0x00, 0x00);
1462 /// let mut w5500 = W5500::new(spi);
1463 /// w5500.set_sn_dhar(Sn::Sn0, &dhar).await?;
1464 /// # w5500.free().done(); Ok(()) }
1465 /// ```
1466 async fn set_sn_dhar(&mut self, sn: Sn, dhar: &Eui48Addr) -> Result<(), Self::Error> {
1467 self.write(SnReg::DHAR0.addr(), sn.block(), &dhar.octets)
1468 .await
1469 }
1470
1471 /// Get the socket destination IP address.
1472 ///
1473 /// This register configures or indicates the destination IP address.
1474 /// It it valid when the socket is in TCP/UDP mode.
1475 ///
1476 /// In TCP client mode it configures the TCP server address before the
1477 /// [`SocketCommand::Connect`] command.
1478 ///
1479 /// In TCP server mode it indicates the IP address of the TCP client after
1480 /// successfully establishing a connection.
1481 ///
1482 /// In UDP mode it configures an IP address of the peer to receive the UDP
1483 /// packet send by the [`SocketCommand::Send`] or [`SocketCommand::SendMac`]
1484 /// command.
1485 ///
1486 /// # Example
1487 ///
1488 /// ```
1489 /// # #[tokio::main(flavor = "current_thread")]
1490 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1491 /// # let spi = ehm::eh1::spi::Mock::new(&[
1492 /// # ehm::eh1::spi::Transaction::transaction_start(),
1493 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x0C, 0x08]),
1494 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0]),
1495 /// # ehm::eh1::spi::Transaction::transaction_end(),
1496 /// # ]);
1497 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr, Sn};
1498 ///
1499 /// let mut w5500 = W5500::new(spi);
1500 /// let dipr = w5500.sn_dipr(Sn::Sn0).await?;
1501 /// assert_eq!(dipr, Ipv4Addr::UNSPECIFIED);
1502 /// # w5500.free().done(); Ok(()) }
1503 /// ```
1504 async fn sn_dipr(&mut self, sn: Sn) -> Result<Ipv4Addr, Self::Error> {
1505 let mut dipr: [u8; 4] = [0; 4];
1506 self.read(SnReg::DIPR0.addr(), sn.block(), &mut dipr)
1507 .await?;
1508 Ok::<Ipv4Addr, Self::Error>(dipr.into())
1509 }
1510
1511 /// Set the socket destination IP address.
1512 ///
1513 /// See [`Registers::sn_dipr`] for more information.
1514 ///
1515 /// # Example
1516 ///
1517 /// ```
1518 /// # #[tokio::main(flavor = "current_thread")]
1519 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1520 /// # let spi = ehm::eh1::spi::Mock::new(&[
1521 /// # ehm::eh1::spi::Transaction::transaction_start(),
1522 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x0C, 0x08 | 0x04]),
1523 /// # ehm::eh1::spi::Transaction::write_vec(vec![192, 168, 0, 11]),
1524 /// # ehm::eh1::spi::Transaction::transaction_end(),
1525 /// # ]);
1526 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, net::Ipv4Addr, Sn};
1527 ///
1528 /// let mut w5500 = W5500::new(spi);
1529 /// w5500
1530 /// .set_sn_dipr(Sn::Sn0, &Ipv4Addr::new(192, 168, 0, 11))
1531 /// .await?;
1532 /// # w5500.free().done(); Ok(()) }
1533 /// ```
1534 async fn set_sn_dipr(&mut self, sn: Sn, dipr: &Ipv4Addr) -> Result<(), Self::Error> {
1535 self.write(SnReg::DIPR0.addr(), sn.block(), &dipr.octets())
1536 .await
1537 }
1538
1539 /// Get the socket destination port.
1540 ///
1541 /// This register configures or indicates the destination port number of
1542 /// the socket.
1543 /// It is valid when the socket is used in TCP/UDP mode.
1544 ///
1545 /// In TCP client mode, it configures the listen port number of the TCP
1546 /// server before the [`SocketCommand::Send`] command.
1547 ///
1548 /// In TCP server mode, it indicates the port number of the TCP client
1549 /// after successfully establishing connection.
1550 ///
1551 /// In UDP mode, it configures the port number of the peer to be transmitted
1552 /// in the UDP packet by the [`SocketCommand::Send`] or
1553 /// [`SocketCommand::SendMac`] command.
1554 ///
1555 /// # Example
1556 ///
1557 /// ```
1558 /// # #[tokio::main(flavor = "current_thread")]
1559 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1560 /// # let spi = ehm::eh1::spi::Mock::new(&[
1561 /// # ehm::eh1::spi::Transaction::transaction_start(),
1562 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x10, 0x08]),
1563 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
1564 /// # ehm::eh1::spi::Transaction::transaction_end(),
1565 /// # ]);
1566 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketMode};
1567 ///
1568 /// let mut w5500 = W5500::new(spi);
1569 /// let socket_destination_port: u16 = w5500.sn_dport(Sn::Sn0).await?;
1570 /// # w5500.free().done(); Ok(()) }
1571 /// ```
1572 async fn sn_dport(&mut self, sn: Sn) -> Result<u16, Self::Error> {
1573 let mut reg: [u8; 2] = [0; 2];
1574 self.read(SnReg::DPORT0.addr(), sn.block(), &mut reg)
1575 .await?;
1576 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
1577 }
1578
1579 /// Set the socket destination port.
1580 ///
1581 /// See [`Registers::sn_dport`] for more information.
1582 ///
1583 /// # Example
1584 ///
1585 /// ```
1586 /// # #[tokio::main(flavor = "current_thread")]
1587 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1588 /// # let spi = ehm::eh1::spi::Mock::new(&[
1589 /// # ehm::eh1::spi::Transaction::transaction_start(),
1590 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x10, 0x08 | 0x04]),
1591 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 67]),
1592 /// # ehm::eh1::spi::Transaction::transaction_end(),
1593 /// # ]);
1594 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1595 ///
1596 /// let mut w5500 = W5500::new(spi);
1597 /// w5500.set_sn_dport(Sn::Sn0, 67).await?;
1598 /// # w5500.free().done(); Ok(()) }
1599 /// ```
1600 async fn set_sn_dport(&mut self, sn: Sn, port: u16) -> Result<(), Self::Error> {
1601 self.write(SnReg::DPORT0.addr(), sn.block(), &u16::to_be_bytes(port))
1602 .await
1603 }
1604
1605 /// Get the socket destination IPv4 and port.
1606 ///
1607 /// This is equivalent to [`Registers::sn_dipr`] and [`Registers::sn_dport`]
1608 /// in a single read transaction.
1609 ///
1610 /// # Example
1611 ///
1612 /// ```
1613 /// # #[tokio::main(flavor = "current_thread")]
1614 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1615 /// # let spi = ehm::eh1::spi::Mock::new(&[
1616 /// # ehm::eh1::spi::Transaction::transaction_start(),
1617 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x0C, 0x08]),
1618 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0, 0, 0]),
1619 /// # ehm::eh1::spi::Transaction::transaction_end(),
1620 /// # ]);
1621 /// use w5500_ll::{
1622 /// aio::Registers,
1623 /// eh1::vdm::W5500,
1624 /// net::{Ipv4Addr, SocketAddrV4},
1625 /// Sn,
1626 /// };
1627 ///
1628 /// let mut w5500 = W5500::new(spi);
1629 /// let addr = w5500.sn_dest(Sn::Sn0).await?;
1630 /// assert_eq!(addr, SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0));
1631 /// # w5500.free().done(); Ok(()) }
1632 /// ```
1633 async fn sn_dest(&mut self, sn: Sn) -> Result<SocketAddrV4, Self::Error> {
1634 let mut buf: [u8; 6] = [0; 6];
1635 self.read(SnReg::DIPR0.addr(), sn.block(), &mut buf).await?;
1636 Ok::<SocketAddrV4, Self::Error>(SocketAddrV4::new(
1637 Ipv4Addr::new(buf[0], buf[1], buf[2], buf[3]),
1638 u16::from_be_bytes([buf[4], buf[5]]),
1639 ))
1640 }
1641
1642 /// Set the socket destination IPv4 and port.
1643 ///
1644 /// This is equivalent to [`Registers::set_sn_dipr`] and
1645 /// [`Registers::set_sn_dport`] in a single writer transaction.
1646 ///
1647 /// # Example
1648 ///
1649 /// ```
1650 /// # #[tokio::main(flavor = "current_thread")]
1651 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1652 /// # let spi = ehm::eh1::spi::Mock::new(&[
1653 /// # ehm::eh1::spi::Transaction::transaction_start(),
1654 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x0C, 0x08 | 0x04]),
1655 /// # ehm::eh1::spi::Transaction::write_vec(vec![192, 168, 0, 11, 0, 67]),
1656 /// # ehm::eh1::spi::Transaction::transaction_end(),
1657 /// # ]);
1658 /// use w5500_ll::{
1659 /// aio::Registers,
1660 /// eh1::vdm::W5500,
1661 /// net::{Ipv4Addr, SocketAddrV4},
1662 /// Sn,
1663 /// };
1664 ///
1665 /// let addr: SocketAddrV4 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 11), 67);
1666 /// let mut w5500 = W5500::new(spi);
1667 /// w5500.set_sn_dest(Sn::Sn0, &addr).await?;
1668 /// # w5500.free().done(); Ok(()) }
1669 /// ```
1670 async fn set_sn_dest(&mut self, sn: Sn, addr: &SocketAddrV4) -> Result<(), Self::Error> {
1671 let buf: [u8; 6] = [
1672 addr.ip().octets()[0],
1673 addr.ip().octets()[1],
1674 addr.ip().octets()[2],
1675 addr.ip().octets()[3],
1676 (addr.port() >> 8) as u8,
1677 addr.port() as u8,
1678 ];
1679 self.write(SnReg::DIPR0.addr(), sn.block(), &buf).await
1680 }
1681
1682 /// Get the socket maximum segment size.
1683 ///
1684 /// This register configures or indicates the MTU (Maximum Transfer Unit)
1685 /// of the socket.
1686 ///
1687 /// The default MTU is valid when the socket is used in TCP / UDP mode.
1688 /// However, when used in PPPoE mode it is determined within the PPPoE MTU.
1689 ///
1690 /// | Mode | Normal Default | Normal Range | PPPoE Default | PPPoE Range |
1691 /// |--------|----------------|--------------|---------------|-------------|
1692 /// | TCP | 1460 | 1 - 1460 | 1452 | 1 - 1452 |
1693 /// | UDP | 1472 | 1 - 1472 | 1464 | 1 - 1464 |
1694 /// | MACRAW | 1514 | 1514 | 1514 | 1514 |
1695 ///
1696 /// When socket n is used in MACRAW mode, the default MTU is applied
1697 /// because the MTU is not processed internally.
1698 /// Therefore, when transmitting the data bigger than default MTU, the host
1699 /// should manually divide the data into the unit of default MTU.
1700 /// When socket n is used in TCP/UDP mode, and transmitting data bigger than
1701 /// the MTU, the data is automatically divided into the unit of MTU.
1702 ///
1703 /// In UDP mode, the configured MTU is used.
1704 /// When transmitting data to a peer with the different MTU size,
1705 /// the ICMP (Fragment MTU) packet might be received.
1706 /// In this case, IR(FMTU) becomes `1` and the peer information such as the
1707 /// MTU size and IP address is indicated from FMTUR and UIPR respectively.
1708 /// If IR\[MTU\] = `1`, the user cannot transmit data to the peer.
1709 ///
1710 /// To resume the communication with peer, do as followed.
1711 /// 1. Close socket n with the [`SocketCommand::Close`] command.
1712 /// 2. Set Sn_MSS to the indicated MTU from FMTUR
1713 /// 3. Open socket n with the [`SocketCommand::Open`] command.
1714 /// 4. Resume the communication with the peer.
1715 ///
1716 /// # Example
1717 ///
1718 /// ```
1719 /// # #[tokio::main(flavor = "current_thread")]
1720 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1721 /// # let spi = ehm::eh1::spi::Mock::new(&[
1722 /// # ehm::eh1::spi::Transaction::transaction_start(),
1723 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x12, 0x08]),
1724 /// # ehm::eh1::spi::Transaction::read_vec(vec![0x00, 0x00]),
1725 /// # ehm::eh1::spi::Transaction::transaction_end(),
1726 /// # ]);
1727 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1728 ///
1729 /// let mut w5500 = W5500::new(spi);
1730 /// let sn__mssr: u16 = w5500.sn_mssr(Sn::Sn0).await?;
1731 /// # w5500.free().done(); Ok(()) }
1732 /// ```
1733 async fn sn_mssr(&mut self, sn: Sn) -> Result<u16, Self::Error> {
1734 let mut reg: [u8; 2] = [0; 2];
1735 self.read(SnReg::MSSR0.addr(), sn.block(), &mut reg).await?;
1736 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
1737 }
1738
1739 /// Set the socket maximum segment size.
1740 ///
1741 /// See [`Registers::sn_mssr`] for lots more information.
1742 ///
1743 /// # Example
1744 ///
1745 /// ```
1746 /// # #[tokio::main(flavor = "current_thread")]
1747 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1748 /// # let spi = ehm::eh1::spi::Mock::new(&[
1749 /// # ehm::eh1::spi::Transaction::transaction_start(),
1750 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x12, 0x08 | 0x04]),
1751 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x05, 0xB4]),
1752 /// # ehm::eh1::spi::Transaction::transaction_end(),
1753 /// # ]);
1754 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1755 ///
1756 /// let mut w5500 = W5500::new(spi);
1757 /// w5500.set_sn_mssr(Sn::Sn0, 1460).await?;
1758 /// # w5500.free().done(); Ok(()) }
1759 /// ```
1760 async fn set_sn_mssr(&mut self, sn: Sn, mssr: u16) -> Result<(), Self::Error> {
1761 self.write(SnReg::MSSR0.addr(), sn.block(), &u16::to_be_bytes(mssr))
1762 .await
1763 }
1764
1765 /// Get the IP type of service.
1766 ///
1767 /// This register configures the TOS (Type of service field in IP header)
1768 /// for socket n.
1769 /// Configure this field before sending the [`SocketCommand::Open`] command.
1770 ///
1771 /// For more details see [iana.org/assignments/ip-parameters].
1772 ///
1773 /// [iana.org/assignments/ip-parameters]: https://www.iana.org/assignments/ip-parameters
1774 ///
1775 /// # Example
1776 ///
1777 /// ```
1778 /// # #[tokio::main(flavor = "current_thread")]
1779 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1780 /// # let spi = ehm::eh1::spi::Mock::new(&[
1781 /// # ehm::eh1::spi::Transaction::transaction_start(),
1782 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x15, 0x08]),
1783 /// # ehm::eh1::spi::Transaction::read(0),
1784 /// # ehm::eh1::spi::Transaction::transaction_end(),
1785 /// # ]);
1786 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1787 ///
1788 /// let mut w5500 = W5500::new(spi);
1789 /// let tos: u8 = w5500.sn_tos(Sn::Sn0).await?;
1790 /// # w5500.free().done(); Ok(()) }
1791 /// ```
1792 async fn sn_tos(&mut self, sn: Sn) -> Result<u8, Self::Error> {
1793 let mut reg: [u8; 1] = [0];
1794 self.read(SnReg::TOS.addr(), sn.block(), &mut reg).await?;
1795 Ok::<u8, Self::Error>(reg[0])
1796 }
1797
1798 /// Set the IP type of service.
1799 ///
1800 /// For more information see [`Registers::sn_tos`].
1801 ///
1802 /// # Example
1803 ///
1804 /// ```
1805 /// # #[tokio::main(flavor = "current_thread")]
1806 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1807 /// # let spi = ehm::eh1::spi::Mock::new(&[
1808 /// # ehm::eh1::spi::Transaction::transaction_start(),
1809 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x15, 0x08 | 0x04]),
1810 /// # ehm::eh1::spi::Transaction::write(0x01),
1811 /// # ehm::eh1::spi::Transaction::transaction_end(),
1812 /// # ]);
1813 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1814 ///
1815 /// let mut w5500 = W5500::new(spi);
1816 /// w5500.set_sn_tos(Sn::Sn0, 1).await?;
1817 /// # w5500.free().done(); Ok(()) }
1818 /// ```
1819 async fn set_sn_tos(&mut self, sn: Sn, tos: u8) -> Result<(), Self::Error> {
1820 self.write(SnReg::TOS.addr(), sn.block(), &[tos]).await
1821 }
1822
1823 /// Get the time to live.
1824 ///
1825 /// This register configures the TTL (Time to Live field in the IP header)
1826 /// for socket n.
1827 ///
1828 /// For more details see <https://www.iana.org/assignments/ip-parameters>.
1829 ///
1830 /// # Example
1831 ///
1832 /// ```
1833 /// # #[tokio::main(flavor = "current_thread")]
1834 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1835 /// # let spi = ehm::eh1::spi::Mock::new(&[
1836 /// # ehm::eh1::spi::Transaction::transaction_start(),
1837 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x16, 0x08]),
1838 /// # ehm::eh1::spi::Transaction::read(0x80),
1839 /// # ehm::eh1::spi::Transaction::transaction_end(),
1840 /// # ]);
1841 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1842 ///
1843 /// let mut w5500 = W5500::new(spi);
1844 /// let ttl: u8 = w5500.sn_ttl(Sn::Sn0).await?;
1845 /// # w5500.free().done(); Ok(()) }
1846 /// ```
1847 async fn sn_ttl(&mut self, sn: Sn) -> Result<u8, Self::Error> {
1848 let mut reg: [u8; 1] = [0];
1849 self.read(SnReg::TTL.addr(), sn.block(), &mut reg).await?;
1850 Ok::<u8, Self::Error>(reg[0])
1851 }
1852
1853 /// Set the time to live.
1854 ///
1855 /// For more information see [`Registers::sn_ttl`].
1856 ///
1857 /// # Example
1858 ///
1859 /// ```
1860 /// # #[tokio::main(flavor = "current_thread")]
1861 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1862 /// # let spi = ehm::eh1::spi::Mock::new(&[
1863 /// # ehm::eh1::spi::Transaction::transaction_start(),
1864 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x16, 0x08 | 0x04]),
1865 /// # ehm::eh1::spi::Transaction::write(0x80),
1866 /// # ehm::eh1::spi::Transaction::transaction_end(),
1867 /// # ]);
1868 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
1869 ///
1870 /// let mut w5500 = W5500::new(spi);
1871 /// w5500.set_sn_ttl(Sn::Sn0, 0x80).await?;
1872 /// # w5500.free().done(); Ok(()) }
1873 /// ```
1874 async fn set_sn_ttl(&mut self, sn: Sn, ttl: u8) -> Result<(), Self::Error> {
1875 self.write(SnReg::TTL.addr(), sn.block(), &[ttl]).await
1876 }
1877
1878 /// Get the socket RX buffer size.
1879 ///
1880 /// The buffer size can be configured to any of the sizes in [`BufferSize`].
1881 ///
1882 /// The sum of all the socket RX buffers cannot exceed 16 KiB.
1883 ///
1884 /// **Note:** This method returns a nested [`core::result::Result`].
1885 ///
1886 /// The outermost `Result` is for handling bus errors, similar to most of
1887 /// the other methods in this trait.
1888 ///
1889 /// The innermost `Result<BufferSize, u8>` is the result of a `u8` to
1890 /// [`BufferSize`] conversion because not every value of `u8` corresponds
1891 /// to a valid [`BufferSize`].
1892 /// * `u8` values that have a corresponding [`BufferSize`] will be
1893 /// converted and returned in the [`Ok`] variant of the inner `Result`.
1894 /// * `u8` values that do not corresponding [`BufferSize`] will have the
1895 /// raw `u8` byte returned in the [`Err`] variant of the inner `Result`.
1896 ///
1897 /// # Example
1898 ///
1899 /// ```
1900 /// # #[tokio::main(flavor = "current_thread")]
1901 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1902 /// # let spi = ehm::eh1::spi::Mock::new(&[
1903 /// # ehm::eh1::spi::Transaction::transaction_start(),
1904 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1E, 0x08]),
1905 /// # ehm::eh1::spi::Transaction::read(0x02),
1906 /// # ehm::eh1::spi::Transaction::transaction_end(),
1907 /// # ]);
1908 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, BufferSize, Sn};
1909 ///
1910 /// let mut w5500 = W5500::new(spi);
1911 /// let sn_rxbuf_size = w5500.sn_rxbuf_size(Sn::Sn0).await?;
1912 /// assert_eq!(sn_rxbuf_size, Ok(BufferSize::KB2));
1913 /// # w5500.free().done(); Ok(()) }
1914 /// ```
1915 ///
1916 /// [`Ok`]: https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok
1917 /// [`Err`]: https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err
1918 async fn sn_rxbuf_size(&mut self, sn: Sn) -> Result<Result<BufferSize, u8>, Self::Error> {
1919 let mut reg: [u8; 1] = [0];
1920 self.read(SnReg::RXBUF_SIZE.addr(), sn.block(), &mut reg)
1921 .await?;
1922 Ok::<Result<BufferSize, u8>, Self::Error>(BufferSize::try_from(reg[0]))
1923 }
1924
1925 /// Set the socket RX buffer size.
1926 ///
1927 /// See [`Registers::sn_rxbuf_size`] for more information.
1928 ///
1929 /// # Example
1930 ///
1931 /// ```
1932 /// # #[tokio::main(flavor = "current_thread")]
1933 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1934 /// # let spi = ehm::eh1::spi::Mock::new(&[
1935 /// # ehm::eh1::spi::Transaction::transaction_start(),
1936 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1E, 0x08 | 0x04]),
1937 /// # ehm::eh1::spi::Transaction::write(1),
1938 /// # ehm::eh1::spi::Transaction::transaction_end(),
1939 /// # ]);
1940 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, BufferSize, Sn};
1941 ///
1942 /// let mut w5500 = W5500::new(spi);
1943 /// w5500.set_sn_rxbuf_size(Sn::Sn0, BufferSize::KB1).await?;
1944 /// # w5500.free().done(); Ok(()) }
1945 /// ```
1946 async fn set_sn_rxbuf_size(&mut self, sn: Sn, size: BufferSize) -> Result<(), Self::Error> {
1947 self.write(SnReg::RXBUF_SIZE.addr(), sn.block(), &[size.into()])
1948 .await
1949 }
1950
1951 /// Get the socket TX buffer size.
1952 ///
1953 /// The buffer size can be configured to any of the sizes in [`BufferSize`].
1954 ///
1955 /// The sum of all the socket TX buffers cannot exceed 16 KiB.
1956 ///
1957 /// **Note:** This method returns a nested [`core::result::Result`].
1958 ///
1959 /// The outermost `Result` is for handling bus errors, similar to most of
1960 /// the other methods in this trait.
1961 ///
1962 /// The innermost `Result<BufferSize, u8>` is the result of a `u8` to
1963 /// [`BufferSize`] conversion because not every value of `u8` corresponds
1964 /// to a valid [`BufferSize`].
1965 /// * `u8` values that have a corresponding [`BufferSize`] will be
1966 /// converted and returned in the [`Ok`] variant of the inner `Result`.
1967 /// * `u8` values that do not corresponding [`BufferSize`] will have the
1968 /// raw `u8` byte returned in the [`Err`] variant of the inner `Result`.
1969 ///
1970 /// # Example
1971 ///
1972 /// ```
1973 /// # #[tokio::main(flavor = "current_thread")]
1974 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
1975 /// # let spi = ehm::eh1::spi::Mock::new(&[
1976 /// # ehm::eh1::spi::Transaction::transaction_start(),
1977 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1F, 0x08]),
1978 /// # ehm::eh1::spi::Transaction::read(0x02),
1979 /// # ehm::eh1::spi::Transaction::transaction_end(),
1980 /// # ]);
1981 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, BufferSize, Sn};
1982 ///
1983 /// let mut w5500 = W5500::new(spi);
1984 /// let sn_txbuf_size = w5500.sn_txbuf_size(Sn::Sn0).await?;
1985 /// assert_eq!(sn_txbuf_size, Ok(BufferSize::KB2));
1986 /// # w5500.free().done(); Ok(()) }
1987 /// ```
1988 ///
1989 /// [`Ok`]: https://doc.rust-lang.org/core/result/enum.Result.html#variant.Ok
1990 /// [`Err`]: https://doc.rust-lang.org/core/result/enum.Result.html#variant.Err
1991 async fn sn_txbuf_size(&mut self, sn: Sn) -> Result<Result<BufferSize, u8>, Self::Error> {
1992 let mut reg: [u8; 1] = [0];
1993 self.read(SnReg::TXBUF_SIZE.addr(), sn.block(), &mut reg)
1994 .await?;
1995 Ok::<Result<BufferSize, u8>, Self::Error>(BufferSize::try_from(reg[0]))
1996 }
1997
1998 /// Set the socket TX buffer size.
1999 ///
2000 /// See [`Registers::sn_rxbuf_size`] for more information.
2001 ///
2002 /// # Example
2003 ///
2004 /// ```
2005 /// # #[tokio::main(flavor = "current_thread")]
2006 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2007 /// # let spi = ehm::eh1::spi::Mock::new(&[
2008 /// # ehm::eh1::spi::Transaction::transaction_start(),
2009 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x1F, 0x08 | 0x04]),
2010 /// # ehm::eh1::spi::Transaction::write(1),
2011 /// # ehm::eh1::spi::Transaction::transaction_end(),
2012 /// # ]);
2013 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, BufferSize, Sn};
2014 ///
2015 /// let mut w5500 = W5500::new(spi);
2016 /// w5500.set_sn_txbuf_size(Sn::Sn0, BufferSize::KB1).await?;
2017 /// # w5500.free().done(); Ok(()) }
2018 /// ```
2019 async fn set_sn_txbuf_size(&mut self, sn: Sn, size: BufferSize) -> Result<(), Self::Error> {
2020 self.write(SnReg::TXBUF_SIZE.addr(), sn.block(), &[size.into()])
2021 .await
2022 }
2023
2024 /// Get transmit buffer free size.
2025 ///
2026 /// This register indicates the free size of socket n TX buffer.
2027 /// It is initialized to the configured size by [`Registers::sn_txbuf_size`].
2028 /// Data bigger than Sn_TX_FSR should not be written to the TX buffer to
2029 /// prevent buffer overflow.
2030 ///
2031 /// Check this register before writing data to the socket TX buffer,
2032 /// and if data is equal or smaller than its checked size, transmit the data
2033 /// with the [`SocketCommand::Send`] or [`SocketCommand::SendMac`] command
2034 /// after saving the data in Socket n TX buffer.
2035 ///
2036 /// If data is bigger than its checked size, transmit the data after
2037 /// dividing into the checked size and saving in the socket TX buffer.
2038 ///
2039 /// If [`Registers::sn_mr`] is not in TCP mode, this register is
2040 /// automatically calculated as the difference between
2041 /// [`Registers::sn_tx_wr`] and [`Registers::sn_tx_rd`].
2042 ///
2043 /// If [`Registers::sn_mr`] is in TCP mode, this register is automatically
2044 /// calculated as the difference between the internal ACK pointer which
2045 /// indicates the point of data is received already by the connected
2046 /// peer.
2047 ///
2048 /// # Example
2049 ///
2050 /// ```
2051 /// # #[tokio::main(flavor = "current_thread")]
2052 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2053 /// # let spi = ehm::eh1::spi::Mock::new(&[
2054 /// # ehm::eh1::spi::Transaction::transaction_start(),
2055 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x20, 0x08]),
2056 /// # ehm::eh1::spi::Transaction::read_vec(vec![0x08, 0x00]),
2057 /// # ehm::eh1::spi::Transaction::transaction_end(),
2058 /// # ]);
2059 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketMode};
2060 ///
2061 /// let mut w5500 = W5500::new(spi);
2062 /// let sn_tx_fsr: u16 = w5500.sn_tx_fsr(Sn::Sn0).await?;
2063 /// # w5500.free().done(); Ok(()) }
2064 /// ```
2065 async fn sn_tx_fsr(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2066 let mut reg: [u8; 2] = [0; 2];
2067 self.read(SnReg::TX_FSR0.addr(), sn.block(), &mut reg)
2068 .await?;
2069 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
2070 }
2071
2072 /// Get the socket TX read pointer.
2073 ///
2074 /// This register is initialized by the [`SocketCommand::Open`] command.
2075 /// However, in TCP mode, this is re-initialized while connecting with TCP.
2076 ///
2077 /// After initialization, this is auto-increased by the
2078 /// [`SocketCommand::Send`] command.
2079 ///
2080 /// The [`SocketCommand::Send`] command transmits the saved data from the
2081 /// current [`Registers::sn_tx_rd`] to the [`Registers::sn_tx_wr`] in the
2082 /// socket n TX buffer.
2083 /// After transmitting the saved data, the [`SocketCommand::Send`] command
2084 /// increases [`Registers::sn_tx_rd`] the as same as
2085 /// [`Registers::sn_tx_wr`].
2086 ///
2087 /// If its increment value exceeds the maximum value `0xFFFF`,
2088 /// (greater than `0x10000` and the carry bit occurs), then the carry bit is
2089 /// ignored and will automatically update with the lower 16 bits value.
2090 ///
2091 /// # Example
2092 ///
2093 /// ```
2094 /// # #[tokio::main(flavor = "current_thread")]
2095 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2096 /// # let spi = ehm::eh1::spi::Mock::new(&[
2097 /// # ehm::eh1::spi::Transaction::transaction_start(),
2098 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x22, 0x08]),
2099 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2100 /// # ehm::eh1::spi::Transaction::transaction_end(),
2101 /// # ]);
2102 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketMode};
2103 ///
2104 /// let mut w5500 = W5500::new(spi);
2105 /// let sn_tx_rd: u16 = w5500.sn_tx_rd(Sn::Sn0).await?;
2106 /// # w5500.free().done(); Ok(()) }
2107 /// ```
2108 async fn sn_tx_rd(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2109 let mut reg: [u8; 2] = [0; 2];
2110 self.read(SnReg::TX_RD0.addr(), sn.block(), &mut reg)
2111 .await?;
2112 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
2113 }
2114
2115 /// Get the socket TX write pointer.
2116 ///
2117 /// This register is initialized by the [`SocketCommand::Open`] command.
2118 /// However, in TCP mode, this is re-initialized while connecting with TCP.
2119 ///
2120 /// This should be updated as follows:
2121 /// 1. Read the starting address for transmitting data.
2122 /// 2. Write data to the socket TX buffer buffer.
2123 /// 3. Update this register by the number of bytes written to the TX buffer.
2124 /// Allow wrapping to occur upon `u16` overflow.
2125 /// 4. Transmit the saved data in the socket TX buffer by using the
2126 /// [`SocketCommand::Send`] command.
2127 ///
2128 /// See [`Registers::set_sn_tx_buf`] for an additional example.
2129 ///
2130 /// # Example
2131 ///
2132 /// ```
2133 /// # #[tokio::main(flavor = "current_thread")]
2134 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2135 /// # let spi = ehm::eh1::spi::Mock::new(&[
2136 /// # ehm::eh1::spi::Transaction::transaction_start(),
2137 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x24, 0x08]),
2138 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2139 /// # ehm::eh1::spi::Transaction::transaction_end(),
2140 /// # ]);
2141 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2142 ///
2143 /// let mut w5500 = W5500::new(spi);
2144 /// let sn_tx_wr: u16 = w5500.sn_tx_wr(Sn::Sn0).await?;
2145 /// # w5500.free().done(); Ok(()) }
2146 /// ```
2147 async fn sn_tx_wr(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2148 let mut reg: [u8; 2] = [0; 2];
2149 self.read(SnReg::TX_WR0.addr(), sn.block(), &mut reg)
2150 .await?;
2151 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
2152 }
2153
2154 /// Set the socket TX write pointer.
2155 ///
2156 /// See [`Registers::sn_tx_wr`] for more information.
2157 ///
2158 /// See [`Registers::set_sn_tx_buf`] for an example.
2159 async fn set_sn_tx_wr(&mut self, sn: Sn, ptr: u16) -> Result<(), Self::Error> {
2160 self.write(SnReg::TX_WR0.addr(), sn.block(), &ptr.to_be_bytes())
2161 .await
2162 }
2163
2164 /// Get the socket TX free size and write pointer
2165 ///
2166 /// This is equivalent to [`Registers::sn_tx_fsr`] and
2167 /// [`Registers::sn_tx_wr`] in a single read transaction.
2168 async fn sn_tx_ptrs(&mut self, sn: Sn) -> Result<TxPtrs, Self::Error> {
2169 let mut buf: [u8; 6] = [0; 6];
2170 self.read(SnReg::TX_FSR0.addr(), sn.block(), &mut buf)
2171 .await?;
2172 Ok(TxPtrs {
2173 fsr: u16::from_be_bytes(buf[..2].try_into().unwrap()),
2174 wr: u16::from_be_bytes(buf[4..].try_into().unwrap()),
2175 })
2176 }
2177
2178 /// Get the socket received data size.
2179 ///
2180 /// This register indicates the data size received and saved in the socket
2181 /// RX buffer.
2182 /// This register does not exceed the configured size
2183 /// ([`Registers::set_sn_rxbuf_size`]) and is calculated as the difference
2184 /// between [`Registers::sn_rx_wr`] and [`Registers::sn_rx_rd`].
2185 ///
2186 /// # Example
2187 ///
2188 /// ```
2189 /// # #[tokio::main(flavor = "current_thread")]
2190 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2191 /// # let spi = ehm::eh1::spi::Mock::new(&[
2192 /// # ehm::eh1::spi::Transaction::transaction_start(),
2193 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x26, 0x08]),
2194 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2195 /// # ehm::eh1::spi::Transaction::transaction_end(),
2196 /// # ]);
2197 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2198 ///
2199 /// let mut w5500 = W5500::new(spi);
2200 /// let sn_rx_rsr: u16 = w5500.sn_rx_rsr(Sn::Sn0).await?;
2201 /// # w5500.free().done(); Ok(()) }
2202 /// ```
2203 async fn sn_rx_rsr(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2204 let mut reg: [u8; 2] = [0; 2];
2205 self.read(SnReg::RX_RSR0.addr(), sn.block(), &mut reg)
2206 .await?;
2207 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
2208 }
2209
2210 /// Get the socket read data pointer.
2211 ///
2212 /// This register is initialized by the [`SocketCommand::Open`] command.
2213 ///
2214 /// This should be updated as follows:
2215 /// 1. Read the starting address for reading data.
2216 /// 2. Read from the socket RX buffer.
2217 /// 3. Update this register by the number of bytes read from the RX buffer.
2218 /// Allow wrapping to occur upon `u16` overflow.
2219 /// 4. Send a [`SocketCommand::Recv`] command to notify the W5500 of the
2220 /// retrieved data.
2221 ///
2222 /// See [`Registers::sn_rx_buf`] for an additional example.
2223 ///
2224 /// # Example
2225 ///
2226 /// ```
2227 /// # #[tokio::main(flavor = "current_thread")]
2228 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2229 /// # let spi = ehm::eh1::spi::Mock::new(&[
2230 /// # ehm::eh1::spi::Transaction::transaction_start(),
2231 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x28, 0x08]),
2232 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2233 /// # ehm::eh1::spi::Transaction::transaction_end(),
2234 /// # ]);
2235 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2236 ///
2237 /// let mut w5500 = W5500::new(spi);
2238 /// let sn_rx_rd: u16 = w5500.sn_rx_rd(Sn::Sn0).await?;
2239 /// # w5500.free().done(); Ok(()) }
2240 /// ```
2241 async fn sn_rx_rd(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2242 let mut reg: [u8; 2] = [0; 2];
2243 self.read(SnReg::RX_RD0.addr(), sn.block(), &mut reg)
2244 .await?;
2245 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
2246 }
2247
2248 /// Set the socket read data pointer.
2249 ///
2250 /// See [`Registers::sn_rx_rd`] for more information.
2251 /// See [`Registers::sn_rx_buf`] for an example.
2252 async fn set_sn_rx_rd(&mut self, sn: Sn, ptr: u16) -> Result<(), Self::Error> {
2253 self.write(SnReg::RX_RD0.addr(), sn.block(), &ptr.to_be_bytes())
2254 .await
2255 }
2256
2257 /// Get the socket RX write pointer.
2258 ///
2259 /// This register is initialized by the [`SocketCommand::Open`] command, and
2260 /// it is auto-incremented by hardware.
2261 ///
2262 /// # Example
2263 ///
2264 /// ```
2265 /// # #[tokio::main(flavor = "current_thread")]
2266 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2267 /// # let spi = ehm::eh1::spi::Mock::new(&[
2268 /// # ehm::eh1::spi::Transaction::transaction_start(),
2269 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2A, 0x08]),
2270 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2271 /// # ehm::eh1::spi::Transaction::transaction_end(),
2272 /// # ]);
2273 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2274 ///
2275 /// let mut w5500 = W5500::new(spi);
2276 /// let sn_rx_wr: u16 = w5500.sn_rx_wr(Sn::Sn0).await?;
2277 /// # w5500.free().done(); Ok(()) }
2278 /// ```
2279 async fn sn_rx_wr(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2280 let mut reg: [u8; 2] = [0; 2];
2281 self.read(SnReg::RX_WR0.addr(), sn.block(), &mut reg)
2282 .await?;
2283 Ok::<u16, Self::Error>(u16::from_be_bytes(reg))
2284 }
2285
2286 /// Get the socket RX received size size and write pointer
2287 ///
2288 /// This is equivalent to [`Registers::sn_rx_rsr`] and
2289 /// [`Registers::sn_rx_rd`] in a single read transaction.
2290 async fn sn_rx_ptrs(&mut self, sn: Sn) -> Result<RxPtrs, Self::Error> {
2291 let mut buf: [u8; 4] = [0; 4];
2292 self.read(SnReg::RX_RSR0.addr(), sn.block(), &mut buf)
2293 .await?;
2294 Ok(RxPtrs {
2295 rsr: u16::from_be_bytes(buf[..2].try_into().unwrap()),
2296 rd: u16::from_be_bytes(buf[2..].try_into().unwrap()),
2297 })
2298 }
2299
2300 /// Get the socket interrupt mask.
2301 ///
2302 /// # Example
2303 ///
2304 /// ```
2305 /// # #[tokio::main(flavor = "current_thread")]
2306 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2307 /// # let spi = ehm::eh1::spi::Mock::new(&[
2308 /// # ehm::eh1::spi::Transaction::transaction_start(),
2309 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2C, 0x08]),
2310 /// # ehm::eh1::spi::Transaction::read(0xFF),
2311 /// # ehm::eh1::spi::Transaction::transaction_end(),
2312 /// # ]);
2313 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketInterruptMask};
2314 ///
2315 /// let mut w5500 = W5500::new(spi);
2316 /// let sn_imr: SocketInterruptMask = w5500.sn_imr(Sn::Sn0).await?;
2317 /// assert_eq!(sn_imr, SocketInterruptMask::default());
2318 /// # w5500.free().done(); Ok(()) }
2319 /// ```
2320 async fn sn_imr(&mut self, sn: Sn) -> Result<SocketInterruptMask, Self::Error> {
2321 let mut reg: [u8; 1] = [0];
2322 self.read(SnReg::IMR.addr(), sn.block(), &mut reg).await?;
2323 Ok::<SocketInterruptMask, Self::Error>(SocketInterruptMask::from(reg[0]))
2324 }
2325
2326 /// Set the socket interrupt mask.
2327 ///
2328 /// # Example
2329 ///
2330 /// ```
2331 /// # #[tokio::main(flavor = "current_thread")]
2332 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2333 /// # let spi = ehm::eh1::spi::Mock::new(&[
2334 /// # ehm::eh1::spi::Transaction::transaction_start(),
2335 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2C, 0x08 | 0x04]),
2336 /// # ehm::eh1::spi::Transaction::write(0xE0),
2337 /// # ehm::eh1::spi::Transaction::transaction_end(),
2338 /// # ]);
2339 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketInterruptMask};
2340 ///
2341 /// let mut w5500 = W5500::new(spi);
2342 /// w5500
2343 /// .set_sn_imr(Sn::Sn0, SocketInterruptMask::ALL_MASKED)
2344 /// .await?;
2345 /// # w5500.free().done(); Ok(()) }
2346 /// ```
2347 async fn set_sn_imr(&mut self, sn: Sn, mask: SocketInterruptMask) -> Result<(), Self::Error> {
2348 self.write(SnReg::IMR.addr(), sn.block(), &[mask.into()])
2349 .await
2350 }
2351
2352 /// Get the socket fragment.
2353 ///
2354 /// This configures the fragment field in the IP header.
2355 ///
2356 /// # Example
2357 ///
2358 /// ```
2359 /// # #[tokio::main(flavor = "current_thread")]
2360 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2361 /// # let spi = ehm::eh1::spi::Mock::new(&[
2362 /// # ehm::eh1::spi::Transaction::transaction_start(),
2363 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2D, 0x08]),
2364 /// # ehm::eh1::spi::Transaction::read_vec(vec![0x40, 0x00]),
2365 /// # ehm::eh1::spi::Transaction::transaction_end(),
2366 /// # ]);
2367 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2368 ///
2369 /// let mut w5500 = W5500::new(spi);
2370 /// let frag: u16 = w5500.sn_frag(Sn::Sn0).await?;
2371 /// assert_eq!(frag, 0x4000);
2372 /// # w5500.free().done(); Ok(()) }
2373 /// ```
2374 async fn sn_frag(&mut self, sn: Sn) -> Result<u16, Self::Error> {
2375 let mut buf: [u8; 2] = [0; 2];
2376 self.read(SnReg::FRAG0.addr(), sn.block(), &mut buf).await?;
2377 Ok::<u16, Self::Error>(u16::from_be_bytes(buf))
2378 }
2379
2380 /// Set the socket fragment.
2381 ///
2382 /// See [`Registers::sn_frag`] for more information.
2383 ///
2384 /// # Example
2385 ///
2386 /// ```
2387 /// # #[tokio::main(flavor = "current_thread")]
2388 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2389 /// # let spi = ehm::eh1::spi::Mock::new(&[
2390 /// # ehm::eh1::spi::Transaction::transaction_start(),
2391 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2D, 0x08 | 0x04]),
2392 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00]),
2393 /// # ehm::eh1::spi::Transaction::transaction_end(),
2394 /// # ]);
2395 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2396 ///
2397 /// let mut w5500 = W5500::new(spi);
2398 /// w5500.set_sn_frag(Sn::Sn0, 0).await?;
2399 /// # w5500.free().done(); Ok(()) }
2400 /// ```
2401 async fn set_sn_frag(&mut self, sn: Sn, frag: u16) -> Result<(), Self::Error> {
2402 self.write(SnReg::FRAG0.addr(), sn.block(), &u16::to_be_bytes(frag))
2403 .await
2404 }
2405
2406 /// Get the socket keep alive time.
2407 ///
2408 /// This register configures the transmitting timer of the keep alive (KA)
2409 /// packet for the socket. This is valid only in TCP mode, and is ignored
2410 /// in all other modes.
2411 ///
2412 /// The time unit is 5 seconds.
2413 ///
2414 /// The KA packet is transmittable after [`Registers::sn_sr`] is changed to
2415 /// [`SocketStatus::Established`] and after the data is transmitted or
2416 /// received to/from a peer at least once.
2417 ///
2418 /// In the case of a non-zero keep alive value the W5500 automatically
2419 /// transmits a KA packet after time-period for checking the TCP connection
2420 /// (automatic-keepalive-process).
2421 ///
2422 /// In case of a zero keep alive value, the keep alive packet can be
2423 /// transmitted with [`SocketCommand::SendKeep`]. This command is ignored
2424 /// for non-zero keep alive values.
2425 ///
2426 /// # Example
2427 ///
2428 /// ```
2429 /// # #[tokio::main(flavor = "current_thread")]
2430 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2431 /// # let spi = ehm::eh1::spi::Mock::new(&[
2432 /// # ehm::eh1::spi::Transaction::transaction_start(),
2433 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2F, 0x08]),
2434 /// # ehm::eh1::spi::Transaction::read(0),
2435 /// # ehm::eh1::spi::Transaction::transaction_end(),
2436 /// # ]);
2437 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2438 ///
2439 /// let mut w5500 = W5500::new(spi);
2440 /// let sn_kpalvtr: u8 = w5500.sn_kpalvtr(Sn::Sn0).await?;
2441 /// # w5500.free().done(); Ok(()) }
2442 /// ```
2443 async fn sn_kpalvtr(&mut self, sn: Sn) -> Result<u8, Self::Error> {
2444 let mut buf: [u8; 1] = [0];
2445 self.read(SnReg::KPALVTR.addr(), sn.block(), &mut buf)
2446 .await?;
2447 Ok::<u8, Self::Error>(buf[0])
2448 }
2449
2450 /// Set the socket keep alive time.
2451 ///
2452 /// See [`Registers::sn_kpalvtr`] for more information.
2453 ///
2454 /// # Example
2455 ///
2456 /// ```
2457 /// # #[tokio::main(flavor = "current_thread")]
2458 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2459 /// # let spi = ehm::eh1::spi::Mock::new(&[
2460 /// # ehm::eh1::spi::Transaction::transaction_start(),
2461 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x2F, 0x08 | 0x04]),
2462 /// # ehm::eh1::spi::Transaction::write(0x0A),
2463 /// # ehm::eh1::spi::Transaction::transaction_end(),
2464 /// # ]);
2465 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn};
2466 ///
2467 /// let mut w5500 = W5500::new(spi);
2468 /// // 50s keep alive timer
2469 /// w5500.set_sn_kpalvtr(Sn::Sn0, 10).await?;
2470 /// # w5500.free().done(); Ok(()) }
2471 /// ```
2472 async fn set_sn_kpalvtr(&mut self, sn: Sn, kpalvtr: u8) -> Result<(), Self::Error> {
2473 self.write(SnReg::KPALVTR.addr(), sn.block(), &[kpalvtr])
2474 .await
2475 }
2476
2477 /// Write the socket TX buffer.
2478 ///
2479 /// # Example
2480 ///
2481 /// ```
2482 /// # #[tokio::main(flavor = "current_thread")]
2483 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2484 /// use core::cmp::min;
2485 /// use w5500_ll::{eh1::vdm::W5500, aio::Registers, Sn, SocketCommand};
2486 /// # let spi = ehm::eh1::spi::Mock::new(&[
2487 /// # // sn_tx_fsr
2488 /// # ehm::eh1::spi::Transaction::transaction_start(),
2489 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, w5500_ll::SnReg::TX_FSR0.addr() as u8, 0x08]),
2490 /// # ehm::eh1::spi::Transaction::read_vec(vec![0x08, 0x00]),
2491 /// # ehm::eh1::spi::Transaction::transaction_end(),
2492 /// # // sn_tx_write
2493 /// # ehm::eh1::spi::Transaction::transaction_start(),
2494 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, w5500_ll::SnReg::TX_WR0.addr() as u8, 0x08]),
2495 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2496 /// # ehm::eh1::spi::Transaction::transaction_end(),
2497 /// # // set_sn_tx_buf
2498 /// # ehm::eh1::spi::Transaction::transaction_start(),
2499 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, (Sn::Sn0.tx_block() as u8) << 3 | 0x04]),
2500 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x12, 0x34, 0x56, 0x78, 0x9A]),
2501 /// # ehm::eh1::spi::Transaction::transaction_end(),
2502 /// # // set_sn_tx_wr
2503 /// # ehm::eh1::spi::Transaction::transaction_start(),
2504 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x24, 0x08 | 0x04]),
2505 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 5]),
2506 /// # ehm::eh1::spi::Transaction::transaction_end(),
2507 /// # // set_sn_cr
2508 /// # ehm::eh1::spi::Transaction::transaction_start(),
2509 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x01, 0x08 | 0x04]),
2510 /// # ehm::eh1::spi::Transaction::write_vec(vec![SocketCommand::Send.into()]),
2511 /// # ehm::eh1::spi::Transaction::transaction_end(),
2512 /// # ]);
2513 /// # let mut w5500 = W5500::new(spi);
2514 ///
2515 /// // the socket should already be opened at this point
2516 /// const THE_SOCKET: Sn = Sn::Sn0;
2517 ///
2518 /// let buf: [u8; 5] = [0x12, 0x34, 0x56, 0x78, 0x9A];
2519 ///
2520 /// // transmit as many bytes as possible
2521 /// // for large buffers this may not transmit all the available data
2522 /// let tx_bytes: u16 = {
2523 /// min(w5500.sn_tx_fsr(THE_SOCKET).await?, u16::try_from(buf.len()).unwrap_or(u16::MAX))
2524 /// };
2525 /// if tx_bytes == 0 {
2526 /// return Ok(());
2527 /// }
2528 ///
2529 /// let ptr: u16 = w5500.sn_tx_wr(THE_SOCKET).await?;
2530 /// w5500.set_sn_tx_buf(THE_SOCKET, ptr, &buf[..usize::from(tx_bytes)]).await?;
2531 /// w5500.set_sn_tx_wr(THE_SOCKET, ptr.wrapping_add(tx_bytes)).await?;
2532 /// w5500.set_sn_cr(THE_SOCKET, SocketCommand::Send).await?;
2533 /// # w5500.free().done(); Ok(()) }
2534 /// ```
2535 async fn set_sn_tx_buf(&mut self, sn: Sn, ptr: u16, buf: &[u8]) -> Result<(), Self::Error> {
2536 self.write(ptr, sn.tx_block(), buf).await
2537 }
2538
2539 /// Read the socket TX buffer.
2540 ///
2541 /// This method is typically unused; there are very few use cases that
2542 /// require reading the TX buffer.
2543 ///
2544 /// # Example
2545 ///
2546 /// ```
2547 /// # #[tokio::main(flavor = "current_thread")]
2548 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2549 /// use core::cmp::min;
2550 /// use w5500_ll::{aio::Registers, eh1::vdm::W5500, Sn, SocketCommand};
2551 /// # let spi = ehm::eh1::spi::Mock::new(&[
2552 /// # ehm::eh1::spi::Transaction::transaction_start(),
2553 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, (Sn::Sn0.tx_block() as u8) << 3]),
2554 /// # ehm::eh1::spi::Transaction::read(0),
2555 /// # ehm::eh1::spi::Transaction::transaction_end(),
2556 /// # ]);
2557 /// # let mut w5500 = W5500::new(spi);
2558 /// let mut buf: [u8; 1] = [0];
2559 /// w5500.sn_tx_buf(Sn::Sn0, 0, &mut buf).await?;
2560 /// # w5500.free().done(); Ok(()) }
2561 /// ```
2562 async fn sn_tx_buf(&mut self, sn: Sn, ptr: u16, buf: &mut [u8]) -> Result<(), Self::Error> {
2563 self.read(ptr, sn.tx_block(), buf).await
2564 }
2565
2566 /// Read the socket RX buffer.
2567 ///
2568 /// # Example
2569 ///
2570 /// ```
2571 /// # #[tokio::main(flavor = "current_thread")]
2572 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2573 /// use core::cmp::min;
2574 /// use w5500_ll::{eh1::vdm::W5500, aio::Registers, Sn, SocketCommand};
2575 /// # let spi = ehm::eh1::spi::Mock::new(&[
2576 /// # ehm::eh1::spi::Transaction::transaction_start(),
2577 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, w5500_ll::SnReg::RX_RSR0.addr() as u8, 0x08]),
2578 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 4]),
2579 /// # ehm::eh1::spi::Transaction::transaction_end(),
2580 /// # ehm::eh1::spi::Transaction::transaction_start(),
2581 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, w5500_ll::SnReg::RX_RD0.addr() as u8, 0x08]),
2582 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0]),
2583 /// # ehm::eh1::spi::Transaction::transaction_end(),
2584 /// # ehm::eh1::spi::Transaction::transaction_start(),
2585 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, (Sn::Sn0.rx_block() as u8) << 3]),
2586 /// # ehm::eh1::spi::Transaction::read_vec(vec![0, 0, 0, 0]),
2587 /// # ehm::eh1::spi::Transaction::transaction_end(),
2588 /// # ehm::eh1::spi::Transaction::transaction_start(),
2589 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, w5500_ll::SnReg::RX_RD0.addr() as u8, 0x08 | 0x04]),
2590 /// # ehm::eh1::spi::Transaction::write_vec(vec![0, 4]),
2591 /// # ehm::eh1::spi::Transaction::transaction_end(),
2592 /// # ehm::eh1::spi::Transaction::transaction_start(),
2593 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, w5500_ll::SnReg::CR.addr() as u8, 0x08 | 0x04]),
2594 /// # ehm::eh1::spi::Transaction::write(SocketCommand::Recv.into()),
2595 /// # ehm::eh1::spi::Transaction::transaction_end(),
2596 /// # ]);
2597 /// # let mut w5500 = W5500::new(spi);
2598 ///
2599 /// // the socket should already be opened at this point
2600 /// // a socket interrupt will indicate there is data to be retrieved
2601 /// const THE_SOCKET: Sn = Sn::Sn0;
2602 ///
2603 /// // in reality you will need a larger buffer for most protocols
2604 /// const BUF_LEN: usize = 16;
2605 /// let mut buf: [u8; BUF_LEN] = [0; BUF_LEN];
2606 ///
2607 /// let rx_bytes: u16 = {
2608 /// min(w5500.sn_rx_rsr(THE_SOCKET).await?, u16::try_from(buf.len()).unwrap_or(u16::MAX))
2609 /// };
2610 /// if rx_bytes == 0 {
2611 /// return Ok(());
2612 /// }
2613 ///
2614 /// let ptr: u16 = w5500.sn_rx_rd(THE_SOCKET).await?;
2615 /// w5500.sn_rx_buf(THE_SOCKET, ptr, &mut buf[..usize::from(rx_bytes)]).await?;
2616 /// w5500.set_sn_rx_rd(THE_SOCKET, ptr.wrapping_add(rx_bytes)).await?;
2617 /// w5500.set_sn_cr(THE_SOCKET, SocketCommand::Recv).await?;
2618 /// # w5500.free().done(); Ok(()) }
2619 /// ```
2620 async fn sn_rx_buf(&mut self, sn: Sn, ptr: u16, buf: &mut [u8]) -> Result<(), Self::Error> {
2621 self.read(ptr, sn.rx_block(), buf).await
2622 }
2623
2624 /// Write the socket RX buffer.
2625 ///
2626 /// This method is typically unused; there are very few use cases that
2627 /// require writing the RX buffer.
2628 ///
2629 /// # Example
2630 ///
2631 /// ```
2632 /// # #[tokio::main(flavor = "current_thread")]
2633 /// # async fn main() -> Result<(), eh1::spi::ErrorKind> {
2634 /// use core::cmp::min;
2635 /// use w5500_ll::{eh1::vdm::W5500, aio::Registers, Sn, SocketCommand};
2636 /// # let spi = ehm::eh1::spi::Mock::new(&[
2637 /// # ehm::eh1::spi::Transaction::transaction_start(),
2638 /// # ehm::eh1::spi::Transaction::write_vec(vec![0x00, 0x00, (Sn::Sn0.rx_block() as u8) << 3 | 0x04]),
2639 /// # ehm::eh1::spi::Transaction::write(0),
2640 /// # ehm::eh1::spi::Transaction::transaction_end(),
2641 /// # ]);
2642 /// # let mut w5500 = W5500::new(spi);
2643 /// let buf: [u8; 1] = [0];
2644 /// w5500.set_sn_rx_buf(Sn::Sn0, 0, &buf).await?;
2645 /// # w5500.free().done(); Ok(()) }
2646 /// ```
2647 async fn set_sn_rx_buf(&mut self, sn: Sn, ptr: u16, buf: &[u8]) -> Result<(), Self::Error> {
2648 self.write(ptr, sn.rx_block(), buf).await
2649 }
2650}