forked from M-Labs/artiq-zynq
cxp upconn fw: add rest of u32 u64 control packet
This commit is contained in:
parent
168c75eaf6
commit
f2d7a67da3
|
@ -1,4 +1,4 @@
|
||||||
use core_io::{Error as IoError, Read, Write};
|
use core_io::{Error as IoError, Write};
|
||||||
use crc::crc32;
|
use crc::crc32;
|
||||||
use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs;
|
use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs;
|
||||||
use io::Cursor;
|
use io::Cursor;
|
||||||
|
@ -92,73 +92,74 @@ pub fn tx_test(timer: &mut GlobalTimer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Packet {
|
pub enum Command<T> {
|
||||||
ControlWrite_u32_no_tag {
|
ControlRead { addr: u32 },
|
||||||
addr: u32,
|
ControlWrite { addr: u32, data: T },
|
||||||
data: u32,
|
ControlReadWithTag { addr: u32, tag: u8 },
|
||||||
packet_type: u8,
|
ControlWriteWithTag { addr: u32, data: T, tag: u8 },
|
||||||
},
|
}
|
||||||
ControlRead_u32_no_tag {
|
|
||||||
addr: u32,
|
|
||||||
packet_type: u8,
|
|
||||||
},
|
|
||||||
ControlWrite_u64_no_tag {
|
|
||||||
addr: u32,
|
|
||||||
data: u64,
|
|
||||||
packet_type: u8,
|
|
||||||
},
|
|
||||||
ControlRead_u64_no_tag {
|
|
||||||
addr: u32,
|
|
||||||
packet_type: u8,
|
|
||||||
},
|
|
||||||
|
|
||||||
ControlWrite_u32_with_tag {
|
pub enum Packet {
|
||||||
addr: u32,
|
ControlU32Reg(Command<u32>),
|
||||||
data: u32,
|
ControlU64Reg(Command<u64>),
|
||||||
packet_type: u8,
|
|
||||||
tag: u8,
|
|
||||||
},
|
|
||||||
ControlRead_u32_with_tag {
|
|
||||||
addr: u32,
|
|
||||||
packet_type: u8,
|
|
||||||
tag: u8,
|
|
||||||
},
|
|
||||||
ControlWrite_u64_with_tag {
|
|
||||||
addr: u32,
|
|
||||||
data: u64,
|
|
||||||
packet_type: u8,
|
|
||||||
tag: u8,
|
|
||||||
},
|
|
||||||
ControlRead_u64_with_tag {
|
|
||||||
addr: u32,
|
|
||||||
packet_type: u8,
|
|
||||||
tag: u8,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Packet {
|
impl Packet {
|
||||||
pub fn write_to<W>(&self, writer: &mut W) -> Result<(), IoError>
|
pub fn write_to<W>(&self, writer: &mut W) -> Result<(), IoError>
|
||||||
where W: Write {
|
where W: Write {
|
||||||
match *self {
|
match self {
|
||||||
Packet::ControlWrite_u32_no_tag {
|
Packet::ControlU32Reg(cmd) => match cmd {
|
||||||
addr,
|
Command::ControlRead { addr } => {
|
||||||
data,
|
writer.write(&[0x02; 4])?;
|
||||||
packet_type,
|
writer.write(&[0x00, 0x00, 0x00, 0x04])?;
|
||||||
} => {
|
writer.write(&addr.to_be_bytes())?;
|
||||||
writer.write(&[packet_type; 4])?;
|
}
|
||||||
writer.write(&[0x01, 0x00, 0x00, 0x04])?;
|
Command::ControlWrite { addr, data } => {
|
||||||
writer.write(&addr.to_be_bytes())?;
|
writer.write(&[0x02; 4])?;
|
||||||
writer.write(&data.to_be_bytes())?;
|
writer.write(&[0x01, 0x00, 0x00, 0x04])?;
|
||||||
}
|
writer.write(&addr.to_be_bytes())?;
|
||||||
Packet::ControlRead_u32_no_tag { addr, packet_type } => {
|
writer.write(&data.to_be_bytes())?;
|
||||||
writer.write(&[packet_type; 4])?;
|
}
|
||||||
writer.write(&[0x00, 0x00, 0x00, 0x04])?;
|
Command::ControlReadWithTag { addr, tag } => {
|
||||||
writer.write(&addr.to_be_bytes())?;
|
writer.write(&[0x05; 4])?;
|
||||||
}
|
writer.write(&[*tag; 4])?;
|
||||||
_ => {
|
writer.write(&[0x00, 0x00, 0x00, 0x04])?;
|
||||||
// // TODO: placeholder for rust borrow checker
|
writer.write(&addr.to_be_bytes())?;
|
||||||
// writer.write_u32(0x00)?;
|
}
|
||||||
}
|
Command::ControlWriteWithTag { addr, data, tag } => {
|
||||||
|
writer.write(&[0x05; 4])?;
|
||||||
|
writer.write(&[*tag; 4])?;
|
||||||
|
writer.write(&[0x01, 0x00, 0x00, 0x04])?;
|
||||||
|
writer.write(&addr.to_be_bytes())?;
|
||||||
|
writer.write(&data.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Packet::ControlU64Reg(cmd) => match cmd {
|
||||||
|
Command::ControlRead { addr } => {
|
||||||
|
writer.write(&[0x02; 4])?;
|
||||||
|
writer.write(&[0x00, 0x00, 0x00, 0x08])?;
|
||||||
|
writer.write(&addr.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
Command::ControlWrite { addr, data } => {
|
||||||
|
writer.write(&[0x02; 4])?;
|
||||||
|
writer.write(&[0x01, 0x00, 0x00, 0x08])?;
|
||||||
|
writer.write(&addr.to_be_bytes())?;
|
||||||
|
writer.write(&data.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
Command::ControlReadWithTag { addr, tag } => {
|
||||||
|
writer.write(&[0x05; 4])?;
|
||||||
|
writer.write(&[*tag; 4])?;
|
||||||
|
writer.write(&[0x00, 0x00, 0x00, 0x08])?;
|
||||||
|
writer.write(&addr.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
Command::ControlWriteWithTag { addr, data, tag } => {
|
||||||
|
writer.write(&[0x05; 4])?;
|
||||||
|
writer.write(&[*tag; 4])?;
|
||||||
|
writer.write(&[0x01, 0x00, 0x00, 0x08])?;
|
||||||
|
writer.write(&addr.to_be_bytes())?;
|
||||||
|
writer.write(&data.to_be_bytes())?;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -171,16 +172,9 @@ pub fn send(packet: &Packet) -> Result<(), IoError> {
|
||||||
|
|
||||||
packet.write_to(&mut writer)?;
|
packet.write_to(&mut writer)?;
|
||||||
|
|
||||||
// // Pad till offset 4, insert checksum there
|
|
||||||
// let padding = (12 - (writer.position() % 8)) % 8;
|
|
||||||
// for _ in 0..padding {
|
|
||||||
// writer.write_u8(0)?;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Section 9.2.2.2 (CXP-001-2021)
|
// Section 9.2.2.2 (CXP-001-2021)
|
||||||
// CoaXpress use the polynomial of IEEE-802.3 (Ethernet) CRC but the checksum calculation is different
|
// 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
|
// Also, the calculation does not include the first 4 bytes of packet_type
|
||||||
|
|
||||||
let checksum = crc32::checksum_ieee(&writer.get_ref()[4..writer.position()]);
|
let checksum = crc32::checksum_ieee(&writer.get_ref()[4..writer.position()]);
|
||||||
writer.write(&(!checksum).to_le_bytes())?;
|
writer.write(&(!checksum).to_le_bytes())?;
|
||||||
|
|
||||||
|
@ -197,22 +191,8 @@ pub fn send(packet: &Packet) -> Result<(), IoError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pipeline_test(timer: &mut GlobalTimer) {
|
pub fn pipeline_test(timer: &mut GlobalTimer) {
|
||||||
let address: u32 = 0x0000_00FF;
|
|
||||||
let tag: u8 = 0x44;
|
|
||||||
let d0: u32 = 0x0000_0032;
|
|
||||||
let d1: u64 = 0x0000_0064;
|
|
||||||
|
|
||||||
// send(&Packet::ControlWrite_u32_no_tag {
|
|
||||||
// addr: address,
|
|
||||||
// data: d0,
|
|
||||||
// packet_type: 0x02,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// CXP CRC example
|
// CXP CRC example
|
||||||
send(&Packet::ControlRead_u32_no_tag {
|
send(&Packet::ControlU32Reg(Command::ControlRead { addr: 0x00 })).expect("Cannot send CoaXpress packet");
|
||||||
addr: 0x00,
|
|
||||||
packet_type: 0x02,
|
|
||||||
});
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
timer.delay_us(1);
|
timer.delay_us(1);
|
||||||
|
|
Loading…
Reference in New Issue