diff --git a/src/libboard_artiq/src/cxp_downconn.rs b/src/libboard_artiq/src/cxp_downconn.rs new file mode 100644 index 0000000..0a1e5ec --- /dev/null +++ b/src/libboard_artiq/src/cxp_downconn.rs @@ -0,0 +1,87 @@ +use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs; +use libboard_zynq::{println, timer::GlobalTimer}; +use log::info; + +use crate::{cxp_phys, cxp_proto, pl::csr::CXP}; + +pub fn loopback_testing(channel: usize, timer: &mut GlobalTimer, speed: cxp_phys::CXP_SPEED) { + println!("=============================================================================="); + cxp_phys::change_linerate(channel, timer, speed); + + unsafe { + info!("waiting for tx&rx setup..."); + timer.delay_us(50_000); + info!( + "tx_phaligndone = {} | rx_phaligndone = {}", + (CXP[channel].downconn_txinit_phaligndone_read)(), + (CXP[channel].downconn_rxinit_phaligndone_read)(), + ); + + // enable txdata tranmission thought MGTXTXP, required by PMA loopback + (CXP[channel].downconn_txenable_write)(1); + + info!("waiting for rx to align..."); + while (CXP[channel].downconn_rx_ready_read)() != 1 {} + info!("rx ready!"); + + (CXP[channel].downconn_tx_stb_write)(1); + cxp_proto::downconn_send_test_packet(channel); + + cxp_proto::downconn_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::downconn_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 + (CXP[channel].downconn_tx_stb_write)(0); + + info!("trig ack = {}", (CXP[channel].downconn_trigger_ack_read)()); + (CXP[channel].downconn_trigger_ack_write)(1); + info!("after clr trig ack = {}", (CXP[channel].downconn_trigger_ack_read)()); + + info!( + "decoder error = {}", + (CXP[channel].downconn_bootstrap_decoder_err_read)() + ); + info!("test error = {}", (CXP[channel].downconn_bootstrap_test_err_read)()); + info!("packet type = {:#06X}", (CXP[channel].downconn_packet_type_read)()); + + cxp_proto::receive(channel).expect("loopback gtx rx error"); + // cxp_proto::downconn_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].downconn_debug_out_dout_valid_read)() == 1 { + pak_arr[i] = (CXP[channel].downconn_debug_out_dout_pak_read)(); + k_arr[i] = (CXP[channel].downconn_debug_out_kout_pak_read)(); + // println!("received {:#04X}", pak_arr[i]); + (CXP[channel].downconn_debug_out_inc_write)(1); + i += 1; + if i == LEN { + break; + } + } + cxp_proto::print_packetu32(&pak_arr, &k_arr); + } +}