use std::fs::read_to_string;
use tof_control::ltb_control::ltb_threshold;
use tof_dataclasses::serialization::{
Serialization,
};
use tof_dataclasses::io::RBEventMemoryStreamer;
use std::path::Path;
use std::time::{
Duration,
Instant
};
use std::{
thread,
time
};
use std::env;
use crossbeam_channel::{Sender};
use crate::control::*;
use crate::memory::*;
use tof_dataclasses::events::{RBEvent,
DataType};
use tof_dataclasses::commands::{
TofOperationMode,
};
use tof_dataclasses::packets::TofPacket;
use tof_dataclasses::commands::config::RunConfig;
use tof_dataclasses::calibrations::RBCalibrations;
use tof_dataclasses::errors::{CalibrationError,
RunError,
SetError};
use tof_control::rb_control::rb_mode::{
select_noi_mode,
select_vcal_mode,
select_tcal_mode,
select_sma_mode
};
use liftof_lib::{
LTBThresholdName
};
const FIVE_SECONDS: Duration = time::Duration::from_millis(5000);
pub fn enable_poisson_self_trigger(rate : f32) {
let max_val : f32 = 4294967295.0;
let reg_val = (rate/(33e6/max_val)) as u32;
info!("Will use random self trigger with rate {reg_val} value for register, corresponding to {rate} Hz");
match set_self_trig_rate(reg_val) {
Err(err) => {
error!("Setting self trigger failed! Er {err}");
error!("To be clear, we are NOT RUNNING IN POISSON SELF-TRIGGER MODE!");
}
Ok(_) => ()
}
}
pub fn wait_while_run_active(n_errors : u32,
interval : Duration,
n_events_exp : u32,
data_type : &DataType,
socket : &zmq::Socket) -> Vec<RBEvent> {
let mut events = Vec::<RBEvent>::new();
let mut errs : u32 = 0;
let start = Instant::now();
let mut triggers_have_stopped = false;
let mut kill_timer = Instant::now();
loop {
debug!("Waiting for 0MQ socket...");
match socket.recv_bytes(0) {
Err(err) => {
error!("Unable to recv on socket! Err {err}");
},
Ok(bytes) => {
debug!("Received {} bytes over 0MQ!", bytes.len());
match TofPacket::from_bytestream(&bytes, &mut 5) {
Err(err) => {
error!("Can't unpack TofPacket, err {err}");
},
Ok(tp) => {
match RBEvent::from_bytestream(&tp.payload, &mut 0) {
Err(err) => {
error!("Can't unpack RBEvent, error {err}");
},
Ok(ev) => {
if ev.data_type == *data_type {
events.push(ev);
}
}
}
}
}
}
}
if events.len() >= n_events_exp as usize {
info!("Acquired {} events!", events.len());
return events;
}
if triggers_have_stopped {
if kill_timer.elapsed().as_secs() > 10 {
info!("Kill timer expired!");
return events;
} else {
continue;
}
}
if start.elapsed() > interval {
match get_triggers_enabled() {
Err(err) => {
error!("Unable to obtain trigger status! Err {err}");
errs += 1;
},
Ok(running) => {
if !running {
info!("Run has apparently terminated!");
triggers_have_stopped = true;
kill_timer = Instant::now();
} else {
info!("We have waited the expected time, but there are still triggers...");
thread::sleep(interval);
}
}
}
if errs == n_errors {
error!("Can't wait anymore since we have seen the configured number of errors! {n_errors}");
return events;
}
}
}
}
pub fn rb_calibration(rc_to_runner : &Sender<RunConfig>,
tp_to_publisher : &Sender<TofPacket>,
save_waveforms : bool,
address : String)
-> Result<(), CalibrationError> {
warn!("Commencing full RB calibration routine! This will take the board out of datataking for a few minutes!");
let mut run_config = RunConfig {
runid : 0,
nevents : 1300,
is_active : true,
nseconds : 0,
tof_op_mode : TofOperationMode::Default,
trigger_poisson_rate : 0,
trigger_fixed_rate : 100,
data_type : DataType::Noi,
rb_buff_size : 100
};
let mut board_id = 0u8;
match get_board_id() {
Err(err) => {
error!("Unable to obtain board id. Calibration might be orphaned. Err {err}");
},
Ok(rb_id) => {
board_id = rb_id as u8;
}
}
let mut calibration = RBCalibrations::new(board_id);
calibration.serialize_event_data = save_waveforms;
let ctx = zmq::Context::new();
let socket : zmq::Socket;
match ctx.socket(zmq::SUB) {
Err(err) => {
error!("Unable to create zmq socket! Err {err}. This is BAD!");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
}
Ok(sock) => {
socket = sock;
}
}
match socket.connect(&address) {
Err(err) => {
error!("Unable to connect to data (PUB) socket {address}, Err {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => ()
}
let topic_local = String::from("LOCAL");
match socket.set_subscribe(&topic_local.as_bytes()) {
Err(err) => error!("Can not subscribe to {topic_local}, err {err}"),
Ok(_) => info!("Subscribing to local packages!"),
}
run_config.data_type = DataType::Noi;
match run_noi_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run no input calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Noi calibration step done!")
}
};
run_config.data_type = DataType::VoltageCalibration;
match run_voltage_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run voltage calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Voltage calibration step done!")
}
};
run_config.data_type = DataType::TimingCalibration;
match run_timing_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run timing calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Timing calibration step done!")
}
};
println!("==> Calibration data taking complete!");
println!("Calibration : {}", calibration);
println!("Cleaning data...");
calibration.clean_input_data();
println!("Calibration : {}", calibration);
info!("Will set board to sma mode!");
match select_sma_mode() {
Err(_) => {
error!("Unable to set sma mode.");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Timing calibration step done!")
}
};
run_config.is_active = false;
match rc_to_runner.send(run_config) {
Err(err) => {
warn!("Can not send runconfig!, Err {err}");
return Err(CalibrationError::CalibrationFailed);
}
Ok(_) => trace!("Success!")
}
thread::sleep(FIVE_SECONDS);
calibration.calibrate()?;
println!("== ==> [rb_calibration] Calibration : {}", calibration);
let calib_pack = TofPacket::from(&calibration);
match tp_to_publisher.send(calib_pack) {
Err(err) => {
error!("Unable to send RBCalibration package! Error {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => ()
}
info!("Calibration done!");
Ok(())
}
pub fn rb_noi_subcalibration(rc_to_runner : &Sender<RunConfig>,
tp_to_publisher : &Sender<TofPacket>)
-> Result<(), CalibrationError> {
warn!("Commencing RB No input sub-calibration routine! This will take the board out of datataking for a few minutes!");
let mut run_config = RunConfig {
runid : 0,
nevents : 1300,
is_active : true,
nseconds : 0,
tof_op_mode : TofOperationMode::Default,
trigger_poisson_rate : 0,
trigger_fixed_rate : 100,
data_type : DataType::Noi,
rb_buff_size : 100
};
let socket = connect_to_zmq().expect("Not able to connect to socket, something REAL strange happened.");
let mut board_id = 0u8;
match get_board_id() {
Err(err) => {
error!("Unable to obtain board id. Calibration might be orphaned. Err {err}");
},
Ok(rb_id) => {
board_id = rb_id as u8;
}
}
let mut calibration = RBCalibrations::new(board_id);
calibration.serialize_event_data = true;
run_config.data_type = DataType::Noi;
match run_noi_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run noi calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Noi calibration step done!");
}
};
println!("==> No input data taking complete!");
println!("Calibration : {}", calibration);
println!("Cleaning data...");
calibration.clean_input_data();
println!("Calibration : {}", calibration);
info!("Will set board to sma mode!");
match select_sma_mode() {
Err(err) => error!("Unable to select sma mode! {err:?}"),
Ok(_) => ()
}
run_config.is_active = false;
match rc_to_runner.send(run_config) {
Err(err) => {
warn!("Can not send runconfig!, Err {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => trace!("Success!")
}
thread::sleep(FIVE_SECONDS);
println!("Calibration won't start cause the calibration data taking chain is not complete!");
let calib_pack = TofPacket::from(&calibration);
match tp_to_publisher.send(calib_pack) {
Err(err) => {
error!("Unable to send RBCalibration package! Error {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => ()
}
info!("Calibration done!");
Ok(())
}
pub fn rb_voltage_subcalibration(rc_to_runner : &Sender<RunConfig>,
tp_to_publisher : &Sender<TofPacket>,
_voltage_level : u16) -> Result<(), CalibrationError> {
warn!("Commencing RB no input + voltage sub-calibration routine! This will take the board out of datataking for a few minutes!");
let mut run_config = RunConfig {
runid : 0,
nevents : 1300,
is_active : true,
nseconds : 0,
tof_op_mode : TofOperationMode::Default,
trigger_poisson_rate : 0,
trigger_fixed_rate : 100,
data_type : DataType::VoltageCalibration,
rb_buff_size : 1000
};
let socket = connect_to_zmq().expect("Not able to connect to socket, something REAL strange happened.");
let mut board_id = 0u8;
match get_board_id() {
Err(err) => {
error!("Unable to obtain board id. Calibration might be orphaned. Err {err}");
},
Ok(rb_id) => {
board_id = rb_id as u8;
}
}
let mut calibration = RBCalibrations::new(board_id);
calibration.serialize_event_data = true;
run_config.data_type = DataType::Noi;
match run_noi_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run noi calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Noi calibration step done!")
}
};
run_config.data_type = DataType::VoltageCalibration;
match run_voltage_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run voltage calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Voltage calibration step done!")
}
};
println!("==> No input + voltage data taking complete!");
println!("Calibration : {}", calibration);
println!("Cleaning data...");
calibration.clean_input_data();
println!("Calibration : {}", calibration);
info!("Will set board to sma mode!");
match select_sma_mode() {
Err(err) => error!("Unable to select SMA mode! {err:?}"),
Ok(_) => ()
}
run_config.is_active = false;
match rc_to_runner.send(run_config) {
Err(err) => {
warn!("Can not send runconfig!, Err {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => trace!("Success!")
}
thread::sleep(FIVE_SECONDS);
println!("Calibration won't start cause the calibration data taking chain is not complete!");
let calib_pack = TofPacket::from(&calibration);
match tp_to_publisher.send(calib_pack) {
Err(err) => {
error!("Unable to send RBCalibration package! Error {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => ()
}
info!("Calibration done!");
Ok(())
}
pub fn rb_timing_subcalibration(rc_to_runner : &Sender<RunConfig>,
tp_to_publisher : &Sender<TofPacket>,
_voltage_level : u16)
-> Result<(), CalibrationError> {
warn!("Commencing RB no input + voltage + timing sub-calibration routine! This will take the board out of datataking for a few minutes!");
let mut run_config = RunConfig {
runid : 0,
nevents : 1300,
is_active : true,
nseconds : 0,
tof_op_mode : TofOperationMode::Default,
trigger_poisson_rate : 0,
trigger_fixed_rate : 100,
data_type : DataType::TimingCalibration,
rb_buff_size : 1000
};
let socket = connect_to_zmq().expect("Not able to connect to socket, something REAL strange happened.");
let mut board_id = 0u8;
match get_board_id() {
Err(err) => {
error!("Unable to obtain board id. Calibration might be orphaned. Err {err}");
},
Ok(rb_id) => {
board_id = rb_id as u8;
}
}
let mut calibration = RBCalibrations::new(board_id);
calibration.serialize_event_data = true;
run_config.data_type = DataType::Noi;
match run_noi_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run no input calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Noi calibration step done!")
}
};
run_config.data_type = DataType::VoltageCalibration;
match run_voltage_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run voltage calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Voltage calibration step done!")
}
};
run_config.data_type = DataType::TimingCalibration;
match run_timing_calibration(rc_to_runner, &socket, &mut calibration, run_config) {
Err(err) => {
error!("Unable to run timing calibration step. Err {err}");
return Err(CalibrationError::CalibrationFailed);
},
Ok(_) => {
info!("Timing calibration step done!")
}
};
println!("==> No input + voltage + timing data taking complete!");
println!("Calibration : {}", calibration);
println!("Cleaning data...");
calibration.clean_input_data();
println!("Calibration : {}", calibration);
info!("Will set board to sma mode!");
match select_sma_mode() {
Err(err) => error!("Unable to select SMA mode! {err:?}"),
Ok(_) => ()
}
run_config.is_active = false;
match rc_to_runner.send(run_config) {
Err(err) => {
warn!("Can not send runconfig! {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => trace!("Success!")
}
thread::sleep(FIVE_SECONDS);
println!("Calibration won't start. The data taking chain is complete, but a sub-calibration routine was called!");
let calib_pack = TofPacket::from(&calibration);
match tp_to_publisher.send(calib_pack) {
Err(err) => {
error!("Unable to send RBCalibration package! Error {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => ()
}
info!("Calibration done!");
Ok(())
}
fn connect_to_zmq() -> Result<zmq::Socket, CalibrationError> {
let mut board_id = 0u8;
match get_board_id() {
Err(err) => {
error!("Unable to obtain board id. Calibration might be orphaned. Err {err}");
},
Ok(rb_id) => {
board_id = rb_id as u8;
}
}
let data_address = format!("tcp://10.0.1.1{:02}:{}", board_id, DATAPORT);
let ctx = zmq::Context::new();
let socket : zmq::Socket;
match ctx.socket(zmq::SUB) {
Err(err) => {
error!("Unable to create zmq socket! Err {err}. This is BAD!");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
}
Ok(sock) => {
socket = sock;
}
}
match socket.connect(&data_address) {
Err(err) => {
error!("Unable to connect to data (PUB) socket {data_address}, Err {err}");
return Err(CalibrationError::CanNotConnectToMyOwnZMQSocket);
},
Ok(_) => ()
}
let topic_local = String::from("LOCAL");
match socket.set_subscribe(&topic_local.as_bytes()) {
Err(err) => error!("Can not subscribe to {topic_local}, err {err}"),
Ok(_) => info!("Subscribing to local packages!"),
}
Ok(socket)
}
fn run_noi_calibration(rc_to_runner: &Sender<RunConfig>,
socket: &zmq::Socket,
calibration: &mut RBCalibrations,
run_config: RunConfig)
-> Result<(), CalibrationError> {
info!("Will set board to no input mode!");
match select_noi_mode() {
Err(err) => error!("Unable to select SMA mode! {err:?}"),
Ok(_) => (),
}
match rc_to_runner.send(run_config) {
Err(err) => warn!("Can not send runconfig!, Err {err}"),
Ok(_) => trace!("Success!")
}
let cal_dtype = DataType::Noi;
calibration.noi_data = wait_while_run_active(20, 4*FIVE_SECONDS, 1000, &cal_dtype, &socket);
println!("==> {} events for no-input (Voltage calibration) data taken!", calibration.noi_data.len());
Ok(())
}
fn run_voltage_calibration(rc_to_runner: &Sender<RunConfig>,
socket: &zmq::Socket,
calibration: &mut RBCalibrations,
mut run_config: RunConfig)
-> Result<(), CalibrationError> {
info!("Will set board to vcal mode!");
match select_vcal_mode() {
Err(err) => error!("Unable to select VCAL mode! {err:?}"),
Ok(_) => ()
}
run_config.data_type = DataType::VoltageCalibration;
match rc_to_runner.send(run_config) {
Err(err) => warn!("Can not send runconfig! {err}"),
Ok(_) => trace!("Success!")
}
let cal_dtype = DataType::VoltageCalibration;
calibration.vcal_data = wait_while_run_active(20, 4*FIVE_SECONDS, 1000, &cal_dtype, &socket);
println!("==> {} events for vcal (voltage calibration) data taken!", calibration.vcal_data.len());
Ok(())
}
fn run_timing_calibration(rc_to_runner: &Sender<RunConfig>,
socket: &zmq::Socket,
calibration: &mut RBCalibrations,
mut run_config: RunConfig)
-> Result<(), CalibrationError> {
info!("Will set board to tcal mode!");
run_config.trigger_poisson_rate = 80;
run_config.nevents = 1800; run_config.trigger_fixed_rate = 0;
run_config.data_type = DataType::TimingCalibration;
match select_tcal_mode() {
Err(err) => error!("Can not set board to TCAL mode! {err:?}"),
Ok(_) => (),
}
match rc_to_runner.send(run_config) {
Err(err) => warn!("Can not send runconfig! {err}"),
Ok(_) => trace!("Success!")
}
let cal_dtype = DataType::TimingCalibration;
calibration.tcal_data = wait_while_run_active(20, 4*FIVE_SECONDS, 1000,&cal_dtype, &socket);
println!("==> {} events for tcal (timing calibration) data taken!", calibration.tcal_data.len());
Ok(())
}
pub fn rb_start_run(rc_to_runner : &Sender<RunConfig>,
rc_config : RunConfig,
_run_type : u8,
_rb_id : u8,
_event_no : u8) -> Result<(), RunError> {
println!("==> Will initialize new run!");
match rc_to_runner.send(rc_config) {
Err(err) => error!("Error initializing run! {err}"),
Ok(_) => ()
};
println!("==> Run successfully started!");
Ok(())
}
pub fn rb_stop_run(rc_to_runner : &Sender<RunConfig>,
_rb_id : u8) -> Result<(), RunError> {
println!("==> Will initialize new run!");
println!("Received command to end run!");
let rc = RunConfig::new();
match rc_to_runner.send(rc) {
Err(err) => error!("Error stopping run! {err}"),
Ok(_) => ()
}
println!("==> Run successfully stopped!");
Ok(())
}
const DMA_RESET_TRIES : u8 = 10; pub const DATAPORT : u32 = 42000;
pub fn is_systemd_process() -> bool {
if env::var("LIFTOF_IS_SYSTEMD").is_ok() {
info!("Running under systemd");
true
} else {
info!("Not running under systemd");
false
}
}
pub fn get_runconfig(rcfile : &Path) -> RunConfig {
match read_to_string(rcfile) {
Err(err) => {
panic!("Unable to read the configuration file! Error {err}");
}
Ok(rc_from_file) => {
println!("==> Found configuration file {}!", rcfile.display());
match serde_json::from_str(&rc_from_file) {
Err(err) => panic!("Can not read json from configuration file. Error {err}"),
Ok(rc_json) => {
rc_json
}
}
}
}
}
pub fn get_active_buffer() -> Result<RamBuffer, RegisterError> {
let dma_ptr = get_dma_pointer()?;
if dma_ptr >= UIO1_MAX_OCCUPANCY {
return Ok(RamBuffer::B);
}
Ok(RamBuffer::A)
}
pub fn prefix_local(input : &mut Vec<u8>) -> Vec<u8> {
let mut bytestream : Vec::<u8>;
let local = String::from("LOCAL");
bytestream = local.as_bytes().to_vec();
bytestream.append(input);
bytestream
}
pub fn prefix_board_id(input : &mut Vec<u8>) -> Vec<u8> {
let board_id = get_board_id().unwrap_or(0);
let mut bytestream : Vec::<u8>;
let board = format!("RB{:02}", board_id);
bytestream = board.as_bytes().to_vec();
bytestream.append(input);
bytestream
}
pub fn prefix_board_id_noquery(board_id : u8, input : &mut Vec<u8>) -> Vec<u8> {
let mut bytestream : Vec::<u8>;
let board = format!("RB{:02}", board_id);
bytestream = board.as_bytes().to_vec();
bytestream.append(input);
bytestream
}
pub fn reset_dma_and_buffers() {
let one_milli = time::Duration::from_millis(1);
let buf_a = RamBuffer::A;
let buf_b = RamBuffer::B;
let mut n_tries = 0u8;
let mut failed = true;
loop {
if failed && n_tries < DMA_RESET_TRIES {
match reset_dma() {
Ok(_) => (),
Err(err) => {
error!("Resetting dma failed, err {:?}", err);
n_tries += 1;
thread::sleep(one_milli);
continue;
}
}
match reset_ram_buffer_occ(&buf_a) {
Ok(_) => (),
Err(err) => {
error!("Problem resetting buffer /dev/uio1 {:?}", err);
n_tries += 1;
thread::sleep(one_milli);
continue;
}
}
match reset_ram_buffer_occ(&buf_b) {
Ok(_) => (),
Err(err) => {
error!("Problem resetting buffer /dev/uio2 {:?}", err);
n_tries += 1;
thread::sleep(one_milli);
continue;
}
}
failed = false;
} else {
break;
}
}
thread::sleep(10*one_milli);
}
pub fn run_check() {
let buf_a = RamBuffer::A;
let buf_b = RamBuffer::B;
let interval = Duration::from_secs(5);
let mut n_iter = 0;
let mut last_occ_a = get_blob_buffer_occ(&buf_a).unwrap();
let mut last_occ_b = get_blob_buffer_occ(&buf_b).unwrap();
match enable_trigger() {
Err(err) => error!("Unable to enable trigger! Err {err}"),
Ok(_) => info!("Triggers enabled")
}
loop {
n_iter += 1;
thread::sleep(interval);
let occ_a = get_blob_buffer_occ(&buf_a).unwrap();
let occ_b = get_blob_buffer_occ(&buf_b).unwrap();
if occ_a - last_occ_a == 0 && occ_b - last_occ_b == 0 {
panic!("We did not observe a change in occupancy for either one of the buffers!");
}
println!("-- buff size A {}", occ_a - last_occ_a);
println!("-- buff size B {}", occ_b - last_occ_b);
println!("---> Iter {n_iter}");
last_occ_a = occ_a;
last_occ_b = occ_b;
}
}
pub fn get_buff_size(which : &RamBuffer) ->Result<usize, RegisterError> {
let size : u32;
let occ = get_blob_buffer_occ(&which)?;
trace!("Got occupancy of {occ} for buff {which:?}");
match which {
RamBuffer::A => {size = occ - UIO1_MIN_OCCUPANCY;},
RamBuffer::B => {size = occ - UIO2_MIN_OCCUPANCY;}
}
let result = size as usize;
Ok(result)
}
pub fn experimental_ram_buffer_handler(buff_trip : usize,
streamer : &mut RBEventMemoryStreamer)
-> Result<(RamBuffer, usize), RegisterError> {
let mut switch_buff = false;
if buff_trip < DATABUF_TOTAL_SIZE {
switch_buff = true;
}
let which = get_active_buffer()?;
let mut buff_size = get_buff_size(&which)?;
if buff_size >= buff_trip {
info!("Buff {which:?} tripped at a size of {buff_size}");
debug!("Buff handler switch buffers {switch_buff}");
if switch_buff {
match switch_ram_buffer() {
Ok(_) => {
info!("Ram buffer switched!");
},
Err(_) => error!("Unable to switch RAM buffers!")
}
}
match read_buffer_into_streamer(&which, buff_size as usize, streamer) {
Err(err) => error!("Can not read data buffer into RBEventMemoryStreamer! {err}"),
Ok(_) => (),
}
match reset_ram_buffer_occ(&which) {
Ok(_) => debug!("Successfully reset the buffer occupancy value"),
Err(_) => error!("Unable to reset buffer!")
}
buff_size = 0;
}
Ok((which, buff_size))
}
pub fn ram_buffer_handler(buff_trip : usize,
bs_sender : &Sender<Vec<u8>>)
-> Result<(RamBuffer, usize, bool), RegisterError> {
let mut switch_buff = false;
let mut has_tripped = false;
if buff_trip < DATABUF_TOTAL_SIZE {
switch_buff = true;
}
let which = get_active_buffer()?;
let mut buff_size = get_buff_size(&which)?;
if buff_size >= buff_trip {
info!("Buff {which:?} tripped at a size of {buff_size}");
debug!("Buff handler switch buffers {switch_buff}");
has_tripped = true;
if switch_buff {
loop {
match daq_is_busy() {
Err(err) => {
trace!("DAQ is busy, not reading out RAM buffers..! {err}");
continue;
}
Ok(busy) => {
if busy {
continue;
}
match switch_ram_buffer() {
Ok(_) => {
info!("Ram buffer switched!");
},
Err(_) => error!("Unable to switch RAM buffers!")
}
break;
}
}
}
}
buff_size = get_buff_size(&which)?;
let mut bytestream = Vec::<u8>::new();
match read_data_buffer(&which, buff_size as usize) {
Err(err) => error!("Can not read data buffer {err}"),
Ok(bs) => bytestream = bs,
}
let bs_len = bytestream.len();
match bs_sender.send(bytestream) {
Err(err) => error!("error sending {err}"),
Ok(_) => {
info!("We are sending {} event bytes for further processing!", bs_len);
}
}
match reset_ram_buffer_occ(&which) {
Ok(_) => debug!("Successfully reset the buffer occupancy value"),
Err(_) => error!("Unable to reset buffer!")
}
buff_size = 0;
}
Ok((which, buff_size, has_tripped))
}
pub fn setup_drs4() -> Result<(), RegisterError> {
let buf_a = RamBuffer::A;
let buf_b = RamBuffer::B;
let one_milli = time::Duration::from_millis(1);
let spike_clean : bool = true;
clear_dma_memory()?;
thread::sleep(one_milli);
info!("Resetting event memory buffers..");
for _ in 0..5 {
reset_ram_buffer_occ(&buf_a)?;
thread::sleep(one_milli);
reset_ram_buffer_occ(&buf_b)?;
thread::sleep(one_milli);
}
let spike_clean_enable : u32 = 4194304; if spike_clean {
let mut value = read_control_reg(0x40).unwrap();
value = value | spike_clean_enable;
write_control_reg(0x40, value)?;
thread::sleep(one_milli);
}
thread::sleep(one_milli);
set_master_trigger_mode()?;
thread::sleep(one_milli);
Ok(())
}
pub fn send_ltb_all_thresholds_set() -> Result<(), SetError> {
match ltb_threshold::set_default_threshold() {
Ok(_) => return Ok(()),
Err(_) => {
error!("Unable to set preamp bias! Error LTBThresholdError!");
return Err(SetError::CanNotConnectToMyOwnZMQSocket)
}
};
}
pub fn send_ltb_all_thresholds_reset() -> Result<(), SetError> {
match ltb_threshold::reset_threshold() {
Ok(_) => (),
Err(_) => {
error!("Unable to set preamp bias! Error LTBThresholdError!");
}
};
Ok(())
}
pub fn send_ltb_threshold_set(_ltb_id: u8, threshold_name: LTBThresholdName, threshold_level: u16) -> Result<(), SetError> {
let ch = LTBThresholdName::get_ch_number(threshold_name).unwrap();
match ltb_threshold::set_threshold(ch, threshold_level as f32) {
Ok(_) => (),
Err(_) => {
error!("Unable to set preamp bias! Error LTBThresholdError!");
}
};
Ok(())
}