AlcapDAQ  1
rpc_master.cpp
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <unistd.h>
5 #include <sys/io.h>
6 
7 #include "midas.h"
8 
9 #include "crate.h"
10 #include "diag.h"
11 #include "odb_wrapper.h"
12 
13 #define DEFINE_RPC_LIST
14 #include "rpc_mucap.h"
15 
16 INT rpc_ready_for_cycle(INT index, void *prpc_param[]);
17 INT rpc_request_stop(INT index, void *prpc_param[]);
18 INT rpc_master_init();
19 INT rpc_master_pre_bor();
20 INT rpc_master_bor();
21 INT rpc_master_eor();
24 INT rpc_master_read(char *pevent);
25 
26 struct {
27  BOOL enabled;
30  BOOL ready[3]; // index indicates RAM cycle (index 0 not used)
31  HNDLE conn;
32 } crate[MAX_CRATES];
33 
36 static BOOL enable_rpc_master;
37 
39  rpc_master_init, // init
40  NULL, // exit
41  rpc_master_pre_bor, // pre_bor
42  rpc_master_bor, // bor
43  rpc_master_eor, // eor
44  rpc_master_poll_live, // poll_live
45  rpc_master_poll_dead, // poll_dead
46  NULL, // start_block
47  NULL, // stop_block
48  rpc_master_read, // read
49 };
50 
51 /*
52  * rpc_master_init
53  *
54  */
55 INT rpc_master_init()
56 {
57  // Determine whether we ought to be the master
59  odb_get_bool("/Equipment/Crate %d/Settings/Master", crate_number);
60  if(!enable_rpc_master) {
61  return SUCCESS;
62  }
63 
64  // register the RPC function that we provide
65  rpc_register_functions(rpc_list_mucap, NULL);
66  rpc_register_function(RPC_READY_FOR_CYCLE, rpc_ready_for_cycle);
67  rpc_register_function(RPC_REQUEST_STOP, rpc_request_stop);
68 
69  return SUCCESS;
70 }
71 
72 /*
73  * rpc_master_pre_bor()
74  */
76 {
77  diag_print(1, "Clearing crate ready flags\n");
78 
79  for(int i = 0; i < MAX_CRATES; i++) {
80  for(int j = 0; j <= 2; j++) {
81  crate[i].ready[j] = FALSE;
82  }
83  }
84 
85  return SUCCESS;
86 }
87 
88 /*
89  * rpc_master_bor()
90  */
91 INT rpc_master_bor()
92 {
93  if(!enable_rpc_master) {
94  return SUCCESS;
95  }
96 
97  for(int i = 0; i < MAX_CRATES; i++) {
98  if(i != crate_number) {
99  bool enabled = false;
100  if(odb_find_key("/Equipment/Crate %d", i) != NULL) {
101  enabled = odb_get_bool("/Equipment/Crate %d/Settings/Enabled", i);
102  }
103  crate[i].enabled = enabled;
104 
105 
106  if(enabled) {
107  crate[i].synchronous =
108  odb_get_bool("/Equipment/Crate %d/Settings/Synchronous", i);
109 
110  char crate_label[10];
111  sprintf(crate_label, "Crate %d", i);
112  cm_connect_client(crate_label, &crate[i].conn);
113  rpc_set_option(crate[i].conn, RPC_OTRANSPORT, RPC_FTCP);
114  rpc_set_option(crate[i].conn, RPC_NODELAY, TRUE);
115  }
116  }
117  }
118 
119  event_number = 1;
120  request_stop_event = 0;
121 
122  return SUCCESS;
123 }
124 
125 /*
126  *
127  */
128 INT rpc_master_eor()
129 {
130  if(!enable_rpc_master) {
131  return SUCCESS;
132  }
133 
134  for(int i = 0; i < MAX_CRATES; i++) {
135  if(i != crate_number && crate[i].enabled) {
136  cm_disconnect_client(crate[i].conn, 0);
137  }
138  }
139 
140  return SUCCESS;
141 }
142 
143 /*
144  *
145  */
146 INT rpc_ready_for_cycle(INT index, void *prpc_param[])
147 {
148  INT crate_number = CINT(0);
149  INT ram_cycle = CINT(1);
150 
151  diag_print(2, "Crate %d is ready for a new cycle on ram=%d.\n",
152  crate_number, ram_cycle);
153 
154  crate[crate_number].ready[ram_cycle] = TRUE;
155 
156 #if 0
157  if(ram_cycle == 0) {
158  crate[crate_number].ready[1] = crate[crate_number].ready[2] = TRUE;
159  } else {
160  crate[crate_number].ready[ram_cycle] = TRUE;
161  }
162 #endif
163 
164  return SUCCESS;
165 }
166 
167 /*
168  *
169  */
170 INT rpc_request_stop(INT index, void *prpc_param[])
171 {
172  INT crate_number = CINT(0);
173  INT event_number_in = CINT(1);
174 
175  diag_print(2, "Crate %d requests end of block %d\n",
176  crate_number, event_number_in);
177 
178  if(event_number_in != event_number) {
179  diag_print(0,
180  "Crate %d requests end of block %d--not the right event number (%d)\n",
181  crate_number, event_number_in, event_number);
182  return SUCCESS;
183  }
184 
185  request_stop_event = event_number_in;
186 
187  return SUCCESS;
188 }
189 
190 /*
191  * Returns whether a particular crate is participating in this cycle.
192  */
193 BOOL crate_is_participating(INT crate_number)
194 {
195  return crate[crate_number].participating;
196 }
197 
198 /*
199  * Returns the TDC400 RAM number (1 or 2) associated with the current
200  * event number.
201  */
203 {
204  return ((event_number + 1) % 2) + 1;
205 }
206 
207 INT rpc_master_read(char *pevent)
208 {
209  if(!enable_rpc_master) {
210  return SUCCESS;
211  }
212 
213  int ram = cycle_ram();
214 
215  // Send a message to other crates that the cycle is now over
216  for(int i = 0; i < MAX_CRATES; i++) {
217  if(i != crate_number && crate[i].enabled) {
219  diag_print(2, "Sending RPC_END_OF_CYCLE to crate %d RAM %d event %d\n",
220  i, ram, event_number);
221  rpc_client_call(crate[i].conn, RPC_END_OF_CYCLE, ram, event_number);
222  }
223  }
224  }
225 
226  // Increment event number
227  event_number++;
228 
229  return SUCCESS;
230 }
231 
233 {
234  if(!enable_rpc_master) {
235  return SUCCESS;
236  }
237 
238  // Yield to receive any pending RPCs
239  cm_yield(0);
240 
241  // Have we received a request to end the event?
243  diag_print(2, "Stopping event.\n");
244  return FE_NEED_STOP;
245  }
246 
247  return SUCCESS;
248 }
249 
251 {
252  if(!enable_rpc_master) {
253  return SUCCESS;
254  }
255 
256  // Yield to receive any pending RPCs
257  cm_yield(0);
258 
259  // Have we received notice from each of the enabled crates that
260  // it is ready to start?
261 
262  BOOL ready_to_start = TRUE;
263 
264  INT ram = cycle_ram();
265 
266  for(int i = 0; i < MAX_CRATES; i++) {
267  if(i != crate_number && crate[i].enabled && crate[i].synchronous &&
268  !(crate[i].ready[ram] || crate[i].ready[0])) {
269  ready_to_start = FALSE;
270  break;
271  }
272  }
273 
274  if(ready_to_start) {
275  for(int i = 0; i < MAX_CRATES; i++) {
276  crate[i].participating = (crate[i].ready[ram] || crate[i].ready[0]);
277 
278  crate[i].ready[ram] = FALSE;
279  crate[i].ready[0] = FALSE;
280  }
281 
282  return FE_NEED_START;
283  } else {
284  return SUCCESS;
285  }
286 }
287