StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
stgc_data_c.cxx
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <string.h>
4 #include <stdlib.h>
5 
6 
7 #include <rtsLog.h>
8 
9 #include "daq_stgc.h"
10 #include "stgc_data_c.h"
11 
12 stgc_data_c::feb_t stgc_data_c::feb[STGC_SECTOR_COU][4][6] ;
13 stgc_data_c::errs_t stgc_data_c::errs[4] ;
14 
15 u_int stgc_data_c::run_type ;
16 u_int stgc_data_c::run_number ;
17 
18 static u_int gray2dec(u_int gray)
19 {
20  u_int dec ;
21 
22  dec = gray ;
23 
24  for(int i=0;i<11;i++) {
25  gray >>= 1 ;
26  dec ^= gray ;
27  }
28 
29  return dec ;
30 
31 }
32 
33 stgc_data_c::stgc_data_c()
34 {
35  id = 0 ;
36 
37  realtime = 0 ;
38  run_type = 3 ;
39  run_number = 123 ;
40 
41  version = 0 ;
42 
43  bad_error = 0 ;
44  want_saved = 0 ;
45 
46  sector1 = 1 ;
47  rdo1 = 1 ;
48 
49  xing_min = -65000 ;
50  xing_max = 65000 ;
51 
52  event_any = event_data = 0 ;
53 
54  return ;
55 }
56 
57 int stgc_data_c::run_start()
58 {
59  bad_error = 0 ;
60  event_any = 0 ;
61  event_data = 0 ;
62 
63  return 0 ;
64 } ;
65 
66 const char *stgc_data_c::type_c(u_short type)
67 {
68 
69  switch(type) {
70  case 0x5244:
71  return "RESPONSE" ;
72  case 0x414B :
73  return "ECHO" ;
74  case 0x5445 :
75  return "TIMER" ;
76  case 0x4544 :
77  return "EVENT" ;
78  case 0x1F00 :
79  return "PROM" ;
80  default :
81  return "UNKNOWN" ;
82  }
83 }
84 
85 int stgc_data_c::hdr_check(u_short *d, int shorts)
86 {
87  u_short st[6] ;
88  const char *c_type ;
89 
90 
91  d16_start = d ; // points to start-comma
92 
93  d += 8 ; // skip TEF header
94  shorts -= 8 ;
95 
96  trg_cou = 0 ;
97  evt_type = 0 ;
98  token = 4096 ;
99  trg_cmd = daq_cmd = 0 ;
100  echo = 0 ;
101  adc_cou = 0 ;
102  version = 0 ;
103  datum_ix = 0 ;
104  fee_status = 0 ;
105 
106  if(d[1] != 0xCCCC) {
107  bad_error |= 1 ;
108  LOG(ERR,"%d: evt %d: corrupt header 0x%04X, shorts %d",rdo1,event_any,d[1],shorts) ;
109  return bad_error ;
110  }
111 
112  version = d[2] ;
113 // if(version != 0x8) {
114 // LOG(ERR,"%d: VERSION 0x%04X",rdo1,d[2]) ;
115 // }
116 
117  evt_type = d[8] ;
118  c_type = type_c(evt_type) ;
119 
120  trg_cmd = d[3]&0xF ;
121  daq_cmd = d[4]&0xF ;
122 
123  int t_hi = (d[4]>>4)&0xF ;
124  int t_mid = (d[4]>>8)&0xF ;
125  int t_lo = (d[4]>>12)&0xF ;
126 
127  token = (t_hi<<8)|(t_mid<<4)|t_lo ;
128 
129 // if(realtime && (token==0)) {
130 // LOG(ERR,"%d: evt %d: token0: 0x%X 0x%X 0x%X 0x%X 0x%X",rdo1,event_any,
131 // d[0],d[1],d[2],d[3],d[4]) ;
132 // }
133 
134  trg_counter = d[5]>>6 ;
135 
136  // FEE status
137  st[5] = d[9]>>8 ;
138  st[4] = d[9]&0xFF ;
139  st[3] = d[10]>>8 ;
140  st[2] = d[10]&0xFF ;
141  st[1] = d[11]>>8 ;
142  st[0] = d[11]&0xFF ;
143 
144  mhz_trg_marker = 0 ;
145  mhz_start_evt_marker = (((unsigned long)d[5]&0x3F)<<32)|((unsigned long)d[6]<<16)|(unsigned long)d[7] ;
146 
147  echo = d[12] ;
148 
149  response = 0 ;
150 
151  d16_last = d + shorts - 2 ; // should be at the last 0xFEED
152 
153 
154  for(int i=0;i<shorts;i++) {
155 // LOG(TERR,"+++ %d/%d = 0x%04X",i,shorts,d16_last[-i]) ;
156  if(d16_last[-i] != 0xFEED) {
157  d16_last = d + shorts - 2 - i ;
158  break ;
159  }
160 
161  }
162 
163  // d16_last[0] should be 0xFEEC
164  if(d16_last[0] != 0xFEEC) {
165  if(realtime) LOG(ERR,"%d: evt %d: last is 0x%04X",rdo1,event_any,d16_last[0]) ;
166  }
167 
168 // LOG(TERR,"d_last is 0x%04X",*d16_last) ; // at the datum just before the first 0xFEED
169 
170  mhz_stop_evt_marker = (d16_last[-2]<<16)|d16_last[-1] ;
171 
172 // if(realtime>90) {
173 // printf("before 0x%04X, last 0x%04X: stop 0x%08X (%u)\n",d16_last[-2],d16_last[-1],mhz_stop_evt_marker,
174 // mhz_stop_evt_marker) ;
175 // }
176 
177  d16_data = d + 13 ; // first datum is at d[13]
178 
179  // adc_cou = d16_last - d16_data + 1 ; // effective ADC length
180  adc_cou = d16_last - d16_data ; // effective ADC length
181  adc_cou -= 2 ; // remove the stop_mhz 2 shorts...
182 
183  // MOVE this only for EVENTS
184  if((evt_type==0x4544 && (adc_cou%4)) || shorts>40000) {
185  if(realtime) LOG(ERR,"%d: evt %d: %s: adc_cou is %d (%d), shorts %d!?",rdo1,event_any,c_type,adc_cou,adc_cou/4,shorts) ;
186  if(realtime>100) {
187  for(int i=0;i<16;i++) {
188  LOG(TERR,"%d/%d = 0x%04X",i,shorts,d[i]) ;
189  LOG(TERR,"last %d = 0x%04X",i,d16_last[-i]) ;
190  }
191  }
192  }
193 
194  adc_cou /= 4 ; // number of ADCs....
195 
196  // echo and timer have len 0
197  // response has adc_cou 4
198  // physics has
199 // LOG(TERR,"%d: type 0x%04X: d_last is 0x%04X; effective length %d",rdo1,evt_type,*d16_last,adc_cou) ; // at the datum just before the first 0xFEED
200 // for(int i=0;i<32;i++) {
201 // LOG(TERR,"... %d/%d = 0x%04X",i,shorts,d[i]) ;
202 // }
203 
204 
205 
206  switch(evt_type) {
207  case 0x5244 : //response
208  {
209  int sh = 3 ;
210  for(int i=0;i<4;i++) {
211  response |= (unsigned long)d[13+i]<<(sh*16) ;
212  sh-- ;
213  }
214  sh = 0 ; // reuse
215  u_int feb = (response>>56)&0xF ;
216  if((feb<1)||(feb>6)) sh |= 1 ;
217  if(((response>>48)&0xF0F0)!=0x1000) {
218  sh |= 2 ;
219  }
220 
221  if(echo==0 || echo==0x00C0) { // VMM config
222 // if((response & 0xFFFFFFFFFFFFFl) != 0x1150000000000l) sh |= 4;
223  }
224  else {
225  if((response & 0xFFFFFFFFFFFFFl) != 0x2C00000000000l) sh |= 8;
226  }
227 
228  if(sh) {
229  LOG(ERR,"S%d:%d: RESPONSE of cmd 0x%04X = 0x%lX: sh 0x%X",sector1,rdo1,echo,response,sh) ;
230  }
231  else {
232  if(realtime>1) LOG(TERR,"S%d:%d: RESPONSE of cmd 0x%04X",sector1,rdo1,echo) ;
233  }
234  }
235 
236  token = 4096 ;
237  trg_cmd = daq_cmd = 0 ;
238  break ;
239  case 0x414B : //echo
240  if(realtime>1) LOG(TERR,"S%d:%d: ECHO of cmd 0x%04X",sector1,rdo1,echo) ;
241 
242  token = 4096 ;
243  trg_cmd = daq_cmd = 0 ;
244 
245  break ;
246  case 0x4544 : // event
247  LOG(NOTE,"S%d:%d: %d: VERSION 0x%04X: T %d, trg %d, daq %d; shorts %d, ADCs %d; start_mhz %ul, delta %d",sector1,rdo1,id,version,token,trg_cmd,daq_cmd,
248  shorts,adc_cou,
249  mhz_start_evt_marker,mhz_stop_evt_marker-mhz_start_evt_marker) ;
250  LOG(NOTE,"%d: evts %d: T %d: trg_counter %d",rdo1,event_any,token,trg_counter) ;
251 
252  break ;
253  case 0x5445 : // timer
254  if(realtime>1) LOG(TERR,"S%d:%d: %d: T %d, trg %d, daq %d; shorts %d (timer evt)",sector1,rdo1,id,token,trg_cmd,daq_cmd,shorts) ;
255 
256  token = 4096 ;
257  trg_cmd = daq_cmd = 0 ;
258 
259  break ;
260  case 0x1F00 : // PROM response
261  token = 4096 ;
262  trg_cmd = daq_cmd = 0 ;
263  break ;
264  default :
265  LOG(ERR,"S%d:%d: evt %d: T %d, trg %d, daq %d, UNKNOWN type 0x%04X; shorts %d",sector1,rdo1,event_any,token,trg_cmd,daq_cmd,evt_type,shorts) ;
266  bad_error |= 2 ;
267 
268  token = 4096 ;
269  trg_cmd = daq_cmd = 0 ;
270 
271  }
272 
273 
274  if(evt_type != 0x5244) { // not a RESPONSE
275  if((d[3] & (1<<14))==0) {
276  LOG(ERR,"%d: %s: RESPONSE FIFO",rdo1,c_type) ;
277  }
278  }
279 
280  status = d[3] ;
281 
282  if((d[3] & (1<<13))==0) {
283  LOG(ERR,"%d: %s: GTP not ready",rdo1,c_type) ;
284  }
285  if((d[3] & (1<<12))==0) {
286  switch(evt_type) {
287  case 0x414B : // echo
288  //case 0x5244 : // response
289  if(echo != 0xF010) LOG(ERR,"%d: %s of echo 0x%04X: RHICx5 PLL not locked",rdo1,c_type,echo) ;
290  break ;
291  }
292  }
293  if((d[3] & (1<<8))) {
294  if(realtime && errs[rdo1-1].fifo==0) {
295  LOG(ERR,"%d: %s: EVENT FIFO FULL latched",rdo1,c_type) ;
296  }
297  errs[rdo1-1].fifo = 1 ;
298  }
299  if((d[3] & (1<<4))==0) {
300  LOG(ERR,"%d: %s: FEB Config FIFO",rdo1,c_type) ;
301  }
302 
303 
304  for(int i=0;i<6;i++) {
305  fee_status |= (((unsigned long)st[i]&0xFF)<<(i*8)) ;
306 
307  //LOG(TERR,"%d: evt %d: FEB %d: 0x%X",rdo1,event_any,i,st[i]) ;
308 
309  switch(st[i]) {
310  case 3 : //present & OK
311  case 0 : //not present
312  break ;
313  default :
314  if(realtime>10) LOG(ERR,"%d: evt %d: %s: FEB %d status: 0x%X",rdo1,event_any,c_type,i,st[i]) ;
315  break ;
316  }
317 
318  //LOG(TERR,"%d: FEE %d: 0x%X (0x%X)",rdo1,i,st[i],fee_status) ;
319  }
320 
321 
322  return bad_error ;
323 }
324 
325 // unused...
326 int stgc_data_c::start_0001(u_short *d, int shorts)
327 {
328  return 0 ;
329 
330 }
331 
332 int stgc_data_c::event_0001()
333 {
334  int evt_err = 0 ;
335  u_int feb_id = 255 ;
336 
337 // LOG(TERR,"ADC cou %d, feb %d",adc_cou,feb_id) ;
338 
339 // if(bad_error) return 0 ;
340  if(adc_cou<=0) return 0 ;
341 
342  u_short d[4] ;
343 
344  for(int i=0;i<4;i++) {
345  d[i] = *d16_data++ ;
346  }
347 
348  u_int dd = ((u_int)d[0]<<16)|(u_int)d[1] ;
349 
350  feb_id = dd>>29 ;
351 
352 #if 0
353  if(rdo1==2) {
354  switch(feb_id) {
355  case 1 :
356  case 3 :
357  case 5 :
358  LOG(WARN,"%d: FEB %d\n",rdo1,feb_id) ;
359  break ;
360  }
361  }
362 #endif
363 
364  datum_ix++ ;
365 
366 
367 
368  if(feb_id==7) { // trigger
369  u_short t_hi, t_mid, t_lo ;
370  u_short t ;
371  u_short mhz_hi ;
372  u_char t_cmd, d_cmd ;
373  u_char err = 0 ;
374  unsigned long mhz_trg ;
375 
376  t_cmd = d[1] & 0xF ;
377  d_cmd = (d[1]>>4) & 0xF ;
378  t_hi = (d[1]>>8)& 0xF ;
379  t_mid = (d[1]>>12)&0xF ;
380  t_lo = (d[0]>>0) & 0xF ;
381 
382  t = (t_hi<<8)|(t_mid<<4)|t_lo ;
383 
384  mhz_hi = (d[0]>>4)&0x1FF ;
385  mhz_trg = ((unsigned long)mhz_hi<<32)|((unsigned long)d[2]<<16)|(unsigned long)d[3] ; // or RHIC clock
386 
387 // if((mhz_trg_marker+1) < mhz_start_evt_marker) err = 1 ;
388 // if(mhz_trg_marker > (mhz_start_evt_marker+1)) err |= 1 ;
389 
390 // if((t != token)||(t_cmd != trg_cmd)||(d_cmd != daq_cmd)) err |= 2 ;
391 
392  if(trg_cou) err |= 4 ; // more than 1 trigger
393 
394 
395  if(t==0) err |= 8 ;
396  if(t_cmd==0) err |= 8 ;
397 
398 
399  if(err) { // typically corrupt data -- should STOP!
400  if(trg_cou==1 && datum_ix==2 && realtime<=1) {
401  err = 0 ;
402  }
403  else {
404  bad_error |= 0x10 ;
405  }
406 
407 
408 
409  if(realtime && err) {
410  LOG(ERR,"%d: evt %d: err 0x%X: 0x%04X 0x%04X 0x%04X 0x%04X at adc_cou %d/%d",rdo1,event_any,err,d[0],d[1],d[2],d[3],datum_ix,adc_cou) ;
411  LOG(ERR,"%d: evt %d: data: trg_cou %d: T %d, trg %d, daq %d; trg_mhz %lu",rdo1,event_any,trg_cou,t,
412  t_cmd,d_cmd,mhz_trg_marker) ;
413  LOG(ERR,"%d: evt %d: hdr : trg_counter %d: T %d, trg %d, daq %d; evt_mhz %lu",rdo1,event_any,trg_counter,token,
414  trg_cmd,daq_cmd,mhz_start_evt_marker) ;
415  }
416 
417  }
418  else {
419  //LOG(INFO,"%d: trg_cou %d: T %d, trg %d, daq %d; mhz_counter %u",rdo1,trg_counter,t,t_cmd,d_cmd,mhz_trg_marker) ;
420  }
421 
422  if(trg_cou==0) { // only use the first!
423  token = t ;
424  trg_cmd = t_cmd ;
425  daq_cmd = d_cmd ;
426 
427  mhz_trg_marker = mhz_trg ;
428  }
429 
430  // to indicate no data!
431  vmm.feb_vmm = 0 ;
432  vmm.ch = 0 ;
433  vmm.adc = 0 ;
434  vmm.bcid = 0 ;
435  vmm.tb = 0 ;
436  vmm.bcid_delta = 0 ;
437 
438  adc_cou-- ;
439  trg_cou++ ;
440 
441 // if(err) return 0 ; // HALT on error
442  return 1 ;
443  }
444 
445  //datum_ix==1 for Trigger
446  // ==2 for the first occurence of ADC data which is often corrupt -- skip it!
447  if(datum_ix==2) {
448  vmm.feb_vmm = 0 ;
449  vmm.ch = 0 ;
450  vmm.adc = 0 ;
451  vmm.bcid = 0 ;
452  vmm.tb = 0 ;
453  vmm.bcid_delta = 0 ;
454 
455  adc_cou-- ;
456  return 1 ;
457  }
458 
459 
460  if(feb_id>5) {
461  evt_err |= 0x20 ; // hard error; corrupt data
462  }
463 
464 
465  u_int mhz_adc_marker = dd & 0x1FFFFFFF ; // 29 bits of trigger
466 
467  u_int vmm_id = (d[2]>>13)&0x7 ;
468  int crc_ok = (d[2]>>12)&1 ;
469  int channel = (d[2]>>6)&0x3F ;
470 
471  int pdo = (d[2]&0x3F)<<4 ;
472  pdo |= (d[3]>>12)&0xF ;
473 
474  int bcid = d[3]&0xFFF ;
475  bcid = gray2dec(bcid) ;
476 
477  if(crc_ok==0) evt_err |= 0x80 ; // soft error
478 
479  if(vmm_id<4) evt_err |= 0x40 ; // hard error; corrupt data
480 
481 
482  if(evt_err) {
483  if(evt_err==0x20 && datum_ix==2 && realtime<=1) {
484  evt_err = 0 ;
485  }
486 
487 
488  char c_err[128] ;
489  c_err[0] = 0 ;
490 
491  if(evt_err&0x20) strcat(c_err,"FEBerr ") ;
492  if(evt_err&0x40) strcat(c_err,"VMMerr ") ;
493  if(evt_err&0x80) strcat(c_err,"CRCerr ") ;
494 
495 
496  vmm.feb_vmm = 0 ;
497  vmm.ch = 0 ;
498  vmm.adc = 0 ;
499  vmm.bcid = 0 ;
500  vmm.tb = 0 ;
501  vmm.bcid_delta = 0 ;
502 
503  bad_error |= evt_err ;
504 
505  if(realtime>1 && evt_err) {
506  LOG(ERR,"S%d:%d: evt %d: FEB %d, VMM %d, ch %d: evt_err [%s]0x%X at adc_cou %d/%d, trg_cou %d",sector1,rdo1,event_any,feb_id,
507  vmm_id,channel,c_err,evt_err,datum_ix,adc_cou,trg_cou) ;
508 
509  if(realtime > 2) {
510  LOG(ERR," 0x%04X 0x%04X 0x%04X 0x%04X",d[0],d[1],d[2],d[3]) ;
511  }
512  }
513 
514  adc_cou-- ;
515  return 0 ; // stop at the first occurence
516 // return 1 ;
517  }
518  else {
519 // vmm.feb_vmm = ((feb_id-1)<<2)|(vmm_id-4) ;
520  vmm.feb_vmm = ((feb_id)<<2)|(vmm_id-4) ;
521  vmm.ch = channel ;
522  vmm.adc = pdo ;
523  vmm.bcid = bcid ;
524 
525  int delta = bcid - (mhz_trg_marker%4096) ;
526 
527  if(delta<0) delta += 4096 ;
528 
529  vmm.bcid_delta = delta ;
530  }
531 
532 
533 // LOG(TERR,"feb_id %d, vmm_id %d, 0x%X",feb_id,vmm_id,vmm.feb_vmm) ;
534 
535  long tb = (long)mhz_adc_marker - (long)(mhz_trg_marker&0x1FFFFFFF) ;
536 
537  // since vmm.tb is only 16 bits
538  if(tb<-0x8000) vmm.tb = 0x8000 ;
539  else if(tb>0x7FFF) vmm.tb = 0x7FFF ;
540  else vmm.tb = tb ;
541 
542 // LOG(ERR,"Hack %d",tb) ;
543 
544  if(vmm.tb<xing_min || vmm.tb>xing_max) {
545  vmm.feb_vmm = 0 ;
546  vmm.ch = 0 ;
547  vmm.adc = 0 ;
548  vmm.bcid = 0 ;
549 
550  // but leave tb as-is
551  }
552 
553 
554  adc_cou-- ;
555  return 1 ;
556 }
557 
558 // unpacks and sanity-checks 1 RDO event
559 int stgc_data_c::start(u_short *d, int shorts)
560 {
561  bad_error = 0 ;
562  want_saved = 0 ;
563 
564  event_any++ ;
565 
566  if(hdr_check(d,shorts)) return -1 ;
567 
568  return 0 ; // stop checking the version
569 
570  switch(version) {
571  case 0x0001 :
572  case 0x0002 :
573  case 0x0003 :
574  case 0x0004 :
575  case 0x0005 :
576  case 0x0006 :
577  case 0x0007 :
578  case 0x0008 :
579  case 0x0009 :
580  case 0x000A :
581  return start_0001(d,shorts) ;
582  default :
583  break ;
584  }
585 
586  // OLD CODE BELOW
587  LOG(ERR,"OLD CODE") ;
588  return -1 ;
589 
590  u_short *d16_last = d + shorts - 2 ; // should be at the last 0xFEED
591 
592  for(int i=0;i<shorts;i++) {
593 // LOG(TERR,"last %d: 0x%04X",i,d16_last[-i]) ;
594 
595  if(d16_last[-i] != 0xFEED) {
596  d16_last = d + shorts - 2 - i ;
597  break ;
598  }
599 
600 
601  }
602 
603  d += 8 ; // at event type
604 
605  event_type = d[0] ;
606 
607 // LOG(TERR,"last final 0x%04X",d16_last[0]) ;
608 
609  //d16_last[0] now points at the command e.g. 0x4544 ;
610  int len = d16_last - d ;
611 
612  LOG(NOTE,"%d: type 0x%04X: token %d, trg_cmd %d, daq_cmd %d - len %d",rdo1,d[0],token,trg_cmd,daq_cmd,len) ;
613 
614  d++ ; // advance to start-of-data, just after event type
615 
616 // for(int i=0;i<len;i++) {
617 // LOG(TERR,"%d/%d = 0x%04X",i,len,d[i]) ;
618 // }
619 
620  d16_data = d ;
621 
622  event_any++ ;
623 
624  switch(event_type) {
625  case 0x4544: // physics
626  event_data++ ;
627  LOG(NOTE,"%d: data %d: chs %d: T %d, trg %d, daq %d",rdo1,event_data,len/4,token,trg_cmd,daq_cmd) ;
628  if(len%4) {
629  LOG(ERR,"%d: data len odd %d",rdo1,len) ;
630  }
631  break ;
632  case 0x5445 : // timer
633  LOG(DBG,"%d: timer",rdo1) ;
634 
635  if((d16_data[0]&0xFF00)==0x0300) feb[sector1-1][rdo1-1][5].present = 1 ;
636  if((d16_data[0]&0xFF)==0x03) feb[sector1-1][rdo1-1][4].present = 1 ;
637  if((d16_data[1]&0xFF00)==0x0300) feb[sector1-1][rdo1-1][3].present = 1 ;
638  if((d16_data[1]&0xFF)==0x03) feb[sector1-1][rdo1-1][2].present = 1 ;
639  if((d16_data[2]&0xFF00)==0x0300) feb[sector1-1][rdo1-1][1].present = 1 ;
640  if((d16_data[2]&0xFF)==0x03) feb[sector1-1][rdo1-1][0].present = 1 ;
641  break ;
642  case 0x414B : // ROD response/echo
643  LOG(DBG,"%d: echo",rdo1) ;
644  break ;
645  case 0x5244 : // FEB response to VMM config
646  LOG(DBG,"%d: FEB response",rdo1) ;
647  break ;
648  default :
649  LOG(ERR,"%d: unknown event type 0x%04X",rdo1,event_type) ;
650  break ;
651  }
652 
653 
654  ch_count = len/4 ;
655 
656  LOG(NOTE,"ch_count %d",ch_count) ;
657 
658  if(len<=0) return 0 ; // nothing there...
659 
660 
661  return 1 ;
662 }
663 
664 
665 int stgc_data_c::event()
666 {
667  u_short d[4] ;
668  int rod_id ;
669  int feb_id ;
670  int vmm_id ;
671  int threshold ;
672  int channel ;
673  int pdo ;
674  int bcid ;
675  int trigger_id ;
676  int err = 0 ;
677 
678  if(version!=0) return event_0001() ;
679 
680 
681  switch(version) {
682  case 0x0001 :
683  case 0x0002 :
684  case 0x0003 :
685  case 0x0004 :
686  case 0x0005 :
687  case 0x0006 :
688  case 0x0007 :
689  case 0x0008 :
690  case 0x0009 :
691  case 0x000A :
692  return event_0001() ;
693  default:
694  break ;
695  }
696 
697  if(ch_count <= 0) return 0 ;
698  if(event_type != 0x4544) return 0 ;
699 
700  for(int i=0;i<4;i++) {
701  d[i] = *d16_data++ ;
702  }
703 
704  // check
705  if((d[0]&0xF000) != 0x1000) err |= 1 ;
706 
707  rod_id = (d[0]>>4)&0xFF ;
708  feb_id = d[0] & 0xF ;
709 
710  // always 1
711  if(rod_id != 1) err |= 2 ;
712 
713  // feb_id is 1..6
714  if(feb_id==0 || feb_id>6) err |= 2 ;
715 
716  trigger_id = d[1] ;
717 
718  vmm_id = (d[2] >> 13) & 0x7 ;
719 
720  threshold = (d[2]>>12) & 1 ; // 1 bit
721 
722  channel = (d[2]>>6) & 0x3F ; // 6 bits
723 
724  pdo = (d[2] & 0x3F)<<4 ; // 10 bits: upper 6
725  pdo |= (d[3]>>12)&0xF ; // lower 4
726 
727  bcid = d[3]&0xFFF ; // 12 bits
728  bcid = gray2dec(bcid) ;
729 
730 
731  if(vmm_id<4) err |= 4 ;
732 
733 
734  if(err) {
735  vmm.feb_vmm = 0 ;
736  vmm.ch = 0 ;
737  vmm.adc = 0 ;
738  vmm.bcid = 0 ;
739 
740  LOG(ERR,"event %d: pkt %3d: rod_id %d, feb_id %d, vmm_id %d, ch %d, trigger %d, threshold %d, pdo %d, bcid %d: error %d",event_data,
741  ch_count,rod_id,feb_id,vmm_id,channel,trigger_id,
742  threshold,pdo,bcid,err) ;
743 
744  }
745  else {
746 
747 // printf("%d: ROD %d, FEB %d\n",rdo1,rod_id,feb_id) ;
748 
749  vmm.feb_vmm = ((feb_id-1)<<2)|(vmm_id-4) ;
750  vmm.ch = channel ;
751  vmm.adc = pdo ;
752  vmm.bcid = bcid ;
753 
754  }
755 
756 
757  ch_count-- ;
758  return 1 ;
759 }
760 
761 
762 int stgc_data_c::event_end(int flag)
763 {
764  return 0 ;
765 }
766