forked from M-Labs/artiq-zynq
proto fw: add helper trait for cursor
This commit is contained in:
parent
35b84c768a
commit
b055abe4eb
|
@ -65,22 +65,44 @@ 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> {
|
||||
let mut tag: Option<u8> = None;
|
||||
if with_tag {
|
||||
tag = Some((read_word(reader)? & 0xFF) as u8);
|
||||
tag = Some(reader.read_4x_u8()?);
|
||||
}
|
||||
|
||||
let ackcode: u8 = (read_word(reader)? & 0xFF) as u8;
|
||||
let ackcode = reader.read_4x_u8()?;
|
||||
|
||||
match ackcode {
|
||||
0x00 => {
|
||||
let length = read_word(reader)?;
|
||||
let length = reader.read_u32()?;
|
||||
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)?;
|
||||
let recv_checksum = reader.read_u32()?;
|
||||
println!("calculated checksum = {:#010X}", checksum);
|
||||
println!("read checksum = {:#010X}", recv_checksum);
|
||||
if recv_checksum != checksum {
|
||||
|
@ -90,12 +112,12 @@ fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Result
|
|||
}
|
||||
0x01 => return Ok(DownConnPacket::CtrlAck { tag }),
|
||||
0x04 => {
|
||||
let length = read_word(reader)?;
|
||||
let length = reader.read_u32()?;
|
||||
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)?;
|
||||
let recv_checksum = reader.read_u32()?;
|
||||
println!("calculated checksum = {:#010X}", checksum);
|
||||
println!("read checksum = {:#010X}", recv_checksum);
|
||||
if recv_checksum != checksum {
|
||||
|
@ -107,6 +129,22 @@ fn capture_ctrl_packet(reader: &mut Cursor<&mut [u8]>, with_tag: bool) -> Result
|
|||
}
|
||||
}
|
||||
|
||||
pub fn receive(channel: usize) -> Result<(), Error> {
|
||||
unsafe {
|
||||
let ptr = CXP_RX_MEM[channel].base as *mut u32;
|
||||
let mut reader = Cursor::new(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
|
||||
let packet_type = (CXP[channel].downconn_packet_type_read)();
|
||||
|
||||
let packet = match packet_type {
|
||||
0x03 => capture_ctrl_packet(&mut reader, false),
|
||||
0x06 => capture_ctrl_packet(&mut reader, true),
|
||||
_ => return Err(Error::UnknownPacket(packet_type)),
|
||||
};
|
||||
println!("{:?}", packet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UpConnPacket {
|
||||
CtrlRead {
|
||||
|
@ -133,12 +171,6 @@ pub enum UpConnPacket {
|
|||
},
|
||||
}
|
||||
|
||||
fn read_word(reader: &mut Cursor<&mut [u8]>) -> Result<u32, Error> {
|
||||
let mut bytes = [0; 4];
|
||||
reader.read(&mut bytes)?;
|
||||
Ok(u32::from_be_bytes(bytes))
|
||||
}
|
||||
|
||||
impl UpConnPacket {
|
||||
pub fn write_to(&self, writer: &mut Cursor<&mut [u8]>) -> Result<(), Error> {
|
||||
// CoaXpress use big endian
|
||||
|
@ -199,7 +231,8 @@ impl UpConnPacket {
|
|||
writer.write(&data[0..length as usize])?;
|
||||
}
|
||||
|
||||
writer.write(&get_cxp_crc(&writer.get_ref()[4..writer.position()]).to_be_bytes())?;
|
||||
let checksum = get_cxp_crc(&writer.get_ref()[4..writer.position()]);
|
||||
writer.write(&checksum.to_be_bytes())?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -207,22 +240,6 @@ impl UpConnPacket {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn receive(channel: usize) -> Result<(), Error> {
|
||||
unsafe {
|
||||
let ptr = CXP_RX_MEM[channel].base as *mut u32;
|
||||
let mut reader = Cursor::new(slice::from_raw_parts_mut(ptr as *mut u8, MEM_LEN));
|
||||
let packet_type = (CXP[channel].downconn_packet_type_read)();
|
||||
|
||||
let packet = match packet_type {
|
||||
0x03 => capture_ctrl_packet(&mut reader, false),
|
||||
0x06 => capture_ctrl_packet(&mut reader, true),
|
||||
_ => return Err(Error::UnknownPacket(packet_type)),
|
||||
};
|
||||
println!("{:?}", packet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn send(channel: usize, packet: &UpConnPacket) -> Result<(), Error> {
|
||||
if unsafe { (CXP[channel].upconn_tx_enable_read)() } == 0 {
|
||||
Err(Error::LinkDown)?
|
||||
|
@ -268,50 +285,50 @@ fn send_test_packet(channel: usize) -> Result<(), Error> {
|
|||
//
|
||||
//
|
||||
//
|
||||
pub fn write_u32(channel: usize, addr: u32, data: u32) -> Result<(), Error> {
|
||||
let mut data_slice: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
|
||||
data_slice[..4].clone_from_slice(&data.to_be_bytes());
|
||||
send(
|
||||
channel,
|
||||
&UpConnPacket::CtrlWrite {
|
||||
tag: None,
|
||||
addr,
|
||||
length: 4,
|
||||
data: data_slice,
|
||||
},
|
||||
)?;
|
||||
// pub fn write_u32(channel: usize, addr: u32, data: u32) -> Result<(), Error> {
|
||||
// let mut data_slice: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
|
||||
// data_slice[..4].clone_from_slice(&data.to_be_bytes());
|
||||
// send(
|
||||
// channel,
|
||||
// &UpConnPacket::CtrlWrite {
|
||||
// tag: None,
|
||||
// addr,
|
||||
// length: 4,
|
||||
// data: data_slice,
|
||||
// },
|
||||
// )?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn read_u32(channel: usize, addr: u32) -> Result<(), Error> {
|
||||
send(
|
||||
channel,
|
||||
&UpConnPacket::CtrlRead {
|
||||
tag: None,
|
||||
addr,
|
||||
length: 4,
|
||||
},
|
||||
)?;
|
||||
// pub fn read_u32(channel: usize, addr: u32) -> Result<(), Error> {
|
||||
// send(
|
||||
// channel,
|
||||
// &UpConnPacket::CtrlRead {
|
||||
// tag: None,
|
||||
// addr,
|
||||
// length: 4,
|
||||
// },
|
||||
// )?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn write_u64(channel: usize, addr: u32, data: u64) -> Result<(), Error> {
|
||||
let mut data_slice: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
|
||||
data_slice[..8].clone_from_slice(&data.to_be_bytes());
|
||||
send(
|
||||
channel,
|
||||
&UpConnPacket::CtrlWrite {
|
||||
tag: None,
|
||||
addr,
|
||||
length: 8,
|
||||
data: data_slice,
|
||||
},
|
||||
)?;
|
||||
// pub fn write_u64(channel: usize, addr: u32, data: u64) -> Result<(), Error> {
|
||||
// let mut data_slice: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
|
||||
// data_slice[..8].clone_from_slice(&data.to_be_bytes());
|
||||
// send(
|
||||
// channel,
|
||||
// &UpConnPacket::CtrlWrite {
|
||||
// tag: None,
|
||||
// addr,
|
||||
// length: 8,
|
||||
// data: data_slice,
|
||||
// },
|
||||
// )?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn print_packet(pak: &[u8]) {
|
||||
println!("pak = [");
|
||||
|
|
Loading…
Reference in New Issue