analyzer: fix overflow behavior on satellite #235

Merged
sb10q merged 1 commits from mwojcik/artiq-zynq:analyzer_fix into master 2024-08-17 17:37:23 +08:00
Showing only changes of commit 5e6dca61a9 - Show all commits

View File

@ -1,3 +1,4 @@
use core::cmp::min;
use libboard_artiq::{drtioaux_proto::ANALYZER_MAX_SIZE, pl::csr}; use libboard_artiq::{drtioaux_proto::ANALYZER_MAX_SIZE, pl::csr};
use libcortex_a9::cache; use libcortex_a9::cache;
@ -32,8 +33,9 @@ fn disarm() {
pub struct Analyzer { pub struct Analyzer {
// necessary for keeping track of sent data // necessary for keeping track of sent data
data_len: usize,
sent_bytes: usize, sent_bytes: usize,
data_iter: usize, data_pointer: usize
} }
pub struct Header { pub struct Header {
@ -47,20 +49,23 @@ pub struct AnalyzerSliceMeta {
pub last: bool, pub last: bool,
} }
impl Drop for Analyzer {
fn drop(&mut self) {
disarm();
}
}
impl Analyzer { impl Analyzer {
pub fn new() -> Analyzer { pub fn new() -> Analyzer {
// create and arm new Analyzer // create and arm new Analyzer
arm(); arm();
Analyzer { Analyzer {
data_len: 0,
sent_bytes: 0, sent_bytes: 0,
data_iter: 0, data_pointer: 0
} }
} }
fn drop(&mut self) {
disarm();
}
pub fn get_header(&mut self) -> Header { pub fn get_header(&mut self) -> Header {
disarm(); disarm();
@ -68,16 +73,17 @@ impl Analyzer {
let bus_err = unsafe { csr::rtio_analyzer::dma_bus_error_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 total_byte_count = unsafe { csr::rtio_analyzer::dma_byte_count_read() as u64 };
let wraparound = total_byte_count >= BUFFER_SIZE as u64; let wraparound = total_byte_count >= BUFFER_SIZE as u64;
self.sent_bytes = if wraparound { self.data_len = if wraparound {
BUFFER_SIZE BUFFER_SIZE
} else { } else {
total_byte_count as usize total_byte_count as usize
}; };
self.data_iter = if wraparound { self.data_pointer = if wraparound {
(total_byte_count % BUFFER_SIZE as u64) as usize (total_byte_count % BUFFER_SIZE as u64) as usize
} else { } else {
0 0
}; };
self.sent_bytes = 0;
if overflow { if overflow {
warn!("overflow occured"); warn!("overflow occured");
@ -88,27 +94,24 @@ impl Analyzer {
Header { Header {
total_byte_count: total_byte_count, total_byte_count: total_byte_count,
sent_bytes: self.sent_bytes as u32, sent_bytes: self.data_len as u32,
error: overflow | bus_err, error: overflow | bus_err,
} }
} }
pub fn get_data(&mut self, data_slice: &mut [u8; ANALYZER_MAX_SIZE]) -> AnalyzerSliceMeta { pub fn get_data(&mut self, data_slice: &mut [u8; ANALYZER_MAX_SIZE]) -> AnalyzerSliceMeta {
let data = unsafe { &BUFFER.data[..] }; let data = unsafe { &BUFFER.data[..] };
let i = self.data_iter; let i = (self.data_pointer + self.sent_bytes) % BUFFER_SIZE;
let len = if i + ANALYZER_MAX_SIZE < self.sent_bytes { let len = min(ANALYZER_MAX_SIZE, self.data_len - self.sent_bytes);
ANALYZER_MAX_SIZE let last = self.sent_bytes + len == self.data_len;
} else {
self.sent_bytes - i
};
let last = i + len == self.sent_bytes;
if i + len >= BUFFER_SIZE { if i + len >= BUFFER_SIZE {
data_slice[..len].clone_from_slice(&data[i..BUFFER_SIZE]); data_slice[..(BUFFER_SIZE-i)].clone_from_slice(&data[i..BUFFER_SIZE]);
data_slice[..len].clone_from_slice(&data[..(i + len) % BUFFER_SIZE]); data_slice[(BUFFER_SIZE-i)..len].clone_from_slice(&data[..(i + len) % BUFFER_SIZE]);
} else { } else {
data_slice[..len].clone_from_slice(&data[i..i + len]); data_slice[..len].clone_from_slice(&data[i..i + len]);
} }
self.data_iter += len; self.sent_bytes += len;
if last { if last {
arm(); arm();