From 3642d816125969122130da84285099e2ebe6f6a4 Mon Sep 17 00:00:00 2001 From: morgan Date: Fri, 4 Oct 2024 16:01:51 +0800 Subject: [PATCH] proto fw: use byteoder crate & add cxpwrite fn --- src/libboard_artiq/src/cxp_proto.rs | 117 ++++++++++++++++------------ 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/src/libboard_artiq/src/cxp_proto.rs b/src/libboard_artiq/src/cxp_proto.rs index 7560d1c..de1e39f 100644 --- a/src/libboard_artiq/src/cxp_proto.rs +++ b/src/libboard_artiq/src/cxp_proto.rs @@ -1,11 +1,11 @@ use core::slice; +use byteorder::{ByteOrder, NetworkEndian}; use core_io::{Error as IoError, Read, Write}; use crc::crc32::checksum_ieee; use io::Cursor; use libboard_zynq::println; -// TODO: fix the import use crate::{mem::mem::{CXP_LOOPBACK_MEM, CXP_RX_MEM, CXP_TX_MEM}, pl::csr::CXP}; @@ -41,6 +41,33 @@ impl From for 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() +} + +trait CxpRead { + fn read_4x_u8(&mut self) -> Result; + + fn read_u32(&mut self) -> Result; +} +impl CxpRead for Cursor { + fn read_4x_u8(&mut self) -> Result { + // TODO: add error correction + let mut bytes = [0; 4]; + self.read_exact(&mut bytes)?; + Ok(bytes[0]) + } + + fn read_u32(&mut self) -> Result { + let mut bytes = [0; 4]; + self.read_exact(&mut bytes)?; + Ok(NetworkEndian::read_u32(&bytes)) + } +} + #[derive(Debug)] pub enum DownConnPacket { CtrlReply { @@ -58,35 +85,6 @@ pub enum DownConnPacket { }, } -// 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() -} - -trait CxpRead { - fn read_4x_u8(&mut self) -> Result; - - fn read_u32(&mut self) -> Result; -} -impl CxpRead for Cursor { - #[inline] - fn read_4x_u8(&mut self) -> Result { - // TODO: add error correction - let mut bytes = [0; 4]; - self.read_exact(&mut bytes)?; - Ok(bytes[0]) - } - - #[inline] - fn read_u32(&mut self) -> Result { - let mut bytes = [0; 4]; - self.read_exact(&mut bytes)?; - Ok(u32::from_be_bytes(bytes)) - } -} - fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Result { let mut tag: Option = None; if with_tag { @@ -145,6 +143,25 @@ pub fn receive(channel: usize) -> Result<(), Error> { Ok(()) } +trait CxpWrite { + fn write_4x_u8(&mut self, value: u8) -> Result<(), Error>; + + fn write_u32(&mut self, value: u32) -> Result<(), Error>; +} +impl CxpWrite for Cursor { + fn write_4x_u8(&mut self, value: u8) -> Result<(), Error> { + self.write_all(&[value; 4])?; + Ok(()) + } + + fn write_u32(&mut self, value: u32) -> Result<(), Error> { + let mut bytes = [0; 4]; + NetworkEndian::write_u32(&mut bytes, value); + self.write_all(&bytes)?; + Ok(()) + } +} + #[derive(Debug)] pub enum UpConnPacket { CtrlRead { @@ -178,20 +195,20 @@ impl UpConnPacket { UpConnPacket::CtrlRead { tag, addr, length } => { match tag { Some(t) => { - writer.write(&[0x05; 4])?; - writer.write(&[t; 4])?; + writer.write_4x_u8(0x05)?; + writer.write_4x_u8(t)?; } None => { - writer.write(&[0x02; 4])?; + writer.write_4x_u8(0x02)?; } } - writer.write(&[0x00, 0x00, 0x00, length])?; - writer.write(&addr.to_be_bytes())?; + writer.write_all(&[0x00, 0x00, 0x00, length])?; + writer.write_u32(addr)?; // Section 9.6.2 (CXP-001-2021) // only bytes after the first 4 are used in calculating the checksum let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]); - writer.write(&checksum.to_be_bytes())?; + writer.write_u32(checksum)?; } UpConnPacket::CtrlWrite { tag, @@ -201,38 +218,38 @@ impl UpConnPacket { } => { match tag { Some(t) => { - writer.write(&[0x05; 4])?; - writer.write(&[t; 4])?; + writer.write_4x_u8(0x05)?; + writer.write_4x_u8(t)?; } None => { - writer.write(&[0x02; 4])?; + writer.write_4x_u8(0x02)?; } } - writer.write(&[0x01, 0x00, 0x00, length])?; - writer.write(&addr.to_be_bytes())?; - writer.write(&data[0..length as usize])?; + writer.write_all(&[0x01, 0x00, 0x00, length])?; + writer.write_u32(addr)?; + writer.write_all(&data[0..length as usize])?; // Section 9.6.2 (CXP-001-2021) // only bytes after the first 4 are used in calculating the checksum let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]); - writer.write(&checksum.to_be_bytes())?; + writer.write_u32(checksum)?; } UpConnPacket::EventAck { packet_tag } => { - writer.write(&[0x08; 4])?; - writer.write(&[packet_tag; 4])?; + writer.write_4x_u8(0x08)?; + writer.write_4x_u8(packet_tag)?; } // DEBUG: Loopback message UpConnPacket::CtrlAckLoopback { ackcode, length, data } => { - writer.write(&[0x03; 4])?; - writer.write(&[ackcode; 4])?; + writer.write_4x_u8(0x03)?; + writer.write_4x_u8(ackcode)?; if ackcode == 0x00 || ackcode == 0x04 { - writer.write(&[0x00, 0x00, 0x00, length])?; - writer.write(&data[0..length as usize])?; + writer.write_all(&[0x00, 0x00, 0x00, length])?; + writer.write_all(&data[0..length as usize])?; } let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]); - writer.write(&checksum.to_be_bytes())?; + writer.write_u32(checksum)?; } _ => {} }