liftof_rb/
control.rs

1//! Convenience functions to read/write
2//!  the various control registers
3//!
4//!  
5//!  For the mapping of registers/addresses, 
6//!  see `registers.rs`
7//!
8
9use crate::registers::*;
10use crate::memory::*;
11
12use std::time::Duration;
13use std::thread;
14
15extern crate liftof_lib;
16
17/// Read the link ID from the MTB 
18///
19/// THe link ID comes from the MTB
20pub fn get_mtb_link_id() -> Result<u32, RegisterError> {
21  trace!("Getting MTB Link ID!");
22  let mut val = read_control_reg(MT_LINK_ID)?;
23  val = val & 0x01F8;
24  val = val >> 3;
25  Ok(val) 
26}
27
28
29/// write header only packets when the drs is busy
30pub fn enable_evt_fragments() -> Result<(), RegisterError> {
31  trace!("Enable event fragment writing!");
32  write_control_reg(WRITE_EVENTFRAGMENT, 1)?;
33  Ok(())
34}
35
36/// use the random self trigger
37pub fn set_self_trig_rate(rate : u32) -> Result<(), RegisterError> {
38  warn!("Setting self trigger rate, writing register {}", TRIG_GEN_RATE);
39  write_control_reg(TRIG_GEN_RATE, rate)?;
40  Ok(())
41}
42
43/// do not write header only packets when the drs is busyu
44pub fn disable_evt_fragments() -> Result<(), RegisterError> {
45  trace!("Disable event fragment writing!");
46  write_control_reg(WRITE_EVENTFRAGMENT, 0)?;
47  Ok(())
48}
49
50/// enable triggering
51pub fn enable_trigger() -> Result<(), RegisterError> {
52  trace!("Enable triggers!");
53  write_control_reg(TRIGGER_ENABLE, 1)?;
54  Ok(())
55}
56
57/// stop all triggers
58pub fn disable_trigger() -> Result<(), RegisterError> {
59  trace!("Enable triggers!");
60  write_control_reg(TRIGGER_ENABLE, 0)?;
61  Ok(())
62}
63
64pub fn daq_is_busy() -> Result<bool, RegisterError> {
65  let busy = (read_control_reg(DAQ_BUSY)? & 0x2) > 0;
66  Ok(busy)
67}
68
69/// Reset the board and prepare for a new run
70///
71/// Procedure as discussed in 12/2023
72/// Trigger disable (0 to 0x11C\[0\])
73/// Set desired trigger mode  (1 to 0x114\[0\] for MTB trigger or 0 to 0x114\[0\] for software trigger)
74/// Soft reset (1 to 0x70\[0\])
75/// Check for soft reset done (read 0x74\[15\])
76/// Trigger enable (1 to 0x11C\[0\])
77pub fn soft_reset_board() -> Result<(), RegisterError> {
78  trace!("Initialize soft reset procedure!");
79  let eight_cycles = Duration::from_micros(4);
80  write_control_reg(SOFT_RESET, 0x1)?;
81  thread::sleep(eight_cycles);
82  let mut ncycles = 0;
83  while !soft_reset_done()? {
84    thread::sleep(eight_cycles);
85    ncycles += 1;
86    if ncycles % 10 == 0 {
87      error!("Not getting SOFT_RESET_DONE acknowledged. Will try DMA reset");
88      match reset_dma() {
89        Err(err) => error!("Unable to reset DMA! {err}"),
90        Ok(_)    => ()
91      }
92    }
93    if ncycles == 29 {
94      return Err(RegisterError::RegisterTimeOut);     
95    }
96  }
97  Ok(())
98}
99
100/// Check if the soft reset procedure has finished
101pub fn soft_reset_done() -> Result<bool, RegisterError> {
102  let mask : u32 = 1 << 15;
103  let value = read_control_reg(SOFT_RESET_DONE)?;
104  return Ok((value & mask) > 0)
105}
106
107
108/// Start DRS4 data acquistion
109pub fn start_drs4_daq() -> Result<(), RegisterError> {
110  trace!("SET DRS4 START");
111  write_control_reg(DRS_START, 1)?;
112  Ok(())
113}
114
115
116/// Put the daq in idle state, that is stop data taking
117pub fn idle_drs4_daq() -> Result<(), RegisterError> {
118  trace!("SET DRS4 IDLE");
119  write_control_reg(DRS_REINIT, 1)?;
120  Ok(())
121}
122
123/// Get the blob buffer occupancy for one of the two buffers
124///  
125/// This is a bit tricky. This will continuously change, as 
126/// the DRS4 is writing into the memory. At some point, it 
127/// will be full, not changing it's value anymore. At that 
128/// point, if set, the firmware has switched automatically 
129/// to the other buffer. 
130///
131/// Also, it will only read something like zero if the 
132/// DMA has completly been reset (calling dma_reset).
133/// 
134/// # Arguments
135///
136/// * which : select the blob buffer to query
137///
138///
139pub fn get_blob_buffer_occ(which : &RamBuffer) -> Result<u32, RegisterError> {
140  let address = match which {
141    RamBuffer::A => RAM_A_OCCUPANCY,
142    RamBuffer::B => RAM_B_OCCUPANCY,
143  };
144
145  let value = read_control_reg(address)?;
146  Ok(value)
147}
148
149
150/// Check if teh TRIGGER_ENABLE register is set
151pub fn get_triggers_enabled() -> Result<bool, RegisterError> {
152  let value = read_control_reg(TRIGGER_ENABLE)?;
153  Ok(value > 0)
154}
155
156/// FIXME
157pub fn get_dma_pointer() -> Result<u32, RegisterError> {
158  let value = read_control_reg(DMA_POINTER)?;
159  Ok(value)
160}
161
162/// Reset the DMA memory (blob data) and write 0s
163pub fn clear_dma_memory() -> Result<(), RegisterError> {
164  trace!("SET DMA CLEAR");
165  write_control_reg(DMA_CLEAR, 1)?;  
166  // the reset takes 8 clock cycles at 33 MHz (about 3.4 micro)
167  let eight_cycles = Duration::from_micros(4);
168  thread::sleep(eight_cycles);
169  Ok(())
170}
171
172
173/// Reset means, the memory can be used again, but it does not mean it 
174/// clears the memory.
175///
176/// The writing into the memory thus can start anywhere in memory (does 
177/// not have to be from 0)
178pub fn reset_ram_buffer_occ(which : &RamBuffer) -> Result<(), RegisterError> {
179  match which { 
180    RamBuffer::A => write_control_reg(RAM_A_OCC_RST, 0x1)?,
181    RamBuffer::B => write_control_reg(RAM_B_OCC_RST, 0x1)?
182  };
183  // the reset takes 8 clock cycles at 33 MHz (about 3.4 micro)
184  let eight_cycles = Duration::from_micros(4);
185  thread::sleep(eight_cycles);
186  Ok(())
187}
188
189/// Get the recorded triggers by the DRS4
190pub fn get_trigger_rate() -> Result<u32, RegisterError> {
191  let value = read_control_reg(TRIGGER_RATE)?;
192  Ok(value)
193}
194
195/// Get the rate of the lost triggers by the DRS4
196pub fn get_lost_trigger_rate() -> Result<u32, RegisterError> {
197  let value = read_control_reg(LOST_TRIGGER_RATE)?;
198  Ok(value)
199}
200
201/// Get the event counter from the DRS4
202///
203/// The event counter is NOT the event id comming from 
204/// the master trigger. It is simply the number of 
205/// events observed since the last reset.
206///
207pub fn get_event_count() -> Result<u32, RegisterError> {
208  let value = read_control_reg(CNT_EVENT)?;
209  Ok(value)
210}
211
212/// Get the event counter as sent from the MTB
213pub fn get_event_count_mt() -> Result<u32, RegisterError> {
214  let value = read_control_reg(MT_EVENT_CNT)?;
215  Ok(value)
216}
217
218/// Get the rate as sent from the MTB
219pub fn get_event_rate_mt() -> Result<u32, RegisterError> {
220  let value = read_control_reg(MT_TRIG_RATE)?;
221  Ok(value)
222}
223
224/// Get the lost events event counter from the DRS4
225pub fn get_lost_event_count() -> Result<u32, RegisterError> {
226  let value = read_control_reg(CNT_LOST_EVENT)?;
227  Ok(value)
228}
229
230/// This simply sets the configure bit.
231///
232/// Unclear what it actually does.
233/// FIXME
234pub fn set_drs4_configure() -> Result<(), RegisterError> {
235  trace!("SET DRS4 CONFIGURE");
236  write_control_reg(DRS_CONFIGURE, 1)?;
237  Ok(())
238}
239
240/// Force a trigger
241///
242/// _If I understand it correctly, this is a single trigger_
243///
244pub fn trigger() -> Result<(), RegisterError> {
245  //warn!("Setting force trigger mode!");
246  write_control_reg(FORCE_TRIG, 1)?;
247  Ok(())
248}
249
250/// Reset of the internal event counter
251///
252///  This is NOT the event id.
253pub fn reset_drs_event_ctr() -> Result<(), RegisterError> {
254  trace!("SET DRS4 EV CNT RESET");
255  write_control_reg(CNT_RESET, 1)?;
256  Ok(())
257}
258
259pub fn reset_daq() -> Result<(), RegisterError> {
260  trace!("SET DAQ RESET");
261  write_control_reg(DAQ_RESET, 1)?;
262  Ok(())
263}
264
265pub fn reset_drs() -> Result<(), RegisterError> {
266  trace!("SET DRS RESET");
267  write_control_reg(DRS_REINIT, 1)?;
268  Ok(())
269}
270
271///! Resets the DMA state machine.
272pub fn reset_dma() -> Result<(), RegisterError> {
273  trace!("SET DMA RESET");
274  write_control_reg(DMA_RESET, 1)?;
275  // the reset takes 8 clock cycles at 33 MHz (about 3.4 micro)
276  let eight_cycles = Duration::from_micros(4);
277  thread::sleep(eight_cycles);
278  Ok(())
279}
280
281
282///! Toggle between the data buffers A and B
283pub fn switch_ram_buffer() -> Result<(), RegisterError> {
284  trace!("SET DMA DATA BUFF TOGGLE");
285  write_control_reg(TOGGLE_RAM, 1)?;
286  Ok(())
287}
288
289///! The device DNA is a unique identifier
290pub fn get_device_dna() -> Result<u64, RegisterError> {
291  let lsb = read_control_reg(DNA_LSBS)?;
292  let msb = read_control_reg(DNA_MSBS)?;
293  let mut value : u64 = 0;
294  value = value | (msb as u64) << 32;
295  value = value | lsb as u64;
296  Ok(value)
297}
298
299
300/// Enable the readout of all channels + the 9th channel
301pub fn set_readout_all_channels_and_ch9() -> Result<(), RegisterError> {
302  warn!("This might be buggy!");
303  let all_channels : u32 = 511;
304  let ch_9         : u32 = 512;
305  let value = all_channels | ch_9;
306  trace!("SET DRS4 READOUT MASK");
307  write_control_reg(READOUT_MASK, value)?;
308  Ok(())
309}
310
311/// Enable active channels by not touching the ch9 bits
312pub fn set_active_channel_mask(ch_mask : u8) -> Result<(), RegisterError> {
313  let mut value   = read_control_reg(READOUT_MASK)?;
314  // FIXME - do debug! instead.
315  println!("==> Got current channel mask! {value}");
316  let ch9_part     = value & 0xFF00; // set all ch to 0;
317  value            = ch9_part | ch_mask as u32;
318  write_control_reg(READOUT_MASK, value)?;
319  println!("==> Wrote {value} to channel mask register!");
320  Ok(())
321}
322
323pub fn set_active_channel_mask_with_ch9(ch_mask : u32) -> Result<(), RegisterError> {
324  let ch_9  : u32 = 256;
325  let value = ch_mask | ch_9;
326  write_control_reg(READOUT_MASK, value)?;
327  Ok(())
328}
329
330/// Enable the master trigger mode
331pub fn set_master_trigger_mode() -> Result<(), RegisterError> {
332  trace!("SET DRS4 MT MODE");
333  write_control_reg(MT_TRIGGER_MODE, 1)?;
334  Ok(())
335}
336
337/// Disable the master trigger
338pub fn disable_master_trigger_mode() -> Result<(), RegisterError> {
339  warn!("Disabeling master trigger mode");
340  write_control_reg(MT_TRIGGER_MODE, 0)?;
341  Ok(())
342}
343
344
345///! Get the board ID from the control registers.
346pub fn get_board_id() -> Result<u32, RegisterError> { 
347  let board_id = read_control_reg(BOARD_ID)?;
348  Ok(board_id)
349}
350
351///! Get the board ID from the control registers.
352pub fn get_board_id_string() -> Result<String, RegisterError> { 
353  let board_id = get_board_id()?;
354  let board_id_string = liftof_lib::to_board_id_string(board_id);
355  Ok(board_id_string)
356}
357
358/// Read te last DRS4 Deadtime
359pub fn get_deadtime() -> Result<u32, RegisterError> {
360  let deadtime = read_control_reg(DRS_DEADTIME)?;
361  Ok(deadtime & 0xffff)
362}