StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
daq_mtd.cxx
1 #include <assert.h>
2 #include <sys/types.h>
3 #include <errno.h>
4 
5 #include <rtsLog.h>
6 #include <rtsSystems.h>
7 
8 #include <SFS/sfs_index.h>
9 
10 #include <DAQ_READER/daqReader.h>
11 #include <DAQ_READER/daq_dta.h>
12 
13 #include "daq_mtd.h"
14 
15 
16 
17 
18 
19 
20 const char *daq_mtd::help_string = "\
21 \n\
22 MTD Help: \n\
23 Supported Banks: \n\
24  raw returns=ptr of start of DDL data; c1=sector[1..1]; c2=rdo[1..4]; \n\
25  legacy returns=ptr to struct mtd_t; \n\
26 \n\
27 \n\
28 " ;
29 
31 {
32 public:
34  daq_det_factory::det_factories[MTD_ID] = this ;
35  }
36 
37  daq_det *create() {
38  return new daq_mtd ;
39  }
40 } ;
41 
42 static daq_det_mtd_factory mtd_factory ;
43 
44 
45 
46 daq_mtd::daq_mtd(daqReader *rts_caller)
47 {
48  rts_id = MTD_ID ;
49  name = rts2name(rts_id) ;
50  sfs_name = "mtd" ;
51  caller = rts_caller ;
52  if(caller) caller->insert(this, rts_id) ;
53 
54  raw = new daq_dta ;
55  legacy = new daq_dta ;
56 
57 
58 
59  LOG(DBG,"%s: constructor: caller %p",name,rts_caller) ;
60  return ;
61 }
62 
63 daq_mtd::~daq_mtd()
64 {
65  LOG(DBG,"%s: DEstructor",name) ;
66 
67  delete raw ;
68  delete legacy ;
69 
70  return ;
71 }
72 
73 
74 
75 daq_dta *daq_mtd::get(const char *bank, int sec, int row, int pad, void *p1, void *p2)
76 {
77  Make() ;
78 
79  if(present==0) return 0 ;
80 
81  LOG(DBG,"%s: looking for bank %s",name,bank) ;
82 
83  if(strcmp(bank,"*")==0) bank = "legacy" ;
84 
85 
86 
87  if(strcasecmp(bank,"raw")==0) {
88  if((present & DET_PRESENT_SFS)==0) return 0 ; // no DDL
89  return handle_raw(sec,row) ; // actually sec, rdo; r1 is the number of bytes
90  }
91  else if(strcasecmp(bank,"legacy")==0) {
92  if((present & DET_PRESENT_SFS)==0) return 0 ; // no legacy
93  return handle_legacy() ;
94  }
95  else {
96  LOG(ERR,"%s: unknown bank type \"%s\"",name,bank) ;
97  }
98 
99  return 0 ;
100 }
101 
102 
103 daq_dta *daq_mtd::handle_legacy()
104 {
105  assert(caller) ;
106 
107  legacy->create(1,"mtd_t",rts_id,DAQ_DTA_STRUCT(mtd_t)) ;
108 
109 
110  mtd_t *mtd_p = (mtd_t *) legacy->request(1) ; // need ONE mtd_t object
111 
112 
113  memset(mtd_p->ddl_words,0,sizeof(mtd_p->ddl_words)) ; // zap it!
114 
115  mtd_p->mode = 1 ; // backward TOF compatibility
116  mtd_p->channels = 0 ; // signal that we have NO old data...
117  mtd_p->max_channels = 0 ; // stale but compatible with old mtdReadaer...
118 
119 
120  for(int r=1;r<=MAX_RDO;r++) {
121  daq_dta *dd = handle_raw(0,r) ;
122  if(dd && dd->iterate()) {
123  u_int *tmp = (u_int *)dd->Void ;
124 
125  u_int words = dd->ncontent/4 ; // mtd wants words...
126 
127  LOG(DBG,"MTD: RDO %d: bytes %d (max %d)",r,dd->ncontent,sizeof(mtd_p->ddl[0])) ;
128 
129  if(words > (sizeof(mtd_p->ddl[0])/4)) {
130  LOG(ERR,"MTD: Huge event in RDO %d: %d words -- clipping to %d words",
131  r,words,sizeof(mtd_p->ddl[0])/4) ;
132 
133  words = sizeof(mtd_p->ddl[0])/4 ;
134  }
135 
136 
137  mtd_p->ddl_words[r-1] = words ;
138 
139 
140  for(u_int i=0;i<words;i++) { //words!
141  mtd_p->ddl[r-1][i] = l2h32(*tmp) ;
142  tmp++ ;
143  }
144 
145  }
146 
147  }
148 
149 
150  legacy->finalize(1,1,0,0) ; // 1 entry; sector 1, row 0, pad 0
151  legacy->rewind() ;
152 
153  return legacy ;
154 }
155 
156 
157 daq_dta *daq_mtd::handle_raw(int sec, int rdo)
158 {
159  char str[128] ;
160  int tot_bytes ;
161  int min_rdo, max_rdo ;
162  int min_sec, max_sec ;
163  struct {
164  int sec ;
165  int rb ;
166  u_int bytes ;
167  } obj[MAX_SEC*MAX_RDO] ;
168 
169  // sanity
170  sec = 1 ; // nothing else for now...
171  min_sec = max_sec = sec ;
172 
173  if(rdo==-1) {
174  min_rdo = 1 ;
175  max_rdo = MAX_RDO ;
176  }
177  else if((rdo<1) || (rdo>MAX_RDO)) return 0 ;
178  else {
179  min_rdo = max_rdo = rdo ;
180  }
181 
182  // bring in the bacon from the SFS file....
183  assert(caller) ;
184 
185  // calc total bytes
186  tot_bytes = 0 ;
187  int o_cou = 0 ;
188  for(int s=min_sec;s<=max_sec;s++) {
189  for(int r=min_rdo;r<=max_rdo;r++) {
190 
191  sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, s, r) ;
192  char *full_name = caller->get_sfs_name(str) ;
193 
194  LOG(DBG,"%s: trying sfs on \"%s\"",name,str) ;
195  if(full_name == 0) continue ;
196 
197  int size = caller->sfs->fileSize(full_name) ; // this is bytes
198 
199  LOG(DBG,"Got %d",size) ;
200 
201  if(size <= 0) {
202  LOG(DBG,"%s: %s: not found in this event",name,str) ;
203  continue ;
204  }
205  else {
206  obj[o_cou].sec = s ;
207  obj[o_cou].rb = r ;
208  obj[o_cou].bytes = size ;
209 
210  o_cou++ ;
211 
212  tot_bytes += size ;
213  LOG(DBG,"%s: %s: reading in \"%s\": bytes %d",name,str,"raw", size) ;
214  }
215  }
216  }
217 
218  raw->create(tot_bytes,"mtd_raw",rts_id,DAQ_DTA_STRUCT(u_char)) ;
219 
220  for(int i=0;i<o_cou;i++) {
221 
222  sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, obj[i].sec, obj[i].rb) ;
223  char *full_name = caller->get_sfs_name(str) ;
224  if(full_name == 0) continue ;
225 
226  char *st = (char *) raw->request(obj[i].bytes) ;
227 
228  int ret = caller->sfs->read(full_name, st, obj[i].bytes) ;
229 
230  if(ret != (int)obj[i].bytes) {
231  LOG(ERR,"%s: %s: read failed, expect %d, got %d [%s]",name,str,
232  obj[i].bytes,ret,strerror(errno)) ;
233  }
234 
235  else {
236  LOG(NOTE,"%s: %s read %d bytes",name,str,ret) ;
237 
238  }
239 
240  raw->finalize(obj[i].bytes,obj[i].sec,obj[i].rb,0) ;
241 
242  }
243 
244  raw->rewind() ;
245  return raw ;
246 }
247 
248 
249 // knows how to get the token out of an event...
250 int daq_mtd::get_token(char *addr, int words)
251 {
252  int cou ;
253  struct daq_trg_word trg[128] ;
254 
255  cou = get_l2(addr,words,trg,1) ;
256 
257  if(cou==0) return -1000 ; // special marker...
258  if(trg[0].t==0) return -ENOSYS ;
259 
260  return trg[0].t ;
261 }
262 
263 // knows how to get a/the L2 command out of the event: SAME AS TOF!
264 int daq_mtd::get_l2(char *addr, int words, struct daq_trg_word *trg, int rdo)
265 {
266  u_int *w ;
267  int cou = 0 ;
268  int t_cou = 0 ;
269  int in_words = words ;
270 
271  int err = 0 ;
272  int trg_start ;
273 
274  w = (u_int *)addr ;
275  words-- ; // point to last datum now...
276 
277  // this will be DBG...
278  LOG(DBG,"First words 0x%08X 0x%08X 0x%08X, last words 0x%08X 0x%08X 0x%08X [+0x%08X], %u",
279  w[0],w[1],w[2],w[words-2],w[words-1],w[words],w[words+1],words+1) ;
280 
281 
282  // prompt token is in word 0!
283  // unless it just reads 0xA0000000, in which case this is purely trigger data -- no
284  // content!
285 
286  trg[t_cou].t = w[0] & 0xFFF ;
287  trg[t_cou].daq = (w[0]>>12) & 0xF ;
288  trg[t_cou].trg = (w[0]>>16) & 0xF ;
289  trg[t_cou].rhic = 0 ;
290  trg[t_cou].rhic_delta = 0 ;
291  t_cou++ ;
292 
293 // LOG(TERR,"MTD event: words %d: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
294 // in_words,w[0],w[1],w[2],w[3],w[4]) ;
295 
296 
297  LOG(NOTE,"prompt: T %4d, trg %d, daq %d [0x%08X]: words %d",trg[0].t,trg[0].trg,trg[0].daq,w[0],in_words) ;
298 
299  if(in_words < 2) { // absolute minimum
300  err |= 1 ;
301  LOG(ERR,"[%d] bad word count %d < 2",rdo,in_words);
302  }
303 
304 
305  if(w[0] == 0xA0000000) { // trigger only
306  trg[0].t = 4097; // trigger only contrib...
307  }
308  else {
309  if(in_words < 3) { // minimum if not trigger-only
310  err |= 1 ;
311  LOG(ERR,"[%d] bad word count %d <= 3",rdo,in_words);
312  }
313 
314  if(trg[0].t == 0) {
315  err |= 2 ;
316  LOG(ERR,"[%d] token 0",rdo);
317  trg[0].t = 4097 ;
318  }
319 
320  if(trg[0].trg != 4) { // we will allow only 4!
321  err |= 2 ;
322  LOG(ERR,"[%d] bad trg_cmd %d != 4",rdo,trg[0].trg);
323  }
324 
325  if(w[1] != 0xDEADFACE) {
326  err |= 1 ;
327  LOG(ERR,"[%d] bad DEADFACE 0x%08X",rdo,w[1]);
328  }
329 
330 
331  }
332 
333  if((w[0] >> 20) != 0xA00) {
334  err |= 1 ;
335  LOG(ERR,"[%d] bad first word 0x%08X doesn't start with 0xA00",rdo,w[0]);
336  trg[0].t = 4097 ;
337  }
338 
339 
340  // move backwards to the start of the trigger block and just count at first
341  while(words) {
342  if((w[words] >> 28)==0xA) { // trigger stuff
343  words-- ;
344  cou++ ;
345  }
346  else { // stop when non 0xA reached...
347  break ;
348  }
349  }
350 
351  if(cou==0) {
352  err |= 1 ;
353  LOG(ERR,"[%d] No Trigger FIFO contribution??",rdo);
354  }
355 
356  words++ ; // move forward to start of trigger
357 
358  trg_start = words ; // mark the word where trigger starts
359 
360  // words now points to the first trigger of the FIFO block
361  for(int i=0;i<cou;i++) {
362  int l_err = 0 ;
363 
364  trg[t_cou].t = w[words+i] & 0xFFF ;
365  trg[t_cou].daq = (w[words+i]>>12) & 0xF ;
366  trg[t_cou].trg = (w[words+i]>>16) & 0xF ;
367  trg[t_cou].rhic = i+1 ;
368  trg[t_cou].rhic_delta = i+1 ;
369 
370  if(trg[t_cou].t == 0) l_err = 1 ; // token 0
371 
372  // we will take OUT all the non-L2 components here...
373  switch(trg[t_cou].trg) {
374  case 4 : // normal
375  continue ; // don't put it in!
376  case 13 : // abort
377  case 15 : // accept
378  break ;
379  default : // take out ALL other L0 commands!
380  l_err = 1 ;
381  break ;
382  }
383 
384  if(l_err) {
385  LOG(ERR,"[%d] bad FIFO trg (%d.): T %4d, trg %d, daq %d [0x%08X]",rdo,words+i,trg[t_cou].t,trg[t_cou].trg,trg[t_cou].daq,w[words+i]);
386  err |= 2 ;
387  continue ; // don't use it!
388  }
389 
390  t_cou++ ;
391 
392  if(t_cou >=120) {
393  err |= 2 ;
394  LOG(ERR,"[%d] Too many trigger contributions %d >= 120",rdo,t_cou) ;
395  break ;
396  }
397  }
398 
399 
400  if(err) {
401  LOG(ERR,"[%d] Bad Event: T %4d: words %d, trg_words %d (start at %d) : 0x%08X 0x%08X 0x%08X",
402  rdo,trg[0].t,in_words,cou,trg_start,w[0],w[1],w[2]) ;
403 
404  //for(int i=0;i<cou;i++) {
405  // LOG(ERR,"[%d] trigger %d: %d/%d: 0x%08X",rdo,i,cou,w[trg_start+i]) ;
406  //}
407  }
408 
409  if(err & 1) { // critical -- blow the whole event
410  return -1 ;
411  }
412 
413  return t_cou ;
414 }
Definition: rb.hh:21
Definition: daq_mtd.h:9