diff --git a/src/libboard_artiq/src/drtioaux_proto.rs b/src/libboard_artiq/src/drtioaux_proto.rs index 39f87b6..576a0aa 100644 --- a/src/libboard_artiq/src/drtioaux_proto.rs +++ b/src/libboard_artiq/src/drtioaux_proto.rs @@ -136,20 +136,20 @@ pub enum Packet { succeeded: bool, }, - AnalyzerHeaderRequest { - destination: u8 - }, - AnalyzerHeader { - sent_bytes: u32, - total_byte_count: u64, - overflow_occurred: bool, - }, - AnalyzerDataRequest { + AnalyzerHeaderRequest { destination: u8, }, - AnalyzerData { - last: bool, - length: u16, + AnalyzerHeader { + sent_bytes: u32, + total_byte_count: u64, + overflow_occurred: bool, + }, + AnalyzerDataRequest { + destination: u8, + }, + AnalyzerData { + last: bool, + length: u16, data: [u8; ANALYZER_MAX_SIZE], }, @@ -316,15 +316,15 @@ impl Packet { }, 0xa0 => Packet::AnalyzerHeaderRequest { - destination: reader.read_u8()? + destination: reader.read_u8()?, }, 0xa1 => Packet::AnalyzerHeader { - sent_bytes: reader.read_u32()?, - total_byte_count: reader.read_u64()?, + sent_bytes: reader.read_u32()?, + total_byte_count: reader.read_u64()?, overflow_occurred: reader.read_bool()?, }, 0xa2 => Packet::AnalyzerDataRequest { - destination: reader.read_u8()? + destination: reader.read_u8()?, }, 0xa3 => { let last = reader.read_bool()?; @@ -334,9 +334,9 @@ impl Packet { Packet::AnalyzerData { last: last, length: length, - data: data + data: data, } - }, + } 0xb0 => { let destination = reader.read_u8()?; @@ -570,11 +570,11 @@ impl Packet { writer.write_u8(0xa0)?; writer.write_u8(destination)?; } - Packet::AnalyzerHeader { - sent_bytes, - total_byte_count, - overflow_occurred - } => { + Packet::AnalyzerHeader { + sent_bytes, + total_byte_count, + overflow_occurred, + } => { writer.write_u8(0xa1)?; writer.write_u32(sent_bytes)?; writer.write_u64(total_byte_count)?; @@ -584,11 +584,7 @@ impl Packet { writer.write_u8(0xa2)?; writer.write_u8(destination)?; } - Packet::AnalyzerData { - last, - length, - data - } => { + Packet::AnalyzerData { last, length, data } => { writer.write_u8(0xa3)?; writer.write_bool(last)?; writer.write_u16(length)?; diff --git a/src/runtime/src/analyzer.rs b/src/runtime/src/analyzer.rs index 16106c9..4eb3268 100644 --- a/src/runtime/src/analyzer.rs +++ b/src/runtime/src/analyzer.rs @@ -1,10 +1,11 @@ +use alloc::{rc::Rc, vec::Vec}; +use core::cell::RefCell; + use libasync::{smoltcp::TcpStream, task}; +use libboard_artiq::drtio_routing; use libboard_zynq::{smoltcp::Error, timer::GlobalTimer}; use libcortex_a9::{cache, mutex::Mutex}; -use log::{debug, info, warn, error}; -use core::cell::RefCell; -use alloc::{rc::Rc, vec::Vec}; -use libboard_artiq::drtio_routing; +use log::{debug, error, info, warn}; use crate::{pl, proto_async::*}; @@ -44,43 +45,45 @@ fn disarm() { pub mod remote_analyzer { use super::*; use crate::rtio_mgt::drtio; - + pub struct RemoteBuffer { pub total_byte_count: u64, pub sent_bytes: u32, pub error: bool, - pub data: Vec + pub data: Vec, } - pub async fn get_data(aux_mutex: &Rc>, + pub async fn get_data( + aux_mutex: &Rc>, routing_table: &drtio_routing::RoutingTable, up_destinations: &Rc>, - timer: GlobalTimer) -> Result { - // gets data from satellites and returns consolidated data - let mut remote_data: Vec = Vec::new(); - let mut remote_error = false; - let mut remote_sent_bytes = 0; - let mut remote_total_bytes = 0; + timer: GlobalTimer, + ) -> Result { + // gets data from satellites and returns consolidated data + let mut remote_data: Vec = Vec::new(); + let mut remote_error = false; + let mut remote_sent_bytes = 0; + let mut remote_total_bytes = 0; - let data_vec = match drtio::analyzer_query(aux_mutex, routing_table, up_destinations, timer).await { - Ok(data_vec) => data_vec, - Err(e) => return Err(e) - }; - for data in data_vec { - remote_total_bytes += data.total_byte_count; - remote_sent_bytes += data.sent_bytes; - remote_error |= data.error; - remote_data.extend(data.data); - } - - Ok(RemoteBuffer { - total_byte_count: remote_total_bytes, - sent_bytes: remote_sent_bytes, - error: remote_error, - data: remote_data - }) + let data_vec = match drtio::analyzer_query(aux_mutex, routing_table, up_destinations, timer).await { + Ok(data_vec) => data_vec, + Err(e) => return Err(e), + }; + for data in data_vec { + remote_total_bytes += data.total_byte_count; + remote_sent_bytes += data.sent_bytes; + remote_error |= data.error; + remote_data.extend(data.data); } -} + + Ok(RemoteBuffer { + total_byte_count: remote_total_bytes, + sent_bytes: remote_sent_bytes, + error: remote_error, + data: remote_data, + }) + } +} #[derive(Debug)] struct Header { @@ -101,10 +104,13 @@ async fn write_header(stream: &mut TcpStream, header: &Header) -> Result<(), Err Ok(()) } -async fn handle_connection(stream: &mut TcpStream, _aux_mutex: &Rc>, +async fn handle_connection( + stream: &mut TcpStream, + _aux_mutex: &Rc>, _routing_table: &drtio_routing::RoutingTable, _up_destinations: &Rc>, - _timer: GlobalTimer) -> Result<(), Error> { + _timer: GlobalTimer, +) -> Result<(), Error> { info!("received connection"); let data = unsafe { &BUFFER.data[..] }; @@ -113,7 +119,11 @@ async fn handle_connection(stream: &mut TcpStream, _aux_mutex: &Rc>, let total_byte_count = unsafe { pl::csr::rtio_analyzer::dma_byte_count_read() as u64 }; let pointer = (total_byte_count % BUFFER_SIZE as u64) as usize; let wraparound = total_byte_count >= BUFFER_SIZE as u64; - let sent_bytes = if wraparound { BUFFER_SIZE as u32 } else { total_byte_count as u32 }; + let sent_bytes = if wraparound { + BUFFER_SIZE as u32 + } else { + total_byte_count as u32 + }; if overflow_occurred { warn!("overflow occured"); @@ -126,23 +136,28 @@ async fn handle_connection(stream: &mut TcpStream, _aux_mutex: &Rc>, let remote = remote_analyzer::get_data(_aux_mutex, _routing_table, _up_destinations, _timer).await; #[cfg(has_drtio)] let (header, remote_data) = match remote { - Ok(remote) => (Header { - total_byte_count: total_byte_count + remote.total_byte_count, - sent_bytes: sent_bytes + remote.sent_bytes, - error_occurred: overflow_occurred | bus_error_occurred | remote.error, - log_channel: pl::csr::CONFIG_RTIO_LOG_CHANNEL as u8, - dds_onehot_sel: true - }, remote.data), + Ok(remote) => ( + Header { + total_byte_count: total_byte_count + remote.total_byte_count, + sent_bytes: sent_bytes + remote.sent_bytes, + error_occurred: overflow_occurred | bus_error_occurred | remote.error, + log_channel: pl::csr::CONFIG_RTIO_LOG_CHANNEL as u8, + dds_onehot_sel: true, + }, + remote.data, + ), Err(e) => { error!("Error getting remote analyzer data: {}", e); - (Header { - total_byte_count: total_byte_count, - sent_bytes: sent_bytes, - error_occurred: true, - log_channel: pl::csr::CONFIG_RTIO_LOG_CHANNEL as u8, - dds_onehot_sel: true - }, - Vec::new()) + ( + Header { + total_byte_count: total_byte_count, + sent_bytes: sent_bytes, + error_occurred: true, + log_channel: pl::csr::CONFIG_RTIO_LOG_CHANNEL as u8, + dds_onehot_sel: true, + }, + Vec::new(), + ) } }; @@ -169,10 +184,12 @@ async fn handle_connection(stream: &mut TcpStream, _aux_mutex: &Rc>, Ok(()) } -pub fn start(aux_mutex: &Rc>, +pub fn start( + aux_mutex: &Rc>, routing_table: &Rc>, up_destinations: &Rc>, - timer: GlobalTimer,) { + timer: GlobalTimer, +) { let aux_mutex = aux_mutex.clone(); let routing_table = routing_table.clone(); let up_destinations = up_destinations.clone(); diff --git a/src/runtime/src/rtio_mgt.rs b/src/runtime/src/rtio_mgt.rs index 1aea5f2..e6d1393 100644 --- a/src/runtime/src/rtio_mgt.rs +++ b/src/runtime/src/rtio_mgt.rs @@ -21,8 +21,8 @@ pub mod drtio { use log::{error, info, warn}; use super::*; - use crate::{rtio_dma::remote_dma, ASYNC_ERROR_BUSY, ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR, - SEEN_ASYNC_ERRORS, analyzer::remote_analyzer::RemoteBuffer}; + use crate::{analyzer::remote_analyzer::RemoteBuffer, rtio_dma::remote_dma, ASYNC_ERROR_BUSY, + ASYNC_ERROR_COLLISION, ASYNC_ERROR_SEQUENCE_ERROR, SEEN_ASYNC_ERRORS}; pub fn startup( aux_mutex: &Rc>, @@ -527,37 +527,48 @@ pub mod drtio { aux_mutex: &Rc>, routing_table: &drtio_routing::RoutingTable, timer: GlobalTimer, - destination: u8 + destination: u8, ) -> Result { let linkno = routing_table.0[destination as usize][0] - 1; let reply = aux_transact( - aux_mutex, - linkno, - &Packet::AnalyzerHeaderRequest { destination: destination }, + aux_mutex, + linkno, + &Packet::AnalyzerHeaderRequest { + destination: destination, + }, timer, ) .await; let (sent, total, overflow) = match reply { - Ok(Packet::AnalyzerHeader { - sent_bytes, total_byte_count, overflow_occurred } - ) => (sent_bytes, total_byte_count, overflow_occurred), + Ok(Packet::AnalyzerHeader { + sent_bytes, + total_byte_count, + overflow_occurred, + }) => (sent_bytes, total_byte_count, overflow_occurred), Ok(_) => return Err("received unexpected aux packet during remote analyzer header request"), - Err(e) => return Err(e) + Err(e) => return Err(e), }; let mut remote_data: Vec = Vec::new(); if sent > 0 { let mut last_packet = false; while !last_packet { - let reply = aux_transact(aux_mutex, linkno, - &Packet::AnalyzerDataRequest { destination: destination }, timer,).await; + let reply = aux_transact( + aux_mutex, + linkno, + &Packet::AnalyzerDataRequest { + destination: destination, + }, + timer, + ) + .await; match reply { - Ok(Packet::AnalyzerData { last, length, data }) => { + Ok(Packet::AnalyzerData { last, length, data }) => { last_packet = last; remote_data.extend(&data[0..length as usize]); - }, + } Ok(_) => return Err("received unexpected aux packet during remote analyzer data request"), - Err(e) => return Err(e) + Err(e) => return Err(e), } } } @@ -566,12 +577,13 @@ pub mod drtio { sent_bytes: sent, total_byte_count: total, error: overflow, - data: remote_data + data: remote_data, }) } - pub async fn analyzer_query(aux_mutex: &Rc>, - routing_table: &drtio_routing::RoutingTable, + pub async fn analyzer_query( + aux_mutex: &Rc>, + routing_table: &drtio_routing::RoutingTable, up_destinations: &Rc>, timer: GlobalTimer, ) -> Result, &'static str> { diff --git a/src/satman/src/analyzer.rs b/src/satman/src/analyzer.rs index ad3b945..8fc7b27 100644 --- a/src/satman/src/analyzer.rs +++ b/src/satman/src/analyzer.rs @@ -1,6 +1,5 @@ -use libboard_artiq::pl::csr; +use libboard_artiq::{drtioaux_proto::ANALYZER_MAX_SIZE, pl::csr}; use libcortex_a9::cache; -use libboard_artiq::drtioaux_proto::ANALYZER_MAX_SIZE; const BUFFER_SIZE: usize = 512 * 1024; @@ -9,9 +8,7 @@ struct Buffer { data: [u8; BUFFER_SIZE], } -static mut BUFFER: Buffer = Buffer { - data: [0; BUFFER_SIZE] -}; +static mut BUFFER: Buffer = Buffer { data: [0; BUFFER_SIZE] }; fn arm() { unsafe { @@ -36,18 +33,18 @@ fn disarm() { pub struct Analyzer { // necessary for keeping track of sent data sent_bytes: usize, - data_iter: usize + data_iter: usize, } pub struct Header { pub total_byte_count: u64, pub sent_bytes: u32, - pub error: bool + pub error: bool, } pub struct AnalyzerSliceMeta { pub len: u16, - pub last: bool + pub last: bool, } impl Analyzer { @@ -56,7 +53,7 @@ impl Analyzer { arm(); Analyzer { sent_bytes: 0, - data_iter: 0 + data_iter: 0, } } @@ -71,43 +68,55 @@ impl Analyzer { 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; - 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 }; - + 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 + }; + if overflow { warn!("overflow occured"); } if bus_err { warn!("bus error occured"); } - + Header { total_byte_count: total_byte_count, sent_bytes: self.sent_bytes as u32, - error: overflow | bus_err + error: overflow | bus_err, } } pub fn get_data(&mut self, data_slice: &mut [u8; ANALYZER_MAX_SIZE]) -> AnalyzerSliceMeta { let data = unsafe { &BUFFER.data[..] }; let i = self.data_iter; - let len = if i + ANALYZER_MAX_SIZE < self.sent_bytes { ANALYZER_MAX_SIZE } else { self.sent_bytes - i }; + let len = if i + ANALYZER_MAX_SIZE < self.sent_bytes { + ANALYZER_MAX_SIZE + } else { + self.sent_bytes - i + }; let last = i + len == self.sent_bytes; if i + len >= BUFFER_SIZE { data_slice[..len].clone_from_slice(&data[i..BUFFER_SIZE]); - data_slice[..len].clone_from_slice(&data[..(i+len) % BUFFER_SIZE]); + data_slice[..len].clone_from_slice(&data[..(i + len) % BUFFER_SIZE]); } 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; if last { arm(); } - + AnalyzerSliceMeta { len: len as u16, - last: last + last: last, } } } diff --git a/src/satman/src/main.rs b/src/satman/src/main.rs index 9cf8406..4af58b2 100644 --- a/src/satman/src/main.rs +++ b/src/satman/src/main.rs @@ -20,15 +20,14 @@ extern crate alloc; use core::sync::atomic::{AtomicBool, Ordering}; -use analyzer::Analyzer as Analyzer; +use analyzer::Analyzer; use dma::Manager as DmaManager; use embedded_hal::blocking::delay::DelayUs; #[cfg(feature = "target_kasli_soc")] use libboard_artiq::io_expander; #[cfg(has_si5324)] use libboard_artiq::si5324; -use libboard_artiq::{drtio_routing, drtioaux, identifier_read, logger, pl::csr}; -use libboard_artiq::{drtioaux_proto::ANALYZER_MAX_SIZE}; +use libboard_artiq::{drtio_routing, drtioaux, drtioaux_proto::ANALYZER_MAX_SIZE, identifier_read, logger, pl::csr}; #[cfg(feature = "target_kasli_soc")] use libboard_zynq::error_led::ErrorLED; use libboard_zynq::{gic, i2c::I2c, mpcore, print, println, stdio, time::Milliseconds, timer::GlobalTimer}; @@ -40,9 +39,9 @@ use libcortex_a9::{asm, interrupt_handler, use libregister::{RegisterR, RegisterW}; use libsupport_zynq::ram; +mod analyzer; mod dma; mod repeater; -mod analyzer; fn drtiosat_reset(reset: bool) { unsafe { @@ -416,24 +415,34 @@ fn process_aux_packet( ) } - drtioaux::Packet::AnalyzerHeaderRequest { destination: _destination } => { + drtioaux::Packet::AnalyzerHeaderRequest { + destination: _destination, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let header = analyzer.get_header(); - drtioaux::send(0, &drtioaux::Packet::AnalyzerHeader { - total_byte_count: header.total_byte_count, - sent_bytes: header.sent_bytes, - overflow_occurred: header.error, - }) + drtioaux::send( + 0, + &drtioaux::Packet::AnalyzerHeader { + total_byte_count: header.total_byte_count, + sent_bytes: header.sent_bytes, + overflow_occurred: header.error, + }, + ) } - drtioaux::Packet::AnalyzerDataRequest { destination: _destination } => { + drtioaux::Packet::AnalyzerDataRequest { + destination: _destination, + } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); let mut data_slice: [u8; ANALYZER_MAX_SIZE] = [0; ANALYZER_MAX_SIZE]; let meta = analyzer.get_data(&mut data_slice); - drtioaux::send(0, &drtioaux::Packet::AnalyzerData { - last: meta.last, - length: meta.len, - data: data_slice, - }) + drtioaux::send( + 0, + &drtioaux::Packet::AnalyzerData { + last: meta.last, + length: meta.len, + data: data_slice, + }, + ) } drtioaux::Packet::DmaAddTraceRequest { @@ -483,7 +492,16 @@ fn process_aux_packets( ) { let result = drtioaux::recv(0).and_then(|packet| { if let Some(packet) = packet { - process_aux_packet(repeaters, routing_table, rank, packet, timer, i2c, dma_manager, analyzer) + process_aux_packet( + repeaters, + routing_table, + rank, + packet, + timer, + i2c, + dma_manager, + analyzer, + ) } else { Ok(()) }