forked from M-Labs/artiq-zynq
proto fw: use byteoder crate & add cxpwrite fn
This commit is contained in:
parent
b15d9cc668
commit
3642d81612
|
@ -1,11 +1,11 @@
|
||||||
use core::slice;
|
use core::slice;
|
||||||
|
|
||||||
|
use byteorder::{ByteOrder, NetworkEndian};
|
||||||
use core_io::{Error as IoError, Read, Write};
|
use core_io::{Error as IoError, Read, Write};
|
||||||
use crc::crc32::checksum_ieee;
|
use crc::crc32::checksum_ieee;
|
||||||
use io::Cursor;
|
use io::Cursor;
|
||||||
use libboard_zynq::println;
|
use libboard_zynq::println;
|
||||||
|
|
||||||
// TODO: fix the import
|
|
||||||
use crate::{mem::mem::{CXP_LOOPBACK_MEM, CXP_RX_MEM, CXP_TX_MEM},
|
use crate::{mem::mem::{CXP_LOOPBACK_MEM, CXP_RX_MEM, CXP_TX_MEM},
|
||||||
pl::csr::CXP};
|
pl::csr::CXP};
|
||||||
|
|
||||||
|
@ -41,6 +41,33 @@ impl From<IoError> 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<u8, Error>;
|
||||||
|
|
||||||
|
fn read_u32(&mut self) -> Result<u32, Error>;
|
||||||
|
}
|
||||||
|
impl<Cursor: Read> CxpRead for Cursor {
|
||||||
|
fn read_4x_u8(&mut self) -> Result<u8, Error> {
|
||||||
|
// TODO: add error correction
|
||||||
|
let mut bytes = [0; 4];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(bytes[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32(&mut self) -> Result<u32, Error> {
|
||||||
|
let mut bytes = [0; 4];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(NetworkEndian::read_u32(&bytes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DownConnPacket {
|
pub enum DownConnPacket {
|
||||||
CtrlReply {
|
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<u8, Error>;
|
|
||||||
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error>;
|
|
||||||
}
|
|
||||||
impl<Cursor: Read> CxpRead for Cursor {
|
|
||||||
#[inline]
|
|
||||||
fn read_4x_u8(&mut self) -> Result<u8, Error> {
|
|
||||||
// TODO: add error correction
|
|
||||||
let mut bytes = [0; 4];
|
|
||||||
self.read_exact(&mut bytes)?;
|
|
||||||
Ok(bytes[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_u32(&mut self) -> Result<u32, Error> {
|
|
||||||
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<DownConnPacket, Error> {
|
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 {
|
||||||
|
@ -145,6 +143,25 @@ pub fn receive(channel: usize) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait CxpWrite {
|
||||||
|
fn write_4x_u8(&mut self, value: u8) -> Result<(), Error>;
|
||||||
|
|
||||||
|
fn write_u32(&mut self, value: u32) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
impl<Cursor: Write> 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)]
|
#[derive(Debug)]
|
||||||
pub enum UpConnPacket {
|
pub enum UpConnPacket {
|
||||||
CtrlRead {
|
CtrlRead {
|
||||||
|
@ -178,20 +195,20 @@ impl UpConnPacket {
|
||||||
UpConnPacket::CtrlRead { tag, addr, length } => {
|
UpConnPacket::CtrlRead { tag, addr, length } => {
|
||||||
match tag {
|
match tag {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
writer.write(&[0x05; 4])?;
|
writer.write_4x_u8(0x05)?;
|
||||||
writer.write(&[t; 4])?;
|
writer.write_4x_u8(t)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
writer.write(&[0x02; 4])?;
|
writer.write_4x_u8(0x02)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.write(&[0x00, 0x00, 0x00, length])?;
|
writer.write_all(&[0x00, 0x00, 0x00, length])?;
|
||||||
writer.write(&addr.to_be_bytes())?;
|
writer.write_u32(addr)?;
|
||||||
|
|
||||||
// Section 9.6.2 (CXP-001-2021)
|
// Section 9.6.2 (CXP-001-2021)
|
||||||
// only bytes after the first 4 are used in calculating the checksum
|
// only bytes after the first 4 are used in calculating the checksum
|
||||||
let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]);
|
let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]);
|
||||||
writer.write(&checksum.to_be_bytes())?;
|
writer.write_u32(checksum)?;
|
||||||
}
|
}
|
||||||
UpConnPacket::CtrlWrite {
|
UpConnPacket::CtrlWrite {
|
||||||
tag,
|
tag,
|
||||||
|
@ -201,38 +218,38 @@ impl UpConnPacket {
|
||||||
} => {
|
} => {
|
||||||
match tag {
|
match tag {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
writer.write(&[0x05; 4])?;
|
writer.write_4x_u8(0x05)?;
|
||||||
writer.write(&[t; 4])?;
|
writer.write_4x_u8(t)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
writer.write(&[0x02; 4])?;
|
writer.write_4x_u8(0x02)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.write(&[0x01, 0x00, 0x00, length])?;
|
writer.write_all(&[0x01, 0x00, 0x00, length])?;
|
||||||
writer.write(&addr.to_be_bytes())?;
|
writer.write_u32(addr)?;
|
||||||
writer.write(&data[0..length as usize])?;
|
writer.write_all(&data[0..length as usize])?;
|
||||||
|
|
||||||
// Section 9.6.2 (CXP-001-2021)
|
// Section 9.6.2 (CXP-001-2021)
|
||||||
// only bytes after the first 4 are used in calculating the checksum
|
// only bytes after the first 4 are used in calculating the checksum
|
||||||
let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]);
|
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 } => {
|
UpConnPacket::EventAck { packet_tag } => {
|
||||||
writer.write(&[0x08; 4])?;
|
writer.write_4x_u8(0x08)?;
|
||||||
writer.write(&[packet_tag; 4])?;
|
writer.write_4x_u8(packet_tag)?;
|
||||||
}
|
}
|
||||||
// DEBUG: Loopback message
|
// DEBUG: Loopback message
|
||||||
UpConnPacket::CtrlAckLoopback { ackcode, length, data } => {
|
UpConnPacket::CtrlAckLoopback { ackcode, length, data } => {
|
||||||
writer.write(&[0x03; 4])?;
|
writer.write_4x_u8(0x03)?;
|
||||||
writer.write(&[ackcode; 4])?;
|
writer.write_4x_u8(ackcode)?;
|
||||||
|
|
||||||
if ackcode == 0x00 || ackcode == 0x04 {
|
if ackcode == 0x00 || ackcode == 0x04 {
|
||||||
writer.write(&[0x00, 0x00, 0x00, length])?;
|
writer.write_all(&[0x00, 0x00, 0x00, length])?;
|
||||||
writer.write(&data[0..length as usize])?;
|
writer.write_all(&data[0..length as usize])?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]);
|
let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]);
|
||||||
writer.write(&checksum.to_be_bytes())?;
|
writer.write_u32(checksum)?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue