aboutsummaryrefslogtreecommitdiff
path: root/embassy-net-adin1110/src/lib.rs
diff options
context:
space:
mode:
authorRenĂ© van Dorst <[email protected]>2023-08-18 00:01:13 +0200
committerRenĂ© van Dorst <[email protected]>2023-08-24 00:43:51 +0200
commite19f7d9a76fa13012b6c606167a6a8f215875a4e (patch)
treeec1eb3e45287a540e595739538449c6ace60e82c /embassy-net-adin1110/src/lib.rs
parentbed1f07c15455f7c88364a06b8c94b3c781c2f68 (diff)
Add embassy-net-adin1110
This add a library for Analog ADIN1110 SPE SPI chip. This library is inspired by `embassy-net-w5500`.
Diffstat (limited to 'embassy-net-adin1110/src/lib.rs')
-rw-r--r--embassy-net-adin1110/src/lib.rs1246
1 files changed, 1246 insertions, 0 deletions
diff --git a/embassy-net-adin1110/src/lib.rs b/embassy-net-adin1110/src/lib.rs
new file mode 100644
index 000000000..a4010d251
--- /dev/null
+++ b/embassy-net-adin1110/src/lib.rs
@@ -0,0 +1,1246 @@
1#![allow(clippy::pedantic)]
2#![feature(type_alias_impl_trait)]
3#![feature(async_fn_in_trait)]
4#![cfg_attr(not(any(test, feature = "std")), no_std)]
5
6use ch::driver::LinkState;
7use embassy_futures::select::{select, Either};
8use embassy_net_driver_channel as ch;
9use embassy_time::{Duration, Timer};
10use embedded_hal_1::digital::OutputPin;
11use embedded_hal_async::digital::Wait;
12use embedded_hal_async::spi::{Operation, SpiDevice};
13use heapless::Vec;
14
15mod crc32;
16mod crc8;
17mod mdio;
18mod phy;
19mod regs;
20
21pub use crc32::ETH_FSC;
22use crc8::crc8;
23pub use mdio::MdioBus;
24pub use phy::{Phy10BaseT1x, RegsC22, RegsC45};
25pub use regs::{Config0, Config2, SpiRegisters as sr, Status0, Status1};
26
27use crate::regs::{LedCntrl, LedFunc, LedPol, LedPolarity, SpiHeader};
28
29pub const PHYID: u32 = 0x0283BC91;
30
31/// Error values ADIN1110
32#[derive(Debug)]
33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
34#[allow(non_camel_case_types)]
35pub enum AdinError<E> {
36 Spi(E),
37 SENDERROR,
38 READERROR,
39 CRC,
40 PACKET_TOO_BIG,
41 PACKET_TOO_SMALL,
42 MDIO_ACC_TIMEOUT,
43}
44
45pub type AEResult<T, SPIE> = core::result::Result<T, AdinError<SPIE>>;
46pub const MDIO_PHY_ADDR: u8 = 0x01;
47pub const MTU: usize = 1500;
48/// Max SPI/Frame buffer size
49pub const MAX_BUFF: usize = 2048;
50
51const DONT_CARE_BYTE: u8 = 0x00;
52const TURN_AROUND_BYTE: u8 = 0x00;
53
54const FEC_LEN: usize = 4;
55const FRAME_HEADER_LEN: usize = 2;
56const WR_HEADER_LEN: usize = 2;
57
58// P1 = 0x00, P2 = 0x01
59const PORT_ID_BYTE: u8 = 0x00;
60
61pub type Packet = Vec<u8, { MTU + FEC_LEN + WR_HEADER_LEN }>;
62
63/// Type alias for the embassy-net driver for ADIN1110
64pub type Device<'d> = embassy_net_driver_channel::Device<'d, MTU>;
65
66/// Internal state for the embassy-net integration.
67pub struct State<const N_RX: usize, const N_TX: usize> {
68 ch_state: ch::State<MTU, N_RX, N_TX>,
69}
70impl<const N_RX: usize, const N_TX: usize> State<N_RX, N_TX> {
71 /// Create a new `State`.
72 pub const fn new() -> Self {
73 Self {
74 ch_state: ch::State::new(),
75 }
76 }
77}
78
79#[derive(Debug)]
80pub struct ADIN1110<SPI> {
81 /// SPI bus
82 spi: SPI,
83 /// Enable CRC on SPI transfer.
84 /// This must match with the hardware pin SPI_CFG0 were 0 = CRC enable, 1 CRC disabled.
85 crc: bool,
86}
87
88// Round size up the N u32;
89pub(crate) fn size_align_u32(size: u32) -> u32 {
90 (size + 3) & 0xFFFF_FFFC
91}
92
93impl<SpiE, SPI> ADIN1110<SPI>
94where
95 SPI: SpiDevice<u8, Error = SpiE>,
96 SpiE: core::fmt::Debug,
97{
98 pub fn new(spi: SPI, crc: bool) -> Self {
99 Self { spi, crc }
100 }
101
102 pub async fn read_reg(&mut self, reg: sr) -> AEResult<u32, SpiE> {
103 let mut tx_buf = Vec::<u8, 16>::new();
104
105 let mut spi_hdr = SpiHeader(0);
106 spi_hdr.set_control(true);
107 spi_hdr.set_addr(reg);
108 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice());
109
110 if self.crc {
111 // Add CRC for header data
112 let _ = tx_buf.push(crc8(&tx_buf));
113 }
114
115 // Turn around byte, TODO: Unknown that this is.
116 let _ = tx_buf.push(TURN_AROUND_BYTE);
117
118 let mut rx_buf = [0; 5];
119
120 let spi_read_len = if self.crc { rx_buf.len() } else { rx_buf.len() - 1 };
121
122 let mut spi_op = [Operation::Write(&tx_buf), Operation::Read(&mut rx_buf[0..spi_read_len])];
123
124 self.spi.transaction(&mut spi_op).await.map_err(AdinError::Spi)?;
125
126 if self.crc {
127 let crc = crc8(&rx_buf[0..4]);
128 if crc != rx_buf[4] {
129 return Err(AdinError::CRC);
130 }
131 }
132
133 let value = u32::from_be_bytes(rx_buf[0..4].try_into().unwrap());
134
135 #[cfg(feature = "defmt")]
136 defmt::trace!("REG Read {} = {:08x} SPI {:02x}", reg, value, &tx_buf);
137
138 Ok(value)
139 }
140
141 pub async fn write_reg(&mut self, reg: sr, value: u32) -> AEResult<(), SpiE> {
142 let mut tx_buf = Vec::<u8, 16>::new();
143
144 let mut spi_hdr = SpiHeader(0);
145 spi_hdr.set_control(true);
146 spi_hdr.set_write(true);
147 spi_hdr.set_addr(reg);
148 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice());
149
150 if self.crc {
151 // Add CRC for header data
152 let _ = tx_buf.push(crc8(&tx_buf));
153 }
154
155 let val = value.to_be_bytes();
156 let _ = tx_buf.extend_from_slice(val.as_slice());
157
158 if self.crc {
159 // Add CRC for header data
160 let _ = tx_buf.push(crc8(val.as_slice()));
161 }
162
163 #[cfg(feature = "defmt")]
164 defmt::trace!("REG Write {} = {:08x} SPI {:02x}", reg, value, &tx_buf);
165
166 self.spi.write(&tx_buf).await.map_err(AdinError::Spi)
167 }
168
169 // helper function for write to MDIO_ACC register and wait for ready!
170 async fn write_mdio_acc_reg(&mut self, mdio_acc_val: u32) -> AEResult<u32, SpiE> {
171 self.write_reg(sr::MDIO_ACC, mdio_acc_val).await?;
172
173 // TODO: Add proper timeout!
174 for _ in 0..100_000 {
175 let val = self.read_reg(sr::MDIO_ACC).await?;
176 if val & 0x8000_0000 != 0 {
177 return Ok(val);
178 }
179 }
180
181 Err(AdinError::MDIO_ACC_TIMEOUT)
182 }
183
184 pub async fn read_fifo(&mut self, packet: &mut [u8]) -> AEResult<usize, SpiE> {
185 let mut tx_buf = Vec::<u8, 16>::new();
186
187 // Size of the frame, also includes the appednded header.
188 let packet_size = self.read_reg(sr::RX_FSIZE).await?;
189
190 // Packet read of write to the MAC packet buffer must be a multipul of 4!
191 let read_size = size_align_u32(packet_size);
192
193 if packet_size < u32::try_from(FRAME_HEADER_LEN + FEC_LEN).unwrap()
194 || read_size > u32::try_from(packet.len()).unwrap()
195 {
196 return Err(AdinError::PACKET_TOO_BIG);
197 }
198
199 let mut spi_hdr = SpiHeader(0);
200 spi_hdr.set_control(true);
201 spi_hdr.set_addr(sr::RX);
202 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice());
203
204 if self.crc {
205 // Add CRC for header data
206 let _ = tx_buf.push(crc8(&tx_buf));
207 }
208
209 // Turn around byte, TODO: Unknown that this is.
210 let _ = tx_buf.push(TURN_AROUND_BYTE);
211
212 let spi_packet = &mut packet[0..read_size as usize];
213
214 assert_eq!(spi_packet.len() & 0x03, 0x00);
215
216 let mut pkt_header = [0, 0];
217
218 let mut spi_op = [
219 Operation::Write(&tx_buf),
220 Operation::Read(&mut pkt_header),
221 Operation::Read(spi_packet),
222 ];
223
224 self.spi.transaction(&mut spi_op).await.map_err(AdinError::Spi)?;
225
226 Ok(packet_size as usize)
227 }
228
229 pub async fn write_fifo(&mut self, frame: &[u8]) -> AEResult<(), SpiE> {
230 let header_len = self.header_write_len();
231 // if packet.len() < header_len {
232 // return Err(AdinError::PACKET_TOO_SMALL);
233 // }
234
235 let mut packet = Packet::new();
236
237 let mut spi_hdr = SpiHeader(0);
238 spi_hdr.set_control(true);
239 spi_hdr.set_write(true);
240 spi_hdr.set_addr(sr::TX);
241
242 packet
243 .extend_from_slice(spi_hdr.0.to_be_bytes().as_slice())
244 .map_err(|_| AdinError::PACKET_TOO_BIG)?;
245
246 if self.crc {
247 assert_eq!(header_len, 5);
248 // Add CRC for header data
249 packet
250 .push(crc8(&packet[0..2]))
251 .map_err(|_| AdinError::PACKET_TOO_BIG)?;
252 }
253
254 // Add port number
255 // packet[header_len - FRAME_HEADER_LEN..header_len]
256 // .copy_from_slice(u16::from(PORT_ID_BYTE).to_be_bytes().as_slice());
257 packet
258 .extend_from_slice(u16::from(PORT_ID_BYTE).to_be_bytes().as_slice())
259 .map_err(|_| AdinError::PACKET_TOO_BIG)?;
260
261 packet.extend_from_slice(frame).map_err(|_| AdinError::PACKET_TOO_BIG)?;
262
263 // Pad data up to 64
264 for _ in packet.len()..(64 - FEC_LEN + header_len) {
265 let _ = packet.push(0x00);
266 }
267
268 // // add ethernet crc32
269 let crc = ETH_FSC::new(&packet[header_len..]);
270 let _ = packet.extend_from_slice(crc.hton_bytes().as_slice());
271
272 let crc = ETH_FSC::new(&packet[header_len..]);
273 assert!(crc.crc_ok());
274
275 let send_len = packet.len() - header_len + FRAME_HEADER_LEN;
276
277 // Packet read of write to the MAC packet buffer must be a multipul of 4!
278 while packet.len() & 0x3 != 0 {
279 let _ = packet.push(DONT_CARE_BYTE);
280 }
281
282 #[cfg(feature = "defmt")]
283 defmt::trace!(
284 "TX: hdr {} [{}] {:02x} SIZE: {}",
285 header_len,
286 packet.len(),
287 &packet,
288 send_len,
289 );
290
291 self.write_reg(sr::TX_FSIZE, send_len as u32).await?;
292
293 // Spi packet must be half word / even length
294 if send_len & 1 != 0 {
295 let _ = packet.push(0x00);
296 }
297
298 self.spi.write(&packet).await.map_err(AdinError::Spi)
299 }
300
301 pub fn header_write_len(&self) -> usize {
302 // u16 + [CRC] + PORT
303 WR_HEADER_LEN + FRAME_HEADER_LEN + usize::from(self.crc)
304 }
305
306 pub fn header_len_read(&self) -> usize {
307 // u16 + [CRC] + u8
308 WR_HEADER_LEN + 1 + usize::from(self.crc)
309 }
310
311 /// Programs the mac address in the mac filters.
312 /// Also set the boardcast address.
313 /// The chip supports 2 priority queues but current code doesn't support this mode.
314 pub async fn set_mac_addr(&mut self, mac: &[u8; 6]) -> AEResult<(), SpiE> {
315 let mac_high_part = u16::from_be_bytes(mac[0..2].try_into().unwrap());
316 let mac_low_part = u32::from_be_bytes(mac[2..6].try_into().unwrap());
317
318 // program our mac address in the mac address filter
319 self.write_reg(sr::ADDR_FILT_UPR0, (1 << 16) | (1 << 30) | u32::from(mac_high_part))
320 .await?;
321 self.write_reg(sr::ADDR_FILT_LWR0, mac_low_part).await?;
322
323 self.write_reg(sr::ADDR_MSK_UPR0, u32::from(mac_high_part)).await?;
324 self.write_reg(sr::ADDR_MSK_LWR0, mac_low_part).await?;
325
326 // Also program broadcast address in the mac address filter
327 self.write_reg(sr::ADDR_FILT_UPR1, (1 << 16) | (1 << 30) | 0xFFFF)
328 .await?;
329 self.write_reg(sr::ADDR_FILT_LWR1, 0xFFFF_FFFF).await?;
330 self.write_reg(sr::ADDR_MSK_UPR1, 0xFFFF).await?;
331 self.write_reg(sr::ADDR_MSK_LWR1, 0xFFFF_FFFF).await?;
332
333 Ok(())
334 }
335}
336
337impl<SpiE, SPI> mdio::MdioBus for ADIN1110<SPI>
338where
339 SPI: SpiDevice<u8, Error = SpiE>,
340 SpiE: core::fmt::Debug,
341{
342 type Error = AdinError<SpiE>;
343
344 /// Read from the PHY Registers as Clause 22.
345 async fn read_cl22(&mut self, phy_id: u8, reg: u8) -> Result<u16, Self::Error> {
346 let mdio_acc_val: u32 =
347 (0x1 << 28) | u32::from(phy_id & 0x1F) << 21 | u32::from(reg & 0x1F) << 16 | (0x3 << 26);
348
349 self.write_mdio_acc_reg(mdio_acc_val).await.map(|val| val as u16)
350 }
351
352 /// Read from the PHY Registers as Clause 45.
353 async fn read_cl45(&mut self, phy_id: u8, regc45: (u8, u16)) -> Result<u16, Self::Error> {
354 let mdio_acc_val: u32 = u32::from(phy_id & 0x1F) << 21 | u32::from(regc45.0 & 0x1F) << 16 | u32::from(regc45.1);
355
356 self.write_mdio_acc_reg(mdio_acc_val).await?;
357
358 let mdio_acc_val: u32 = u32::from(phy_id & 0x1F) << 21 | u32::from(regc45.0 & 0x1F) << 16 | (0x03 << 26);
359
360 self.write_mdio_acc_reg(mdio_acc_val).await.map(|val| val as u16)
361 }
362
363 /// Write to the PHY Registers as Clause 22.
364 async fn write_cl22(&mut self, phy_id: u8, reg: u8, val: u16) -> Result<(), Self::Error> {
365 let mdio_acc_val: u32 =
366 (0x1 << 28) | u32::from(phy_id & 0x1F) << 21 | u32::from(reg & 0x1F) << 16 | (0x1 << 26) | u32::from(val);
367
368 self.write_mdio_acc_reg(mdio_acc_val).await.map(|_| ())
369 }
370
371 /// Write to the PHY Registers as Clause 45.
372 async fn write_cl45(&mut self, phy_id: u8, regc45: (u8, u16), value: u16) -> AEResult<(), SpiE> {
373 let phy_id = u32::from(phy_id & 0x1F) << 21;
374 let dev_addr = u32::from(regc45.0 & 0x1F) << 16;
375 let reg = u32::from(regc45.1);
376
377 let mdio_acc_val: u32 = phy_id | dev_addr | reg;
378 self.write_mdio_acc_reg(mdio_acc_val).await?;
379
380 let mdio_acc_val: u32 = phy_id | dev_addr | (0x01 << 26) | u32::from(value);
381 self.write_mdio_acc_reg(mdio_acc_val).await.map(|_| ())
382 }
383}
384
385/// Background runner for the ADIN110.
386///
387/// You must call `.run()` in a background task for the ADIN1100 to operate.
388pub struct Runner<'d, SPI, INT, RST> {
389 mac: ADIN1110<SPI>,
390 ch: ch::Runner<'d, MTU>,
391 int: INT,
392 is_link_up: bool,
393 _reset: RST,
394}
395
396impl<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, SPI, INT, RST> {
397 pub async fn run(mut self) -> ! {
398 loop {
399 let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split();
400
401 loop {
402 #[cfg(feature = "defmt")]
403 defmt::debug!("Waiting for interrupts");
404 match select(self.int.wait_for_low(), tx_chan.tx_buf()).await {
405 Either::First(_) => {
406 let mut status1_clr = Status1(0);
407 let mut status1 = Status1(self.mac.read_reg(sr::STATUS1).await.unwrap());
408
409 while status1.p1_rx_rdy() {
410 #[cfg(feature = "defmt")]
411 defmt::debug!("alloc RX packet buffer");
412 match select(rx_chan.rx_buf(), tx_chan.tx_buf()).await {
413 // Handle frames that needs to transmit from the wire.
414 // Note: rx_chan.rx_buf() channel don´t accept new request
415 // when the tx_chan is full. So these will be handled
416 // automaticly.
417 Either::First(frame) => match self.mac.read_fifo(frame).await {
418 Ok(n) => {
419 rx_chan.rx_done(n);
420 }
421 Err(e) => match e {
422 AdinError::PACKET_TOO_BIG => {
423 #[cfg(feature = "defmt")]
424 defmt::error!("RX Packet to big, DROP");
425 self.mac.write_reg(sr::FIFO_CLR, 1).await.unwrap();
426 }
427 AdinError::Spi(_) => {
428 #[cfg(feature = "defmt")]
429 defmt::error!("RX Spi error")
430 }
431 _ => {
432 #[cfg(feature = "defmt")]
433 defmt::error!("RX Error")
434 }
435 },
436 },
437 Either::Second(frame) => {
438 // Handle frames that needs to transmit to the wire.
439 self.mac.write_fifo(frame).await.unwrap();
440 tx_chan.tx_done();
441 }
442 }
443 status1 = Status1(self.mac.read_reg(sr::STATUS1).await.unwrap());
444 }
445
446 let status0 = Status0(self.mac.read_reg(sr::STATUS0).await.unwrap());
447 if status1.0 & !0x1b != 0 {
448 #[cfg(feature = "defmt")]
449 defmt::error!("SPE CHIP STATUS 0:{:08x} 1:{:08x}", status0.0, status1.0);
450 }
451
452 if status1.tx_rdy() {
453 status1_clr.set_tx_rdy(true);
454 #[cfg(feature = "defmt")]
455 defmt::info!("TX_DONE");
456 }
457
458 if status1.link_change() {
459 let link = status1.p1_link_status();
460 self.is_link_up = link;
461
462 #[cfg(feature = "defmt")]
463 if link {
464 let link_status = self
465 .mac
466 .read_cl45(MDIO_PHY_ADDR, RegsC45::DA7::AN_STATUS_EXTRA.into())
467 .await
468 .unwrap();
469
470 let volt = if link_status & (0b11 << 5) == (0b11 << 5) {
471 "2.4"
472 } else {
473 "1.0"
474 };
475
476 let mse = self
477 .mac
478 .read_cl45(MDIO_PHY_ADDR, RegsC45::DA1::MSE_VAL.into())
479 .await
480 .unwrap();
481
482 defmt::info!("LINK Changed: Link Up, Volt: {} V p-p, MSE: {:0004}", volt, mse);
483 } else {
484 defmt::info!("LINK Changed: Link Down");
485 }
486
487 state_chan.set_link_state(if link { LinkState::Up } else { LinkState::Down });
488 status1_clr.set_link_change(true);
489 }
490
491 if status1.tx_ecc_err() {
492 #[cfg(feature = "defmt")]
493 defmt::error!("SPI TX_ECC_ERR error, CLEAR TX FIFO");
494 self.mac.write_reg(sr::FIFO_CLR, 2).await.unwrap();
495 status1_clr.set_tx_ecc_err(true);
496 }
497
498 if status1.rx_ecc_err() {
499 #[cfg(feature = "defmt")]
500 defmt::error!("SPI RX_ECC_ERR error");
501 status1_clr.set_rx_ecc_err(true);
502 }
503
504 if status1.spi_err() {
505 #[cfg(feature = "defmt")]
506 defmt::error!("SPI SPI_ERR CRC error");
507 status1_clr.set_spi_err(true);
508 }
509
510 if status0.phyint() {
511 let crsm_irq_st = self
512 .mac
513 .read_cl45(MDIO_PHY_ADDR, RegsC45::DA1E::CRSM_IRQ_STATUS.into())
514 .await
515 .unwrap();
516
517 let phy_irq_st = self
518 .mac
519 .read_cl45(MDIO_PHY_ADDR, RegsC45::DA1F::PHY_SYBSYS_IRQ_STATUS.into())
520 .await
521 .unwrap();
522 #[cfg(feature = "defmt")]
523 defmt::warn!(
524 "SPE CHIP PHY CRSM_IRQ_STATUS {:04x} PHY_SUBSYS_IRQ_STATUS {:04x}",
525 crsm_irq_st,
526 phy_irq_st
527 );
528 }
529
530 if status0.txfcse() {
531 #[cfg(feature = "defmt")]
532 defmt::error!("SPE CHIP PHY TX Frame CRC error");
533 }
534
535 // Clear status0
536 self.mac.write_reg(sr::STATUS0, 0xFFF).await.unwrap();
537 self.mac.write_reg(sr::STATUS1, status1_clr.0).await.unwrap();
538 }
539 Either::Second(packet) => {
540 // Handle frames that needs to transmit to the wire.
541 self.mac.write_fifo(packet).await.unwrap();
542 tx_chan.tx_done();
543 }
544 }
545 }
546 }
547 }
548}
549
550/// Obtain a driver for using the ADIN1110 with [`embassy-net`](crates.io/crates/embassy-net).
551pub async fn new<const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait, RST: OutputPin>(
552 mac_addr: [u8; 6],
553 state: &'_ mut State<N_RX, N_TX>,
554 spi_dev: SPI,
555 int: INT,
556 mut reset: RST,
557 crc: bool,
558) -> (Device<'_>, Runner<'_, SPI, INT, RST>) {
559 use crate::regs::{IMask0, IMask1};
560
561 #[cfg(feature = "defmt")]
562 defmt::info!("INIT ADIN1110");
563
564 // Reset sequence
565 reset.set_low().unwrap();
566 // Wait t1: 20-43mS
567 Timer::after(Duration::from_millis(30)).await;
568
569 reset.set_high().unwrap();
570
571 // Wait t3: 50mS
572 Timer::after(Duration::from_millis(50)).await;
573
574 // Create device
575 let mut mac = ADIN1110::new(spi_dev, crc);
576
577 // Check PHYID
578 let id = mac.read_reg(sr::PHYID).await.unwrap();
579 assert_eq!(id, PHYID);
580
581 #[cfg(feature = "defmt")]
582 defmt::debug!("SPE: CHIP MAC/ID: {:08x}", id);
583
584 #[cfg(feature = "defmt")]
585 let adin_phy = Phy10BaseT1x::default();
586 #[cfg(feature = "defmt")]
587 let phy_id = adin_phy.get_id(&mut mac).await.unwrap();
588 #[cfg(feature = "defmt")]
589 defmt::debug!("SPE: CHIP: PHY ID: {:08x}", phy_id);
590
591 let mi_control = mac.read_cl22(MDIO_PHY_ADDR, RegsC22::CONTROL as u8).await.unwrap();
592 #[cfg(feature = "defmt")]
593 defmt::println!("SPE CHIP PHY MI_CONTROL {:04x}", mi_control);
594 if mi_control & 0x0800 != 0 {
595 let val = mi_control & !0x0800;
596 #[cfg(feature = "defmt")]
597 defmt::println!("SPE CHIP PHY MI_CONTROL Disable PowerDown");
598 mac.write_cl22(MDIO_PHY_ADDR, RegsC22::CONTROL as u8, val)
599 .await
600 .unwrap();
601 }
602
603 // Config2: CRC_APPEND
604 let mut config2 = Config2(0x00000800);
605 config2.set_crc_append(true);
606 mac.write_reg(sr::CONFIG2, config2.0).await.unwrap();
607
608 // Pin Mux Config 1
609 let led_val = (0b11 << 6) | (0b11 << 4); // | (0b00 << 1);
610 mac.write_cl45(MDIO_PHY_ADDR, RegsC45::DA1E::DIGIO_PINMUX.into(), led_val)
611 .await
612 .unwrap();
613
614 let mut led_pol = LedPolarity(0);
615 led_pol.set_led1_polarity(LedPol::ActiveLow);
616 led_pol.set_led0_polarity(LedPol::ActiveLow);
617
618 // Led Polarity Regisgere Active Low
619 mac.write_cl45(MDIO_PHY_ADDR, RegsC45::DA1E::LED_POLARITY.into(), led_pol.0)
620 .await
621 .unwrap();
622
623 // Led Both On
624 let mut led_cntr = LedCntrl(0x0);
625
626 // LED1: Yellow
627 led_cntr.set_led1_en(true);
628 led_cntr.set_led1_function(LedFunc::TxLevel2P4);
629 // LED0: Green
630 led_cntr.set_led0_en(true);
631 led_cntr.set_led0_function(LedFunc::LinkupTxRxActicity);
632
633 mac.write_cl45(MDIO_PHY_ADDR, RegsC45::DA1E::LED_CNTRL.into(), led_cntr.0)
634 .await
635 .unwrap();
636
637 // Set ADIN1110 Interrupts, RX_READY and LINK_CHANGE
638 // Enable interrupts LINK_CHANGE, TX_RDY, RX_RDY(P1), SPI_ERR
639 // Have to clear the mask the enable it.
640 let mut imask0_val = IMask0(0x0000_1FBF);
641 imask0_val.set_txfcsem(false);
642 imask0_val.set_phyintm(false);
643 imask0_val.set_txboem(false);
644 imask0_val.set_rxboem(false);
645 imask0_val.set_txpem(false);
646
647 mac.write_reg(sr::IMASK0, imask0_val.0).await.unwrap();
648
649 // Set ADIN1110 Interrupts, RX_READY and LINK_CHANGE
650 // Enable interrupts LINK_CHANGE, TX_RDY, RX_RDY(P1), SPI_ERR
651 // Have to clear the mask the enable it.
652 let mut imask1_val = IMask1(0x43FA_1F1A);
653 imask1_val.set_link_change_mask(false);
654 imask1_val.set_p1_rx_rdy_mask(false);
655 imask1_val.set_spi_err_mask(false);
656 imask1_val.set_tx_ecc_err_mask(false);
657 imask1_val.set_rx_ecc_err_mask(false);
658
659 mac.write_reg(sr::IMASK1, imask1_val.0).await.unwrap();
660
661 // Program mac address but also sets mac filters.
662 mac.set_mac_addr(&mac_addr).await.unwrap();
663
664 let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr));
665 (
666 device,
667 Runner {
668 ch: runner,
669 mac,
670 int,
671 is_link_up: false,
672 _reset: reset,
673 },
674 )
675}
676
677#[cfg(test)]
678mod tests {
679 use core::convert::Infallible;
680
681 use embedded_hal_1::digital::{ErrorType, OutputPin};
682 use embedded_hal_async::delay::DelayUs;
683 use embedded_hal_bus::spi::ExclusiveDevice;
684 use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
685
686 #[derive(Debug, Default)]
687 struct CsPinMock {
688 pub high: u32,
689 pub low: u32,
690 }
691 impl OutputPin for CsPinMock {
692 fn set_low(&mut self) -> Result<(), Self::Error> {
693 self.low += 1;
694 Ok(())
695 }
696
697 fn set_high(&mut self) -> Result<(), Self::Error> {
698 self.high += 1;
699 Ok(())
700 }
701 }
702 impl ErrorType for CsPinMock {
703 type Error = Infallible;
704 }
705
706 use super::*;
707
708 // TODO: This is currently a workaround unit `ExclusiveDevice` is moved to `embedded-hal-bus`
709 // see https://github.com/rust-embedded/embedded-hal/pull/462#issuecomment-1560014426
710 struct MockDelay {}
711
712 impl DelayUs for MockDelay {
713 async fn delay_us(&mut self, _us: u32) {
714 todo!()
715 }
716
717 async fn delay_ms(&mut self, _ms: u32) {
718 todo!()
719 }
720 }
721
722 #[futures_test::test]
723 async fn mac_read_registers_without_crc() {
724 // Configure expectations
725 let expectations = [
726 // 1st
727 SpiTransaction::write_vec(vec![0x80, 0x01, TURN_AROUND_BYTE]),
728 SpiTransaction::read_vec(vec![0x02, 0x83, 0xBC, 0x91]),
729 SpiTransaction::flush(),
730 // 2nd
731 SpiTransaction::write_vec(vec![0x80, 0x02, TURN_AROUND_BYTE]),
732 SpiTransaction::read_vec(vec![0x00, 0x00, 0x06, 0xC3]),
733 SpiTransaction::flush(),
734 ];
735 let mut spi = SpiMock::new(&expectations);
736
737 let cs = CsPinMock::default();
738 let delay = MockDelay {};
739 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
740 let mut spe = ADIN1110::new(spi_dev, false);
741
742 // Read PHIID
743 match spe.read_reg(sr::PHYID).await {
744 Ok(val) => assert_eq!(val, 0x0283BC91),
745 Err(_e) => panic!("Error:"),
746 };
747
748 // Read CAPAVILITY
749 match spe.read_reg(sr::CAPABILITY).await {
750 Ok(val) => assert_eq!(val, 0x000006C3),
751 Err(_e) => panic!("Error:"),
752 };
753
754 spi.done();
755 }
756
757 #[futures_test::test]
758 async fn mac_read_registers_with_crc() {
759 // Configure expectations
760 let expectations = [
761 // 1st
762 SpiTransaction::write_vec(vec![0x80, 0x01, 177, TURN_AROUND_BYTE]),
763 SpiTransaction::read_vec(vec![0x02, 0x83, 0xBC, 0x91, 215]),
764 SpiTransaction::flush(),
765 // 2nd
766 SpiTransaction::write_vec(vec![0x80, 0x02, 184, TURN_AROUND_BYTE]),
767 SpiTransaction::read_vec(vec![0x00, 0x00, 0x06, 0xC3, 57]),
768 SpiTransaction::flush(),
769 ];
770 let mut spi = SpiMock::new(&expectations);
771
772 let cs = CsPinMock::default();
773 let delay = MockDelay {};
774 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
775
776 let mut spe = ADIN1110::new(spi_dev, true);
777
778 assert_eq!(crc8(0x0283BC91_u32.to_be_bytes().as_slice()), 215);
779 assert_eq!(crc8(0x000006C3_u32.to_be_bytes().as_slice()), 57);
780
781 // Read PHIID
782 match spe.read_reg(sr::PHYID).await {
783 Ok(val) => assert_eq!(val, 0x0283BC91),
784 Err(e) => panic!("Error: {e:?}"),
785 };
786
787 // Read CAPAVILITY
788 match spe.read_reg(sr::CAPABILITY).await {
789 Ok(val) => assert_eq!(val, 0x000006C3),
790 Err(_e) => panic!("Error:"),
791 };
792
793 spi.done();
794 }
795
796 #[futures_test::test]
797 async fn mac_write_registers_without_crc() {
798 // Configure expectations
799 let expectations = [
800 SpiTransaction::write_vec(vec![0xA0, 0x09, 0x12, 0x34, 0x56, 0x78]),
801 SpiTransaction::flush(),
802 ];
803 let mut spi = SpiMock::new(&expectations);
804
805 let cs = CsPinMock::default();
806 let delay = MockDelay {};
807 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
808
809 let mut spe = ADIN1110::new(spi_dev, false);
810
811 // Write reg: 0x1FFF
812 assert!(spe.write_reg(sr::STATUS1, 0x1234_5678).await.is_ok());
813
814 spi.done();
815 }
816
817 #[futures_test::test]
818 async fn mac_write_registers_with_crc() {
819 // Configure expectations
820 let expectations = [
821 SpiTransaction::write_vec(vec![0xA0, 0x09, 39, 0x12, 0x34, 0x56, 0x78, 28]),
822 SpiTransaction::flush(),
823 ];
824 let mut spi = SpiMock::new(&expectations);
825
826 let cs = CsPinMock::default();
827 let delay = MockDelay {};
828 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
829
830 let mut spe = ADIN1110::new(spi_dev, true);
831
832 // Write reg: 0x1FFF
833 assert!(spe.write_reg(sr::STATUS1, 0x1234_5678).await.is_ok());
834
835 spi.done();
836 }
837
838 #[test]
839 fn align_size() {
840 assert_eq!(size_align_u32(1), 4);
841 assert_eq!(size_align_u32(2), 4);
842 assert_eq!(size_align_u32(3), 4);
843 assert_eq!(size_align_u32(4), 4);
844 assert_eq!(size_align_u32(5), 8);
845 assert_eq!(size_align_u32(6), 8);
846 assert_eq!(size_align_u32(7), 8);
847 assert_eq!(size_align_u32(8), 8);
848 }
849
850 // #[test]
851 // fn write_packet_to_fifo_less_64b_with_crc() {
852 // // Configure expectations
853 // let mut expectations = vec![
854 // // HEADER
855 // SpiTransaction::send(0xA0),
856 // SpiTransaction::read(DONT_CARE_BYTE),
857 // SpiTransaction::send(0x30),
858 // SpiTransaction::read(DONT_CARE_BYTE),
859 // SpiTransaction::send(136),
860 // SpiTransaction::read(DONT_CARE_BYTE),
861 // // Frame Size
862 // SpiTransaction::send(0x00),
863 // SpiTransaction::read(DONT_CARE_BYTE),
864 // SpiTransaction::send(0x00),
865 // SpiTransaction::read(DONT_CARE_BYTE),
866 // SpiTransaction::send(0x00),
867 // SpiTransaction::read(DONT_CARE_BYTE),
868 // SpiTransaction::send(66),
869 // SpiTransaction::read(DONT_CARE_BYTE),
870 // SpiTransaction::send(201),
871 // SpiTransaction::read(DONT_CARE_BYTE),
872 // // HEADER
873 // SpiTransaction::send(0xA0),
874 // SpiTransaction::read(DONT_CARE_BYTE),
875 // SpiTransaction::send(0x31),
876 // SpiTransaction::read(DONT_CARE_BYTE),
877 // // Port
878 // SpiTransaction::send(0x00),
879 // SpiTransaction::read(DONT_CARE_BYTE),
880 // SpiTransaction::send(PORT_ID_BYTE),
881 // SpiTransaction::read(DONT_CARE_BYTE),
882 // ];
883
884 // let mut packet = Packet::new();
885 // packet.resize(64, 0).unwrap();
886
887 // for &byte in &packet[4..] {
888 // expectations.push(SpiTransaction::send(byte));
889 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
890 // }
891
892 // // padding
893 // for _ in packet.len() as u32..65 {
894 // expectations.push(SpiTransaction::send(0x00));
895 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
896 // }
897
898 // // fcs
899 // for &byte in &[8, 137, 18, 4] {
900 // expectations.push(SpiTransaction::send(byte));
901 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
902 // }
903
904 // let spi = SpiMock::new(&expectations);
905
906 // let cs = CsPinMock {};
907 // let mut spe = Adin1110::new(spi, cs, true);
908
909 // assert!(spe.write_fifo(&mut packet).is_ok());
910 // }
911
912 // #[test]
913 // fn write_packet_to_fifo_less_64b_no_crc() {
914 // // Configure expectations
915 // let mut expectations = vec![
916 // // HEADER
917 // SpiTransaction::send(0xA0),
918 // SpiTransaction::read(DONT_CARE_BYTE),
919 // SpiTransaction::send(0x30),
920 // SpiTransaction::read(DONT_CARE_BYTE),
921 // // Frame Size
922 // SpiTransaction::send(0x00),
923 // SpiTransaction::read(DONT_CARE_BYTE),
924 // SpiTransaction::send(0x00),
925 // SpiTransaction::read(DONT_CARE_BYTE),
926 // SpiTransaction::send(0x00),
927 // SpiTransaction::read(DONT_CARE_BYTE),
928 // SpiTransaction::send(66),
929 // SpiTransaction::read(DONT_CARE_BYTE),
930 // // HEADER
931 // SpiTransaction::send(0xA0),
932 // SpiTransaction::read(DONT_CARE_BYTE),
933 // SpiTransaction::send(0x31),
934 // SpiTransaction::read(DONT_CARE_BYTE),
935 // // Port
936 // SpiTransaction::send(0x00),
937 // SpiTransaction::read(DONT_CARE_BYTE),
938 // SpiTransaction::send(PORT_ID_BYTE),
939 // SpiTransaction::read(DONT_CARE_BYTE),
940 // ];
941
942 // let mut packet = Packet::new();
943 // packet.resize(64, 0).unwrap();
944
945 // for &byte in &packet[4..] {
946 // expectations.push(SpiTransaction::send(byte));
947 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
948 // }
949
950 // // padding
951 // for _ in packet.len() as u32..64 {
952 // expectations.push(SpiTransaction::send(0x00));
953 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
954 // }
955
956 // // fcs
957 // for &byte in &[8, 137, 18, 4] {
958 // expectations.push(SpiTransaction::send(byte));
959 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
960 // }
961
962 // let spi = SpiMock::new(&expectations);
963
964 // let cs = CsPinMock {};
965 // let mut spe = Adin1110::new(spi, cs, false);
966
967 // assert!(spe.write_fifo(&mut packet).is_ok());
968 // }
969
970 // #[test]
971 // fn write_packet_to_fifo_1500b() {
972 // // Configure expectations
973 // let mut expectations = vec![
974 // // HEADER
975 // SpiTransaction::send(0xA0),
976 // SpiTransaction::read(DONT_CARE_BYTE),
977 // SpiTransaction::send(0x30),
978 // SpiTransaction::read(DONT_CARE_BYTE),
979 // // Frame Size
980 // SpiTransaction::send(0x00),
981 // SpiTransaction::read(DONT_CARE_BYTE),
982 // SpiTransaction::send(0x00),
983 // SpiTransaction::read(DONT_CARE_BYTE),
984 // SpiTransaction::send(0x05),
985 // SpiTransaction::read(DONT_CARE_BYTE),
986 // SpiTransaction::send(0xDE),
987 // SpiTransaction::read(DONT_CARE_BYTE),
988 // // HEADER
989 // SpiTransaction::send(0xA0),
990 // SpiTransaction::read(DONT_CARE_BYTE),
991 // SpiTransaction::send(0x31),
992 // SpiTransaction::read(DONT_CARE_BYTE),
993 // // Port
994 // SpiTransaction::send(0x00),
995 // SpiTransaction::read(DONT_CARE_BYTE),
996 // SpiTransaction::send(PORT_ID_BYTE),
997 // SpiTransaction::read(DONT_CARE_BYTE),
998 // ];
999
1000 // let mut packet = Packet::new();
1001 // packet.resize(1500, 0).unwrap();
1002
1003 // for &byte in &packet[4..] {
1004 // expectations.push(SpiTransaction::send(byte));
1005 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1006 // }
1007
1008 // // fcs
1009 // for &byte in &[212, 114, 18, 50] {
1010 // expectations.push(SpiTransaction::send(byte));
1011 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1012 // }
1013
1014 // let spi = SpiMock::new(&expectations);
1015
1016 // let cs = CsPinMock {};
1017 // let mut spe = Adin1110::new(spi, cs, false);
1018
1019 // assert!(spe.write_fifo(&mut packet).is_ok());
1020 // }
1021
1022 // #[test]
1023 // fn write_packet_to_fifo_65b() {
1024 // // Configure expectations
1025 // let mut expectations = vec![
1026 // // HEADER
1027 // SpiTransaction::send(0xA0),
1028 // SpiTransaction::read(DONT_CARE_BYTE),
1029 // SpiTransaction::send(0x30),
1030 // SpiTransaction::read(DONT_CARE_BYTE),
1031 // // Frame Size
1032 // SpiTransaction::send(0x00),
1033 // SpiTransaction::read(DONT_CARE_BYTE),
1034 // SpiTransaction::send(0x00),
1035 // SpiTransaction::read(DONT_CARE_BYTE),
1036 // SpiTransaction::send(0x00),
1037 // SpiTransaction::read(DONT_CARE_BYTE),
1038 // SpiTransaction::send(67),
1039 // SpiTransaction::read(DONT_CARE_BYTE),
1040 // // HEADER
1041 // SpiTransaction::send(0xA0),
1042 // SpiTransaction::read(DONT_CARE_BYTE),
1043 // SpiTransaction::send(0x31),
1044 // SpiTransaction::read(DONT_CARE_BYTE),
1045 // // Port
1046 // SpiTransaction::send(0x00),
1047 // SpiTransaction::read(DONT_CARE_BYTE),
1048 // SpiTransaction::send(PORT_ID_BYTE),
1049 // SpiTransaction::read(DONT_CARE_BYTE),
1050 // ];
1051
1052 // let mut packet = Packet::new();
1053 // packet.resize(65, 0).unwrap();
1054
1055 // for &byte in &packet[4..] {
1056 // expectations.push(SpiTransaction::send(byte));
1057 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1058 // }
1059
1060 // // padding
1061 // for _ in packet.len() as u32..64 {
1062 // expectations.push(SpiTransaction::send(0x00));
1063 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1064 // }
1065
1066 // // fcs
1067 // for &byte in &[54, 117, 221, 220] {
1068 // expectations.push(SpiTransaction::send(byte));
1069 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1070 // }
1071
1072 // let spi = SpiMock::new(&expectations);
1073
1074 // let cs = CsPinMock {};
1075 // let mut spe = Adin1110::new(spi, cs, false);
1076
1077 // assert!(spe.write_fifo(&mut packet).is_ok());
1078 // }
1079
1080 // #[test]
1081 // fn write_packet_to_fifo_66b() {
1082 // // Configure expectations
1083 // let mut expectations = vec![
1084 // // HEADER
1085 // SpiTransaction::send(0xA0),
1086 // SpiTransaction::read(DONT_CARE_BYTE),
1087 // SpiTransaction::send(0x30),
1088 // SpiTransaction::read(DONT_CARE_BYTE),
1089 // // Frame Size
1090 // SpiTransaction::send(0x00),
1091 // SpiTransaction::read(DONT_CARE_BYTE),
1092 // SpiTransaction::send(0x00),
1093 // SpiTransaction::read(DONT_CARE_BYTE),
1094 // SpiTransaction::send(0x00),
1095 // SpiTransaction::read(DONT_CARE_BYTE),
1096 // SpiTransaction::send(68),
1097 // SpiTransaction::read(DONT_CARE_BYTE),
1098 // // HEADER
1099 // SpiTransaction::send(0xA0),
1100 // SpiTransaction::read(DONT_CARE_BYTE),
1101 // SpiTransaction::send(0x31),
1102 // SpiTransaction::read(DONT_CARE_BYTE),
1103 // // Port
1104 // SpiTransaction::send(0x00),
1105 // SpiTransaction::read(DONT_CARE_BYTE),
1106 // SpiTransaction::send(PORT_ID_BYTE),
1107 // SpiTransaction::read(DONT_CARE_BYTE),
1108 // ];
1109
1110 // let mut packet = Packet::new();
1111 // packet.resize(66, 0).unwrap();
1112
1113 // for &byte in &packet[4..] {
1114 // expectations.push(SpiTransaction::send(byte));
1115 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1116 // }
1117
1118 // // padding
1119 // for _ in packet.len() as u32..64 {
1120 // expectations.push(SpiTransaction::send(0x00));
1121 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1122 // }
1123
1124 // // fcs
1125 // for &byte in &[97, 167, 100, 29] {
1126 // expectations.push(SpiTransaction::send(byte));
1127 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1128 // }
1129 // let spi = SpiMock::new(&expectations);
1130
1131 // let cs = CsPinMock {};
1132 // let mut spe = Adin1110::new(spi, cs, false);
1133
1134 // assert!(spe.write_fifo(&mut packet).is_ok());
1135 // }
1136
1137 // #[test]
1138 // fn write_packet_to_fifo_67b() {
1139 // // Configure expectations
1140 // let mut expectations = vec![
1141 // // HEADER
1142 // SpiTransaction::send(0xA0),
1143 // SpiTransaction::read(DONT_CARE_BYTE),
1144 // SpiTransaction::send(0x30),
1145 // SpiTransaction::read(DONT_CARE_BYTE),
1146 // // Frame Size
1147 // SpiTransaction::send(0x00),
1148 // SpiTransaction::read(DONT_CARE_BYTE),
1149 // SpiTransaction::send(0x00),
1150 // SpiTransaction::read(DONT_CARE_BYTE),
1151 // SpiTransaction::send(0x00),
1152 // SpiTransaction::read(DONT_CARE_BYTE),
1153 // SpiTransaction::send(69),
1154 // SpiTransaction::read(DONT_CARE_BYTE),
1155 // // HEADER
1156 // SpiTransaction::send(0xA0),
1157 // SpiTransaction::read(DONT_CARE_BYTE),
1158 // SpiTransaction::send(0x31),
1159 // SpiTransaction::read(DONT_CARE_BYTE),
1160 // // Port
1161 // SpiTransaction::send(0x00),
1162 // SpiTransaction::read(DONT_CARE_BYTE),
1163 // SpiTransaction::send(PORT_ID_BYTE),
1164 // SpiTransaction::read(DONT_CARE_BYTE),
1165 // ];
1166
1167 // let mut packet = Packet::new();
1168 // packet.resize(67, 0).unwrap();
1169
1170 // for &byte in &packet[4..] {
1171 // expectations.push(SpiTransaction::send(byte));
1172 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1173 // }
1174
1175 // // padding
1176 // for _ in packet.len() as u32..64 {
1177 // expectations.push(SpiTransaction::send(0x00));
1178 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1179 // }
1180
1181 // // fcs
1182 // for &byte in &[228, 218, 170, 232] {
1183 // expectations.push(SpiTransaction::send(byte));
1184 // expectations.push(SpiTransaction::read(DONT_CARE_BYTE));
1185 // }
1186 // let spi = SpiMock::new(&expectations);
1187
1188 // let cs = CsPinMock {};
1189 // let mut spe = Adin1110::new(spi, cs, false);
1190
1191 // assert!(spe.write_fifo(&mut packet).is_ok());
1192 // }
1193
1194 #[futures_test::test]
1195 async fn write_packet_to_fifo_arp_46bytes() {
1196 // Configure expectations
1197 let mut expectations = vec![];
1198
1199 let mut packet = Packet::new();
1200 //arp packet;
1201 packet
1202 .extend_from_slice(&[
1203 34, 51, 68, 85, 102, 119, 18, 52, 86, 120, 154, 188, 8, 6, 0, 1, 8, 0, 6, 4, 0, 2, 18, 52, 86, 120,
1204 154, 188, 192, 168, 16, 4, 34, 51, 68, 85, 102, 119, 192, 168, 16, 1,
1205 ])
1206 .unwrap();
1207
1208 let mut spi_packet = Packet::new();
1209
1210 // Write TX_SIZE reg
1211 expectations.push(SpiTransaction::write_vec(vec![160, 48, 136, 0, 0, 0, 66, 201]));
1212 expectations.push(SpiTransaction::flush());
1213
1214 // Write TX reg.
1215 // Header
1216 spi_packet.extend_from_slice(&[160, 49, 143, 0, 0]).unwrap();
1217 // Packet data
1218 spi_packet.extend_from_slice(&packet).unwrap();
1219 // Packet padding up to 60 (64 - FCS)
1220 for _ in packet.len() as u32..60 {
1221 spi_packet.push(0x00).unwrap();
1222 }
1223 // Packet FCS
1224 spi_packet.extend_from_slice(&[147, 149, 213, 68]).unwrap();
1225
1226 // SPI HEADER Padding of u32
1227 for _ in spi_packet.len() as u32..size_align_u32(spi_packet.len() as u32) {
1228 spi_packet.push(0x00).unwrap();
1229 }
1230
1231 expectations.push(SpiTransaction::write_vec(spi_packet.to_vec()));
1232 expectations.push(SpiTransaction::flush());
1233
1234 let mut spi = SpiMock::new(&expectations);
1235
1236 let cs = CsPinMock::default();
1237 let delay = MockDelay {};
1238 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
1239
1240 let mut spe = ADIN1110::new(spi_dev, true);
1241
1242 assert!(spe.write_fifo(&mut packet).await.is_ok());
1243
1244 spi.done();
1245 }
1246}