1
0
Fork 0

proto fw: refactor cxp crc into helper function

This commit is contained in:
morgan 2024-10-04 12:09:32 +08:00
parent 25f29bc009
commit 90fff28b84
1 changed files with 29 additions and 26 deletions

View File

@ -1,7 +1,7 @@
use core::slice;
use core_io::{Error as IoError, Read, Write};
use crc::crc32;
use crc::crc32::checksum_ieee;
use io::Cursor;
use libboard_zynq::println;
@ -58,7 +58,14 @@ pub enum DownConnPacket {
},
}
pub fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Result<DownConnPacket, Error> {
// Section 9.2.2.2 (CXP-001-2021)
// Only Control packet need CRC32 appended in the end of the packet
// CoaXpress use the polynomial of IEEE-802.3 (Ethernet) CRC but the checksum calculation is different
fn get_cxp_crc(bytes: &[u8]) -> u32 {
(!checksum_ieee(bytes)).swap_bytes()
}
fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Result<DownConnPacket, Error> {
let mut tag: Option<u8> = None;
if with_tag {
tag = Some((read_word(reader)? & 0xFF) as u8);
@ -71,6 +78,14 @@ pub fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Re
let length = read_word(reader)?;
let mut data: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
reader.read(&mut data[0..length as usize])?;
let checksum = get_cxp_crc(&reader.get_ref()[0..reader.position()]);
let recv_checksum = read_word(reader)?;
println!("calculated checksum = {:#010X}", checksum);
println!("read checksum = {:#010X}", recv_checksum);
if recv_checksum != checksum {
return Err(Error::CorruptedPacket);
}
return Ok(DownConnPacket::CtrlReply { tag, length, data });
}
0x01 => return Ok(DownConnPacket::CtrlAck { tag }),
@ -78,6 +93,14 @@ pub fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Re
let length = read_word(reader)?;
let mut time: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
reader.read(&mut time[0..length as usize])?;
let checksum = get_cxp_crc(&reader.get_ref()[0..reader.position()]);
let recv_checksum = read_word(reader)?;
println!("calculated checksum = {:#010X}", checksum);
println!("read checksum = {:#010X}", recv_checksum);
if recv_checksum != checksum {
return Err(Error::CorruptedPacket);
}
return Ok(DownConnPacket::CtrlDelay { tag, length, time });
}
_ => return Err(Error::CtrlAckError(ackcode)),
@ -172,22 +195,18 @@ impl Packet {
writer.write(&data[0..length as usize])?;
}
let checksum = (!crc::crc32::checksum_ieee(&writer.get_ref()[4..writer.position()])).swap_bytes();
writer.write(&checksum.to_be_bytes())?;
writer.write(&get_cxp_crc(&writer.get_ref()[4..writer.position()]).to_be_bytes())?;
}
_ => {}
}
// Section 9.2.2.2 (CXP-001-2021)
// Only Control packet need CRC32 appended in the end of the packet
// CoaXpress use the polynomial of IEEE-802.3 (Ethernet) CRC but the checksum calculation is different
// Also, the calculation does not include the first 4 bytes of packet_type
// The crc calculation does not include the first 4 bytes of packet_type
match *self {
Packet::CtrlRead { .. }
| Packet::CtrlWrite { .. }
| Packet::CtrlReadWithTag { .. }
| Packet::CtrlWriteWithTag { .. } => {
let checksum = (!crc::crc32::checksum_ieee(&writer.get_ref()[4..writer.position()])).swap_bytes();
writer.write(&checksum.to_be_bytes())?;
writer.write(&get_cxp_crc(&writer.get_ref()[4..writer.position()]).to_be_bytes())?;
}
_ => {}
}
@ -204,27 +223,11 @@ pub fn receive(channel: usize) -> Result<(), Error> {
let packet = match packet_type {
0x03 => capture_ctrl_packet(&mut reader, false),
0x06 => capture_ctrl_packet(&mut reader, false),
0x06 => capture_ctrl_packet(&mut reader, true),
_ => return Err(Error::UnknownPacket(packet_type)),
};
println!("{:?}", packet);
// Section 9.2.2.2 (CXP-001-2021)
// Only Control packet need CRC32 appended in the end of the packet
// CoaXpress use the polynomial of IEEE-802.3 (Ethernet) CRC but the checksum calculation is different
// Also, the calculation does not include the first 4 bytes of packet_type
if packet_type == 0x03 || packet_type == 0x06 {
let checksum_at = reader.position();
let checksum = (!crc::crc32::checksum_ieee(&reader.get_ref()[0..checksum_at])).swap_bytes();
println!("checksum location = {:#010X}", checksum_at);
println!("calculated checksum = {:#010X}", checksum);
println!("read checksum = {:#010X}", read_word(&mut reader)?);
reader.set_position(checksum_at);
if read_word(&mut reader)? != checksum {
return Err(Error::CorruptedPacket);
}
}
print_packet(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
}
Ok(())