forked from M-Labs/artiq-zynq
upconn fw: use cxp_protco and remove unused function
This commit is contained in:
parent
98095664ce
commit
b1069f524a
|
@ -4,23 +4,9 @@ use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs;
|
||||||
use io::Cursor;
|
use io::Cursor;
|
||||||
use libboard_zynq::{println, timer::GlobalTimer};
|
use libboard_zynq::{println, timer::GlobalTimer};
|
||||||
|
|
||||||
|
pub use crate::cxp_proto;
|
||||||
use crate::pl::csr;
|
use crate::pl::csr;
|
||||||
|
|
||||||
const MAX_PACKET: usize = 128;
|
|
||||||
const DATA_MAXSIZE: usize = /*max size*/MAX_PACKET - /*Tag*/4 - /*Op code & length*/4 - /*addr*/4 - /*CRC*/4 ;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
BufferError,
|
|
||||||
LinkDown,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<IoError> for Error {
|
|
||||||
fn from(_: IoError) -> Error {
|
|
||||||
Error::BufferError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn tx_test(timer: &mut GlobalTimer) {
|
pub fn tx_test(timer: &mut GlobalTimer) {
|
||||||
const LEN: usize = 4 * 50;
|
const LEN: usize = 4 * 50;
|
||||||
let mut pak_arr: [u8; LEN] = [0; LEN];
|
let mut pak_arr: [u8; LEN] = [0; LEN];
|
||||||
|
@ -33,8 +19,8 @@ pub fn tx_test(timer: &mut GlobalTimer) {
|
||||||
// read_u32(0x00).expect("Cannot Write CoaXpress Register");
|
// read_u32(0x00).expect("Cannot Write CoaXpress Register");
|
||||||
csr::cxp::upconn_tx_enable_write(1);
|
csr::cxp::upconn_tx_enable_write(1);
|
||||||
timer.delay_us(2); // send one word
|
timer.delay_us(2); // send one word
|
||||||
// send(&Packet::EventAck { packet_tag: 0x04 }).expect("Cannot send CoaXpress packet");
|
cxp_proto::send(&cxp_proto::Packet::EventAck { packet_tag: 0x04 }).expect("Cannot send CoaXpress packet");
|
||||||
send(&Packet::TestPacket).expect("Cannot send CoaXpress packet");
|
// cxp_proto::send(&cxp_proto::Packet::TestPacket).expect("Cannot send CoaXpress packet");
|
||||||
|
|
||||||
// timer.delay_us(2);
|
// timer.delay_us(2);
|
||||||
// DEBUG: Trigger packet
|
// DEBUG: Trigger packet
|
||||||
|
@ -60,177 +46,6 @@ pub fn tx_test(timer: &mut GlobalTimer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_packet(&pak_arr);
|
cxp_proto::print_packet(&pak_arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Packet {
|
|
||||||
CtrlRead {
|
|
||||||
addr: u32,
|
|
||||||
length: u8,
|
|
||||||
},
|
|
||||||
CtrlWrite {
|
|
||||||
addr: u32,
|
|
||||||
length: u8,
|
|
||||||
data: [u8; DATA_MAXSIZE],
|
|
||||||
}, // max register size is 8 bytes
|
|
||||||
CtrlReadWithTag {
|
|
||||||
tag: u8,
|
|
||||||
addr: u32,
|
|
||||||
length: u8,
|
|
||||||
},
|
|
||||||
CtrlWriteWithTag {
|
|
||||||
tag: u8,
|
|
||||||
addr: u32,
|
|
||||||
length: u8,
|
|
||||||
data: [u8; DATA_MAXSIZE],
|
|
||||||
}, // max register size is 8 bytes
|
|
||||||
EventAck {
|
|
||||||
packet_tag: u8,
|
|
||||||
},
|
|
||||||
TestPacket,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Packet {
|
|
||||||
pub fn write_to(&self, writer: &mut Cursor<&mut [u8]>) -> Result<(), Error> {
|
|
||||||
// CoaXpress use big endian
|
|
||||||
match *self {
|
|
||||||
Packet::CtrlRead { addr, length } => {
|
|
||||||
writer.write(&[0x02; 4])?;
|
|
||||||
writer.write(&[0x00, 0x00, 0x00, length])?;
|
|
||||||
writer.write(&addr.to_be_bytes())?;
|
|
||||||
}
|
|
||||||
Packet::CtrlWrite { addr, length, data } => {
|
|
||||||
writer.write(&[0x02; 4])?;
|
|
||||||
writer.write(&[0x01, 0x00, 0x00, length])?;
|
|
||||||
writer.write(&addr.to_be_bytes())?;
|
|
||||||
writer.write(&data[0..length as usize])?;
|
|
||||||
}
|
|
||||||
Packet::CtrlReadWithTag { tag, addr, length } => {
|
|
||||||
writer.write(&[0x05; 4])?;
|
|
||||||
writer.write(&[tag; 4])?;
|
|
||||||
writer.write(&[0x00, 0x00, 0x00, length])?;
|
|
||||||
writer.write(&addr.to_be_bytes())?;
|
|
||||||
}
|
|
||||||
Packet::CtrlWriteWithTag {
|
|
||||||
tag,
|
|
||||||
addr,
|
|
||||||
length,
|
|
||||||
data,
|
|
||||||
} => {
|
|
||||||
writer.write(&[0x05; 4])?;
|
|
||||||
writer.write(&[tag; 4])?;
|
|
||||||
writer.write(&[0x01, 0x00, 0x00, length])?;
|
|
||||||
writer.write(&addr.to_be_bytes())?;
|
|
||||||
writer.write(&data[0..length as usize])?;
|
|
||||||
}
|
|
||||||
Packet::EventAck { packet_tag } => {
|
|
||||||
writer.write(&[0x08; 4])?;
|
|
||||||
writer.write(&[packet_tag; 4])?;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
// 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
|
|
||||||
match *self {
|
|
||||||
Packet::CtrlRead { .. }
|
|
||||||
| Packet::CtrlWrite { .. }
|
|
||||||
| Packet::CtrlReadWithTag { .. }
|
|
||||||
| Packet::CtrlWriteWithTag { .. } => {
|
|
||||||
let checksum = crc32::checksum_ieee(&writer.get_ref()[4..writer.position()]);
|
|
||||||
writer.write(&(!checksum).to_le_bytes())?;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send(packet: &Packet) -> Result<(), Error> {
|
|
||||||
// DEBUG: remove the comment out section
|
|
||||||
// if unsafe { csr::cxp::upconn_tx_enable_read() } == 0 {
|
|
||||||
// Err(Error::LinkDown)?
|
|
||||||
// }
|
|
||||||
|
|
||||||
match *packet {
|
|
||||||
Packet::TestPacket => send_test_packet(),
|
|
||||||
_ => send_data_packet(packet),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_data_packet(packet: &Packet) -> Result<(), Error> {
|
|
||||||
let mut buffer: [u8; MAX_PACKET] = [0; MAX_PACKET];
|
|
||||||
let mut writer = Cursor::new(&mut buffer[..]);
|
|
||||||
|
|
||||||
packet.write_to(&mut writer)?;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let len = writer.position();
|
|
||||||
csr::cxp::upconn_command_len_write(len as u8);
|
|
||||||
for data in writer.get_ref()[..len].iter() {
|
|
||||||
while csr::cxp::upconn_command_writeable_read() == 0 {}
|
|
||||||
csr::cxp::upconn_command_data_write(*data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_test_packet() -> Result<(), Error> {
|
|
||||||
unsafe {
|
|
||||||
while csr::cxp::upconn_tx_busy_read() == 1 {}
|
|
||||||
csr::cxp::upconn_tx_testmode_en_write(1);
|
|
||||||
// timer.delay_us(2);
|
|
||||||
csr::cxp::upconn_testseq_stb_write(1);
|
|
||||||
while csr::cxp::upconn_testseq_busy_read() == 1 {}
|
|
||||||
csr::cxp::upconn_tx_testmode_en_write(0);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_u32(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(&Packet::CtrlWrite {
|
|
||||||
addr,
|
|
||||||
length: 4,
|
|
||||||
data: data_slice,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_u32(addr: u32) -> Result<(), Error> {
|
|
||||||
send(&Packet::CtrlRead { addr, length: 4 })?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_u64(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(&Packet::CtrlWrite {
|
|
||||||
addr,
|
|
||||||
length: 8,
|
|
||||||
data: data_slice,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_packet(pak: &[u8]) {
|
|
||||||
println!("pak = [");
|
|
||||||
for i in 0..(pak.len() / 4) {
|
|
||||||
println!(
|
|
||||||
"{:#03} {:#04X} {:#04X} {:#04X} {:#04X},",
|
|
||||||
i + 1,
|
|
||||||
pak[i * 4],
|
|
||||||
pak[i * 4 + 1],
|
|
||||||
pak[i * 4 + 2],
|
|
||||||
pak[i * 4 + 3]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
println!("]");
|
|
||||||
println!("============================================");
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue