aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenĂ© van Dorst <[email protected]>2023-08-26 01:29:06 +0200
committerRenĂ© van Dorst <[email protected]>2023-08-28 00:28:40 +0200
commit13a0be628937125042a961175861bbdba6dcab34 (patch)
treeacc090bcf291528890471ab518aa74c8b8f9d3c8
parent7f7256050cd8a4f1cb1bb270ee39cb9c8dfdafb2 (diff)
Validate FCS in fifo_read() and refactor tests.
Adding TestHarnass to declutter the tests. Also added a test for FCS and SPI_CRC.
-rw-r--r--embassy-net-adin1110/src/crc32.rs29
-rw-r--r--embassy-net-adin1110/src/lib.rs447
-rw-r--r--embassy-net-adin1110/src/regs.rs2
3 files changed, 305 insertions, 173 deletions
diff --git a/embassy-net-adin1110/src/crc32.rs b/embassy-net-adin1110/src/crc32.rs
index a3474f70a..ec020b70c 100644
--- a/embassy-net-adin1110/src/crc32.rs
+++ b/embassy-net-adin1110/src/crc32.rs
@@ -257,29 +257,30 @@ pub const CRC32R_LOOKUP_TABLE: [u32; 256] = [
257 0x2D02_EF8D, 257 0x2D02_EF8D,
258]; 258];
259 259
260/// Generate Ethernet Frame Check Sequence
260#[allow(non_camel_case_types)] 261#[allow(non_camel_case_types)]
261#[derive(Debug)] 262#[derive(Debug)]
262pub struct ETH_FSC(pub u32); 263pub struct ETH_FCS(pub u32);
263 264
264impl ETH_FSC { 265impl ETH_FCS {
265 pub const CRC32_OK: u32 = 0x2144_df1c; 266 pub const CRC32_OK: u32 = 0x2144_df1c;
266 267
267 #[must_use] 268 #[must_use]
268 pub fn new(data: &[u8]) -> Self { 269 pub fn new(data: &[u8]) -> Self {
269 let fsc = data.iter().fold(u32::MAX, |crc, byte| { 270 let fcs = data.iter().fold(u32::MAX, |crc, byte| {
270 let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte; 271 let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte;
271 CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8) 272 CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8)
272 }) ^ u32::MAX; 273 }) ^ u32::MAX;
273 Self(fsc) 274 Self(fcs)
274 } 275 }
275 276
276 #[must_use] 277 #[must_use]
277 pub fn update(self, data: &[u8]) -> Self { 278 pub fn update(self, data: &[u8]) -> Self {
278 let fsc = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| { 279 let fcs = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| {
279 let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte; 280 let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte;
280 CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8) 281 CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8)
281 }) ^ u32::MAX; 282 }) ^ u32::MAX;
282 Self(fsc) 283 Self(fcs)
283 } 284 }
284 285
285 #[must_use] 286 #[must_use]
@@ -319,24 +320,24 @@ mod tests {
319 ]; 320 ];
320 321
321 // Packet A 322 // Packet A
322 let own_crc = ETH_FSC::new(&packet_a[0..60]); 323 let own_crc = ETH_FCS::new(&packet_a[0..60]);
323 let crc_bytes = own_crc.hton_bytes(); 324 let crc_bytes = own_crc.hton_bytes();
324 println!("{:08x} {:02x?}", own_crc.0, crc_bytes); 325 println!("{:08x} {:02x?}", own_crc.0, crc_bytes);
325 assert_eq!(&crc_bytes, &packet_a[60..64]); 326 assert_eq!(&crc_bytes, &packet_a[60..64]);
326 327
327 let own_crc = ETH_FSC::new(packet_a); 328 let own_crc = ETH_FCS::new(packet_a);
328 println!("{:08x}", own_crc.0); 329 println!("{:08x}", own_crc.0);
329 assert_eq!(own_crc.0, ETH_FSC::CRC32_OK); 330 assert_eq!(own_crc.0, ETH_FCS::CRC32_OK);
330 331
331 // Packet B 332 // Packet B
332 let own_crc = ETH_FSC::new(&packet_b[0..60]); 333 let own_crc = ETH_FCS::new(&packet_b[0..60]);
333 let crc_bytes = own_crc.hton_bytes(); 334 let crc_bytes = own_crc.hton_bytes();
334 println!("{:08x} {:02x?}", own_crc.0, crc_bytes); 335 println!("{:08x} {:02x?}", own_crc.0, crc_bytes);
335 assert_eq!(&crc_bytes, &packet_b[60..64]); 336 assert_eq!(&crc_bytes, &packet_b[60..64]);
336 337
337 let own_crc = ETH_FSC::new(packet_b); 338 let own_crc = ETH_FCS::new(packet_b);
338 println!("{:08x}", own_crc.0); 339 println!("{:08x}", own_crc.0);
339 assert_eq!(own_crc.0, ETH_FSC::CRC32_OK); 340 assert_eq!(own_crc.0, ETH_FCS::CRC32_OK);
340 } 341 }
341 342
342 #[test] 343 #[test]
@@ -349,9 +350,9 @@ mod tests {
349 ]; 350 ];
350 351
351 let (part_a, part_b) = full_data.split_at(16); 352 let (part_a, part_b) = full_data.split_at(16);
352 let crc_partially = ETH_FSC::new(part_a).update(part_b); 353 let crc_partially = ETH_FCS::new(part_a).update(part_b);
353 354
354 let crc_full = ETH_FSC::new(full_data); 355 let crc_full = ETH_FCS::new(full_data);
355 356
356 assert_eq!(crc_full.0, crc_partially.0); 357 assert_eq!(crc_full.0, crc_partially.0);
357 } 358 }
diff --git a/embassy-net-adin1110/src/lib.rs b/embassy-net-adin1110/src/lib.rs
index 4042bd73c..8d73e024f 100644
--- a/embassy-net-adin1110/src/lib.rs
+++ b/embassy-net-adin1110/src/lib.rs
@@ -13,7 +13,7 @@ mod phy;
13mod regs; 13mod regs;
14 14
15use ch::driver::LinkState; 15use ch::driver::LinkState;
16pub use crc32::ETH_FSC; 16pub use crc32::ETH_FCS;
17use crc8::crc8; 17use crc8::crc8;
18use embassy_futures::select::{select, Either}; 18use embassy_futures::select::{select, Either};
19use embassy_net_driver_channel as ch; 19use embassy_net_driver_channel as ch;
@@ -35,16 +35,22 @@ pub const PHYID: u32 = 0x0283_BC91;
35#[cfg_attr(feature = "defmt", derive(defmt::Format))] 35#[cfg_attr(feature = "defmt", derive(defmt::Format))]
36#[allow(non_camel_case_types)] 36#[allow(non_camel_case_types)]
37pub enum AdinError<E> { 37pub enum AdinError<E> {
38 /// SPI-BUS Error
38 Spi(E), 39 Spi(E),
39 SENDERROR, 40 /// Ethernet FCS error
40 READERROR, 41 FCS,
41 CRC, 42 /// SPI Header CRC error
43 SPI_CRC,
44 /// Received or sended ethernet packet is too big
42 PACKET_TOO_BIG, 45 PACKET_TOO_BIG,
46 /// Received or sended ethernet packet is too small
43 PACKET_TOO_SMALL, 47 PACKET_TOO_SMALL,
48 /// MDIO transaction timeout
44 MDIO_ACC_TIMEOUT, 49 MDIO_ACC_TIMEOUT,
45} 50}
46 51
47pub type AEResult<T, SPIError> = core::result::Result<T, AdinError<SPIError>>; 52pub type AEResult<T, SPIError> = core::result::Result<T, AdinError<SPIError>>;
53/// Internet PHY address
48pub const MDIO_PHY_ADDR: u8 = 0x01; 54pub const MDIO_PHY_ADDR: u8 = 0x01;
49 55
50/// Maximum Transmission Unit 56/// Maximum Transmission Unit
@@ -59,9 +65,9 @@ const TURN_AROUND_BYTE: u8 = 0x00;
59/// Packet minimal frame/packet length 65/// Packet minimal frame/packet length
60const ETH_MIN_LEN: usize = 64; 66const ETH_MIN_LEN: usize = 64;
61/// Ethernet `Frame Check Sequence` length 67/// Ethernet `Frame Check Sequence` length
62const FSC_LEN: usize = 4; 68const FCS_LEN: usize = 4;
63/// Packet minimal frame/packet length without `Frame Check Sequence` length 69/// Packet minimal frame/packet length without `Frame Check Sequence` length
64const ETH_MIN_WITHOUT_FSC_LEN: usize = ETH_MIN_LEN - FSC_LEN; 70const ETH_MIN_WITHOUT_FCS_LEN: usize = ETH_MIN_LEN - FCS_LEN;
65 71
66/// SPI Header, contains SPI action and register id. 72/// SPI Header, contains SPI action and register id.
67const SPI_HEADER_LEN: usize = 2; 73const SPI_HEADER_LEN: usize = 2;
@@ -74,7 +80,7 @@ const FRAME_HEADER_LEN: usize = 2;
74/// Space for last bytes to create multipule 4 bytes on the end of a FIFO read/write. 80/// Space for last bytes to create multipule 4 bytes on the end of a FIFO read/write.
75const SPI_SPACE_MULTIPULE: usize = 3; 81const SPI_SPACE_MULTIPULE: usize = 3;
76 82
77// P1 = 0x00, P2 = 0x01 83/// P1 = 0x00, P2 = 0x01
78const PORT_ID_BYTE: u8 = 0x00; 84const PORT_ID_BYTE: u8 = 0x00;
79 85
80/// Type alias for the embassy-net driver for ADIN1110 86/// Type alias for the embassy-net driver for ADIN1110
@@ -100,12 +106,18 @@ pub struct ADIN1110<SPI> {
100 spi: SPI, 106 spi: SPI,
101 /// Enable CRC on SPI transfer. 107 /// Enable CRC on SPI transfer.
102 /// This must match with the hardware pin `SPI_CFG0` were low = CRC enable, high = CRC disabled. 108 /// This must match with the hardware pin `SPI_CFG0` were low = CRC enable, high = CRC disabled.
103 crc: bool, 109 spi_crc: bool,
110 /// Append FCS by the application of transmit packet, false = FCS is appended by the MAC, true = FCS appended by the application.
111 append_fcs_on_tx: bool,
104} 112}
105 113
106impl<SPI: SpiDevice> ADIN1110<SPI> { 114impl<SPI: SpiDevice> ADIN1110<SPI> {
107 pub fn new(spi: SPI, crc: bool) -> Self { 115 pub fn new(spi: SPI, spi_crc: bool, append_fcs_on_tx: bool) -> Self {
108 Self { spi, crc } 116 Self {
117 spi,
118 spi_crc,
119 append_fcs_on_tx,
120 }
109 } 121 }
110 122
111 pub async fn read_reg(&mut self, reg: sr) -> AEResult<u32, SPI::Error> { 123 pub async fn read_reg(&mut self, reg: sr) -> AEResult<u32, SPI::Error> {
@@ -116,7 +128,7 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
116 spi_hdr.set_addr(reg); 128 spi_hdr.set_addr(reg);
117 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice()); 129 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice());
118 130
119 if self.crc { 131 if self.spi_crc {
120 // Add CRC for header data 132 // Add CRC for header data
121 let _ = tx_buf.push(crc8(&tx_buf)); 133 let _ = tx_buf.push(crc8(&tx_buf));
122 } 134 }
@@ -126,16 +138,16 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
126 138
127 let mut rx_buf = [0; 5]; 139 let mut rx_buf = [0; 5];
128 140
129 let spi_read_len = if self.crc { rx_buf.len() } else { rx_buf.len() - 1 }; 141 let spi_read_len = if self.spi_crc { rx_buf.len() } else { rx_buf.len() - 1 };
130 142
131 let mut spi_op = [Operation::Write(&tx_buf), Operation::Read(&mut rx_buf[0..spi_read_len])]; 143 let mut spi_op = [Operation::Write(&tx_buf), Operation::Read(&mut rx_buf[0..spi_read_len])];
132 144
133 self.spi.transaction(&mut spi_op).await.map_err(AdinError::Spi)?; 145 self.spi.transaction(&mut spi_op).await.map_err(AdinError::Spi)?;
134 146
135 if self.crc { 147 if self.spi_crc {
136 let crc = crc8(&rx_buf[0..4]); 148 let crc = crc8(&rx_buf[0..4]);
137 if crc != rx_buf[4] { 149 if crc != rx_buf[4] {
138 return Err(AdinError::CRC); 150 return Err(AdinError::SPI_CRC);
139 } 151 }
140 } 152 }
141 153
@@ -156,7 +168,7 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
156 spi_hdr.set_addr(reg); 168 spi_hdr.set_addr(reg);
157 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice()); 169 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice());
158 170
159 if self.crc { 171 if self.spi_crc {
160 // Add CRC for header data 172 // Add CRC for header data
161 let _ = tx_buf.push(crc8(&tx_buf)); 173 let _ = tx_buf.push(crc8(&tx_buf));
162 } 174 }
@@ -164,7 +176,7 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
164 let val = value.to_be_bytes(); 176 let val = value.to_be_bytes();
165 let _ = tx_buf.extend_from_slice(val.as_slice()); 177 let _ = tx_buf.extend_from_slice(val.as_slice());
166 178
167 if self.crc { 179 if self.spi_crc {
168 // Add CRC for header data 180 // Add CRC for header data
169 let _ = tx_buf.push(crc8(val.as_slice())); 181 let _ = tx_buf.push(crc8(val.as_slice()));
170 } 182 }
@@ -193,18 +205,18 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
193 /// Read out fifo ethernet packet memory received via the wire. 205 /// Read out fifo ethernet packet memory received via the wire.
194 pub async fn read_fifo(&mut self, frame: &mut [u8]) -> AEResult<usize, SPI::Error> { 206 pub async fn read_fifo(&mut self, frame: &mut [u8]) -> AEResult<usize, SPI::Error> {
195 const HEAD_LEN: usize = SPI_HEADER_LEN + SPI_HEADER_CRC_LEN + SPI_HEADER_TA_LEN; 207 const HEAD_LEN: usize = SPI_HEADER_LEN + SPI_HEADER_CRC_LEN + SPI_HEADER_TA_LEN;
196 const TAIL_LEN: usize = FSC_LEN + SPI_SPACE_MULTIPULE; 208 const TAIL_LEN: usize = FCS_LEN + SPI_SPACE_MULTIPULE;
197 209
198 let mut tx_buf = Vec::<u8, HEAD_LEN>::new(); 210 let mut tx_buf = Vec::<u8, HEAD_LEN>::new();
199 211
200 // Size of the frame, also includes the `frame header` and `FSC`. 212 // Size of the frame, also includes the `frame header` and `FCS`.
201 let fifo_frame_size = self.read_reg(sr::RX_FSIZE).await? as usize; 213 let fifo_frame_size = self.read_reg(sr::RX_FSIZE).await? as usize;
202 214
203 if fifo_frame_size < ETH_MIN_LEN + FRAME_HEADER_LEN { 215 if fifo_frame_size < ETH_MIN_LEN + FRAME_HEADER_LEN {
204 return Err(AdinError::PACKET_TOO_SMALL); 216 return Err(AdinError::PACKET_TOO_SMALL);
205 } 217 }
206 218
207 let packet_size = fifo_frame_size - FRAME_HEADER_LEN - FSC_LEN; 219 let packet_size = fifo_frame_size - FRAME_HEADER_LEN - FCS_LEN;
208 220
209 if packet_size > frame.len() { 221 if packet_size > frame.len() {
210 #[cfg(feature = "defmt")] 222 #[cfg(feature = "defmt")]
@@ -217,7 +229,7 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
217 spi_hdr.set_addr(sr::RX); 229 spi_hdr.set_addr(sr::RX);
218 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice()); 230 let _ = tx_buf.extend_from_slice(spi_hdr.0.to_be_bytes().as_slice());
219 231
220 if self.crc { 232 if self.spi_crc {
221 // Add CRC for header data 233 // Add CRC for header data
222 let _ = tx_buf.push(crc8(&tx_buf)); 234 let _ = tx_buf.push(crc8(&tx_buf));
223 } 235 }
@@ -226,27 +238,36 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
226 let _ = tx_buf.push(TURN_AROUND_BYTE); 238 let _ = tx_buf.push(TURN_AROUND_BYTE);
227 239
228 let mut frame_header = [0, 0]; 240 let mut frame_header = [0, 0];
229 let mut fsc_and_extra = [0; TAIL_LEN]; 241 let mut fcs_and_extra = [0; TAIL_LEN];
230 242
231 // Packet read of write to the MAC packet buffer must be a multipul of 4! 243 // Packet read of write to the MAC packet buffer must be a multipul of 4!
232 let tail_size = (fifo_frame_size & 0x03) + FSC_LEN; 244 let tail_size = (fifo_frame_size & 0x03) + FCS_LEN;
233 245
234 let mut spi_op = [ 246 let mut spi_op = [
235 Operation::Write(&tx_buf), 247 Operation::Write(&tx_buf),
236 Operation::Read(&mut frame_header), 248 Operation::Read(&mut frame_header),
237 Operation::Read(&mut frame[0..packet_size]), 249 Operation::Read(&mut frame[0..packet_size]),
238 Operation::Read(&mut fsc_and_extra[0..tail_size]), 250 Operation::Read(&mut fcs_and_extra[0..tail_size]),
239 ]; 251 ];
240 252
241 self.spi.transaction(&mut spi_op).await.map_err(AdinError::Spi)?; 253 self.spi.transaction(&mut spi_op).await.map_err(AdinError::Spi)?;
242 254
243 Ok(packet_size) 255 // According to register `CONFIG2`, bit 5 `CRC_APPEND` discription:
256 // "Similarly, on receive, the CRC32 is forwarded with the frame to the host where the host must verify it is correct."
257 // The application must allways check the FCS. It seems that the MAC/PHY has no option to handle this.
258 let fcs_calc = ETH_FCS::new(&frame[0..packet_size]);
259
260 if fcs_calc.hton_bytes() == fcs_and_extra[0..4] {
261 Ok(packet_size)
262 } else {
263 Err(AdinError::FCS)
264 }
244 } 265 }
245 266
246 /// Write to fifo ethernet packet memory send over the wire. 267 /// Write to fifo ethernet packet memory send over the wire.
247 pub async fn write_fifo(&mut self, frame: &[u8]) -> AEResult<(), SPI::Error> { 268 pub async fn write_fifo(&mut self, frame: &[u8]) -> AEResult<(), SPI::Error> {
248 const HEAD_LEN: usize = SPI_HEADER_LEN + SPI_HEADER_CRC_LEN + FRAME_HEADER_LEN; 269 const HEAD_LEN: usize = SPI_HEADER_LEN + SPI_HEADER_CRC_LEN + FRAME_HEADER_LEN;
249 const TAIL_LEN: usize = ETH_MIN_LEN - FSC_LEN + FSC_LEN + SPI_SPACE_MULTIPULE; 270 const TAIL_LEN: usize = ETH_MIN_LEN - FCS_LEN + FCS_LEN + SPI_SPACE_MULTIPULE;
250 271
251 if frame.len() < (6 + 6 + 2) { 272 if frame.len() < (6 + 6 + 2) {
252 return Err(AdinError::PACKET_TOO_SMALL); 273 return Err(AdinError::PACKET_TOO_SMALL);
@@ -269,7 +290,7 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
269 .extend_from_slice(spi_hdr.0.to_be_bytes().as_slice()) 290 .extend_from_slice(spi_hdr.0.to_be_bytes().as_slice())
270 .map_err(|_e| AdinError::PACKET_TOO_BIG)?; 291 .map_err(|_e| AdinError::PACKET_TOO_BIG)?;
271 292
272 if self.crc { 293 if self.spi_crc {
273 // Add CRC for header data 294 // Add CRC for header data
274 head_data 295 head_data
275 .push(crc8(&head_data[0..2])) 296 .push(crc8(&head_data[0..2]))
@@ -281,18 +302,22 @@ impl<SPI: SpiDevice> ADIN1110<SPI> {
281 .extend_from_slice(u16::from(PORT_ID_BYTE).to_be_bytes().as_slice()) 302 .extend_from_slice(u16::from(PORT_ID_BYTE).to_be_bytes().as_slice())
282 .map_err(|_e| AdinError::PACKET_TOO_BIG)?; 303 .map_err(|_e| AdinError::PACKET_TOO_BIG)?;
283 304
284 let mut frame_fcs = ETH_FSC::new(frame);
285
286 // ADIN1110 MAC and PHY don´t accept ethernet packet smaller than 64 bytes. 305 // ADIN1110 MAC and PHY don´t accept ethernet packet smaller than 64 bytes.
287 // So padded the data minus the FCS, FCS is automatilly added to by the MAC. 306 // So padded the data minus the FCS, FCS is automatilly added to by the MAC.
288 if frame.len() < ETH_MIN_WITHOUT_FSC_LEN { 307 if frame.len() < ETH_MIN_WITHOUT_FCS_LEN {
289 let _ = tail_data.resize(ETH_MIN_WITHOUT_FSC_LEN - frame.len(), 0x00); 308 let _ = tail_data.resize(ETH_MIN_WITHOUT_FCS_LEN - frame.len(), 0x00);
290 frame_fcs = frame_fcs.update(&tail_data);
291 } 309 }
292 310
293 // Add ethernet FCS only over the ethernet packet. 311 // Append FCS by the application
294 // Only usefull when `CONFIG0`, `Transmit Frame Check Sequence Validation Enable` bit is enabled. 312 if self.append_fcs_on_tx {
295 let _ = tail_data.extend_from_slice(frame_fcs.hton_bytes().as_slice()); 313 let mut frame_fcs = ETH_FCS::new(frame);
314
315 if !tail_data.is_empty() {
316 frame_fcs = frame_fcs.update(&tail_data);
317 }
318
319 let _ = tail_data.extend_from_slice(frame_fcs.hton_bytes().as_slice());
320 }
296 321
297 // len = frame_size + optional padding + 2 bytes Frame header 322 // len = frame_size + optional padding + 2 bytes Frame header
298 let send_len_orig = frame.len() + tail_data.len() + FRAME_HEADER_LEN; 323 let send_len_orig = frame.len() + tail_data.len() + FRAME_HEADER_LEN;
@@ -583,7 +608,8 @@ pub async fn new<const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait
583 spi_dev: SPI, 608 spi_dev: SPI,
584 int: INT, 609 int: INT,
585 mut reset: RST, 610 mut reset: RST,
586 crc: bool, 611 spi_crc: bool,
612 append_fcs_on_tx: bool,
587) -> (Device<'_>, Runner<'_, SPI, INT, RST>) { 613) -> (Device<'_>, Runner<'_, SPI, INT, RST>) {
588 use crate::regs::{IMask0, IMask1}; 614 use crate::regs::{IMask0, IMask1};
589 615
@@ -602,7 +628,7 @@ pub async fn new<const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait
602 Timer::after(Duration::from_millis(50)).await; 628 Timer::after(Duration::from_millis(50)).await;
603 629
604 // Create device 630 // Create device
605 let mut mac = ADIN1110::new(spi_dev, crc); 631 let mut mac = ADIN1110::new(spi_dev, spi_crc, append_fcs_on_tx);
606 632
607 // Check PHYID 633 // Check PHYID
608 let id = mac.read_reg(sr::PHYID).await.unwrap(); 634 let id = mac.read_reg(sr::PHYID).await.unwrap();
@@ -630,18 +656,15 @@ pub async fn new<const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait
630 .unwrap(); 656 .unwrap();
631 } 657 }
632 658
633 // Check if the FCS is valid in the TX path.
634 let tx_fsc_validation_enable = true;
635
636 // Config0 659 // Config0
637 let mut config0 = Config0(0x0000_0006); 660 let mut config0 = Config0(0x0000_0006);
638 config0.set_txfcsve(tx_fsc_validation_enable); 661 config0.set_txfcsve(mac.append_fcs_on_tx);
639 mac.write_reg(sr::CONFIG0, config0.0).await.unwrap(); 662 mac.write_reg(sr::CONFIG0, config0.0).await.unwrap();
640 663
641 // Config2 664 // Config2
642 let mut config2 = Config2(0x0000_0800); 665 let mut config2 = Config2(0x0000_0800);
643 // crc_append must be disable if tx_fsc_validation_enable is true! 666 // crc_append must be disable if tx_fcs_validation_enable is true!
644 config2.set_crc_append(!tx_fsc_validation_enable); 667 config2.set_crc_append(!mac.append_fcs_on_tx);
645 mac.write_reg(sr::CONFIG2, config2.0).await.unwrap(); 668 mac.write_reg(sr::CONFIG2, config2.0).await.unwrap();
646 669
647 // Pin Mux Config 1 670 // Pin Mux Config 1
@@ -721,6 +744,7 @@ mod tests {
721 use embedded_hal_1::digital::{ErrorType, OutputPin}; 744 use embedded_hal_1::digital::{ErrorType, OutputPin};
722 use embedded_hal_async::delay::DelayUs; 745 use embedded_hal_async::delay::DelayUs;
723 use embedded_hal_bus::spi::ExclusiveDevice; 746 use embedded_hal_bus::spi::ExclusiveDevice;
747 use embedded_hal_mock::common::Generic;
724 use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction}; 748 use embedded_hal_mock::eh1::spi::{Mock as SpiMock, Transaction as SpiTransaction};
725 749
726 #[derive(Debug, Default)] 750 #[derive(Debug, Default)]
@@ -759,6 +783,30 @@ mod tests {
759 } 783 }
760 } 784 }
761 785
786 struct TestHarnass {
787 spe: ADIN1110<ExclusiveDevice<embedded_hal_mock::common::Generic<SpiTransaction>, CsPinMock, MockDelay>>,
788 spi: Generic<SpiTransaction>,
789 }
790
791 impl TestHarnass {
792 pub fn new(expectations: &[SpiTransaction], spi_crc: bool, append_fcs_on_tx: bool) -> Self {
793 let cs = CsPinMock::default();
794 let delay = MockDelay {};
795 let spi = SpiMock::new(expectations);
796 let spi_dev: ExclusiveDevice<embedded_hal_mock::common::Generic<SpiTransaction>, CsPinMock, MockDelay> =
797 ExclusiveDevice::new(spi.clone(), cs, delay);
798 let spe: ADIN1110<
799 ExclusiveDevice<embedded_hal_mock::common::Generic<SpiTransaction>, CsPinMock, MockDelay>,
800 > = ADIN1110::new(spi_dev, spi_crc, append_fcs_on_tx);
801
802 Self { spe, spi }
803 }
804
805 pub fn done(&mut self) {
806 self.spi.done();
807 }
808 }
809
762 #[futures_test::test] 810 #[futures_test::test]
763 async fn mac_read_registers_without_crc() { 811 async fn mac_read_registers_without_crc() {
764 // Configure expectations 812 // Configure expectations
@@ -772,22 +820,20 @@ mod tests {
772 SpiTransaction::read_vec(vec![0x00, 0x00, 0x06, 0xC3]), 820 SpiTransaction::read_vec(vec![0x00, 0x00, 0x06, 0xC3]),
773 SpiTransaction::flush(), 821 SpiTransaction::flush(),
774 ]; 822 ];
775 let mut spi = SpiMock::new(&expectations);
776 823
777 let cs = CsPinMock::default(); 824 // Create TestHarnass
778 let delay = MockDelay {}; 825 let mut th = TestHarnass::new(&expectations, false, true);
779 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
780 let mut spe = ADIN1110::new(spi_dev, false);
781 826
782 // Read PHIID 827 // Read PHIID
783 let val = spe.read_reg(sr::PHYID).await.expect("Error"); 828 let val = th.spe.read_reg(sr::PHYID).await.expect("Error");
784 assert_eq!(val, 0x0283_BC91); 829 assert_eq!(val, 0x0283_BC91);
785 830
786 // Read CAPAVILITY 831 // Read CAPAVILITY
787 let val = spe.read_reg(sr::CAPABILITY).await.expect("Error"); 832 let val = th.spe.read_reg(sr::CAPABILITY).await.expect("Error");
788 assert_eq!(val, 0x0000_06C3); 833 assert_eq!(val, 0x0000_06C3);
789 834
790 spi.done(); 835 // Mark end of the SPI test.
836 th.done();
791 } 837 }
792 838
793 #[futures_test::test] 839 #[futures_test::test]
@@ -803,26 +849,23 @@ mod tests {
803 SpiTransaction::read_vec(vec![0x00, 0x00, 0x06, 0xC3, 57]), 849 SpiTransaction::read_vec(vec![0x00, 0x00, 0x06, 0xC3, 57]),
804 SpiTransaction::flush(), 850 SpiTransaction::flush(),
805 ]; 851 ];
806 let mut spi = SpiMock::new(&expectations);
807
808 let cs = CsPinMock::default();
809 let delay = MockDelay {};
810 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
811 852
812 let mut spe = ADIN1110::new(spi_dev, true); 853 // Create TestHarnass
854 let mut th = TestHarnass::new(&expectations, true, true);
813 855
814 assert_eq!(crc8(0x0283_BC91_u32.to_be_bytes().as_slice()), 215); 856 assert_eq!(crc8(0x0283_BC91_u32.to_be_bytes().as_slice()), 215);
815 assert_eq!(crc8(0x0000_06C3_u32.to_be_bytes().as_slice()), 57); 857 assert_eq!(crc8(0x0000_06C3_u32.to_be_bytes().as_slice()), 57);
816 858
817 // Read PHIID 859 // Read PHIID
818 let val = spe.read_reg(sr::PHYID).await.expect("Error"); 860 let val = th.spe.read_reg(sr::PHYID).await.expect("Error");
819 assert_eq!(val, 0x0283_BC91); 861 assert_eq!(val, 0x0283_BC91);
820 862
821 // Read CAPAVILITY 863 // Read CAPAVILITY
822 let val = spe.read_reg(sr::CAPABILITY).await.expect("Error"); 864 let val = th.spe.read_reg(sr::CAPABILITY).await.expect("Error");
823 assert_eq!(val, 0x0000_06C3); 865 assert_eq!(val, 0x0000_06C3);
824 866
825 spi.done(); 867 // Mark end of the SPI test.
868 th.done();
826 } 869 }
827 870
828 #[futures_test::test] 871 #[futures_test::test]
@@ -832,18 +875,15 @@ mod tests {
832 SpiTransaction::write_vec(vec![0xA0, 0x09, 0x12, 0x34, 0x56, 0x78]), 875 SpiTransaction::write_vec(vec![0xA0, 0x09, 0x12, 0x34, 0x56, 0x78]),
833 SpiTransaction::flush(), 876 SpiTransaction::flush(),
834 ]; 877 ];
835 let mut spi = SpiMock::new(&expectations);
836
837 let cs = CsPinMock::default();
838 let delay = MockDelay {};
839 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
840 878
841 let mut spe = ADIN1110::new(spi_dev, false); 879 // Create TestHarnass
880 let mut th = TestHarnass::new(&expectations, false, true);
842 881
843 // Write reg: 0x1FFF 882 // Write reg: 0x1FFF
844 assert!(spe.write_reg(sr::STATUS1, 0x1234_5678).await.is_ok()); 883 assert!(th.spe.write_reg(sr::STATUS1, 0x1234_5678).await.is_ok());
845 884
846 spi.done(); 885 // Mark end of the SPI test.
886 th.done();
847 } 887 }
848 888
849 #[futures_test::test] 889 #[futures_test::test]
@@ -854,17 +894,14 @@ mod tests {
854 SpiTransaction::flush(), 894 SpiTransaction::flush(),
855 ]; 895 ];
856 896
857 // Basic test init block 897 // Create TestHarnass
858 let mut spi = SpiMock::new(&expectations); 898 let mut th = TestHarnass::new(&expectations, true, true);
859 let cs = CsPinMock::default();
860 let delay = MockDelay {};
861 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
862 let mut spe = ADIN1110::new(spi_dev, true);
863 899
864 // Write reg: 0x1FFF 900 // Write reg: 0x1FFF
865 assert!(spe.write_reg(sr::STATUS1, 0x1234_5678).await.is_ok()); 901 assert!(th.spe.write_reg(sr::STATUS1, 0x1234_5678).await.is_ok());
866 902
867 spi.done(); 903 // Mark end of the SPI test.
904 th.done();
868 } 905 }
869 906
870 #[futures_test::test] 907 #[futures_test::test]
@@ -885,7 +922,7 @@ mod tests {
885 922
886 let mut tail = std::vec::Vec::<u8>::with_capacity(100); 923 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
887 // Padding 924 // Padding
888 if let Some(padding_len) = (ETH_MIN_LEN - FSC_LEN).checked_sub(packet.len()) { 925 if let Some(padding_len) = (ETH_MIN_LEN - FCS_LEN).checked_sub(packet.len()) {
889 tail.resize(padding_len, 0x00); 926 tail.resize(padding_len, 0x00);
890 } 927 }
891 // Packet FCS + optinal padding 928 // Packet FCS + optinal padding
@@ -894,17 +931,49 @@ mod tests {
894 expectations.push(SpiTransaction::write_vec(tail)); 931 expectations.push(SpiTransaction::write_vec(tail));
895 expectations.push(SpiTransaction::flush()); 932 expectations.push(SpiTransaction::flush());
896 933
897 let mut spi = SpiMock::new(&expectations); 934 // Create TestHarnass
935 let mut th = TestHarnass::new(&expectations, true, true);
936
937 assert!(th.spe.write_fifo(&packet).await.is_ok());
938
939 // Mark end of the SPI test.
940 th.done();
941 }
942
943 #[futures_test::test]
944 async fn write_packet_to_fifo_minimal_with_crc_without_fcs() {
945 // Configure expectations
946 let mut expectations = vec![];
947
948 // Write TX_SIZE reg
949 expectations.push(SpiTransaction::write_vec(vec![160, 48, 136, 0, 0, 0, 62, 186]));
950 expectations.push(SpiTransaction::flush());
951
952 // Write TX reg.
953 // SPI Header + optional CRC + Frame Header
954 expectations.push(SpiTransaction::write_vec(vec![160, 49, 143, 0, 0]));
955 // Packet data
956 let packet = [0xFF_u8; 60];
957 expectations.push(SpiTransaction::write_vec(packet.to_vec()));
898 958
899 let cs = CsPinMock::default(); 959 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
900 let delay = MockDelay {}; 960 // Padding
901 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay); 961 if let Some(padding_len) = (ETH_MIN_LEN - FCS_LEN).checked_sub(packet.len()) {
962 tail.resize(padding_len, 0x00);
963 }
964 // Packet FCS + optinal padding
965 tail.extend_from_slice(&[DONT_CARE_BYTE, DONT_CARE_BYTE]);
966
967 expectations.push(SpiTransaction::write_vec(tail));
968 expectations.push(SpiTransaction::flush());
902 969
903 let mut spe = ADIN1110::new(spi_dev, true); 970 // Create TestHarnass
971 let mut th = TestHarnass::new(&expectations, true, false);
904 972
905 assert!(spe.write_fifo(&packet).await.is_ok()); 973 assert!(th.spe.write_fifo(&packet).await.is_ok());
906 974
907 spi.done(); 975 // Mark end of the SPI test.
976 th.done();
908 } 977 }
909 978
910 #[futures_test::test] 979 #[futures_test::test]
@@ -926,7 +995,7 @@ mod tests {
926 995
927 let mut tail = std::vec::Vec::<u8>::with_capacity(100); 996 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
928 // Padding 997 // Padding
929 if let Some(padding_len) = (ETH_MIN_LEN - FSC_LEN).checked_sub(packet.len()) { 998 if let Some(padding_len) = (ETH_MIN_LEN - FCS_LEN).checked_sub(packet.len()) {
930 tail.resize(padding_len, 0x00); 999 tail.resize(padding_len, 0x00);
931 } 1000 }
932 // Packet FCS + optinal padding 1001 // Packet FCS + optinal padding
@@ -935,17 +1004,13 @@ mod tests {
935 expectations.push(SpiTransaction::write_vec(tail)); 1004 expectations.push(SpiTransaction::write_vec(tail));
936 expectations.push(SpiTransaction::flush()); 1005 expectations.push(SpiTransaction::flush());
937 1006
938 let mut spi = SpiMock::new(&expectations); 1007 // Create TestHarnass
1008 let mut th = TestHarnass::new(&expectations, true, true);
939 1009
940 let cs = CsPinMock::default(); 1010 assert!(th.spe.write_fifo(&packet).await.is_ok());
941 let delay = MockDelay {};
942 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
943 1011
944 let mut spe = ADIN1110::new(spi_dev, true); 1012 // Mark end of the SPI test.
945 1013 th.done();
946 assert!(spe.write_fifo(&packet).await.is_ok());
947
948 spi.done();
949 } 1014 }
950 1015
951 #[futures_test::test] 1016 #[futures_test::test]
@@ -958,24 +1023,23 @@ mod tests {
958 // Max packet size = MAX_BUFF - FRAME_HEADER_LEN 1023 // Max packet size = MAX_BUFF - FRAME_HEADER_LEN
959 let packet = [0xAA_u8; MAX_BUFF - FRAME_HEADER_LEN + 1]; 1024 let packet = [0xAA_u8; MAX_BUFF - FRAME_HEADER_LEN + 1];
960 1025
961 let mut spi = SpiMock::new(&expectations); 1026 // Create TestHarnass
962 1027 let mut th = TestHarnass::new(&expectations, true, true);
963 let cs = CsPinMock::default();
964 let delay = MockDelay {};
965 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
966
967 let mut spe = ADIN1110::new(spi_dev, true);
968 1028
969 // minimal 1029 // minimal
970 assert!(matches!( 1030 assert!(matches!(
971 spe.write_fifo(&packet[0..(6 + 6 + 2 - 1)]).await, 1031 th.spe.write_fifo(&packet[0..(6 + 6 + 2 - 1)]).await,
972 Err(AdinError::PACKET_TOO_SMALL) 1032 Err(AdinError::PACKET_TOO_SMALL)
973 )); 1033 ));
974 1034
975 // max + 1 1035 // max + 1
976 assert!(matches!(spe.write_fifo(&packet).await, Err(AdinError::PACKET_TOO_BIG))); 1036 assert!(matches!(
1037 th.spe.write_fifo(&packet).await,
1038 Err(AdinError::PACKET_TOO_BIG)
1039 ));
977 1040
978 spi.done(); 1041 // Mark end of the SPI test.
1042 th.done();
979 } 1043 }
980 1044
981 #[futures_test::test] 1045 #[futures_test::test]
@@ -999,7 +1063,7 @@ mod tests {
999 1063
1000 let mut tail = std::vec::Vec::<u8>::with_capacity(100); 1064 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
1001 // Padding 1065 // Padding
1002 if let Some(padding_len) = (ETH_MIN_LEN - FSC_LEN).checked_sub(packet.len()) { 1066 if let Some(padding_len) = (ETH_MIN_LEN - FCS_LEN).checked_sub(packet.len()) {
1003 tail.resize(padding_len, 0x00); 1067 tail.resize(padding_len, 0x00);
1004 } 1068 }
1005 // Packet FCS + optinal padding 1069 // Packet FCS + optinal padding
@@ -1008,17 +1072,13 @@ mod tests {
1008 expectations.push(SpiTransaction::write_vec(tail)); 1072 expectations.push(SpiTransaction::write_vec(tail));
1009 expectations.push(SpiTransaction::flush()); 1073 expectations.push(SpiTransaction::flush());
1010 1074
1011 let mut spi = SpiMock::new(&expectations); 1075 // Create TestHarnass
1076 let mut th = TestHarnass::new(&expectations, true, true);
1012 1077
1013 let cs = CsPinMock::default(); 1078 assert!(th.spe.write_fifo(&packet).await.is_ok());
1014 let delay = MockDelay {};
1015 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
1016 1079
1017 let mut spe = ADIN1110::new(spi_dev, true); 1080 // Mark end of the SPI test.
1018 1081 th.done();
1019 assert!(spe.write_fifo(&packet).await.is_ok());
1020
1021 spi.done();
1022 } 1082 }
1023 1083
1024 #[futures_test::test] 1084 #[futures_test::test]
@@ -1042,7 +1102,7 @@ mod tests {
1042 1102
1043 let mut tail = std::vec::Vec::<u8>::with_capacity(100); 1103 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
1044 // Padding 1104 // Padding
1045 if let Some(padding_len) = (ETH_MIN_LEN - FSC_LEN).checked_sub(packet.len()) { 1105 if let Some(padding_len) = (ETH_MIN_LEN - FCS_LEN).checked_sub(packet.len()) {
1046 tail.resize(padding_len, 0x00); 1106 tail.resize(padding_len, 0x00);
1047 } 1107 }
1048 // Packet FCS + optinal padding 1108 // Packet FCS + optinal padding
@@ -1051,17 +1111,13 @@ mod tests {
1051 expectations.push(SpiTransaction::write_vec(tail)); 1111 expectations.push(SpiTransaction::write_vec(tail));
1052 expectations.push(SpiTransaction::flush()); 1112 expectations.push(SpiTransaction::flush());
1053 1113
1054 let mut spi = SpiMock::new(&expectations); 1114 // Create TestHarnass
1055 1115 let mut th = TestHarnass::new(&expectations, false, true);
1056 let cs = CsPinMock::default();
1057 let delay = MockDelay {};
1058 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
1059
1060 let mut spe = ADIN1110::new(spi_dev, false);
1061 1116
1062 assert!(spe.write_fifo(&packet).await.is_ok()); 1117 assert!(th.spe.write_fifo(&packet).await.is_ok());
1063 1118
1064 spi.done(); 1119 // Mark end of the SPI test.
1120 th.done();
1065 } 1121 }
1066 1122
1067 #[futures_test::test] 1123 #[futures_test::test]
@@ -1070,7 +1126,7 @@ mod tests {
1070 let mut expectations = vec![]; 1126 let mut expectations = vec![];
1071 1127
1072 // Read RX_SIZE reg 1128 // Read RX_SIZE reg
1073 let rx_size: u32 = u32::try_from(ETH_MIN_LEN + FRAME_HEADER_LEN + FSC_LEN).unwrap(); 1129 let rx_size: u32 = u32::try_from(ETH_MIN_LEN + FRAME_HEADER_LEN + FCS_LEN).unwrap();
1074 let mut rx_size_vec = rx_size.to_be_bytes().to_vec(); 1130 let mut rx_size_vec = rx_size.to_be_bytes().to_vec();
1075 rx_size_vec.push(crc8(&rx_size_vec)); 1131 rx_size_vec.push(crc8(&rx_size_vec));
1076 1132
@@ -1078,20 +1134,16 @@ mod tests {
1078 expectations.push(SpiTransaction::read_vec(rx_size_vec)); 1134 expectations.push(SpiTransaction::read_vec(rx_size_vec));
1079 expectations.push(SpiTransaction::flush()); 1135 expectations.push(SpiTransaction::flush());
1080 1136
1081 let mut spi = SpiMock::new(&expectations);
1082
1083 let cs = CsPinMock::default();
1084 let delay = MockDelay {};
1085 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
1086
1087 let mut spe = ADIN1110::new(spi_dev, true);
1088
1089 let mut frame = [0; MTU]; 1137 let mut frame = [0; MTU];
1090 1138
1091 let ret = spe.read_fifo(&mut frame[0..ETH_MIN_LEN - 1]).await; 1139 // Create TestHarnass
1140 let mut th = TestHarnass::new(&expectations, true, true);
1141
1142 let ret = th.spe.read_fifo(&mut frame[0..ETH_MIN_LEN - 1]).await;
1092 assert!(matches!(dbg!(ret), Err(AdinError::PACKET_TOO_BIG))); 1143 assert!(matches!(dbg!(ret), Err(AdinError::PACKET_TOO_BIG)));
1093 1144
1094 spi.done(); 1145 // Mark end of the SPI test.
1146 th.done();
1095 } 1147 }
1096 1148
1097 #[futures_test::test] 1149 #[futures_test::test]
@@ -1102,11 +1154,11 @@ mod tests {
1102 // This value is importen for this test! 1154 // This value is importen for this test!
1103 assert_eq!(ETH_MIN_LEN, 64); 1155 assert_eq!(ETH_MIN_LEN, 64);
1104 1156
1105 // Packet data, size = `ETH_MIN_LEN` - `FSC_LEN` - 1 1157 // Packet data, size = `ETH_MIN_LEN` - `FCS_LEN` - 1
1106 let packet = [0; 64 - FSC_LEN - 1]; 1158 let packet = [0; 64 - FCS_LEN - 1];
1107 1159
1108 // Read RX_SIZE reg 1160 // Read RX_SIZE reg
1109 let rx_size: u32 = u32::try_from(packet.len() + FRAME_HEADER_LEN + FSC_LEN).unwrap(); 1161 let rx_size: u32 = u32::try_from(packet.len() + FRAME_HEADER_LEN + FCS_LEN).unwrap();
1110 let mut rx_size_vec = rx_size.to_be_bytes().to_vec(); 1162 let mut rx_size_vec = rx_size.to_be_bytes().to_vec();
1111 rx_size_vec.push(crc8(&rx_size_vec)); 1163 rx_size_vec.push(crc8(&rx_size_vec));
1112 1164
@@ -1114,20 +1166,84 @@ mod tests {
1114 expectations.push(SpiTransaction::read_vec(rx_size_vec)); 1166 expectations.push(SpiTransaction::read_vec(rx_size_vec));
1115 expectations.push(SpiTransaction::flush()); 1167 expectations.push(SpiTransaction::flush());
1116 1168
1117 let mut spi = SpiMock::new(&expectations); 1169 let mut frame = [0; MTU];
1170
1171 // Create TestHarnass
1172 let mut th = TestHarnass::new(&expectations, true, true);
1118 1173
1119 let cs = CsPinMock::default(); 1174 let ret = th.spe.read_fifo(&mut frame).await;
1120 let delay = MockDelay {}; 1175 assert!(matches!(dbg!(ret), Err(AdinError::PACKET_TOO_SMALL)));
1121 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
1122 1176
1123 let mut spe = ADIN1110::new(spi_dev, true); 1177 // Mark end of the SPI test.
1178 th.done();
1179 }
1124 1180
1181 #[futures_test::test]
1182 async fn read_packet_from_fifo_packet_corrupted_fcs() {
1125 let mut frame = [0; MTU]; 1183 let mut frame = [0; MTU];
1184 // Configure expectations
1185 let mut expectations = vec![];
1126 1186
1127 let ret = spe.read_fifo(&mut frame).await; 1187 let packet = [0xDE; 60];
1128 assert!(matches!(dbg!(ret), Err(AdinError::PACKET_TOO_SMALL))); 1188 let crc_en = true;
1189
1190 // Read RX_SIZE reg
1191 let rx_size: u32 = u32::try_from(packet.len() + FRAME_HEADER_LEN + FCS_LEN).unwrap();
1192 let mut rx_size_vec = rx_size.to_be_bytes().to_vec();
1193 if crc_en {
1194 rx_size_vec.push(crc8(&rx_size_vec));
1195 }
1196
1197 // SPI Header with CRC
1198 let mut rx_fsize = vec![128, 144, 79, TURN_AROUND_BYTE];
1199 if !crc_en {
1200 // remove the CRC on idx 2
1201 rx_fsize.swap_remove(2);
1202 }
1203 expectations.push(SpiTransaction::write_vec(rx_fsize));
1204 expectations.push(SpiTransaction::read_vec(rx_size_vec));
1205 expectations.push(SpiTransaction::flush());
1129 1206
1130 spi.done(); 1207 // Read RX reg, SPI Header with CRC
1208 let mut rx_reg = vec![128, 145, 72, TURN_AROUND_BYTE];
1209 if !crc_en {
1210 // remove the CRC on idx 2
1211 rx_reg.swap_remove(2);
1212 }
1213 expectations.push(SpiTransaction::write_vec(rx_reg));
1214 // Frame Header
1215 expectations.push(SpiTransaction::read_vec(vec![0, 0]));
1216 // Packet data
1217 expectations.push(SpiTransaction::read_vec(packet.to_vec()));
1218
1219 let packet_crc = ETH_FCS::new(&packet);
1220
1221 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
1222
1223 tail.extend_from_slice(&packet_crc.hton_bytes());
1224 // increase last byte with 1.
1225 if let Some(crc) = tail.last_mut() {
1226 *crc = crc.wrapping_add(1);
1227 }
1228
1229 // Need extra bytes?
1230 let pad = (packet.len() + FCS_LEN + FRAME_HEADER_LEN) & 0x03;
1231 if pad != 0 {
1232 // Packet FCS + optinal padding
1233 tail.resize(tail.len() + pad, DONT_CARE_BYTE);
1234 }
1235
1236 expectations.push(SpiTransaction::read_vec(tail));
1237 expectations.push(SpiTransaction::flush());
1238
1239 // Create TestHarnass
1240 let mut th = TestHarnass::new(&expectations, crc_en, false);
1241
1242 let ret = th.spe.read_fifo(&mut frame).await.expect_err("Error!");
1243 assert!(matches!(ret, AdinError::FCS));
1244
1245 // Mark end of the SPI test.
1246 th.done();
1131 } 1247 }
1132 1248
1133 #[futures_test::test] 1249 #[futures_test::test]
@@ -1136,7 +1252,7 @@ mod tests {
1136 let mut frame = [0; MTU]; 1252 let mut frame = [0; MTU];
1137 let mut expectations = std::vec::Vec::with_capacity(16); 1253 let mut expectations = std::vec::Vec::with_capacity(16);
1138 1254
1139 // Packet data, size = `ETH_MIN_LEN` - `FSC_LEN` 1255 // Packet data, size = `ETH_MIN_LEN` - `FCS_LEN`
1140 for packet_size in [60, 61, 62, 63, 64, MTU - 4, MTU - 3, MTU - 2, MTU - 1, MTU] { 1256 for packet_size in [60, 61, 62, 63, 64, MTU - 4, MTU - 3, MTU - 2, MTU - 1, MTU] {
1141 for crc_en in [false, true] { 1257 for crc_en in [false, true] {
1142 expectations.clear(); 1258 expectations.clear();
@@ -1144,7 +1260,7 @@ mod tests {
1144 let packet = &packet_buffer[0..packet_size]; 1260 let packet = &packet_buffer[0..packet_size];
1145 1261
1146 // Read RX_SIZE reg 1262 // Read RX_SIZE reg
1147 let rx_size: u32 = u32::try_from(packet.len() + FRAME_HEADER_LEN + FSC_LEN).unwrap(); 1263 let rx_size: u32 = u32::try_from(packet.len() + FRAME_HEADER_LEN + FCS_LEN).unwrap();
1148 let mut rx_size_vec = rx_size.to_be_bytes().to_vec(); 1264 let mut rx_size_vec = rx_size.to_be_bytes().to_vec();
1149 if crc_en { 1265 if crc_en {
1150 rx_size_vec.push(crc8(&rx_size_vec)); 1266 rx_size_vec.push(crc8(&rx_size_vec));
@@ -1172,14 +1288,14 @@ mod tests {
1172 // Packet data 1288 // Packet data
1173 expectations.push(SpiTransaction::read_vec(packet.to_vec())); 1289 expectations.push(SpiTransaction::read_vec(packet.to_vec()));
1174 1290
1175 let packet_crc = ETH_FSC::new(packet); 1291 let packet_crc = ETH_FCS::new(packet);
1176 1292
1177 let mut tail = std::vec::Vec::<u8>::with_capacity(100); 1293 let mut tail = std::vec::Vec::<u8>::with_capacity(100);
1178 1294
1179 tail.extend_from_slice(&packet_crc.hton_bytes()); 1295 tail.extend_from_slice(&packet_crc.hton_bytes());
1180 1296
1181 // Need extra bytes? 1297 // Need extra bytes?
1182 let pad = (packet_size + FSC_LEN + FRAME_HEADER_LEN) & 0x03; 1298 let pad = (packet_size + FCS_LEN + FRAME_HEADER_LEN) & 0x03;
1183 if pad != 0 { 1299 if pad != 0 {
1184 // Packet FCS + optinal padding 1300 // Packet FCS + optinal padding
1185 tail.resize(tail.len() + pad, DONT_CARE_BYTE); 1301 tail.resize(tail.len() + pad, DONT_CARE_BYTE);
@@ -1188,19 +1304,34 @@ mod tests {
1188 expectations.push(SpiTransaction::read_vec(tail)); 1304 expectations.push(SpiTransaction::read_vec(tail));
1189 expectations.push(SpiTransaction::flush()); 1305 expectations.push(SpiTransaction::flush());
1190 1306
1191 let mut spi = SpiMock::new(&expectations); 1307 // Create TestHarnass
1192 1308 let mut th = TestHarnass::new(&expectations, crc_en, false);
1193 let cs = CsPinMock::default();
1194 let delay = MockDelay {};
1195 let spi_dev = ExclusiveDevice::new(spi.clone(), cs, delay);
1196
1197 let mut spe = ADIN1110::new(spi_dev, crc_en);
1198 1309
1199 let ret = spe.read_fifo(&mut frame).await.expect("Error!"); 1310 let ret = th.spe.read_fifo(&mut frame).await.expect("Error!");
1200 assert_eq!(ret, packet_size); 1311 assert_eq!(ret, packet_size);
1201 1312
1202 spi.done(); 1313 // Mark end of the SPI test.
1314 th.done();
1203 } 1315 }
1204 } 1316 }
1205 } 1317 }
1318
1319 #[futures_test::test]
1320 async fn spi_crc_error() {
1321 // Configure expectations
1322 let expectations = vec![
1323 SpiTransaction::write_vec(vec![128, 144, 79, TURN_AROUND_BYTE]),
1324 SpiTransaction::read_vec(vec![0x00, 0x00, 0x00, 0x00, 0xDD]),
1325 SpiTransaction::flush(),
1326 ];
1327
1328 // Create TestHarnass
1329 let mut th = TestHarnass::new(&expectations, true, false);
1330
1331 let ret = th.spe.read_reg(sr::RX_FSIZE).await;
1332 assert!(matches!(dbg!(ret), Err(AdinError::SPI_CRC)));
1333
1334 // Mark end of the SPI test.
1335 th.done();
1336 }
1206} 1337}
diff --git a/embassy-net-adin1110/src/regs.rs b/embassy-net-adin1110/src/regs.rs
index 4557929f0..46466c7d1 100644
--- a/embassy-net-adin1110/src/regs.rs
+++ b/embassy-net-adin1110/src/regs.rs
@@ -174,7 +174,7 @@ bitfield! {
174 pub sdf_detect_src, set_sdf_detect_src : 7; 174 pub sdf_detect_src, set_sdf_detect_src : 7;
175 /// Statistics Clear on Reading 175 /// Statistics Clear on Reading
176 pub stats_clr_on_rd, set_stats_clr_on_rd : 6; 176 pub stats_clr_on_rd, set_stats_clr_on_rd : 6;
177 /// Enable CRC Append 177 /// Enable SPI CRC
178 pub crc_append, set_crc_append : 5; 178 pub crc_append, set_crc_append : 5;
179 /// Admit Frames with IFG Errors on Port 1 (P1) 179 /// Admit Frames with IFG Errors on Port 1 (P1)
180 pub p1_rcv_ifg_err_frm, set_p1_rcv_ifg_err_frm : 4; 180 pub p1_rcv_ifg_err_frm, set_p1_rcv_ifg_err_frm : 4;