tof_dataclasses/commands/
factory.rs

1//! The actual command list - one function per ocmmand
2//!
3//! These are factory functions and each of them will 
4//! return a single command
5
6use std::collections::HashMap;
7
8use crate::commands::{
9  TofCommandV2,
10  TofCommandCode
11};
12
13use crate::commands::config::{
14  TriggerConfig,
15  TOFEventBuilderConfig,
16  DataPublisherConfig,
17  TofRunConfig,
18  TofRBConfig,
19};
20
21use crate::serialization::Serialization;
22
23/// A hardwired map of RB -> RAT
24pub fn get_rbratmap_hardcoded() ->  HashMap<u8,u8> {
25  warn!("Using hardcoded rbratmap!");
26  let mapping = HashMap::<u8,u8>::from(
27      [(1, 10), 
28       (2, 15), 
29       (3,  1),  
30       (4, 15), 
31       (5, 20), 
32       (6, 19), 
33       (7, 17), 
34       (8,  9),
35       (9, 13),  
36       (11,10),
37       (13, 4), 
38       (14, 2), 
39       (15, 1), 
40       (16, 8), 
41       (17,17),
42       (18,13),
43       (19, 7), 
44       (20, 7), 
45       (21, 5), 
46       (22,11),
47       (23, 5), 
48       (24, 6), 
49       (25, 8), 
50       (26,11),
51       (27, 6), 
52       (28,20),
53       (29, 3), 
54       (30, 9), 
55       (31, 3), 
56       (32, 2), 
57       (33,18),
58       (34,18),
59       (35, 4), 
60       (36,19),
61       (39,12),
62       (40,12),
63       (41,14),
64       (42,14),
65       (44,16),
66       (46,16)]);
67  mapping
68}
69
70/// A hardwired map of RAT -> (RB1, RB2)
71pub fn get_ratrbmap_hardcoded() ->  HashMap<u8,(u8,u8)> {
72  warn!("Using hardcoded ratrb map!");
73  let mapping = HashMap::<u8,(u8,u8)>::from(
74      [(1, (3,15)), 
75       (2, (32,14)), 
76       (3, (31,29)),  
77       (4, (35,13)), 
78       (5, (23,21)), 
79       (6, (27,24)), 
80       (7, (20,19)), 
81       (8, (16,25)),  
82       (9, (8,30)),
83       (10,(1,11)), 
84       (11,(26,22)), 
85       (12,(39,40)),
86       (13,(9,18)), 
87       (14,(41,42)),
88       (15,(2,4)),
89       (16,(46,44)), 
90       (17,(7,17)), 
91       (18,(33,34)), 
92       (19,(36,6)), 
93       (20,(28,5))]); 
94  mapping
95}
96
97/// A hardwired map of PDU #id PDUCHANNEL #id to (RAT,RAT)
98///
99/// Can be used to synchronize powering down proces for 
100/// RATs
101pub fn get_ratpdumap_hardcoded() ->  HashMap<u8,HashMap::<u8, (u8,u8)>> {
102  warn!("Using hardcoded rat-pdu map!");
103  let mut mapping = HashMap::<u8,HashMap::<u8,(u8,u8)>>::new();
104  let mut ch_map = HashMap::<u8, (u8,u8)>::from([(3, (15,16)), (7, (8,9))]);
105  mapping.insert(0u8, ch_map.clone());
106  ch_map = HashMap::<u8, (u8, u8)>::from([(2, (2,17)), (3, (4,5)), (5, (13,14))]);
107  mapping.insert(1u8, ch_map.clone());
108  ch_map = HashMap::<u8, (u8, u8)>::from([(3, (12,20)), (4, (10,11)), (5, (8,9))]);
109  mapping.insert(2u8, ch_map.clone());
110  ch_map = HashMap::<u8, (u8, u8)>::from([(2, (6,7)), (3, (1,3))]);
111  mapping.insert(3u8, ch_map.clone());
112  mapping
113}
114
115/// Send the 'sudo shutdown now' command to a single RB
116///
117/// # Arguements:
118///   * rb :  The RB id of the RB to be shutdown 
119///           (NOT RAT)
120pub fn shutdown_rb(rb : u8) -> Option<TofCommandV2> {
121  let code = TofCommandCode::ShutdownRB;
122  let mut cmd  = TofCommandV2::new();
123  cmd.command_code = code;
124  cmd.payload = vec![rb];
125  Some(cmd)
126}
127
128/// Send the 'sudo shutdown now' command to all RBs in a RAT
129///
130/// # Arguments:
131///   * rat : The RAT id for the rat the RBs to be 
132///           shutdown live in 
133pub fn shutdown_rat(rat : u8) -> Option<TofCommandV2> {
134  let code = TofCommandCode::ShutdownRAT;
135  let mut cmd  = TofCommandV2::new();
136  cmd.command_code = code;
137  cmd.payload = Vec::<u8>::new();
138  let ratmap = get_ratrbmap_hardcoded();
139  match ratmap.get(&rat) {
140    None => {
141      error!("Don't know RBs in RAT {}", rat);
142      return None
143    }
144    Some(pair) => {
145      cmd.payload.push(pair.0);
146      cmd.payload.push(pair.1);
147    }
148  }
149  Some(cmd)
150}
151
152/// Send the 'sudo shutdown now' command to all RBs in a RAT
153/// 
154/// This will prepare the shutdown command for the RBs in the 
155/// RATs which are connected to a specific pdu channel
156///
157/// # Arguments:
158///   * pdu        : PDU ID (0-3)
159///   * pduchannel : PDU Channel (0-7)
160pub fn shutdown_ratpair(pdu : u8, pduchannel : u8) -> Option<TofCommandV2> {
161  let code     = TofCommandCode::ShutdownRATPair;
162  let mut cmd  = TofCommandV2::new();
163  cmd.command_code = code;
164  cmd.payload = Vec::<u8>::new();
165  let ratmap    = get_ratrbmap_hardcoded();
166  let ratpdumap = get_ratpdumap_hardcoded();
167  match ratpdumap.get(&pdu) {
168    None => {
169      error!("Don't know that there is a RAT connected to PDU {}!", pdu);
170      return None;
171    }
172    Some(select_pdu) => {
173      match select_pdu.get(&pduchannel) {
174        None => {
175          error!("Don't know that there is a RAT connected to PDU {}, channel {}!", pdu, pduchannel);
176          return None;
177        }
178        Some(rats) => {
179          match ratmap.get(&rats.0) {
180            Some(rbs) => {
181              cmd.payload.push(rbs.0);
182              cmd.payload.push(rbs.1);
183            }
184            None => {
185              error!("RAT mapping incorrect!");
186              return None;
187            }
188          }
189          match ratmap.get(&rats.1) {
190            Some(rbs) => {
191              cmd.payload.push(rbs.0);
192              cmd.payload.push(rbs.1);
193            },
194            None => {
195              error!("RAT mapping incorrect!");
196              return None;
197            }
198          }
199        }
200      }
201    }
202  }
203  Some(cmd)
204}
205
206/// Send the 'sudo shutdown now' command to
207/// ALL RBs
208pub fn shutdown_all_rbs() -> Option<TofCommandV2> {
209  Some(TofCommandV2 {
210    command_code : TofCommandCode::ShutdownRB,
211    payload      : Vec::<u8>::new()
212  })
213}
214
215/// Send the 'sudo shutdown now command to
216/// the TOF main computer ("TOFCPU")
217pub fn shutdown_tofcpu() -> Option<TofCommandV2> {
218  Some(TofCommandV2 {
219    command_code : TofCommandCode::ShutdownCPU,
220    payload      : Vec::<u8>::new()
221  })
222}
223
224/// Restart the liftof-rb clients on the given boards
225///
226/// # Arguments
227///   * rbs: restart the client on the given rb ids, 
228///          if empty, restart on all of them
229pub fn restart_liftofrb(rbs : &Vec<u8>) -> Option<TofCommandV2> {
230  Some(TofCommandV2 {
231    command_code : TofCommandCode::RestartLiftofRBClients,
232    payload      : rbs.clone()
233  })
234}
235
236/// Trigger the start of a new data run with 
237/// the next active config
238pub fn start_run() -> Option<TofCommandV2> {
239  Some(TofCommandV2 {
240    command_code : TofCommandCode::DataRunStart,
241    payload      : Vec::<u8>::new(),
242  })
243}
244
245/// Stop the current active run and idle
246pub fn stop_run() -> Option<TofCommandV2> {
247  Some(TofCommandV2 {
248    command_code : TofCommandCode::DataRunStop,
249    payload      : Vec::<u8>::new(),
250  })
251}
252
253/// Run a calibration of all RBs
254///
255/// # Arguments:
256///   * pre_run_calibration : Run the RBCalibration routine before 
257///                           every run start
258///   * send_packetes       : Send the RBCalibration packets
259///   * save_events         : Save the events to the RBCalibration
260///                           packets
261pub fn rb_calibration(pre_run_calibration : bool, send_packets : bool, save_events : bool) -> Option<TofCommandV2> {
262  let payload = vec![pre_run_calibration as u8, send_packets as u8, save_events as u8];
263  Some(TofCommandV2 {
264    command_code : TofCommandCode::RBCalibration,
265    payload      : payload,
266  })
267}
268
269/// Change the MTBSettings in the config file with relevant trigger settings
270pub fn change_triggerconfig(cfg : &TriggerConfig) -> Option<TofCommandV2> {
271  let payload = cfg.to_bytestream();
272  Some(TofCommandV2 {
273    command_code : TofCommandCode::SetMTConfig,
274    payload      : payload,
275  })
276}
277
278/// Change the EventBuilderSettings in the config file
279pub fn change_tofeventbuilderconfig(cfg : &TOFEventBuilderConfig) -> Option<TofCommandV2> {
280  let payload = cfg.to_bytestream();
281  Some(TofCommandV2 {
282    command_code : TofCommandCode::SetTOFEventBuilderConfig,
283    payload      : payload,
284  })
285}
286
287/// Change the data publisher config part of the config file
288pub fn change_datapublisherconfig(cfg : &DataPublisherConfig) -> Option<TofCommandV2> {
289  let payload = cfg.to_bytestream();
290  Some(TofCommandV2 {
291    command_code : TofCommandCode::SetDataPublisherConfig,
292    payload      : payload,
293  })
294}
295
296/// Change the data publisher config part of the config file
297pub fn change_tofrunconfig(cfg : &TofRunConfig) -> Option<TofCommandV2> {
298  let payload = cfg.to_bytestream();
299  Some(TofCommandV2 {
300    command_code : TofCommandCode::SetTofRunConfig,
301    payload      : payload,
302  })
303}
304
305pub fn change_tofrbconfig(cfg : &TofRBConfig) -> Option<TofCommandV2> {
306  let payload = cfg.to_bytestream();
307  Some(TofCommandV2 {
308    command_code : TofCommandCode::SetTofRBConfig,
309    payload      : payload,
310  })
311}
312