diff --git a/src/libksupport/src/cxp.rs b/src/libksupport/src/cxp.rs new file mode 100644 index 0000000..5e9210c --- /dev/null +++ b/src/libksupport/src/cxp.rs @@ -0,0 +1,224 @@ +use byteorder::{ByteOrder, NetworkEndian}; +use cslice::CMutSlice; +use libboard_artiq::{cxp::{setup, MASTER_CHANNEL}, + cxp_ctrl, + cxp_proto::DATA_MAXSIZE}; + +// for downloading the XML files +// TODO: change this to read bytes and accept TBytearray +pub extern "C" fn cxp_read_words(addr: i32, val: &mut CMutSlice, with_tag: bool) { + let mut bytes: [u8; DATA_MAXSIZE] = [0; DATA_MAXSIZE]; + cxp_ctrl::read_bytes(MASTER_CHANNEL, addr as u32, &mut bytes[..val.len() * 4], with_tag) + .unwrap_or_else(|e| panic!("CXP readu64 failure: {}", e)); + + for i in 0..val.len() { + val.as_mut_slice()[i] = NetworkEndian::read_u32(&bytes[i * 4..(i + 1) * 4]) as i32; + } +} + +pub extern "C" fn cxp_readu32(addr: i32, with_tag: bool) -> i32 { + // TODO: use artiq_raise like i2c? + cxp_ctrl::read_u32(MASTER_CHANNEL, addr as u32, with_tag).unwrap_or_else(|e| panic!("CXP readu64 failure: {}", e)) + as i32 +} + +pub extern "C" fn cxp_readu64(addr: i32, with_tag: bool) -> i64 { + // TODO: use artiq_raise like i2c? + cxp_ctrl::read_u64(MASTER_CHANNEL, addr as u32, with_tag).unwrap_or_else(|e| panic!("CXP read u64 failure: {}", e)) + as i64 +} + +pub extern "C" fn cxp_writeu32(addr: i32, val: i32, with_tag: bool) { + // TODO: use artiq_raise like i2c? + cxp_ctrl::write_u32(MASTER_CHANNEL, addr as u32, val as u32, with_tag) + .unwrap_or_else(|e| panic!("CXP write u32 failure: {}", e)); +} + +pub extern "C" fn cxp_writeu64(addr: i32, val: i64, with_tag: bool) { + // TODO: use artiq_raise like i2c? + cxp_ctrl::write_u64(MASTER_CHANNEL, addr as u32, val as u64, with_tag) + .unwrap_or_else(|e| panic!("CXP write u64 failure: {}", e)); +} + +pub extern "C" fn cxp_setup() -> bool { + setup().unwrap() +} + +// DEBUG: ONLY +pub extern "C" fn cxp_debug_frame_print() { + use libboard_zynq::println; + + use crate::pl::csr::{cxp_frame_pipeline, CXP}; + const LEN: usize = 200; + let mut eop: [u8; LEN] = [0; LEN]; + let mut pak_arr: [u32; LEN] = [0; LEN]; + let mut k_arr: [u8; LEN] = [0; LEN]; + let mut err: [u8; LEN] = [0; LEN]; + let mut i: usize = 0; + unsafe { + while cxp_frame_pipeline::debug_out_dout_valid_read() == 1 { + pak_arr[i] = cxp_frame_pipeline::debug_out_dout_pak_read(); + k_arr[i] = cxp_frame_pipeline::debug_out_kout_pak_read(); + eop[i] = cxp_frame_pipeline::debug_out_eop_read(); + err[i] = cxp_frame_pipeline::debug_out_crc_error_read(); + // println!("received {:#04X}", pak_arr[i]); + cxp_frame_pipeline::debug_out_inc_write(1); + i += 1; + if i == LEN { + break; + } + } + // let channel: 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; + // } + // } + println!( + "Decode error = {}", + (CXP[MASTER_CHANNEL as usize].downconn_bootstrap_decoder_err_read)() + ); + println!( + "Trigger ack = {}", + (CXP[MASTER_CHANNEL as usize].downconn_trigger_ack_read)() + ); + if (CXP[MASTER_CHANNEL as usize].downconn_trigger_ack_read)() == 1 { + println!("Trigger ack clear"); + (CXP[MASTER_CHANNEL as usize].downconn_trigger_ack_write)(1); + }; + } + cxp_ctrl::print_decode_error(MASTER_CHANNEL); + if i > 0 { + print_packetu32(&pak_arr, &k_arr, &err, &eop, i as usize); + } else { + println!("No frame data received"); + } +} + +pub fn print_packetu32(pak: &[u32], k: &[u8], err: &[u8], eop: &[u8], len: usize) { + use libboard_zynq::println; + println!("pak = ["); + let mut i_stream_id: usize = len + 1; + let mut i_pak_tag: usize = len + 1; + let mut i_size_0: usize = len + 1; + let mut i_size_1: usize = len + 1; + for i in 0..len { + let data: [u8; 4] = pak[i].to_be_bytes(); + // if eop[i] == 1 { + // if err[i] == 1 { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | eop crc error", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } else { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | eop", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } + // i_stream_id = i + 1; + // i_pak_tag = i + 2; + // i_size_0 = i + 3; + // i_size_1 = i + 4 + // } else if i == i_stream_id { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | stream id", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } else if i == i_pak_tag { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | packet tag", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } else if i == i_size_0 { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | DsizeP[15:8]", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } else if i == i_size_1 { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | DsizeP[7:0]", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } else { + // if err[i] == 1 { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | crc error", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } else { + // println!( + // "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} |", + // i + 1, + // data[0], + // data[1], + // data[2], + // data[3], + // k[i], + // ); + // } + if err[i] == 1 { + println!( + "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} | crc error", + i + 1, + data[0], + data[1], + data[2], + data[3], + k[i], + ); + } else { + println!( + "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} |", + i + 1, + data[0], + data[1], + data[2], + data[3], + k[i], + ); + }; + } + println!("]"); + println!("============================================"); +} diff --git a/src/libksupport/src/kernel/api.rs b/src/libksupport/src/kernel/api.rs index ef77e43..2c58c57 100644 --- a/src/libksupport/src/kernel/api.rs +++ b/src/libksupport/src/kernel/api.rs @@ -11,6 +11,8 @@ use super::{cache, core1::rtio_get_destination_status, dma, linalg, rpc::{rpc_recv, rpc_send, rpc_send_async}}; +#[cfg(has_cxp_phys)] +use crate::cxp; use crate::{eh_artiq, i2c, rtio}; extern "C" { @@ -126,6 +128,22 @@ pub fn resolve(required: &[u8]) -> Option { #[cfg(has_drtio)] api!(subkernel_await_message = subkernel::await_message), + // CoaXPress + #[cfg(has_cxp_phys)] + api!(cxp_read_words = cxp::cxp_read_words), + #[cfg(has_cxp_phys)] + api!(cxp_readu32 = cxp::cxp_readu32), + #[cfg(has_cxp_phys)] + api!(cxp_readu64 = cxp::cxp_readu64), + #[cfg(has_cxp_phys)] + api!(cxp_writeu32 = cxp::cxp_writeu32), + #[cfg(has_cxp_phys)] + api!(cxp_writeu64 = cxp::cxp_writeu64), + #[cfg(has_cxp_phys)] + api!(cxp_setup = cxp::cxp_setup), + #[cfg(has_cxp_phys)] + api!(cxp_debug_frame_print = cxp::cxp_debug_frame_print), + // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 api!(__aeabi_dadd), diff --git a/src/libksupport/src/lib.rs b/src/libksupport/src/lib.rs index 630f19e..a243d01 100644 --- a/src/libksupport/src/lib.rs +++ b/src/libksupport/src/lib.rs @@ -35,6 +35,8 @@ pub mod rtio; #[path = "../../../build/pl.rs"] pub mod pl; +#[cfg(has_cxp_phys)] +pub mod cxp; #[derive(Debug, Clone)] pub struct RPCException {