cxp upconn & downconn firmware: packet testing

downconn FW: fix compile err
This commit is contained in:
morgan 2024-07-23 16:40:17 +08:00
parent 5b4878f156
commit 3c44c66ab2
2 changed files with 180 additions and 0 deletions

View File

@ -0,0 +1,89 @@
use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs;
use libboard_zynq::{println, timer::GlobalTimer};
use log::info;
use crate::{cxp_phys, pl::csr::CXP};
pub fn loopback_testing(channel: usize, timer: &mut GlobalTimer, speed: cxp_phys::CXP_SPEED) {
println!("==============================================================================");
cxp_phys::change_linerate(speed);
unsafe {
info!("waiting for tx&rx setup...");
timer.delay_us(50_000);
// info!(
// "tx_phaligndone = {} | rx_phaligndone = {}",
// (CXP[channel].rx_txinit_phaligndone_read)(),
// (CXP[channel].rx_rxinit_phaligndone_read)(),
// );
// enable txdata tranmission thought MGTXTXP, required by PMA loopback
// (CXP[channel].rx_txenable_write)(1);
info!("waiting for rx to align...");
while (CXP[channel].rx_ready_read)() != 1 {}
info!("rx ready!");
// cxp_proto::rx_send_test_packet(channel);
// FIXME: why test + trig ack doesn't work well for rx??
// cxp_proto::rx_debug_send_trig_ack(channel);
// const DATA_MAXSIZE: usize = 253;
// let data_size = 4; // no. of bytes
// let data: u32 = 0xDADA as u32;
// let mut data_slice: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE];
// data_slice[..4].clone_from_slice(&data.to_be_bytes());
// cxp_proto::rx_debug_send(
// channel,
// &cxp_proto::UpConnPacket::Event {
// conn_id: 0x1234_5678_u32,
// packet_tag: 0x69_u8,
// length: data_size + 3,
// event_size: data_size,
// namespace: 0x02_u8,
// event_id: 0x00_6969u16,
// timestamp: 0x1234_5678u64,
// data: data_slice,
// },
// )
// .expect("loopback gtx tx error");
// timer.delay_us(1000); // wait packet has arrive at RX async fifo
// if (CXP[channel].rx_trigger_ack_read)() == 1 {
// (CXP[channel].rx_trigger_ack_write)(1);
// info!("trig ack and cleared");
// }
// if (CXP[channel].rx_bootstrap_decoder_err_read)() == 1 {
// info!("!!!!!!!DECODER ERROR!!!!!!! and cleared");
// (CXP[channel].rx_bootstrap_decoder_err_write)(1);
// }
// info!("packet type = {:#06X}", (CXP[channel].rx_packet_type_read)());
// // cxp_proto::receive(channel as u8).expect("loopback gtx rx error");
// // cxp_proto::rx_debug_mem_print(channel);
// // DEBUG: print loopback packets
// const LEN: usize = 20;
// let mut pak_arr: [u32; LEN] = [0; LEN];
// let mut k_arr: [u8; LEN] = [0; LEN];
// let mut i: usize = 0;
// while (CXP[channel].rx_debug_out_dout_valid_read)() == 1 {
// pak_arr[i] = (CXP[channel].rx_debug_out_dout_pak_read)();
// k_arr[i] = (CXP[channel].rx_debug_out_kout_pak_read)();
// // println!("received {:#04X}", pak_arr[i]);
// (CXP[channel].rx_debug_out_inc_write)(1);
// i += 1;
// if i == LEN {
// break;
// }
// }
// info!("rx ready = {}", (CXP[channel].rx_rx_ready_read)());
// // cxp_proto::print_packetu32(&pak_arr, &k_arr);
}
}

View File

@ -0,0 +1,91 @@
use core::slice;
use embedded_hal::blocking::delay::DelayUs;
use io::Cursor;
use libboard_zynq::{println, timer::GlobalTimer};
use crate::{cxp_proto,
mem::mem::CXP_MEM,
pl::csr::{self, CXP}};
const BUF_LEN: usize = 0x800;
pub fn tx_test(channel: u8, timer: &mut GlobalTimer) {
const LEN: usize = 4 * 100;
let mut pak_arr: [u8; LEN] = [0; LEN];
let channel = channel as usize;
unsafe {
// (CXP[channel].tx_trig_delay_write)(0x86);
// (CXP[channel].tx_linktrigger_write)(0x00);
// DEBUG: prepare the packet before tx enable to avoid overhead
preload_tx_packet(
channel as u8,
&cxp_proto::TXPacket::CtrlRead {
tag: None,
addr: 0,
length: 4,
},
);
csr::cxp_phys::tx_enable_write(1);
timer.delay_us(1);
// DEBUG: send ctrl packet or test
(CXP[channel].tx_writer_stb_write)(1);
(CXP[channel].tx_writer_stb_testseq_write)(1);
// DEBUG: Trigger packet (NOTE: disconnected in Gateware)
// (CXP[channel].upconn_trig_stb_write)(1); // send trig
// DEBUG: Trigger ACK packet
// (CXP[channel].upconn_ack_write)(1);
timer.delay_us(2000);
csr::cxp_phys::tx_enable_write(0);
// Collect data
let mut i: usize = 0;
// match channel {
// 0 => {
// while csr::cxp_phys::tx_tx0_debug_buf_dout_valid_read() == 1 {
// pak_arr[i] = csr::cxp_phys::tx_tx0_debug_buf_dout_pak_read();
// csr::cxp_phys::tx_tx0_debug_buf_inc_write(1);
// i += 1;
// if i == LEN {
// break;
// }
// }
// }
// 1 => {
// while csr::cxp_phys::tx_tx1_debug_buf_dout_valid_read() == 1 {
// pak_arr[i] = csr::cxp_phys::tx_tx1_debug_buf_dout_pak_read();
// csr::cxp_phys::tx_tx1_debug_buf_inc_write(1);
// i += 1;
// if i == LEN {
// break;
// }
// }
// }
// _ => {}
// }
cxp_proto::print_packet(&pak_arr);
}
}
fn preload_tx_packet(channel: u8, packet: &cxp_proto::TXPacket) {
let channel = channel as usize;
unsafe {
while (CXP[channel].tx_writer_busy_read)() == 1 {}
let ptr = CXP_MEM[channel].base as *mut u32;
let mut writer = Cursor::new(slice::from_raw_parts_mut(ptr as *mut u8, BUF_LEN));
packet.write_to(&mut writer).expect("unstable to write to tx mem");
// DEBUG:
println!("TX MEM after writing");
cxp_proto::print_packet(&writer.get_ref()[0..40]);
(CXP[channel].tx_writer_word_len_write)(writer.position() as u16 / 4);
}
}