diff --git a/src/libksupport/src/cxp.rs b/src/libksupport/src/cxp.rs new file mode 100644 index 0000000..4dd4bb8 --- /dev/null +++ b/src/libksupport/src/cxp.rs @@ -0,0 +1,262 @@ +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; + const LEN: usize = 512; + 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 { + use crate::pl::csr::cxp_frame_pipeline; + println!( + "arbiter active ch = {:#06b} | CRC error count = {} ", + cxp_frame_pipeline::arbiter_active_ch_read(), + cxp_frame_pipeline::crc_error_cnt_read(), + ); + println!( + "roi counter = {} | roi update = {}", + cxp_frame_pipeline::roi_counter_read(), + cxp_frame_pipeline::roi_update_read() + ); + if cxp_frame_pipeline::roi_update_read() == 1 { + println!("roi update clear"); + cxp_frame_pipeline::roi_update_write(1); + }; + println!("pixel4x[0] y = {}", cxp_frame_pipeline::pix_y_read(),); + println!( + "header decode l_size = {} | x_size = {} | y_size = {} | new lines count = {}", + cxp_frame_pipeline::header_l_size_read(), + cxp_frame_pipeline::header_x_size_read(), + cxp_frame_pipeline::header_y_size_read(), + cxp_frame_pipeline::header_new_line_read(), + ); + + // 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].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; + // } + // } + // println!( + // "Decode error = {}", + // (CXP[MASTER_CHANNEL as usize].rx_reader_decode_err_read)() + // ); + if (CXP[MASTER_CHANNEL as usize].rx_trigger_ack_read)() == 1 { + println!("Trigger ack recv and clear"); + (CXP[MASTER_CHANNEL as usize].rx_trigger_ack_write)(1); + } else { + println!("NO Trigger ack"); + } + } + 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::{print, 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], + // ); + // }; + print!( + "{:#03} {:#04X} {:#04X} {:#04X} {:#04X} | K {:04b} |", + i + 1, + data[0], + data[1], + data[2], + data[3], + k[i], + ); + if err[i] == 1 { + print!(" crc error |") + }; + if eop[i] == 1 { + print!(" eop |") + }; + println!("") + } + 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 {