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::slice;
use core_io::{Error as IoError, Read, Write}; use core_io::{Error as IoError, Read, Write};
use crc::crc32; use crc::crc32::checksum_ieee;
use io::Cursor; use io::Cursor;
use libboard_zynq::println; 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; let mut tag: Option<u8> = None;
if with_tag { if with_tag {
tag = Some((read_word(reader)? & 0xFF) as u8); 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 length = read_word(reader)?;
let mut data: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE]; let mut data: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
reader.read(&mut data[0..length as usize])?; 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 }); return Ok(DownConnPacket::CtrlReply { tag, length, data });
} }
0x01 => return Ok(DownConnPacket::CtrlAck { tag }), 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 length = read_word(reader)?;
let mut time: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE]; let mut time: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
reader.read(&mut time[0..length as usize])?; 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 Ok(DownConnPacket::CtrlDelay { tag, length, time });
} }
_ => return Err(Error::CtrlAckError(ackcode)), _ => return Err(Error::CtrlAckError(ackcode)),
@ -172,22 +195,18 @@ impl Packet {
writer.write(&data[0..length as usize])?; writer.write(&data[0..length as usize])?;
} }
let checksum = (!crc::crc32::checksum_ieee(&writer.get_ref()[4..writer.position()])).swap_bytes(); writer.write(&get_cxp_crc(&writer.get_ref()[4..writer.position()]).to_be_bytes())?;
writer.write(&checksum.to_be_bytes())?;
} }
_ => {} _ => {}
} }
// Section 9.2.2.2 (CXP-001-2021) // Section 9.2.2.2 (CXP-001-2021)
// Only Control packet need CRC32 appended in the end of the packet // The crc calculation does not include the first 4 bytes of packet_type
// 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
match *self { match *self {
Packet::CtrlRead { .. } Packet::CtrlRead { .. }
| Packet::CtrlWrite { .. } | Packet::CtrlWrite { .. }
| Packet::CtrlReadWithTag { .. } | Packet::CtrlReadWithTag { .. }
| Packet::CtrlWriteWithTag { .. } => { | Packet::CtrlWriteWithTag { .. } => {
let checksum = (!crc::crc32::checksum_ieee(&writer.get_ref()[4..writer.position()])).swap_bytes(); writer.write(&get_cxp_crc(&writer.get_ref()[4..writer.position()]).to_be_bytes())?;
writer.write(&checksum.to_be_bytes())?;
} }
_ => {} _ => {}
} }
@ -204,27 +223,11 @@ pub fn receive(channel: usize) -> Result<(), Error> {
let packet = match packet_type { let packet = match packet_type {
0x03 => capture_ctrl_packet(&mut reader, false), 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)), _ => return Err(Error::UnknownPacket(packet_type)),
}; };
println!("{:?}", packet); 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)); print_packet(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
} }
Ok(()) Ok(())