2023-05-24 10:00:48 +08:00
|
|
|
use libboard_artiq::{drtioaux_proto::ANALYZER_MAX_SIZE, pl::csr};
|
2023-05-19 12:53:33 +08:00
|
|
|
use libcortex_a9::cache;
|
|
|
|
|
|
|
|
const BUFFER_SIZE: usize = 512 * 1024;
|
|
|
|
|
|
|
|
#[repr(align(64))]
|
|
|
|
struct Buffer {
|
|
|
|
data: [u8; BUFFER_SIZE],
|
|
|
|
}
|
|
|
|
|
2023-05-24 10:00:48 +08:00
|
|
|
static mut BUFFER: Buffer = Buffer { data: [0; BUFFER_SIZE] };
|
2023-05-19 12:53:33 +08:00
|
|
|
|
|
|
|
fn arm() {
|
|
|
|
unsafe {
|
|
|
|
let base_addr = &mut BUFFER.data[0] as *mut _ as usize;
|
|
|
|
let last_addr = &mut BUFFER.data[BUFFER_SIZE - 1] as *mut _ as usize;
|
|
|
|
csr::rtio_analyzer::dma_base_address_write(base_addr as u32);
|
|
|
|
csr::rtio_analyzer::message_encoder_overflow_reset_write(1);
|
|
|
|
csr::rtio_analyzer::dma_last_address_write(last_addr as u32);
|
|
|
|
csr::rtio_analyzer::dma_reset_write(1);
|
|
|
|
csr::rtio_analyzer::enable_write(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn disarm() {
|
|
|
|
unsafe {
|
|
|
|
csr::rtio_analyzer::enable_write(0);
|
|
|
|
while csr::rtio_analyzer::busy_read() != 0 {}
|
|
|
|
cache::dcci_slice(&BUFFER.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Analyzer {
|
|
|
|
// necessary for keeping track of sent data
|
|
|
|
sent_bytes: usize,
|
2023-05-24 10:00:48 +08:00
|
|
|
data_iter: usize,
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Header {
|
|
|
|
pub total_byte_count: u64,
|
|
|
|
pub sent_bytes: u32,
|
2023-05-24 10:00:48 +08:00
|
|
|
pub error: bool,
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct AnalyzerSliceMeta {
|
|
|
|
pub len: u16,
|
2023-05-24 10:00:48 +08:00
|
|
|
pub last: bool,
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Analyzer {
|
|
|
|
pub fn new() -> Analyzer {
|
|
|
|
// create and arm new Analyzer
|
|
|
|
arm();
|
|
|
|
Analyzer {
|
|
|
|
sent_bytes: 0,
|
2023-05-24 10:00:48 +08:00
|
|
|
data_iter: 0,
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
disarm();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_header(&mut self) -> Header {
|
|
|
|
disarm();
|
|
|
|
|
|
|
|
let overflow = unsafe { csr::rtio_analyzer::message_encoder_overflow_read() != 0 };
|
|
|
|
let bus_err = unsafe { csr::rtio_analyzer::dma_bus_error_read() != 0 };
|
|
|
|
let total_byte_count = unsafe { csr::rtio_analyzer::dma_byte_count_read() as u64 };
|
|
|
|
let wraparound = total_byte_count >= BUFFER_SIZE as u64;
|
2023-05-24 10:00:48 +08:00
|
|
|
self.sent_bytes = if wraparound {
|
|
|
|
BUFFER_SIZE
|
|
|
|
} else {
|
|
|
|
total_byte_count as usize
|
|
|
|
};
|
|
|
|
self.data_iter = if wraparound {
|
|
|
|
(total_byte_count % BUFFER_SIZE as u64) as usize
|
|
|
|
} else {
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
2023-05-19 13:17:04 +08:00
|
|
|
if overflow {
|
|
|
|
warn!("overflow occured");
|
|
|
|
}
|
|
|
|
if bus_err {
|
|
|
|
warn!("bus error occured");
|
|
|
|
}
|
2023-05-24 10:00:48 +08:00
|
|
|
|
2023-05-19 12:53:33 +08:00
|
|
|
Header {
|
|
|
|
total_byte_count: total_byte_count,
|
|
|
|
sent_bytes: self.sent_bytes as u32,
|
2023-05-24 10:00:48 +08:00
|
|
|
error: overflow | bus_err,
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_data(&mut self, data_slice: &mut [u8; ANALYZER_MAX_SIZE]) -> AnalyzerSliceMeta {
|
|
|
|
let data = unsafe { &BUFFER.data[..] };
|
|
|
|
let i = self.data_iter;
|
2023-05-24 10:00:48 +08:00
|
|
|
let len = if i + ANALYZER_MAX_SIZE < self.sent_bytes {
|
|
|
|
ANALYZER_MAX_SIZE
|
|
|
|
} else {
|
|
|
|
self.sent_bytes - i
|
|
|
|
};
|
2023-05-19 12:53:33 +08:00
|
|
|
let last = i + len == self.sent_bytes;
|
|
|
|
if i + len >= BUFFER_SIZE {
|
|
|
|
data_slice[..len].clone_from_slice(&data[i..BUFFER_SIZE]);
|
2023-05-24 10:00:48 +08:00
|
|
|
data_slice[..len].clone_from_slice(&data[..(i + len) % BUFFER_SIZE]);
|
2023-05-19 12:53:33 +08:00
|
|
|
} else {
|
2023-05-24 10:00:48 +08:00
|
|
|
data_slice[..len].clone_from_slice(&data[i..i + len]);
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
self.data_iter += len;
|
|
|
|
|
|
|
|
if last {
|
|
|
|
arm();
|
|
|
|
}
|
2023-05-24 10:00:48 +08:00
|
|
|
|
2023-05-19 12:53:33 +08:00
|
|
|
AnalyzerSliceMeta {
|
|
|
|
len: len as u16,
|
2023-05-24 10:00:48 +08:00
|
|
|
last: last,
|
2023-05-19 12:53:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|