StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
itpcInterpreter.cxx
1 #include <stdio.h>
2 #include <ctype.h>
3 #include <string.h>
4 #include <time.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <math.h>
8 #include <stdlib.h>
9 
10 #include <rtsLog.h>
11 #include <DAQ_READER/daq_dta.h>
12 
13 #include <I386/atomic.h>
14 
15 #include "itpcInterpreter.h"
16 #include "itpcPed.h"
17 
18 static void hammingdecode(unsigned int buffer[2], bool& error, bool& uncorrectable, bool fix_data) ;
19 
20 struct itpcInterpreter::itpc_config_t itpcInterpreter::itpc_config[25] ;
21 
22 
23 int itpcInterpreter::itpc_fee_map[24][4][16] = {
24 {//S1 checked
25  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
26  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35}, //ok
27  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
28  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
29 },
30 {//S2 checked
31  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
32  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
33 //usual { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
34 // { 7, 1,17,12,24, 0,13, 8,28, 2,19,20,29,25,21, 3}, // moved #6 to #11
35  { 7, 1, 0,12,24,17,13, 8,28, 2,19,20,29,25,21, 3}, // moved #6 to #11; and #3 to #6
36  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
37 },
38 {//S3 checked
39  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
40  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
41  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
42  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
43 
44 },
45 {//S4 checked
46  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
47  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
48  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
49  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
50 
51 },
52 {//S5 checked
53  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
54  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
55 // { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
56  { 7, 1,17,12,24,19,13, 8,28, 2, 3,20,29,25,21, 0},
57  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
58 
59 },
60 {//S6 checked
61  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
62  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
63  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
64  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
65 
66 },
67 {//S7 checked
68  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
69  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
70  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
71  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
72 
73 },
74 {//S8 mess with mapping
75  {49,52,46, 0, 0, 54,0,47, 0,50,48,55, 0, 0,51,53}, //FY21: bad port #13 on RDO ID 0x0052ED7C moved to #11
76  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
77  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
78  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
79 
80 },
81 {//S9 mess with mapping
82  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
83  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
84  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
85  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
86 
87 },
88 {//S10 checked
89  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
90  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
91  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
92  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
93 
94 },
95 {//S11
96 // {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53}, // usual
97  {49,52,46,47, 0, 54,0, 0, 0,50, 0,55,48, 0,51,53}, // new: bad port #8 on RDO ID 0x0052F5EA, moved to #4
98  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
99  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
100  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
101 
102 },
103 {//S12
104  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
105  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
106  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
107  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
108 
109 },
110 {//S13
111  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
112  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
113  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
114  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
115 },
116 {//S14
117  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
118  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
119  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
120  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
121 },
122 {//S15
123  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
124  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
125  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
126  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
127 },
128 {//S16
129  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
130  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
131  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
132  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
133 },
134 {//S17
135 // {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53}, // 29Mar03: bad port 3 moved to good port 5
136  {49,52, 0, 0,46, 54,0,47, 0,50, 0,55,48, 0,51,53},
137  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
138  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
139  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
140 },
141 {//S18
142  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
143  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
144  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
145  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
146 },
147 {//S19
148  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
149  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
150  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
151  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
152 },
153 {//S20
154  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
155  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
156  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
157  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
158 },
159 {//S21
160 // {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
161  {49,52,46, 0, 0,54,47, 0, 0,50, 0,55,48, 0,51,53}, // moved #8 to #7
162  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
163  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
164  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
165 },
166 {//S22
167  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
168  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
169  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
170  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
171 },
172 {//S23
173  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
174  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
175  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
176  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
177 },
178 {//S24
179  {49,52,46, 0, 0, 54,0,47, 0,50, 0,55,48, 0,51,53},
180  {36,32,40,43,37,33, 0,41, 0,44,38,34,42,45,39,35},
181  { 7, 1,17,12,24,19,13, 8,28, 2, 0,20,29,25,21, 3},
182  { 9, 4,26,14,15,10,30,22,27, 5,31,23,18,16,11, 6}
183 },
184 } ;
185 
186 int itpcInterpreter::fee_map_check()
187 {
188  LOG(TERR,"fee_map_check") ;
189 
190  for(int s=0;s<24;s++) {
191  u_int padplane[64] ;
192 
193  memset(padplane,0xFF,sizeof(padplane)) ;
194 
195  for(int r=0;r<4;r++) {
196  for(int p=0;p<16;p++) {
197  int pd = itpc_fee_map[s][r][p] ;
198 
199  if(pd==0) continue ; // no FEE connected
200 
201  if(padplane[pd] == 0xFFFFFFFF) {
202  padplane[pd] = ((r+1)<<8)|(p + 1);
203  }
204  else {
205  int rdo = padplane[pd]>>8 ;
206  int port = padplane[pd]&0xFF ;
207  LOG(ERR,"S%02d:%d -- port %d, padplane %2d: taken padlane by port %d:%02d",s+1,r+1,p+1,pd,rdo,port) ;
208  }
209  }
210  }
211 
212  for(int p=0;p<64;p++) {
213  u_int pd = padplane[p] ;
214 
215  if((p==0)||(p>55)) {
216  if(pd != 0xFFFFFFFF) {
217  LOG(ERR,"S%02d: illegal padplane %2d",s+1,p) ;
218  }
219  }
220  else {
221  if(pd==0xFFFFFFFF) {
222  LOG(ERR,"S%02d: padplane %2d missing",s+1,p) ;
223  }
224  }
225  }
226 
227  }
228 
229  return 0 ;
230 }
231 
232 u_int itpcInterpreter::ifee_mask(int sec1, int rdo1)
233 {
234  u_int mask = 0 ;
235 
236  for(int i=0;i<16;i++) {
237  if(itpc_fee_map[sec1-1][rdo1-1][i]) mask |= (1<<i) ;
238  }
239 
240  return mask ;
241 
242 #if 0
243  switch(rdo1) {
244  case 1 :
245  return 0xAE9B ; // was 0x9D9B in FY18
246  case 2 :
247  return 0xFEBF ; // was 0xFE7F in FY18
248  case 3 :
249  return 0xFFFD ;
250  case 4 :
251  return 0xFFFF ;
252  }
253 
254  LOG(ERR,"WHAT %d???",rdo1) ;
255  return 0xFFFF ;
256 #endif
257 
258 }
259 
260 
261 
262 int itpcInterpreter::parse_default()
263 {
264  fee_map_check() ;
265 
266  memset(&itpc_config,0,sizeof(itpc_config)) ;
267 
268  for(int sec=1;sec<=24;sec++) {
269  for(int rb=0;rb<4;rb++) {
270  u_int mask = ifee_mask(sec,rb+1) ;
271 
272  itpc_config[sec].rdo[rb].rdo_id = rb+1 ;
273  itpc_config[sec].rdo[rb].wire1 = 0 ;
274  itpc_config[sec].rdo[rb].fee_mask = mask ;
275  itpc_config[sec].rdo[rb].phase = 90 ;
276 
277  for(int i=0;i<16;i++) {
278  if(mask & (1<<i)) itpc_config[sec].rdo[rb].fee_count++ ;
279  }
280 
281  //LOG(TERR,"S%02d:%d: fee mask 0x%04X, fee_count %d",sec,rb+1,mask,itpc_config[sec].rdo[rb].fee_count) ;
282 
283  for(int port=0;port<16;port++) {
284  itpc_config[sec].rdo[rb].fee[port].wire1 = 0 ;
285  itpc_config[sec].rdo[rb].fee[port].padplane_id = itpc_fee_map[sec-1][rb][port] ;
286  itpc_config[sec].rdo[rb].fee[port].sampa_version = 3 ; // assume V3
287  }
288  }
289  }
290 
291  return 0 ;
292 
293 }
294 
295 int itpcInterpreter::parse_config(const char *fname)
296 {
297  LOG(ERR,"Should not use parse_config") ;
298  return -1 ;
299 
300  if(fname==0) fname = "/RTS/conf/itpc/itpc_config.txt" ;
301 
302  FILE *f = fopen(fname,"r") ;
303  if(f==0) {
304  LOG(ERR,"%s: %s [%s]",__PRETTY_FUNCTION__,fname,strerror(errno)) ;
305  return -1 ;
306  }
307 
308  memset(&itpc_config,0,sizeof(itpc_config)) ;
309 
310  while(!feof(f)) {
311  char line[128] ;
312  int sec,rdo,rb,phase,port,padplane ;
313  u_int wire1, mask ;
314  int ret ;
315 
316  if(fgets(line,sizeof(line),f)==0) continue ;
317 
318  if(strncmp(line,"R ",2)==0) { // RDO section
319  ret = sscanf(line,"R %d %d %d %X %X %d",&sec,&rdo,&rb,&wire1,&mask,&phase) ;
320  if(ret != 6) {
321  LOG(ERR,"%s: malformed line [%s]",fname,line) ;
322  continue ;
323  }
324 
325  itpc_config[sec].rdo[rb].rdo_id = rdo ;
326  itpc_config[sec].rdo[rb].wire1 = wire1 ;
327  itpc_config[sec].rdo[rb].fee_mask = mask ;
328  itpc_config[sec].rdo[rb].phase = phase ;
329 
330  for(int i=0;i<16;i++) {
331  if(mask & (1<<i)) itpc_config[sec].rdo[rb].fee_count++ ;
332  }
333  LOG(TERR,"RDO %d: fee mask 0x%04X, fee_count %d",rb+1,mask,itpc_config[sec].rdo[rb].fee_count) ;
334 
335  }
336  else if(strncmp(line,"F ",2)==0) { // FEE section
337  int v ;
338 
339  ret = sscanf(line,"F %d %d %X %d %d",&sec,&rdo,&wire1,&port,&padplane) ;
340  if(ret != 5) {
341  LOG(ERR,"%s: malformed line [%s]",fname,line) ;
342  continue ;
343  }
344 
345  // special deal for SAMPA version
346  if(strstr(line,"V3")) v = 3 ;
347  else if(strstr(line,"V4")) v = 4 ;
348  else v = 2 ;
349 
350  for(int i=0;i<4;i++) {
351  if(itpc_config[sec].rdo[i].rdo_id == rdo) {
352  itpc_config[sec].rdo[i].fee[port].wire1 = wire1 ;
353  itpc_config[sec].rdo[i].fee[port].padplane_id = padplane ;
354  itpc_config[sec].rdo[i].fee[port].sampa_version = v ;
355  if(v != 2) {
356  LOG(WARN,"S%02d:%2d:#%02d: 0x%X SAMPA is V%d",sec+1,i+1,port,wire1,v) ;
357  }
358  }
359  }
360 
361 
362  }
363  }
364 
365  fclose(f) ;
366 
367  return 0 ;
368 }
369 
370 
371 itpcInterpreter::itpcInterpreter()
372 {
373  id = 0 ; // not valid
374 
375  evt_ix = 0 ;
376  realtime = 0 ;
377  dbg_level = 0 ;
378 
379  fee_evt_cou = 0 ;
380  run_number = 0 ;
381 
382  fout = 0 ;
383 
384  fpga_fee_v_all = 0 ;
385 
386  fee_version = 0 ; // original pre-Mar 2018
387  rdo_version = 0 ;
388 
389  expected_rdo_version = -1 ; // uknown; don't check
390  expected_fee_version = -1 ; // unknown; don't check
391 
392 
393  memset(fee,0,sizeof(fee)) ;
394  memset(itpc_config,0,sizeof(itpc_config)) ;
395 
396  ped_c = 0 ;
397 }
398 
399 atomic_t itpcInterpreter::run_errors[4][16] ;
400 
401 void itpcInterpreter::run_start(u_int run)
402 {
403  run_number = run ;
404  evt_ix = 0 ;
405  fee_evt_cou = 0 ;
406 
407  if(fout) {
408  fprintf(fout,"***** RUN_START: %08u\n",run_number) ;
409  fflush(fout) ;
410  }
411 
412  if(id==1) memset(run_errors,0,sizeof(run_errors)) ;
413 
414  LOG(DBG,"Starting run %08u",run_number) ;
415 }
416 
417 void itpcInterpreter::run_err_add(int rdo1, int type)
418 {
419  atomic_inc(&run_errors[rdo1-1][type]) ;
420 }
421 
422 void itpcInterpreter::run_stop()
423 {
424 
425  if(fout) {
426  fprintf(fout,"***** RUN_STOP: %08u\n",run_number) ;
427  fflush(fout) ;
428  fclose(fout) ;
429  fout = 0 ;
430  }
431 
432  LOG(INFO,"%d: stopping run %08u after %d/%d events",id,run_number,fee_evt_cou,evt_ix) ;
433 
434  if(id==1) {
435  for(int i=0;i<4;i++) {
436  for(int j=0;j<16;j++) {
437  if(atomic_read(&run_errors[i][j])) {
438  LOG(ERR,"RDO %d: error type %d = %u",i+1,j,atomic_read(&run_errors[i][j])) ;
439  }
440  }
441  }
442  }
443 }
444 
445 
446 void itpcInterpreter::start_event(u_int bytes)
447 {
448  evt_ix++ ; //events will start from 1
449 
450  evt_bytes = bytes ; //store length
451 
452  //zap stuff
453  word_ix = 0 ;
454 
455  status = 0 ;
456 
457  state = S_IDLE ;
458 
459  fee_port = -1 ;
460 
461  d_cou = -1 ;
462 
463  sampa_bx = -1 ;
464 
465  ascii_cou = 0 ;
466 
467  memset(evt_err,0,sizeof(evt_err)) ;
468 }
469 
470 void itpcInterpreter::stop_event()
471 {
472  for(int i=0;i<8;i++) {
473  if(evt_err[i]) LOG(ERR,"%d: event errors[%d] = %u",rdo_id,i,evt_err[i]) ;
474  }
475 
476 }
477 
478 
479 
480 static inline u_int sw16(u_int d)
481 {
482  u_int tmp = d ;
483 
484  d >>= 16 ;
485 
486  d |= (tmp & 0xFFFF)<<16 ;
487 
488  return d ;
489 }
490 
491 
492 
493 /*
494  This is the pre-April 2018 version for rdo_version = fee_version = 0 ;
495 */
496 /* We start with 0x980000008 */
497 u_int *itpcInterpreter::fee_scan(u_int *start, u_int *end)
498 {
499  u_int *d = start ;
500  u_int dd ;
501  int hdr ;
502  int trg ;
503  int cfg ;
504 
505 // LOG(TERR,"len %d: 0x%X 0x%X 0x%X",end-start,d[0],d[1],d[2]) ;
506 
507  d++ ; // skip over 0x98000008 ;
508 
509  // next is FEE port (from 0)
510  fee_port = *d++ ; // fee port
511  fee_port++ ; // start from 1
512 
513  fee_id = -1 ;
514  trg = 0 ; // event is triggered
515  hdr = 0 ;
516  cfg = 0 ;
517  ascii_cou = 0 ;
518 
519  // We are at the start of FEE data:
520  u_int dd_x = d[0] & 0xFFC000FF ; // command
521 
522  // I should now point at 0x80xx0001
523  if(dd_x != 0x80000001) {
524  // HAPPENS
525  //LOG(WARN,"Missing start 0x%08X",d[0]) ;
526 
527  //for(int i=0;i<32;i++) {
528  // LOG(TERR,"%d = 0x%08X",i-8,d[i-8]) ;
529  //}
530 
531  fee_bx = 0 ; // dummy
532 
533  cfg++ ;
534  trg++ ;
535  }
536 
537  while(d<end) {
538  dd = *d++ ;
539  dd_x = dd & 0xFFC000FF ; // just commands
540  u_int dd_a ;
541 
542  LOG(NOTE,"FEE #%d: %u 0x%08X",fee_port,d-start,dd) ;
543 
544  // let's get non-FEE headers out of the way first
545  switch(dd_x) {
546  case 0x980000F8 : // End-of-FEE status (from RDO)
547  //LOG(TERR,"0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",dd,d[0],d[1],d[-1],d[-2]) ;
548 
549  if(d[1]) { // fee_status (from RDO)
550  LOG(ERR,"%d: FEE #%d[%d] END: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",rdo_id,fee_port,fee_id,
551  d[0],d[1],d[2],d[3],d[4],d[5],d[6]) ;
552  }
553  else {
554  LOG(NOTE,"FEE #%d[%d] END: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",fee_port,fee_id,
555  d[0],d[1],d[2],d[3],d[4],d[5],d[6]) ;
556  }
557 
558  // check word _before_ the RDO header; should come from a FEE
559  if((d[-2]&0xFFC00000) != 0x40000000) {
560  // might fire due to a bug in readout
561  if((d[-2]&0xFFC00000) != 0x80000000) {
562  //LOG(ERR,"%d: FEE #%d: Before END 0x%08X",rdo_id,fee_port,d[-2]) ;
563  }
564  else {
565  //OFTEN
566  //LOG(WARN,"%d: FEE #%d: Before END 0x%08X",rdo_id,fee_port,d[-2]) ;
567  }
568  }
569 
570  // search for RDO-END-FEE marker
571  for(int i=0;i<16;i++) {
572  dd = *d++ ;
573  if(dd == 0x58000009) {
574  dd-- ; // go back one
575  goto stop_loop ;
576  }
577  }
578 
579  LOG(ERR,"%d: FEE #%d: can't find RDO-END",rdo_id,fee_port) ;
580  goto stop_loop ;
581 
582  }
583 
584 
585 
586  u_int t_fee_id = (dd >> 16) & 0x3F ;
587  if(fee_id<0) {
588  if((dd_x & 0xFF000000)==0x80000000) fee_id = t_fee_id ;
589  }
590  else {
591  if(fee_id != t_fee_id) {
592  evt_err[ERR_DIFFERENT_FEE_IDS]++ ;
593  LOG(NOTE,"FEE #%d: IDs differ: expect %d, is %d, 0x%08X",fee_port,fee_id,t_fee_id,dd) ;
594  }
595  }
596 
597  switch(dd_x) {
598  case 0xA00000A0 : // ASCII start
599  break ;
600  case 0x600000A0 : // ASCII end
601  break ;
602  case 0xA00000B0 : // binary start
603  LOG(ERR,"%d: FEE #%d: Unexpected 0x%08X",rdo_id,fee_port,dd) ;
604  break ;
605  case 0x600000B0 : // binary end
606  LOG(ERR,"%d: FEE #%d: Unexpected 0x%08X",rdo_id,fee_port,dd) ;
607  break ;
608  case 0x80000001 : // START EVENT (also hdr)
609  // this can be missing! and can also show up at the very end!
610  {
611  u_int bx_lo = d[4] & 0xFFFF ;
612  u_int bx_hi = d[5] & 0xFFFF ;
613 
614  bx_lo |= (bx_hi<<16) ;
615 
616  fee_bx = bx_lo ;
617  //LOG(TERR,"BX %u 0x%08X",bx_lo&0xFFFFF,bx_lo) ;
618  }
619 
620  //for(int jj=-2;jj<6;jj++) {
621  // LOG(TERR,"... %d = 0x%08X",jj,d[jj]) ;
622  //}
623  cfg++ ;
624  trg++ ;
625  break ;
626  case 0x60000001 : // end event hdr
627  //LOG(TERR,"END event %d %d",cfg,trg) ;
628  cfg = 0 ;
629  if(trg==1) {
630  fee_id = (dd>>16)&0x3F ;
631  //LOG(TERR,"FEE #%d(%d) start SAMPA: FEE BX %u (0x%08X)",fee_port,fee_id,fee_bx&0xFFFFF,fee_bx) ;
632 
633  for(int i=0;i<4;i++) {
634  u_int expect_mask ;
635  //u_int *cur_d = d ;
636 
637  switch(i) {
638  case 0 :
639  case 2 :
640  expect_mask = 0x0000FFFF ;
641  break ;
642  default :
643  expect_mask = 0xFFFF0000 ;
644  break ;
645  }
646 
647  //if(i==0 || i==2) found_ch_mask = 0 ;
648  found_ch_mask = 0 ;
649 
650  d = sampa_lane_scan(d,end) ;
651  //LOG(TERR,"fee_port %d: lane %d was %d words",fee_port,i,d-cur_d) ;
652 
653  //if(i==1 || i==3) {
654  if(found_ch_mask != expect_mask) {
655  //LOG(ERR,"expect 0x%08X",expect_mask) ;
656  LOG(ERR,"%d: fee_port %d: missing ch after lane %d: 0x%08X",
657  rdo_id,fee_port,i,found_ch_mask) ;
658  }
659  //}
660 
661 
662  }
663  break ;
664  }
665  LOG(ERR,"%d: FEE #%d: %u 0x%08X -- odd",rdo_id,fee_port,d-start,dd) ;
666  break ;
667  case 0xA0000001 : // start event trailer
668  cfg++ ;
669  break ;
670  case 0x40000001 : // END EVENT (also trailer)
671  if(dd & 0xFF00) {
672  LOG(ERR,"%d: FEE #%d: EVENT error 0x%02X",rdo_id,fee_port,(dd>>8)&0xFF) ;
673  fee[fee_port].event_errs++ ;
674  }
675  cfg = 0 ;
676  break ;
677  case 0x80000002 : // START SEND_CONFIG (also header)
678  hdr++ ;
679  cfg++ ;
680  break ;
681  case 0x60000002 : // end send_config header
682  cfg = 0 ;
683  break ;
684  case 0xA00000FA : // start config data
685  cfg++ ;
686  break ;
687  case 0x600000FA : // end config data
688  cfg = 0 ;
689  break ;
690  case 0xA00000EC : // start monitoring header
691  break ;
692  case 0x600000EC : // end monitoring header
693  break ;
694  case 0xA00000ED : // start monitoring trailer
695  break ;
696  case 0x600000ED : // end monitoring trailer
697  break ;
698  case 0xA0000002 : // start send_config trailier
699  cfg++ ;
700  break ;
701  case 0x40000002 : // END SEND_CONFIG event/trailer
702  cfg = 0 ;
703  if(dd & 0xFF00) {
704  fee[fee_port].send_config_errs++ ;
705  LOG(ERR,"FEE #%d: SEND_CONFIG error 0x%02X",fee_port,(dd>>8)&0xFF) ;
706  }
707  break ;
708  case 0x80000003 : // START of pedestal confirm
709  //LOG(TERR,"Start Ped, fee %d",fee_port) ;
710  {
711  u_int delta = ((d[3]&0xFFFF)<<16)|(d[2]&0xFFFF) ;
712  int for_me = (d[0] & 0x8000)?1:0 ;
713  int timebins = d[0] & 0x3FF ;
714  int ch = (d[0]>>10)&0x3F ;
715  LOG(TERR,"FEE #%d: ped: for me %d, ch %d, timebins %d, chsum %u, delta %u",fee_port,for_me,ch,timebins,d[1]&0xFFFF,delta) ;
716  }
717  d += 5 ;
718 
719  break ;
720  case 0x40000003 : // END of pedestal confirm event
721  if(dd & 0xFF00) {
722  fee[fee_port].pedestal_errs++ ;
723  LOG(ERR,"FEE #%d: PEDESTAL error 0x%02X",fee_port,(dd>>8)&0xFF) ;
724  }
725 
726  LOG(ERR,"Shouldn't be 0x%X",dd) ;
727  break ;
728  case 0x80000004 :
729  break ;
730  case 0x40000004 :
731  break ;
732  default : // none of the above...
733 
734  dd_a = dd & 0xFFC0FF00 ; // for ASCII
735  if(dd_a == 0x0000F500 || dd_a==0x00800000) { // ASCII char
736  u_char c = dd & 0xFF ;
737  //LOG(TERR,"... [0x%08X]",dd) ;
738 
739  if(isprint(c) || isspace(c)) ;
740  else c = '?' ;
741 
742  ascii_dta[ascii_cou++] = c ;
743  if(c=='\n') {
744  int last ;
745 
746  ascii_dta[ascii_cou++] = 0 ;
747  if(fout) {
748  fprintf(fout,"#%02d: %s",fee_port,ascii_dta) ;
749  fflush(fout) ;
750  }
751 
752 
753  last = strlen(ascii_dta) - 1 ;
754  if(ascii_dta[last]=='\n') ascii_dta[last] = 0 ;
755  if(last > 1) {
756  LOG(TERR,"FEE_asc %d:#%02d: \"%s\"",rdo_id,fee_port,ascii_dta) ;
757  }
758 
759  if(fee_port > 0) { // this must be!
760  u_int id1 = 0 ;
761  if(strncmp(ascii_dta,"1Wire:",6)==0) {
762  char *id = strstr(ascii_dta,"ID") ;
763  if(id) {
764  if(sscanf(id,"ID 0x%X",&id1)==1) {
765  //printf("********** port %d, WIRE 0x%08X\n",fee_port,id1) ;
766  fee[fee_port].wire1_id = id1 ;
767  }
768  }
769  }
770  else if(strncmp(ascii_dta,"Padplane ",9)==0) {
771  if(sscanf(ascii_dta,"Padplane %d",&id1)==1) {
772  //printf("********** port %d, PADPLANE %d\n",fee_port,id1) ;
773  fee[fee_port].padplane_id = id1 ;
774  }
775  }
776 
777  if(strstr(ascii_dta,"ERROR")) {
778  last = strlen(ascii_dta) - 1 ;
779  if(ascii_dta[last]=='\n') ascii_dta[last] = 0 ;
780  LOG(ERR,"%d: FEE #%d: [%s]",rdo_id,fee_port,ascii_dta) ;
781  }
782 
783  }
784 
785 
786  ascii_cou = 0 ;
787  }
788  break ;
789  }
790  if(cfg) break ;
791 
792  evt_err[ERR_UNKNOWN]++ ;
793  LOG(NOTE,"FEE #%d: %u 0x%08X -- unkown",fee_port,d-start,dd) ;
794  break ;
795  }
796 
797  }
798 
799  stop_loop: ;
800 
801 
802  if(fee_id < 0) { // Hm, never seen any FEE data really...
803 // LOG(ERR,"%d: fee_id %d, FEE #%d [0x%08X]: format error [%u 0x%08X]",rdo_id,fee_id,fee_port,(u_int)fee_port,d-start,*d) ;
804  return d ;
805  }
806 
807 
808  return d ;
809 }
810 
811 // Used when not running FCF
812 int itpcInterpreter::sampa_ch_scan()
813 {
814  int err = 0 ;
815  int t_stop_last = -1 ;
816  int s,r,p ;
817 
818 // LOG(TERR,"sampa_ch_scan") ;
819 
820 
821  s = sector_id - 1 ; // from 0
822  r = rdo_id - 1 ;
823  p = fee_port - 1 ;
824 
825  if(ped_c) {
826  ped_c->sector = s ;
827  ped_c->rdo = r ;
828  ped_c->port = p ;
829  ped_c->fee_id = fee_id ;
830 
831  ped_c->ch_start(fee_ch) ;
832  }
833 
834 
835  for(int i=0;i<tb_cou;) {
836 // LOG(TERR,"i %d",i) ;
837 
838  int t_cou = tb_buff[i++] ;
839  int t_start = tb_buff[i++] ;
840 
841 
842 
843  int t_stop = t_start + t_cou - 1 ;
844 
845 // LOG(TERR,"DDD %d %d %d",t_start,t_cou,t_stop) ;
846 
847  if(t_start <= t_stop_last) {
848  LOG(ERR,"%d: t_start %d, t_cou %d, t_stop %d, t_stop_last %d",rdo_id,t_start,t_cou,t_stop,t_stop_last) ;
849  err = -1 ;
850  break ;
851  }
852 
853  if(t_stop > 512) {
854  LOG(ERR,"%d: t_start %d, t_cou %d, t_stop %d, t_stop_last %d",rdo_id,t_start,t_cou,t_stop,t_stop_last) ;
855  err = -2 ;
856  break ;
857  }
858 
859  t_stop_last = t_stop ;
860 
861  if(ped_c) {
862  for(int t=t_start;t<=t_stop;t++) {
863  u_short adc = tb_buff[i++] ;
864 
865  ped_c->accum(s,r,p,fee_id,fee_ch,t,adc) ;
866  //ped_c->accum(t,adc) ;
867  }
868  }
869  else {
870  i += t_stop - t_start + 1 ;
871  }
872  }
873 
874 
875  if(ped_c) ped_c->ch_done(err) ;
876 
877  if(err) {
878  //run_err_add(rdo_id,6) ;
879 
880 // for(int i=0;i<tb_cou;i++) {
881 // LOG(NOTE,"%d/%d = %u",i,tb_cou,tb_buff[i]) ;
882 // }
883  }
884 
885  return err ;
886 }
887 
888 u_int *itpcInterpreter::sampa_ch_hunt(u_int *start, u_int *end)
889 {
890  // I expect to be pointed to the SAMPA channel header!
891  u_int *data = start ;
892  u_int *data_start ;
893 
894  u_int d ;
895  u_int err ;
896  u_int h[6] ;
897  bool hamming_err ;
898  u_int l_sampa_bx ;
899  u_int type, words ;
900  unsigned long long hc ;
901  u_int hh[2] ;
902  bool uncorrectable ;
903  int p_cou ;
904  u_int hdr[2] ;
905 
906  u_int sampa_id, sampa_ch ; // shadow class variables on purpose!
907 
908 
909  retry:;
910 
911  err = 0 ;
912  hdr[0] = hdr[1] = 0xFFFFEEEE ;
913 
914  data_start = data ;
915 
916  if(data>=end) goto err_end ;
917  d = *data++ ;
918  hdr[0] = d ;
919 
920  if(d & 0xC0000000) {
921  err |= 0x1 ;
922  //LOG(ERR,"%d: Bad Hdr 1",rdo_id) ;
923  goto err_ret ;
924  }
925 
926  h[0] = (d >> 20) & 0x3FF ;
927  h[1] = (d >> 10) & 0x3FF ;
928  h[2] = d & 0x3FF ;
929 
930  if(data>=end) goto err_end ;
931  d = *data++ ;
932  hdr[1] = d ;
933 
934  if(d & 0xC0000000) {
935  err |= 0x2 ;
936  //LOG(ERR,"%d: Bad Hdr 2",rdo_id) ;
937  goto err_ret ;
938  }
939 
940  h[3] = (d >> 20) & 0x3FF ;
941  h[4] = (d >> 10) & 0x3FF ;
942 
943  h[5] = d & 0x3FF ;
944 
945 // if(h[5] != 0xAB) {
946 // err |= 0x4 ;
947 // goto err_ret ;
948 // }
949 
950 
951  type = h[0] >> 7 ;
952  words = h[1] ;
953  sampa_id = h[2] & 0xF ;
954  sampa_ch = (h[2]>>4) & 0x1F ;
955 
956 
957 
958  l_sampa_bx = (h[2]&0x200) >> 9 ;
959  l_sampa_bx |= (h[3]<<1) ;
960  l_sampa_bx |= (h[4]&0x1FF)<<11 ;
961 
962 // LOG(WARN,"....... %d %d %u",sampa_id,sampa_ch,l_sampa_bx) ;
963 
964  // check parity
965  p_cou = 0 ;
966  for(int i=0;i<=4;i++) {
967  for(int j=0;j<10;j++) {
968  if(h[i] & (1<<j)) p_cou++ ;
969  }
970  }
971 
972  if(p_cou&1) { // parity error
973  err |= 0x11 ;
974  goto err_ret ;
975  }
976 
977 
978  hc = ((long long)h[4]<<40)|((long long)h[3]<<30)|(h[2]<<20)|(h[1]<<10)|h[0];
979  hh[0] = hc & 0x3FFFFFFF ;
980  hh[1] = (hc>>30) ;
981 
982 
983  hammingdecode(hh, hamming_err,uncorrectable,0) ;
984 
985 
986  if(hamming_err) {
987  //LOG(ERR,"%d:%d: Type %d, words %d, SAMPA %d:%d, BX %u, errors %d:%d",rdo_id,fee_port,type,words,sampa_id,sampa_ch,l_sampa_bx,parity_err,hamming_err) ;
988  // and I should do something here!
989  err |= 0x10 ;
990  goto err_ret ;
991  }
992 
993 
994  switch(type) {
995  case 0 : // heartbeat
996  if(words != 0) {
997  err |= 0x20 ;
998  goto err_ret ;
999  }
1000  if(sampa_ch != 21) {
1001  err |= 0x21 ;
1002  goto err_ret ;
1003  }
1004  break ;
1005  case 4 : // physics
1006  break ;
1007  default :
1008  //LOG(ERR,"%d: Type %d, words %d, SAMPA %d:%d, BX %u",rdo_id,type,words,sampa_id,sampa_ch,l_sampa_bx) ;
1009  err |= 0x40 ;
1010  goto err_ret ;
1011  }
1012 
1013 
1014  err_ret:;
1015  if(err) {
1016 // LOG(WARN,"... 0x%08X 0x%08X",hdr[0],hdr[1]) ;
1017  goto retry ;
1018  }
1019 
1020  LOG(WARN,"Found SAMPA %d:%d [0x%08X 0x%08X]",sampa_id,sampa_ch,hdr[0],hdr[1]) ;
1021  return data_start ; // got one!
1022 
1023  err_end:;
1024 
1025  LOG(ERR,"Found no SAMPA channels") ;
1026  return 0 ;
1027 }
1028 
1029 u_int *itpcInterpreter::sampa_lane_scan(u_int *start, u_int *end)
1030 {
1031  u_int d ;
1032  u_int h[6] ;
1033  u_int type, words ;
1034  u_int word32 ;
1035  u_char lane ;
1036  u_int err = 0 ;
1037  u_int *data ;
1038  int ch_loop_cou = 0 ;
1039  int l_sampa_bx ;
1040  u_int lane_hdr ;
1041  bool parity_err ;
1042  bool hamming_err ;
1043  unsigned long long hc ;
1044  u_int hh[2] ;
1045  bool uncorrectable ;
1046  int p_cou ;
1047  u_int hdr[2] ;
1048  u_int first_b ;
1049 
1050  data = start ;
1051 
1052 
1053  // first datum is the 0xB....
1054  d = *data++ ;
1055  lane_hdr = d ;
1056 
1057  first_b = d ;
1058 
1059  fee_id = (d >> 16) & 0x3F ;
1060  lane = (d>>24) & 0x3 ;
1061 
1062  if((first_b & 0xFC000000)!=0xB0000000) {
1063  LOG(ERR,"SAMPA FIFO overwrite 0x%08X!",first_b) ;
1064  }
1065 
1066 // LOG(TERR,"SAMPA lane: FEE %3d, lane %d [0x%08X]",fee_id,lane,d) ;
1067 
1068  new_ch:; // start of channel data
1069 
1070  ch_loop_cou++ ; // count how many channels we found
1071 
1072  // data is now at the SAMPA header
1073  d = *data++ ;
1074  hdr[0] = d ;
1075 
1076  if(d & 0xC0000000) {
1077  hdr[1] = 0xAABBCCDD ;
1078  memset(h,0xAB,sizeof(h)) ;
1079 
1080  err |= 0x100 ;
1081  LOG(ERR,"%d: Bad Hdr 1",rdo_id) ;
1082  goto err_ret ;
1083  }
1084 
1085  h[0] = (d >> 20) & 0x3FF ;
1086  h[1] = (d >> 10) & 0x3FF ;
1087  h[2] = d & 0x3FF ;
1088 
1089  d = *data++ ;
1090  hdr[1] = d ;
1091 
1092  if(d & 0xC0000000) {
1093  h[3] = h[4] = h[5] = 0x11223344 ;
1094  err |= 0x200 ;
1095  LOG(ERR,"%d: Bad Hdr 2",rdo_id) ;
1096  goto err_ret ;
1097  }
1098 
1099  h[3] = (d >> 20) & 0x3FF ;
1100  h[4] = (d >> 10) & 0x3FF ;
1101  h[5] = d & 0x3FF ;
1102 
1103 // if(h[5] != 0xAB) {
1104 // err |= 1 ;
1105 // goto err_ret ;
1106 // }
1107 
1108 
1109  type = h[0] >> 7 ;
1110  words = h[1] ;
1111  sampa_id = h[2] & 0xF ;
1112  sampa_ch = (h[2]>>4) & 0x1F ;
1113 
1114 
1115  switch(lane) {
1116  case 0 :
1117  case 1 :
1118  if((sampa_id&1)) {
1119  LOG(ERR,"sampa_id %d, lane %d",sampa_id,lane) ;
1120  }
1121  break ;
1122  case 2 :
1123  case 3 :
1124  if(!(sampa_id&1)) {
1125  LOG(ERR,"sampa_id %d, lane %d",sampa_id,lane) ;
1126  }
1127  break ;
1128  }
1129 
1130 
1131 // I don't really need this check; it's handled by missing channel later on
1132 #if 0
1133  if(ch_loop_cou==1) {
1134  switch(lane) {
1135  case 0 :
1136  case 2 :
1137  if(sampa_ch != 0) {
1138  // this happens if I'm missing a channel
1139  LOG(WARN,"first in lane sampa_ch is %d not 0?",sampa_ch) ;
1140  }
1141  break ;
1142  case 1 :
1143  case 3 :
1144  if(sampa_ch != 16) {
1145  // this happens if I'm missing a channel
1146  LOG(WARN,"first in lane sampa_ch is %d not 16?",sampa_ch) ;
1147  }
1148  break ;
1149  }
1150  }
1151 #endif
1152 
1153  if(sampa_id & 1) fee_ch = sampa_ch + 32 ;
1154  else fee_ch = sampa_ch ;
1155 
1156  l_sampa_bx = (h[2]&0x200) >> 9 ;
1157  l_sampa_bx |= (h[3]<<1) ;
1158  l_sampa_bx |= (h[4]&0x1FF)<<11 ;
1159 
1160 
1161 // LOG(TERR,"+++ %d %d %u",sampa_id,sampa_ch,l_sampa_bx) ;
1162 
1163  // check parity
1164  p_cou = 0 ;
1165  for(int i=0;i<=4;i++) {
1166  for(int j=0;j<10;j++) {
1167  if(h[i] & (1<<j)) p_cou++ ;
1168  }
1169  }
1170 
1171  if(p_cou&1) {
1172  parity_err = 1 ;
1173  }
1174  else {
1175  parity_err = 0 ;
1176  }
1177 
1178 
1179  hc = ((long long)h[4]<<40)|((long long)h[3]<<30)|(h[2]<<20)|(h[1]<<10)|h[0];
1180 
1181  hh[0] = hc & 0x3FFFFFFF ;
1182  hh[1] = (hc>>30) ;
1183 
1184 
1185  hammingdecode(hh, hamming_err,uncorrectable,0) ;
1186 
1187 
1188  if(parity_err || hamming_err) {
1189  LOG(ERR,"%d:%d: Type %d, words %d, SAMPA %d:%d, BX %u, errors %d:%d",rdo_id,fee_port,type,words,sampa_id,sampa_ch,l_sampa_bx,parity_err,hamming_err) ;
1190  // and I should do something here!
1191  err |= 1 ;
1192  goto err_ret ;
1193  }
1194  else {
1195 // LOG(TERR,"Type %d, words %d, SAMPA %d:%d, BX %u, errors %d:%d, fee_port %d",type,words,sampa_id,sampa_ch,l_sampa_bx,parity_err,hamming_err,fee_port) ;
1196  }
1197 
1198 
1199  switch(type) {
1200  case 0 : // heartbeat
1201  LOG(WARN,"%d: Type %d, words %d, SAMPA %d:%d, BX %u, errors %d:%d, fee_port %d, lane_hdr 0x%08X",
1202  rdo_id,type,words,sampa_id,sampa_ch,l_sampa_bx,parity_err,hamming_err,fee_port,lane_hdr) ;
1203 
1204  if(words != 0) {
1205  err |= 2 ;
1206  goto err_ret ;
1207  }
1208  if(sampa_ch != 21) {
1209  err |= 4 ;
1210  goto err_ret ;
1211  }
1212  break ;
1213  case 4 : // physics
1214  //if(dbg_level) LOG(WARN,"Type %d, words %d, SAMPA %d:%d, BX %u",type,words,sampa_id,sampa_ch,l_sampa_bx) ;
1215  break ;
1216  case 1 : // trigger overrun
1217  LOG(ERR,"%d: Type %d, words %d, SAMPA %d:%d, BX %u [lane_hdr 0x%08X],fee_port %d",rdo_id,type,words,sampa_id,sampa_ch,l_sampa_bx,lane_hdr,fee_port) ;
1218  err |= 8 ;
1219  goto err_ret ;
1220  break ;
1221  default :
1222  LOG(ERR,"%d: Type %d, words %d, SAMPA %d:%d, BX %u [lane_hdr 0x%08X]",rdo_id,type,words,sampa_id,sampa_ch,l_sampa_bx,lane_hdr) ;
1223  err |= 8 ;
1224  goto err_ret ;
1225  }
1226 
1227 
1228  if(sampa_bx < 0) {
1229  sampa_bx = l_sampa_bx ;
1230  }
1231  else if(sampa_bx != l_sampa_bx) {
1232  if(abs(sampa_bx - l_sampa_bx)>1) {
1233  // I could have a difference of 1 here...
1234  //LOG(WARN,"%d:#%02d:%d expect %u, got %u",rdo_id,fee_port,fee_ch,sampa_bx,l_sampa_bx) ;
1235  }
1236  }
1237 
1238 
1239  //now go for the data...
1240  word32 = words / 3 + (words%3?1:0) ;
1241 
1242  //LOG(TERR,"words %d, word32 %d",words,word32) ;
1243  tb_cou = words ;
1244 
1245  if(ped_c && ped_c->want_data) { // I will handle my own data; FCF
1246 
1247  ped_c->sector = sector_id ;
1248  ped_c->rdo = rdo_id ;
1249  ped_c->port = fee_port ;
1250 
1251  if(ped_c->do_ch(fee_id, fee_ch, data, words)) {
1252  err |= 0x400 ;
1253  }
1254 
1255  data += word32 ;
1256  }
1257  else { // done in pedestal runs
1258 
1259  int t_cou = 0 ; // local
1260  for(u_int i=0;i<word32;i++) {
1261  d = *data++ ;
1262 
1263  if((d&0xC0000000)) {
1264  LOG(ERR,"%d:%d: %d:%d sampa data word %d/%d = 0x%08X",rdo_id,fee_port,sampa_id,sampa_ch,i,word32,d) ;
1265  err |= 0x10 ;
1266  i-- ;
1267 
1268  if(d==0x980000F8) { //end of event!!!
1269  LOG(ERR,"Returning here") ;
1270  return data-1 ;
1271  }
1272  continue ;
1273  }
1274 
1275  //LOG(TERR,"... 0x%08X",d) ;
1276 
1277  tb_buff[t_cou++] = (d>>20) & 0x3FF ;
1278  tb_buff[t_cou++] = (d>>10) & 0x3FF ;
1279  tb_buff[t_cou++] = d & 0x3FF ;
1280  }
1281 
1282  if(sampa_ch_scan()<0) {
1283  err |= 0x400 ;
1284  }
1285  }
1286 
1287  //note this hack
1288  //tb_cou = words ;
1289 
1290 
1291 
1292  if(err) {
1293  if(err & 0x400) { // various timebin errors
1294  run_err_add(rdo_id,6) ;
1295  }
1296  LOG(ERR,"%d: Last SAMPA: FEE #%d: %d:%d = 0x%08X [err 0x%0x]",rdo_id,fee_port,sampa_id,sampa_ch,*data,err) ;
1297  }
1298  else {
1299  if(found_ch_mask & (1<<sampa_ch)) {
1300  LOG(ERR,"SAMPA ch %d already found!",sampa_ch) ;
1301  }
1302  found_ch_mask |= (1<<sampa_ch) ;
1303  LOG(NOTE,"Last SAMPA %d:%d = 0x%08X [err 0x%0x]",sampa_id,sampa_ch,*data,err) ;
1304  }
1305 
1306  err = 0 ; // clear error before we go into a new channel
1307 
1308 
1309 // LOG(TERR,"Data at end is now 0x%08X",*data) ;
1310 
1311  if(*data & 0xC0000000) {
1312  // this must be 0x7xxxxxxx
1313  if((data[0] & 0xFC000000)!=0x70000000) {
1314  LOG(ERR,"bad end 0x%08X",data[0]) ;
1315  }
1316  //if((data[0] & 0x0FFFFFFF)!=(first_b & 0x0FFFFFFF)) {
1317  // LOG(ERR,"bad start/stop 0x%08X 0x%08X",first_b,data[0]) ;
1318  //}
1319  if(ch_loop_cou != 16) { // this is a SAMPA2 bug!!!
1320  //LOG(ERR,"Found only %d channels; datum is 0x%08X 0x%08X, last ch is %d, bx %u",ch_loop_cou,data[0],data[1],sampa_ch,sampa_bx) ;
1321  //LOG(ERR," first_b 0x%08X, 0x%08X 0x%08X",first_b,data[-2],data[-1]) ;
1322  }
1323  data++ ; // move to the 0xB... of the next lane!
1324  return data ; //keep the signature
1325  }
1326  else {
1327  goto new_ch ;
1328  }
1329 
1330  err_ret:
1331 
1332  LOG(ERR,"%d: ERR 0x%X: 0x%03X 0x%03X 0x%03X 0x%03X 0x%03X 0x%03X",rdo_id,err,
1333  h[0],h[1],h[2],h[3],h[4],h[5]) ;
1334  LOG(ERR," 0x%08X 0x%08X",hdr[0],hdr[1]) ;
1335 
1336 #if 0
1337  u_int *n_data = sampa_ch_hunt(data,end) ;
1338  if(n_data) {
1339  err = 0 ;
1340  data = n_data ;
1341  goto new_ch ;
1342  }
1343 #endif
1344 
1345  return data ;
1346 }
1347 
1348 
1349 void itpcInterpreter::fee_dbase(const char *fname)
1350 {
1351  FILE *db ;
1352  char hname[128] ;
1353  char uname[128] ;
1354 
1355  //date,time
1356 
1357  //hostname
1358  strcpy(hname,"host-unknown") ;
1359  gethostname(hname,sizeof(hname)) ;
1360 
1361  //user
1362  strcpy(uname,"user-unknown") ;
1363  getlogin_r(uname,sizeof(uname)) ;
1364 
1365 
1366  if(fname==0) {
1367  fname = "/RTScache/fee_dbase.csv" ;
1368 
1369  }
1370 
1371  db = fopen(fname,"a") ;
1372 
1373  if(db==0) {
1374  LOG(ERR,"%s: %s [%s]",__PRETTY_FUNCTION__,fname,strerror(errno)) ;
1375  return ;
1376  }
1377 
1378  time_t tm = time(0) ;
1379 
1380  char *ct = ctime(&tm) ;
1381  ct[strlen(ct)-1] = 0 ;
1382 
1383 // LOG(TERR,"ped_c %p: %d %d",ped_c,sector_id,rdo_id) ;
1384 
1385  for(int i=1;i<=16;i++) {
1386  char err_str[32] ;
1387  if(fee[i].wire1_id == 0) continue ; //skip non-FEEs
1388 
1389 
1390  itpcPed *p_c = (itpcPed *) ped_c ;
1391  int err = 0 ;
1392  int flag = 0 ;
1393  int bad_pin = 0 ;
1394  int reflow = 0 ;
1395 
1396  for(int c=0;c<64;c++) {
1397  if(p_c && p_c->fee_err[sector_id-1][rdo_id-1][i-1][c]) {
1398  err++ ;
1399 
1400  int fl = p_c->fee_err[sector_id-1][rdo_id-1][i-1][c] ;
1401  flag |= fl ;
1402 
1403 
1404  if(fl & 3) {
1405  bad_pin++ ;
1406  }
1407  else if(fl & 4) {
1408  if(c<=31) reflow |= 1 ;
1409  else reflow |= 2 ;
1410  }
1411 
1412 
1413 
1414  }
1415  else {
1416 
1417  }
1418  }
1419 
1420  if(err) {
1421  err_str[0] = 0 ;
1422 
1423  if(bad_pin <= 1) ;
1424  else {
1425  sprintf(err_str,"PINS_%d ",bad_pin) ;
1426  }
1427 
1428 
1429  if(reflow) {
1430  strcat(err_str,"REFLOW SAMPA ") ;
1431  }
1432  else if(bad_pin <= 1) {
1433  goto skip_err ;
1434  }
1435 
1436  if(reflow & 1) {
1437  strcat(err_str,"0 ") ;
1438  }
1439  if(reflow & 2) {
1440  if(reflow & 1) {
1441  strcat(err_str,"and 1") ;
1442  }
1443  else {
1444  strcat(err_str,"1") ;
1445  }
1446  }
1447 
1448  LOG(ERR,"FEE 0x%08X, port %2d: BAD: %s",fee[i].wire1_id,i,err_str) ;
1449 
1450  skip_err:;
1451  }
1452 
1453  if(err) {
1454  sprintf(err_str,"errs%d=0x%X",err,flag) ;
1455  }
1456  else {
1457  sprintf(err_str,"NC") ;
1458  }
1459 
1460  //1wire1, padplane, port, RDO 1wire, RDO #, host, uname,date, comment
1461  fprintf(db,"0x%08X,%2d,%2d,0x%08X,%d,%s,%s,%s,%s\n",fee[i].wire1_id,fee[i].padplane_id,i,
1462  rdo_wire1_id,rdo_id,uname,hname,ct,err_str) ;
1463 
1464 
1465 
1466  }
1467  fprintf(db,"\n") ; //one more NL
1468 
1469  fclose(db) ;
1470 
1471 }
1472 
1473 int itpcInterpreter::ana_send_config(u_int *data, u_int *data_end)
1474 {
1475  u_int d ;
1476 
1477  data++ ; // skip FD71
1478 
1479  data++ ; // skip "version"??
1480 
1481  if(*data != 0x98000066) {
1482  LOG(ERR,"data is 0x%08X",*data) ;
1483  return -1 ;
1484  }
1485 
1486  data++ ; // skip 0066
1487 
1488  ascii_cou = 0 ;
1489  while(data<data_end) {
1490  d = *data++ ;
1491 
1492  if((d & 0xFFFFFF00)==0x9800F500) { //ASCII
1493  int c = d & 0xFF ;
1494  if(c=='\n' || ascii_cou==120) {
1495  ascii_dta[ascii_cou++] = 0 ;
1496 
1497  LOG(INFO,"%d: \"%s\"",rdo_id,ascii_dta) ;
1498  ascii_cou = 0 ;
1499  }
1500  else {
1501  ascii_dta[ascii_cou++] = c ;
1502  }
1503  }
1504  else {
1505  if(d==0x58000067) ;
1506  else LOG(ERR,"end at 0x%08X [%d]",d,data_end-data) ;
1507 
1508  break ;
1509  }
1510  }
1511 
1512  // I should now be at the RDO configuration
1513  d = *data++ ;
1514 
1515  if(d != 0x980000FA) {
1516  LOG(ERR,"%d: Bad FA 0x%08X",rdo_id,d) ;
1517  return -1 ;
1518  }
1519 
1520 // for(int i=0;i<16;i++) {
1521 // LOG(TERR,"FA: %d: 0x%08X",i,data[i]) ;
1522 // }
1523 
1524 
1525  rdo_wire1_id = data[7] ;
1526 
1527  data += 10 ;
1528 
1529  d = *data++ ;
1530 
1531  // I should ne at the end of RDO configuraion
1532  if(d != 0x580000FB) {
1533  LOG(ERR,"%d: Bad FB 0x%08X",rdo_id,d) ;
1534  return -1 ;
1535  }
1536 
1537  d = *data++ ;
1538 
1539  // I should be now at start of RDO monitoring
1540  if(d != 0x980000FC) {
1541  LOG(ERR,"%d: Bad FC 0x%08X",rdo_id,d) ;
1542  return -1 ;
1543  }
1544 
1545  ascii_cou = 0 ;
1546  while(data<data_end) {
1547  d = *data++ ;
1548 
1549  if((d & 0xFFFFFF00)==0x9800F500) { //ASCII
1550  int c = d & 0xFF ;
1551  if(c=='\n' || ascii_cou==120) {
1552  ascii_dta[ascii_cou++] = 0 ;
1553 
1554  LOG(INFO,"%d: \"%s\"",rdo_id,ascii_dta) ;
1555  ascii_cou = 0 ;
1556  }
1557  else {
1558  ascii_dta[ascii_cou++] = c ;
1559  }
1560  }
1561  else {
1562  if(d==0x580000FD) ;
1563  else LOG(ERR,"end at 0x%08X [%d]",d,data_end-data) ;
1564 
1565  break ;
1566  }
1567  }
1568 
1569 #if 0
1570  // I should now be at the start of FEE stuff
1571  d = *data++ ;
1572 
1573  if(d != 0x98000018) {
1574  LOG(ERR,"%d: Bad 18 0x%08X",rdo_id,d) ;
1575  return -1 ;
1576  }
1577 
1578  // now the data is from FEE e.g. 0xA03600A0
1579  d = *data++ ;
1580 
1581  if((d & 0xFF00FFFF)!=0xA00000A0) {
1582  LOG(ERR,"%d: bad FEE ASCII 0x%08X",rdo_id,d) ;
1583  }
1584 #endif
1585 
1586  fee_port = -1 ;
1587  ascii_cou = 0 ;
1588 
1589  while(data<data_end) {
1590  u_int dd_a, dd_b, dd_c ;
1591  //u_int fee_id ;
1592 
1593  d = *data++ ;
1594 
1595  //fee_id = (d>>16) & 0xFF ;
1596 
1597  dd_a = d & 0xFFC0FF00 ;
1598  dd_b = d & 0xFFC000FF ;
1599  dd_c = d & 0xFFC0000F ;
1600 
1601  if(dd_c==0x98000008) { // start of FEE in fee_dump() ;
1602  fee_port = (d >> 4) & 0xFF ;
1603  //LOG(WARN,"fee_port %d",fee_port) ;
1604  }
1605  else if(dd_a==0x0000F500 || dd_a==0x00800000) { //ASCII
1606  int c = d & 0xFF ;
1607  if(c=='\n' || ascii_cou==120) {
1608  ascii_dta[ascii_cou++] = 0 ;
1609 
1610 
1611  u_int id1 = 0 ;
1612  if(strncmp(ascii_dta,"1Wire:",6)==0) {
1613  char *id = strstr(ascii_dta,"ID") ;
1614  if(id) {
1615  if(sscanf(id,"ID 0x%X",&id1)==1) {
1616  fee[fee_port].wire1_id = id1 ;
1617  }
1618  }
1619  }
1620  else if(strncmp(ascii_dta,"Padplane ",9)==0) {
1621  if(sscanf(ascii_dta,"Padplane %d",&id1)==1) {
1622  fee[fee_port].padplane_id = id1 ;
1623  }
1624  }
1625  else if(strncmp(ascii_dta,"V: all",6)==0) {
1626  if(sscanf(ascii_dta,"V: all 0x%X",&id1)==1) {
1627  fpga_fee_v_all = id1 ;
1628  //LOG(WARN,"FEE_asc %d:#%02d: FPGA 0x%08X",rdo_id,fee_port,id1) ;
1629  }
1630  }
1631 
1632 
1633  if(strstr(ascii_dta,"ERROR")) {
1634  LOG(ERR,"FEE_asc %d:#%02d: \"%s\"",rdo_id,fee_port,ascii_dta) ;
1635  }
1636  else {
1637  LOG(TERR,"FEE_asc %d:#%02d: \"%s\"",rdo_id,fee_port,ascii_dta) ;
1638  }
1639 
1640 
1641  ascii_cou = 0 ;
1642  }
1643  else {
1644  ascii_dta[ascii_cou++] = c ;
1645  }
1646  }
1647  else if(dd_b==0xA00000A0 || dd_b==0x600000A0) { // ASCII start/stop
1648 
1649  }
1650  else {
1651  //LOG(ERR,"end at 0x%08X [%d]",d,data_end-data) ;
1652 
1653  //break ;
1654  }
1655  }
1656 
1657 
1658  if((data_end-data)==0) ;
1659  else LOG(ERR,"at end 0x%08X [%d]",*data,data_end-data) ;
1660 
1661  return 0 ;
1662 }
1663 
1664 
1665 int itpcInterpreter::ana_triggered(u_int *data, u_int *data_end)
1666 {
1667  u_int trg ;
1668  u_int err = 0 ;
1669  u_int soft_err = 0 ;
1670  int fee_cou = 0 ;
1671  u_int evt_status = 0 ;
1672 
1673  int expect_fee_cou = itpc_config[sector_id].rdo[rdo_id-1].fee_count ;
1674 
1675  fee_port = 0 ;
1676 
1677  //data[0] is 0x98000vv4
1678 
1679  trg = data[1] ; // trigger_fired
1680  if(trg==0) return 0 ; // no triggers
1681 
1682  // start of FEE is at data[2] ;
1683  data += 2 ;
1684 
1685 
1686  fee_start:;
1687 
1688  // start of FEE is 0x80ff0010 ;
1689 
1690  fee_version = 0 ;
1691 
1692  if(data[0] == 0x98001000) return 0 ; // no FEEs;
1693 
1694  if(fee_cou==0) fee_evt_cou++ ;
1695 
1696  fee_port = 0 ; // claim unknown
1697  fee_id = 0 ; // claim unknown
1698  fee_cou++ ; // so it starts from 1
1699 
1700 
1701  // at FEE start; FEE header
1702  //for(int i=0;i<12;i++) {
1703  // LOG(TERR,"%d: FEE header %d: 0x%08X",rdo_id,i,data[i]) ;
1704  //}
1705 
1706 #if 0
1707  // new on Feb 7, 2019 -- added dummy at the very start of run
1708  // nah, didn't work
1709  if(data[0]==0x0FEEC0DE) {
1710  data++ ;
1711  }
1712  else if((data[0]&0xFF00FFFF)==0x80000010) { // normal...
1713 
1714  }
1715  else {
1716  // the dummy can get corrupted
1717  LOG(ERR,"%d: bad first FEE datum 0x%08X",rdo_id,data[0]) ;
1718  if((data[0]&0x0000FFFF)==0xC0DE) { // good enough
1719  data++ ;
1720  }
1721  }
1722 #endif
1723 
1724  if((data[0] & 0xFFC0FFFF)==0x80000001) {
1725  fee_version = 0 ;
1726  fee_id = (data[0]>>16) & 0xFF ;
1727  }
1728  else {
1729  u_int f_id[3], d_x[3] ;
1730  u_int f_ok = 0 ;
1731 
1732  // gotta be fee_version 1
1733  fee_version = 1 ;
1734 
1735  // I have to have
1736  // 0x80ff0010
1737  // 0x00ff4321
1738  // 0x00ff8765 ;
1739 
1740  // get fee_ids
1741  f_id[0] = (data[0]>>16) & 0x3F ;
1742  f_id[1] = (data[1]>>16) & 0x3F ;
1743  f_id[2] = (data[2]>>16) & 0x3F ;
1744 
1745  // get decoded
1746  d_x[0] = data[0] & 0xFFC0FFFF ;
1747  d_x[1] = data[1] & 0xFFC0FFFF ;
1748  d_x[2] = data[2] & 0xFFC0FFFF ;
1749 
1750  if(d_x[0]==0x80000010) {
1751  f_ok |= 1 ;
1752  if(d_x[1]==0x00004321) f_ok |= 2 ;
1753  if(d_x[2]==0x00008765) f_ok |= 4 ;
1754 
1755  if(f_id[0]==f_id[1]) f_ok |= 8 ;
1756  if(f_id[1]==f_id[2]) f_ok |= 0x10 ;
1757  if(f_id[0]==f_id[2]) f_ok |= 0x20 ;
1758  }
1759 
1760  u_int w = data[0]>>28 ;
1761 
1762  switch(w) {
1763  case 0 :
1764  case 8 :
1765  break ;
1766  default :
1767  LOG(ERR,"%d: 0x%08X 0x%08X 0x%08X [0x%02X] (not an error)",rdo_id,data[0],data[1],data[2],f_ok) ;
1768  LOG(ERR,"%d: 0x%08X 0x%08X 0x%08X [0x%02X] (not an error)",rdo_id,data[-3],data[-2],data[-1],f_ok) ;
1769  break ;
1770  }
1771 
1772  if(f_ok!=0x3F) { // all was NOT OK; hm, this happens ALL the time
1773  // I see e.g.
1774  //
1775  //LOG(ERR,"%d: 0x%08X 0x%08X 0x%08X [0x%02X] (not an error)",rdo_id,data[0],data[1],data[2],f_ok) ;
1776  run_err_add(rdo_id,0) ;
1777  }
1778 
1779 
1780  for(int i=0;i<3;i++) { // hunt for 0x4321
1781  if(d_x[i]==0x00004321) {
1782  data = data+i ;
1783  }
1784  }
1785  }
1786 
1787  if(expected_fee_version >= 0) {
1788  if(fee_version != expected_fee_version) {
1789  LOG(ERR,"FEE version %d, expected %d",fee_version,expected_fee_version) ;
1790  }
1791  }
1792 
1793  //at this point data[0]==0x00004321
1794  // UNLESS there's a complete screwup which needs recovery!!!
1795  // The screwup usually happens when the FEE has a FIFO overrun for some reason
1796 
1797  fee_id = (data[0]>>16) & 0x3F ;
1798 
1799  switch(fee_version) {
1800  case 1 :
1801  if(data[0] != ((fee_id<<16)|0x4321)) err |= 0x10000 ;
1802  if(data[1] != ((fee_id<<16)|0x8765)) err |= 0x20000 ;
1803 
1804  if((u_int)fee_version != (data[2] & 0xFFFF)) err |= 0x40000 ;
1805 
1806  if(data[3]&0xFFF0) err |= 0x40000 ;
1807  fee_port = (data[3] & 0xF) + 1 ;
1808  //data[4] & data[5] are BX
1809 
1810  if(data[6] != ((fee_id<<16)|0x60000010)) err |= 0x80000 ; // end of FEE hdr
1811 
1812  if(err) { // this is a complete screwup!
1813  run_err_add(rdo_id,3) ;
1814  goto done ;
1815  }
1816 
1817  break ;
1818  default :
1819  break ;
1820  }
1821 
1822 // for(int i=0;i<10;i++) {
1823 // LOG(TERR,"... fee V%d hdr: %d = 0x%08X",fee_version,i,data[i]) ;
1824 // }
1825 
1826  // I need fee_port here!!!
1827 
1828 // LOG(TERR,"... %d: port %d, id %d",fee_cou,fee_port,fee_id) ;
1829 
1830 
1831  //data[7] is the start of lane data!!!
1832  data += 7 ;
1833 
1834 // LOG(TERR,"into sampa_lane_scan: fee_id %d",fee_id) ;
1835 
1836 
1837  for(int i=0;i<4;i++) {
1838  u_int expect_mask ;
1839 
1840  if((*data & 0xFC000000) != 0xB0000000) {
1841  // bits 0x1011abxx e.g. 0xB4
1842  // a is sync_fifo_overflow
1843  // b is fifo_overflow and once they latch I _must_ auto-recover!
1844 
1845  if((*data & 0xF0000000) == 0xB0000000) {
1846 
1847  run_err_add(rdo_id,1) ;
1848  LOG(ERR,"%d:#%02d: lane %d: FIFO overflow 0x%08X",rdo_id,fee_port,i,*data) ;
1849 
1850  }
1851  else {
1852  run_err_add(rdo_id,4) ;
1853  LOG(ERR,"%d:#%02d: lane %d: bad sig 0x%08X",rdo_id,fee_port,i,*data) ;
1854  }
1855 
1856  err |= 0x100 ;
1857  goto done ;
1858  }
1859 
1860  switch(i) {
1861  case 0 :
1862  case 2 :
1863  expect_mask = 0x0000FFFF ;
1864  break ;
1865  default :
1866  expect_mask = 0xFFFF0000 ;
1867  break ;
1868  }
1869 
1870  found_ch_mask = 0 ;
1871  data = sampa_lane_scan(data,data_end) ;
1872 
1873  if(found_ch_mask != expect_mask) { // SAMPA2 error!!!
1874  run_err_add(rdo_id,2) ;
1875  //dbg_level = 1 ;
1876  LOG(ERR,"%d: evt %d: fee_port %d: missing channels in lane %d: expect 0x%08X, got 0x%08X",
1877  rdo_id,evt_ix,fee_port,i,expect_mask,found_ch_mask) ;
1878 
1879  // enumarte in FEE port
1880 #if 0
1881  for(int j=0;j<32;j++) {
1882  if(expect_mask & (1<<j)) {
1883  if(!(found_ch_mask & (1<<j))) {
1884  int ch ;
1885 
1886  switch(i) {
1887  case 0 :
1888  case 1 :
1889  ch = j ;
1890  break ;
1891  case 2 :
1892  case 3 :
1893  ch = j + 32 ;
1894  break ;
1895  }
1896 
1897  LOG(ERR,"%d:#%d ch %d missing",rdo_id,fee_port,ch) ;
1898  }
1899  }
1900  }
1901 #endif
1902  // 26-Jan-2022: enabling
1903  soft_err |= 0x100 ;
1904  //err |= 0x400 ;
1905  //goto done ;
1906  }
1907 
1908  if(data==0) {
1909  LOG(ERR,"data 0!!!!") ;
1910  err |= 0x200 ;
1911  goto done ;
1912  }
1913  }
1914 
1915 
1916 // for(int i=0;i<10;i++) {
1917 // LOG(TERR,"fee trl %d = 0x%08X",i,data[i]) ;
1918 // }
1919 
1920  // I expect 8 words of end-of-event from the FEE
1921  switch(fee_version) {
1922  default :
1923  break ;
1924  case 1 :
1925  // I can have a normal 0xA0000010 trailer or
1926  // monitoring 0xA00000EC header
1927  if(data[0] == ((fee_id<<16)|0xA00000EC)) { // monitoring
1928  //LOG(WARN,"Monitoring...") ;
1929 
1930  int found_end = 0 ;
1931  while(data<data_end) {
1932  if(*data == ((fee_id<<16)|0xA0000010)) {
1933  found_end = 1 ;
1934  break ;
1935  }
1936 
1937  u_int dd_a = data[0] & 0xFFC0FF00 ;
1938 
1939  if(dd_a==0x0000F500 || dd_a==0x00800000) { //ASCII
1940  int c = data[0] & 0xFF ;
1941 
1942  if(c=='\n' || ascii_cou==120) {
1943  ascii_dta[ascii_cou++] = 0 ;
1944 
1945  if(strstr(ascii_dta,"ERROR")) {
1946  LOG(ERR,"FEE_asc %d:#%02d: \"%s\"",rdo_id,fee_port,ascii_dta) ;
1947  }
1948  else {
1949  LOG(TERR,"FEE_asc %d:#%02d: \"%s\"",rdo_id,fee_port,ascii_dta) ;
1950  }
1951 
1952 
1953  ascii_cou = 0 ;
1954  }
1955  else {
1956  ascii_dta[ascii_cou++] = c ;
1957  }
1958  }
1959  data++ ;
1960  }
1961 
1962  if(found_end) {
1963  //LOG(WARN,"monitoring end") ;
1964  }
1965  else {
1966  LOG(ERR,"No monitoring end?") ;
1967  err |= 0x100000 ;
1968  }
1969 
1970  }
1971 
1972 
1973  // at end of FEE data; FEE trailer
1974  //for(int i=0;i<12;i++) {
1975  // LOG(TERR,"%d: FEE trailer: %d: 0x%08X",rdo_id,i,data[i]) ;
1976  //}
1977 
1978  if(data[0] != ((fee_id<<16)|0xA0000010)) {
1979  err |= 0x10 ;
1980  LOG(ERR,"%d:#%02d: hdr FEE word 0x%08X",rdo_id,fee_port,data[0]) ;
1981  }
1982 
1983 // if(data[7] != ((fee_id<<16)|0x40000010)) {
1984 // for(int i=0;i<8;i++) {
1985 // LOG(TERR,"%d: %d: 0x%08X",rdo_id,i,data[i]) ;
1986 // }
1987 // }
1988 
1989  if(data[7] != ((fee_id<<16)|0x40000010)) {
1990  LOG(ERR,"%d:#%02d: last FEE word 0x%08X not 0x40..",rdo_id,fee_port,data[7]) ;
1991  err |= 0x20 ; // this is the last guy and can misfire
1992  }
1993 
1994  if((data[1] & 0xFFFF)||(data[2]&0xFFFF)||(data[3]&0xFFFF)||(data[4]&0xFFFF)) {
1995  LOG(ERR,"%d:#%02d: FEE event errors: 0x%X 0x%X 0x%X 0x%X",rdo_id,fee_port,
1996  data[1],data[2],data[3],data[4]) ;
1997  }
1998 
1999  if(err) {
2000  run_err_add(rdo_id,5) ;
2001  goto done ;
2002  }
2003  break ;
2004  }
2005 
2006 
2007 
2008  data += 8 ; // start of new FEE
2009 
2010 
2011  if(data > data_end) goto done ;
2012 
2013  if(data[0]==0x98001000) goto done ; // end of FEE section marker!!!
2014 
2015  if(data[1]==0x98001000) { // still happens!
2016  //LOG(ERR,"%d:#%d, fee_count %d -- delayed end-event marker [0x%08X]?",rdo_id,fee_port,fee_cou,data[0]) ;
2017  data++ ; // advance so not to confuse further checks
2018  goto done ; // occassionally a "delayed FEE" is the last one
2019  }
2020 
2021  if(data[0]==0x980000FC) goto done ; // RDO-mon start
2022 
2023  if(itpc_config[sector_id-1].rdo[rdo_id-1].fee_count && (fee_cou>itpc_config[sector_id-1].rdo[rdo_id-1].fee_count)) {
2024  LOG(ERR,"RDO %d: fee_count %d",rdo_id,fee_cou) ;
2025  goto done ;
2026  }
2027 
2028  // a bug which causes the 1st FEE datum 0x80xx0010 to seep in
2029  if((data[0]&0xFF00FFFF)==0x80000010 && fee_cou==expect_fee_cou) {
2030 // LOG(ERR,"%d: what? 0x%08X",rdo_id,data[0]) ;
2031  if(data[1]==0x980000FC) {
2032  data++ ;
2033  goto done ;
2034  }
2035  }
2036 
2037  goto fee_start ;
2038 
2039 
2040  done:;
2041 
2042  // End of FEE section; at RDO trailer
2043 
2044  //for(int i=0;i<8;i++) {
2045  // LOG(TERR,"%d: RDO trailer check %d: 0x%08X",rdo_id,i,data[i]) ;
2046  //}
2047 
2048 
2049 
2050 
2051  if(err || soft_err) {
2052  run_err_add(rdo_id,7) ;
2053 
2054  LOG(ERR,"%d:#%02d(id %d,cou %d) evt %d: error 0x%X 0x%X",
2055  rdo_id,fee_port,fee_id,fee_cou,evt_ix,err,soft_err) ;
2056 
2057  if(dbg_level>=1) {
2058  for(int i=-4;i<8;i++) {
2059  LOG(ERR,".... %d = 0x%08X",i,data[i]) ;
2060  }
2061  }
2062 
2063  if(err || soft_err) return -1 ; // this is a bit harsh to return already here???
2064  }
2065 
2066  // this only works online
2067  if(realtime) {
2068  // needs more work in case of a masked fee
2069 // if(fee_cou != expect_fee_cou) {
2070 // LOG(ERR,"%d: fees found %d, expect %d",rdo_id,fee_cou,expect_fee_cou) ;
2071 // }
2072  }
2073 
2074  after_fee:;
2075 
2076  // I can either have the trailer with the trigger data
2077  // OR I can have the monitoring event following...
2078 
2079  switch(data[0]) {
2080  case 0x98001000 : // start of trailer
2081  evt_status = data[1] ;
2082  if(evt_status!=0) { // event status
2083  run_err_add(rdo_id,8) ;
2084 
2085  LOG(ERR,"RDO %d: bad event status 0x%08X",rdo_id,data[1]) ;
2086  }
2087 
2088  {
2089  int trg_cou = data[2] ;
2090 
2091  data += 2+trg_cou+1 ;
2092  }
2093 
2094  if(data[0] != 0x58001001) {
2095  LOG(ERR,"RDO %d: no end-of-trailer 0x%08X",rdo_id,data[0]) ;
2096  }
2097 
2098  data++ ;
2099 
2100  //data[0] & data[1] are the FEE stop,start pairs (hi,lo)
2101  //for(int i=0;i<8;i++) {
2102  // LOG(TERR,"%d: %d: 0x%08X",rdo_id,i,data[i]) ;
2103  //}
2104 
2105 
2106  break ;
2107  case 0x980000FC : // RDO_mon
2108  data++ ;
2109  ascii_cou = 0 ;
2110  while(data<data_end) {
2111  u_int d = *data++ ;
2112 
2113  if((d&0xFFFFFF00)==0x9800F500) {
2114  int c = d & 0xFF ;
2115 
2116  if(c=='\n' || ascii_cou==120) {
2117  ascii_dta[ascii_cou++] = 0 ;
2118 
2119  LOG(INFO,"RDO_asc %d: \"%s\"",rdo_id,ascii_dta) ;
2120 
2121  ascii_cou = 0 ;
2122  }
2123  else {
2124  ascii_dta[ascii_cou++] = c ;
2125  }
2126 
2127  }
2128  else if(d==0x580000FD) goto after_fee ;
2129  else LOG(WARN,".... %d 0x%08X",data_end-data,d) ;
2130  }
2131 
2132 
2133  break ;
2134  default :
2135  for(int i=0;i<16;i++) {
2136  LOG(ERR,"After FEE: %d [%d] = 0x%08X",i,data_end-data,*data) ;
2137  data++ ;
2138  }
2139  break ;
2140  }
2141 
2142  if(evt_status) {
2143  LOG(ERR,"%d: evt_status 0x%08X",rdo_id,evt_status) ;
2144  }
2145 
2146  return 0 ;
2147 }
2148 
2149 int itpcInterpreter::ana_pedestal(u_int *data, u_int *data_end)
2150 {
2151  int fee_port = 0 ;
2152 
2153  data++ ; // skip 9800FD60
2154 
2155  while(data<data_end) {
2156  u_int dd_f = data[0] & 0xFF00FFFF ;
2157  u_int dd_r = data[0] & 0xFF00000F ;
2158 
2159  if(data[0]==0x5800FD61) {
2160  LOG(INFO,"pedestal packet done") ;
2161  break ;
2162  }
2163 
2164  if((data[0] & 0xFFFFFF00)==0x98AAAA00) {
2165  LOG(TERR,"-> Done port %d",(data[0]&0xFF)+1) ;
2166  }
2167  else if((data[0] & 0xFFFFFF00)==0x98BBBB00) {
2168  LOG(TERR,"--> Done channel %d",data[0]&0xFF) ;
2169  }
2170  else if(dd_r==0x98000008) {
2171  fee_port = ((data[0])>>4)&0x1F ;
2172  }
2173  else if(dd_r==0x58000009) {
2174 
2175  }
2176  else if(dd_f==0x80000003) {
2177  u_int s[7] ;
2178 
2179  int fee_id = (data[0] >> 16) & 0xFF ;
2180 
2181  for(int i=0;i<7;i++) {
2182  s[i] = data[1+i] & 0xFFFF ;
2183  }
2184 
2185  int for_me = s[0]&1 ;
2186  int my_port = (s[0]>>8) & 0xFF ;
2187 
2188  int len = s[1] & 0x3FF ;
2189  int ch = (s[1]>>10)&0x3F ;
2190 
2191  u_int ticks1 = (s[4]<<16)|s[3] ;
2192  u_int ticks2 = (s[6]<<16)|s[5] ;
2193  LOG(TERR,"#%02d(%02d): fee_id %02d: for_me %d: ch %2d, len %3d",fee_port,my_port,fee_id,for_me,ch,len) ;
2194  LOG(TERR," chsum 0x%04X, ticks %u %u",s[2],ticks1,ticks2) ;
2195 
2196 
2197 
2198  data += 7 ;
2199 
2200  }
2201  else {
2202  LOG(TERR,"... 0x%08X",data[0]) ;
2203  }
2204  data++ ;
2205  }
2206 
2207  return 0 ;
2208 }
2209 
2210 int itpcInterpreter::rdo_scan_top(u_int *data, int words)
2211 {
2212  u_int *data_end = data + words ;
2213  u_int *data_start = data ;
2214  u_int d ;
2215  int ret = 0 ;
2216 
2217  //some preliminaries which used to be in start_event
2218  evt_ix++ ;
2219  evt_bytes = words*4 ;
2220  word_ix = 0 ;
2221  status = 0 ;
2222  state = S_IDLE ;
2223  fee_port = -1 ;
2224  d_cou = 01 ;
2225  sampa_bx = -1 ;
2226  ascii_cou = 0 ;
2227  memset(evt_err,0,sizeof(evt_err)) ;
2228  evt_status = 0 ;
2229 
2230  // move forward until I hit start-comma
2231  int w_cou = (words<16)?words:16 ;
2232 
2233  // the data is already SWAPPED if processed in the sector brokers!!!
2234  for(int i=0;i<w_cou;i++) {
2235 // LOG(TERR,"...%d/%d = 0x%08X",i,words,data[i]) ;
2236 
2237  if((data[i] == 0xCCCC001C)||(data[i] == 0x001CCCCC)) {
2238  data = data + i ;
2239  break ;
2240  }
2241  }
2242 
2243  w_cou = data_end - data ;
2244 
2245  if(data[0]==0xCCCC001C) { // need swapping!!!!
2246 // LOG(TERR,"swapping: data 0x%08X, w_cou %d",data[0],w_cou) ;
2247  for(int i=0;i<w_cou;i++) {
2248  data[i] = sw16(data[i]) ;
2249  }
2250  }
2251 
2252  d = *data++ ; // now at start comma
2253 
2254  switch(d) {
2255  case 0xFFFF001C :
2256  case 0x001CCCCC :
2257  break ;
2258  default :
2259  LOG(ERR,"%d: First word is not a START comma!? [0x%08X 0x%08X 0x%08X]",rdo_id,data[-1],data[0],data[1]) ;
2260  return -1 ;
2261  }
2262 
2263 
2264  int no_fees = 0 ;
2265  //ds is of the form 0x98000014
2266 
2267 
2268 
2269  if((data[0]&0xFF00000F)==0x98000004) {
2270  rdo_version = (data[0]>>4)&0xFF ; // aka 1
2271  }
2272  else {
2273  // I'll also be here if the data is from the new FY2023 iTPC Upgrade!
2274  no_fees = 1 ; // not a triggered event - no FEEs
2275  }
2276 
2277 // if(dbg_level>1) LOG(TERR,"%d: ds 0x%08X, 0x%X %d, words %d,%d",rdo_id,data[0],rdo_version,no_fees,words,w_cou) ;
2278 // LOG(TERR,"%d: ds 0x%08X, 0x%X %d, words %d,%d",rdo_id,data[0],rdo_version,no_fees,words,w_cou) ;
2279 
2280  // I need the event status ala get_l2
2281 
2282  int trl_ix = -1 ;
2283  int trl_stop_ix = -1 ;
2284 
2285 
2286 // for(int i=(words-6);i>=0;i--) {
2287  for(int i=(words-12);i>=0;i--) {
2288  if(dbg_level>1) LOG(TERR,"%d: 0x%08X",i,data[i]) ;
2289 
2290  if(data[i]==0x98001000) {
2291  trl_ix = i ;
2292  break ;
2293  }
2294  if(data[i]==0x58001001) {
2295  trl_stop_ix = i ;
2296  }
2297  }
2298 
2299  if(no_fees==0) { // triggered event with FEEs
2300  if(trl_ix < 0) {
2301  LOG(ERR,"%d: no trailer found, trl_stop_ix %d",rdo_id,trl_stop_ix) ;
2302  }
2303  else {
2304  trl_ix++ ;
2305 
2306  evt_status = (data[trl_ix++]) ;
2307  int trg_cou = (data[trl_ix++]) & 0xFFFF ;
2308 
2309  //if(dbg_level>1) LOG(TERR,"%d: evt_status 0x%08X, trg_cou %d, words %d",rdo_id,evt_status,trg_cou,words) ;
2310  if(evt_status != 0 || trl_stop_ix<0) { // FEE timeout
2311  LOG(ERR,"%d: evt_status 0x%08X, trg_cou %d, words %d, trl_ix %d, trl_stop_ix %d",rdo_id,evt_status,trg_cou,words,trl_ix,trl_stop_ix) ;
2312 
2313 #if 0
2314  for(int i=0;i<8;i++) {
2315  LOG(TERR,"%d = 0x%08X",i,data[i]) ;
2316  }
2317  for(int i=(words-32);i<words;i++) {
2318  LOG(TERR,"%d = 0x%08X",i,data[i]) ;
2319  }
2320 #endif
2321 
2322  //return -1 ;
2323  }
2324  }
2325  }
2326 
2327 
2328 // for(int i=0;i<16;i++) {
2329 // LOG(TERR,"%d/%d = 0x%08X",i,words,data[i]) ;
2330 // }
2331 
2332  d = *data ; // now at start packet word from RDO
2333 
2334  switch(d) {
2335  case 0x9800FD71 : // send config packet
2336  // dump to special handler
2337  // but fish the rdo_version, eh?
2338  ret = ana_send_config(data,data_end) ;
2339  break ;
2340  case 0x9800FD80 : // start run
2341  // check some basics immediatelly here
2342  LOG(TERR,"%d: run_start packet: 0x%08X 0x%08X 0x%08X",rdo_id,data[0],data[1],data[2]) ;
2343 
2344  if(data[2] != 0x11223344) {
2345  LOG(ERR,"%d: run_start: bad signature 0x%08X",rdo_id,data[2]) ;
2346  goto err_ret ;
2347  }
2348 
2349  if(data[1]) {
2350  LOG(ERR,"%d: run_start: already bad status 0x%08X",rdo_id,data[1]) ;
2351  goto err_ret ;
2352  }
2353 
2354  return 0 ;
2355 
2356  break ;
2357  case 0x9800FD60 : // pedestal response from FEE
2358  ret = ana_pedestal(data,data_end) ;
2359  break ;
2360  case 0x5800FD81 : // end of run???
2361  LOG(WARN,"End of run 0x%08X",d) ;
2362  break ;
2363  default :
2364  if((d & 0xFF00000F)==0x98000004) { // triggered event
2365  rdo_version = (d >> 4) & 0xFF ;
2366 
2367  LOG(NOTE,"rdo_version %d",rdo_version) ;
2368 
2369  if(rdo_version==0) { // used the old code (which remains frozen)
2370  ret = rdo_scan(data_start,words) ;
2371  }
2372  else {
2373  ret = ana_triggered(data,data_end) ;
2374 
2375 
2376  }
2377  break ;
2378  }
2379  LOG(ERR,"Unknown packet 0x%08X",d) ;
2380  goto err_ret ;
2381  }
2382 
2383 
2384 // done:;
2385 
2386  // from stop_event
2387  for(int i=0;i<8;i++) {
2388  if(evt_err[i]) LOG(ERR,"%d: event errors[%d] = %u",rdo_id,i,evt_err[i]) ;
2389  }
2390 
2391 
2392  return ret ;
2393 
2394 
2395  err_ret:;
2396 
2397  for(int i=0;i<16;i++) {
2398  LOG(TERR,".... bad evt: %d = 0x%08X",i,data[i]) ;
2399  }
2400 
2401  return -1 ;
2402 }
2403 
2404 /*
2405  This is the frozen, pre-April 2018 unpacker for rdo_version=0
2406 */
2407 int itpcInterpreter::rdo_scan(u_int *data, int words)
2408 {
2409 // int status = 0 ;
2410  int log_start = 0 ;
2411 
2412  u_int *data_end = data + words ;
2413  u_int *data_start = data ;
2414  u_int rh_xing_start = 0 ;
2415  u_int flags = 0 ;
2416 
2417  u_int d ;
2418 
2419  char mon_string[512] ;
2420  int mon_cou = 0 ;
2421 
2422  if(data[0] != 0xDDDDDDDD) {
2423  LOG(ERR,"%d: words %d = 0x%08X",rdo_id,words,data[0]) ;
2424  }
2425 
2426 // for(int i=(words-16);i<(words+32);i++) {
2427 // LOG(TERR,"E %d/%d = 0x%08X",i,words,data[i]) ;
2428 // }
2429 
2430  // the data is already SWAPPED if processed in the sector brokers!!!
2431  for(int i=0;i<16;i++) {
2432  LOG(NOTE,"...%d/%d = 0x%08X",i,words,data[i]) ;
2433 
2434  if((data[i] == 0xCCCC001C)||(data[i] == 0x001CCCCC)) {
2435  data = data + i ;
2436  words-- ;
2437  break ;
2438  }
2439  }
2440 
2441 
2442  if(words<=0) {
2443  LOG(ERR,"%d: words %d = 0x%08X",rdo_id,words,data[0]) ;
2444  }
2445 
2446  if((data[0] == 0xCCCC001C)||(data[0] == 0x001CCCCC)) ; //as it should be
2447  else {
2448  LOG(ERR,"%d: words %d = 0x%08X",rdo_id,words,data[0]) ;
2449  }
2450 
2451  if(data[0]==0xCCCC001C) { // need swapping!!!!
2452  LOG(NOTE,"swapping") ;
2453  for(int i=0;i<words;i++) {
2454  data[i] = sw16(data[i]) ;
2455  }
2456  }
2457  else {
2458  LOG(NOTE,"%d: words %d = 0x%08X",rdo_id,words,data[0]) ;
2459  }
2460 
2461  d = *data++ ;
2462 
2463  switch(d) {
2464  case 0xFFFF001C : //old style
2465  case 0x001CCCCC : // new style
2466  flags |= 1 ;
2467  break ;
2468  default:
2469  LOG(ERR,"%d: First word is not a START comma!? [0x%08X 0x%08X 0x%08X]",rdo_id,data[-1],data[0],data[1]) ;
2470  }
2471 
2472 // LOG(TERR,"RDO scan") ;
2473 
2474  while(data<data_end) {
2475  u_int hdr ;
2476 
2477  word_ix = data - data_start ;
2478 
2479  d = *data++ ;
2480 
2481  LOG(NOTE,"%d/%d = 0x%08X",word_ix,words,d) ;
2482 
2483  switch(d) {
2484  //case 0x5800FD71 : // end of send_config
2485  //case 0x5800FD81 : // end of run
2486  case 0x5800FD61 : // end of manual "Fd"
2487  LOG(INFO,"END of something [0x%08X]",d) ;
2488  return 0 ;
2489  }
2490 
2491  if(log_start) {
2492  LOG(TERR,"... %d = 0x%08X",word_ix,d) ;
2493  }
2494 
2495  if(d==0x5800FD01) {
2496  LOG(WARN,"End of run (but still %d words)",data_end-data) ;
2497  return -1 ;
2498  //goto re_loop ;
2499  }
2500 
2501  switch(state) {
2502  case S_FEE_ASCII :
2503  if((d&0xFFFF0000)==0x00AA0000) {
2504  u_char c = d & 0xFF ;
2505 
2506  if(isprint(c) || isspace(c)) ;
2507  else c = '?' ;
2508 
2509  ascii_dta[ascii_cou++] = c ;
2510  if(c=='\n') {
2511  ascii_dta[ascii_cou++] = 0 ;
2512  LOG(ERR,"WTF?") ;
2513  printf("HERE #%02d: %s",fee_port,ascii_dta) ;
2514 
2515  if(strncmp(ascii_dta,"1Wire ",6)) {
2516  u_int id1 ;
2517  char *id = strstr(ascii_dta,"ID") ;
2518  sscanf(id,"ID 0x%X",&id1) ;
2519  printf("=====> 0x%08X",id1) ;
2520  }
2521  fflush(stdout) ;
2522  ascii_cou = 0 ;
2523  }
2524  }
2525  else {
2526  LOG(ERR,"Bad: %d = 0x%08X",word_ix,d) ;
2527  }
2528  state = S_FEE_ASCII_END ;
2529  goto re_loop ;
2530 
2531  case S_FEE_ASCII_END :
2532  if((d&0xF80000FF)!=0x600000A1) {
2533  LOG(ERR,"Bad %d = 0x%08X",word_ix,d) ;
2534  }
2535  state = S_IDLE ;
2536  goto re_loop ;
2537  case S_FEE_PORT :
2538  fee_port = (d&0xFF)+1 ;
2539  LOG(NOTE,"FEE port #%02d",fee_port) ;
2540  state = S_IDLE ;
2541  goto re_loop ;
2542  case S_TRIGGER :
2543  LOG(TERR,"Trg %2d = 0x%08X",d_cou,d) ;
2544  d_cou++ ;
2545  if((d&0xF80000FF)==0x58000005) {
2546  state = S_IDLE ;
2547  }
2548  goto re_loop ;
2549  case S_IDLE :
2550  default :
2551  break ;
2552  }
2553 
2554  if((d & 0xF80000FF)==0xA00000A0) {
2555  state = S_FEE_ASCII ;
2556  goto re_loop ;
2557  }
2558 
2559 
2560  hdr = d & 0xF800FFFF ;
2561 
2562  switch(hdr) {
2563  case 0x9800FD70 :
2564  LOG(INFO,"SEND_CONFIG: start") ;
2565  break ;
2566  case 0x5800FD71 :
2567  if(fout) {
2568  fprintf(fout,"%d: 1-wire Id 0x%08X\n",rdo_id,rdo_wire1_id) ;
2569  }
2570 
2571  LOG(INFO,"SEND_CONFIG: end for RDO ID 0x%08X",rdo_wire1_id) ;
2572  for(int i=1;i<=16;i++) {
2573  LOG(INFO," FEE #%02d: Padplane %02d, 1Wire 0x%08X",i,fee[i].padplane_id,fee[i].wire1_id) ;
2574  if(fout) {
2575  fprintf(fout," FEE #%02d: Padplane %02d, 1Wire 0x%08X\n",i,fee[i].padplane_id,fee[i].wire1_id) ;
2576  }
2577  }
2578 
2579  if(fout) fflush(fout) ;
2580 
2581  //fee_dbase() ;
2582 
2583  return 2 ;
2584  break ;
2585  case 0x9800FD80 :
2586  LOG(INFO,"RUN_START: start") ;
2587  break ;
2588  case 0x5800FD81 :
2589  LOG(INFO,"RUN_START: stop, events %u",evt_ix) ;
2590  return 0 ;
2591  break ;
2592  case 0x98000008 :
2593  // sometimes I get ASCII immediatelly
2594  if((data[1]&0xFFC00000)!=0x80000000) {
2595  if((data[1]&0xFFC0FFFF)!=0xA00000A0) {
2596  // I read e.g. 0x002E0000 instread of 0x802E0001
2597  //LOG(ERR,"%d: evt %d: After start 0x%08X, FEE #%d",rdo_id,evt_ix,data[1],data[0]+1) ;
2598  }
2599  }
2600 
2601 
2602  data = fee_scan(data-1, data_end) ;
2603 #if 0
2604  {
2605  LOG(TERR,"Left fee_port %d: %d",fee_port,data_end-data) ;
2606  if(fee_port==16) {
2607  u_int *d = data ;
2608 
2609  while(d<=data_end) {
2610  LOG(TERR,"%d = 0x%08X",data_end-d,*d) ;
2611  d++ ;
2612  }
2613  }
2614  }
2615 #endif
2616 #if 0
2617  fee_port = *data++ ;
2618  fee_port &= 0xFF ;
2619  fee_port++ ;
2620  LOG(NOTE,"RDO FEE data: START: fee_port %d",fee_port) ;
2621 #endif
2622  break ;
2623  case 0x58000009 :
2624  LOG(NOTE,"RDO FEE data: END: fee_port %d",fee_port) ;
2625  break ;
2626  case 0x98000004 :
2627  if(flags & 0x6) {
2628  LOG(ERR,"Duplicate hdr") ;
2629  }
2630 
2631  flags |= 2 ;
2632  LOG(NOTE,"RDO Event Header: START") ;
2633  {
2634  u_int *d_now = data ;
2635 
2636  for(int i=0;i<10;i++) {
2637 
2638  LOG(NOTE,"Event Header %2d = 0x%08X",i,d) ;
2639 
2640  if(d==0x58000005) {
2641  flags |= 4 ;
2642  break ;
2643  }
2644  else {
2645  d = *data++ ;
2646  }
2647  }
2648 
2649  if((data-d_now)!=8) {
2650  LOG(ERR,"RDO Event Header corrupt %d",data-d_now) ;
2651  }
2652 
2653  }
2654  break ;
2655  case 0x58000005 :
2656  LOG(ERR,"RDO Event Header: END (could be spurious)") ;
2657  break ;
2658  case 0x98000006 :
2659  fee_evt_cou++ ;
2660  LOG(NOTE,"RDO FEE complement: START") ;
2661  break ;
2662  case 0x58000007 :
2663  LOG(NOTE,"RDO FEE complement: END") ;
2664  break ;
2665 #if 0
2666  case 0x98000044 :
2667  d = *data++ ;
2668  if(d) {
2669  LOG(ERR,"RDO FEE Readout Status: START: status 0x%08X",d) ;
2670  }
2671  else {
2672  LOG(NOTE,"RDO FEE Readout Status: START: status 0x%08X",d) ;
2673  }
2674  break ;
2675  case 0x58000045 :
2676  LOG(NOTE,"RDO FEE Readout Status: END") ;
2677  break ;
2678 #endif
2679 
2680  case 0x98000066 :
2681  LOG(NOTE,"RDO Boottext: START: %d = 0x%08X",word_ix,d) ;
2682  for(;;) {
2683  d = *data++ ;
2684  if((d & 0xFFFFFF00)==0x9800F500) {
2685  int c = d & 0xFF ;
2686  if(c=='\n') {
2687  mon_string[mon_cou++] = 0 ;
2688 
2689  if(fout) {
2690  fprintf(fout,"%d: %s\n",rdo_id,mon_string) ;
2691  fflush(fout) ;
2692  }
2693  LOG(INFO,"%d: \"%s\"",rdo_id,mon_string) ;
2694  mon_cou = 0 ;
2695  }
2696  else {
2697  mon_string[mon_cou++] = c ;
2698  }
2699  //printf("%c",d&0xFF) ;
2700  }
2701  else {
2702  LOG(NOTE,"RDO Boottext: END: %d = 0x%08X",word_ix,d) ;
2703  mon_cou = 0 ;
2704  break ;
2705  }
2706  }
2707  fflush(stdout) ;
2708  break ;
2709  case 0x58000067 : // should not see it here...
2710  LOG(ERR,"RDO Boottext: END: %d = 0x%08X",word_ix,d) ;
2711  break ;
2712 
2713  case 0x980000FC :
2714  LOG(NOTE,"RDO Monitoring: START: %d = 0x%08X",word_ix,d) ;
2715  for(;;) {
2716  d = *data++ ;
2717  if((d & 0xFFFFFF00)==0x9800F500) {
2718  int c = d & 0xFF ;
2719  if(c=='\n') {
2720  mon_string[mon_cou++] = 0 ;
2721  LOG(INFO,"%d: \"%s\"",rdo_id,mon_string) ;
2722  if(fout) {
2723  fprintf(fout,"%d: \"%s\"\n",rdo_id,mon_string) ;
2724  fflush(fout) ;
2725  }
2726  mon_cou = 0 ;
2727  }
2728  else {
2729  mon_string[mon_cou++] = c ;
2730  }
2731  //printf("%c",d&0xFF) ;
2732  }
2733  else {
2734  LOG(NOTE,"RDO Monitoring: END: %d = 0x%08X",word_ix,d) ;
2735  mon_cou =0 ;
2736  break ;
2737  }
2738  }
2739  fflush(stdout) ;
2740  break ;
2741  case 0x580000FD : // should not see it here...
2742  LOG(ERR,"RDO Monitoring: END: %d = 0x%08X",word_ix,d) ;
2743  break ;
2744  case 0x98001000 :
2745  if(flags & 0x18) {
2746  LOG(ERR,"RDO %d: duplicate trailer",rdo_id) ;
2747  }
2748  flags |= 8 ;
2749  LOG(NOTE,"RDO: Event Trailer Start") ;
2750  {
2751  u_int trg_cou ;
2752  u_int *d_now = data ;
2753  int suspect = 0 ;
2754 
2755  if(data[0] != 0xABCD0000) {
2756  suspect = 1 ;
2757  LOG(ERR,"RDO %d: Event Trailer %u/%u = ABCD 0x%08X",rdo_id,word_ix,words,data[0]) ;
2758  }
2759 
2760  if(data[1] != 0) {
2761  suspect = 1 ;
2762  //often!
2763  //LOG(ERR,"RDO %d: Event Trailer %u/%u = status 0x%08X",rdo_id,word_ix,words,data[1]) ;
2764  }
2765 
2766  trg_cou=data[2] ;
2767  if(trg_cou>100) {
2768  suspect = 1 ;
2769  //often
2770  //LOG(ERR,"RDO %d: Event Trailer %u/%u = trg_cou 0x%08X",rdo_id,word_ix,words,data[2]) ;
2771  trg_cou = 0 ;
2772  }
2773 
2774  if(suspect) {
2775  // almost always 0xF which is correct.
2776  if(flags != 0xF) LOG(ERR,"flags 0x%X",flags) ;
2777  }
2778 
2779  if((data[3+trg_cou+2]&0xF800FFFF)!=0x58001001) suspect = 1 ; // very often
2780 
2781 
2782  //LOG(TERR,"END 0x%08X",data[3+trg_cou+2]) ;
2783 
2784  // data[0] = 0xabcd0000 ;
2785  // data[1] = status (must be 0)
2786  // data[2] = trigger count
2787  // data[3..] = triggers
2788  // data[x] = yada ;
2789  // data[x+1] = yada
2790  // data[x+2] = 0x58001001 ;
2791 
2792  for(int i=0;i<100;i++) {
2793  //if(i==2 && d) { //status
2794  // LOG(ERR,"FEE #%d: Event Trailer %u = 0x%08X",fee_port,word_ix,d) ;
2795  //}
2796 
2797  LOG(NOTE,"Event Trailer %2d = 0x%08X",i,d) ;
2798 
2799  if((d&0xF800FFFF)==0x58001001) {
2800  flags |= 0x10 ;
2801  break ;
2802  }
2803  else {
2804  d = *data++ ;
2805  if(data>data_end) {
2806  flags |= 0x1000 ;
2807  suspect = 2 ;
2808  break ;
2809  }
2810  }
2811  }
2812 
2813  // unfortuntatelly this is not a fixed value... THINK!
2814  // ALSO -- it seems to be 100 easily which means that I am missing the end of event!
2815  int t_len = data - d_now ;
2816  if(0) {
2817  //if(suspect) {
2818  LOG(ERR,"RDO %d: Event Trailer Suspect %d - %d",rdo_id,suspect,t_len) ;
2819  for(int i=0;i<16;i++) {
2820  LOG(TERR,"%d/%d = 0x%08X",d_now-data_start,words,*d_now) ;
2821  d_now++ ;
2822  }
2823  data = data_end + 1 ; // to make sure it's over
2824  }
2825  }
2826 
2827  break ;
2828  case 0x58001001 : // should not see it here
2829  LOG(ERR,"RDO: Event Trailer End") ;
2830  break ;
2831 
2832  case 0x980000FA :
2833  LOG(NOTE,"RDO Configuration: START: %d = 0x%08X",word_ix,d) ;
2834  //LOG(TERR,"RDO wire1_id 0x%08X",data[7]) ;
2835  rdo_wire1_id = data[7] ;
2836  data += 10 ;
2837  break ;
2838  case 0x580000FB :
2839  LOG(NOTE,"RDO Configuration: END: %d = 0x%08X",word_ix,d) ;
2840  break ;
2841  case 0x9800FD60:
2842  LOG(NOTE,"RDO FEE DUMP : START") ;
2843  break ;
2844  case 0x980000F8 :
2845  if(data[1]) {
2846  LOG(ERR,"%d: FEE #%d: stat 0x%08X 0x%08X 0x%08X 0x%08X",rdo_id,fee_port,data[1],data[2],data[3],data[4]) ;
2847  }
2848  else {
2849  LOG(TERR,"%d: FEE #%d: stat 0x%08X 0x%08X 0x%08X 0x%08X",rdo_id,fee_port,data[1],data[2],data[3],data[4]) ;
2850  }
2851  //log_start = 1 ;
2852  break ;
2853 
2854 
2855  // FEE headers
2856  // 0x8 is start triggered
2857  // 0x4 is end triggred
2858  // 0xA is start header
2859  // 0x6 is end header
2860 
2861  case 0x80000010 :
2862  {
2863 
2864  u_int h, l ;
2865  u_int glo_status ;
2866 
2867  l = (*data++) & 0xFFFF ;
2868  h = (*data++) & 0xFFFF ;
2869 
2870  glo_status = (h<<16) | l ;
2871 
2872  if(glo_status) {
2873  LOG(ERR,"FEE SEND_CONFIG: START 0: status 0x%08X",glo_status) ;
2874  }
2875  else {
2876  LOG(NOTE,"FEE SEND_CONFIG: START 0: status 0x%08X",glo_status) ;
2877  }
2878  }
2879  break ;
2880  case 0x60000011 :
2881  LOG(NOTE,"FEE SEND_CONFIG: END 0") ;
2882  break ;
2883 
2884  case 0xA00000FA :
2885  LOG(NOTE,"FEE Configuration: START") ;
2886  break ;
2887  case 0x600000FB :
2888  LOG(NOTE,"FEE Configuration: END") ;
2889  break ;
2890 
2891  case 0xA00000EC :
2892  LOG(NOTE,"FEE Monitoring: START 0") ;
2893  break ;
2894  case 0x600000ED :
2895  LOG(NOTE,"FEE Monitoring: END 0") ;
2896  break ;
2897  case 0xA00000FC :
2898  LOG(NOTE,"FEE Monitoring: START 1") ;
2899  break ;
2900  case 0x600000FD :
2901  LOG(NOTE,"FEE Monitoring: END 1") ;
2902  break ;
2903 
2904  case 0xA0000020 :
2905  {
2906 
2907  u_int h, l ;
2908  u_int glo_status ;
2909 
2910  l = (*data++) & 0xFFFF ;
2911  h = (*data++) & 0xFFFF ;
2912 
2913  glo_status = (h<<16) | l ;
2914 
2915  if(glo_status) {
2916  LOG(ERR,"FEE SEND_CONFIG: START 1: status 0x%08X",glo_status) ;
2917  }
2918  else {
2919  LOG(NOTE,"FEE SEND_CONFIG: START 1: status 0x%08X",glo_status) ;
2920  }
2921  }
2922 
2923  break ;
2924  case 0x40000021 :
2925  LOG(NOTE,"FEE SEND_CONFIG: END 1 (all)") ;
2926  break ;
2927 
2928 
2929  case 0x80000200 :
2930  LOG(NOTE,"FEE Trigger: START: TRIGGERED") ;
2931  {
2932  u_int h, l ;
2933  u_int bx_xing ;
2934  u_int glo_status ;
2935  u_int fee_evt ;
2936  u_int type ;
2937 
2938  l = (*data++) & 0xFFFF ;
2939  h = (*data++) & 0xFFFF ;
2940 
2941  glo_status = (h<<16) | l ;
2942 
2943 
2944  l = (*data++) & 0xFFFF ;
2945  h = (*data++) & 0xFFFF ;
2946 
2947  rh_xing_start = (h<<16) | l ;
2948 
2949 
2950  l = (*data++) & 0xFFFF ;
2951  h = (*data++) & 0xFFFF ;
2952 
2953  bx_xing = (h<<16) | l ;
2954 
2955 
2956  l = (*data++) & 0xFFFF ;
2957  h = (*data++) & 0xFFFF ;
2958 
2959  type = (h<<16) | l ;
2960 
2961  l = (*data++) & 0xFFFF ;
2962  h = (*data++) & 0xFFFF ;
2963 
2964  fee_evt = (h<<16) | l ;
2965 
2966 
2967  int fee_id = (d>>16)&0x3F ;
2968 
2969  if(glo_status) {
2970  LOG(ERR,"FEE %d(#%d) START Event %d: type 0x%08X, xing %u, 20bit %u, RHIC %u, glo 0x%08X",fee_id,fee_port,
2971  fee_evt,type,bx_xing,bx_xing&0xFFFFF,rh_xing_start,glo_status) ;
2972  }
2973  else {
2974  LOG(TERR,"FEE %d(#%d) START Event %d: type 0x%08X, xing %u, 20bit %u, RHIC %u, glo 0x%08X",fee_id,fee_port,
2975  fee_evt,type,bx_xing,bx_xing&0xFFFFF,rh_xing_start,glo_status) ;
2976  }
2977 
2978  }
2979  break ;
2980  case 0x60000201 :
2981  LOG(NOTE,"FEE Trigger: END: hdr") ;
2982  break ;
2983  case 0xA0000300:
2984  {
2985  u_int a, b ;
2986  u_int status ;
2987  u_int xing ;
2988  u_int glo_status ;
2989  u_int fee_evt ;
2990 
2991  a = (*data++) & 0xFFFF ; //lo
2992  b = (*data++) & 0xFFFF ; //ji
2993 
2994  glo_status = (b<<16) | a ;
2995 
2996 
2997  a = (*data++) & 0xFFFF ; //lo
2998  b = (*data++) & 0xFFFF ; //ji
2999 
3000  status = (b<<16) | a ;
3001 
3002  a = (*data++) & 0xFFFF ; //lo
3003  b = (*data++) & 0xFFFF ; //ji
3004 
3005  xing = (b<<16) | a ;
3006 
3007  a = (*data++) & 0xFFFF ; //lo
3008  b = (*data++) & 0xFFFF ; //ji
3009 
3010  fee_evt = (b<<16) | a ;
3011 
3012  if(glo_status || status) {
3013  LOG(ERR,"FEE END Event %d: glo 0x%08X, status 0x%08X, xing %u, delta %u",
3014  fee_evt,glo_status,status, xing, xing-rh_xing_start) ;
3015  }
3016  else {
3017  LOG(TERR,"FEE END Event %d: glo 0x%08X, status 0x%08X, xing %u, delta %u",
3018  fee_evt,glo_status,status, xing, xing-rh_xing_start) ;
3019  }
3020  }
3021  break ;
3022  case 0x40000301:
3023  LOG(WARN,"FEE Event: END") ;
3024  break ;
3025  default : // all other cases
3026 
3027  if(words==(data-data_start)) { // last word
3028  if((d & 0xFFFF0000)==0x005C0000) break ; // last word and it's a end-comma -- normal
3029 
3030  //last word but it's some gibberish -- it can happen occassionally, don't know why
3031  //LOG(WARN,"%d: last huh 0x%08X at %d/%d",rdo_id,d,word_ix,words) ;
3032  break ;
3033  }
3034 
3035 
3036  //LOG(WARN,"%d: huh 0x%08X at %d/%d",rdo_id,d,word_ix,words) ;
3037 
3038 #if 0
3039  if((d & 0xFFFF0000)==0x005C0000) ; // stop-comma is OK here
3040  else {
3041  if(words==(data-data_start)) ; // OK for the last word
3042  else {
3043  // junk at the end of event
3044  //LOG(WARN,"%d: datum huh 0x%08X at %d/%d",rdo_id,d,data-data_start,words) ;
3045  }
3046  }
3047 #endif
3048 
3049  break ;
3050  }
3051 
3052 
3053  if(flags & 0x10) {
3054  //LOG(TERR,"flags 0x%X",flags) ;
3055  break ;
3056  }
3057  re_loop: ;
3058 
3059  }
3060 
3061 
3062 
3063 // if((flags != 0x1F) || ((data_end-data) != 0)) {
3064  if((flags != 0x1F)) {
3065  LOG(ERR,"At end: %d, flags 0x%X",data_end-data,flags) ;
3066  for(int i=0;i<32;i++) {
3067  LOG(WARN,"... %2d = 0x%08X",i,data_end[16-i]) ;
3068  }
3069  }
3070 
3071  if((data[-1] & 0xFFFF0000)==0x005C0000) {
3072  log_start = 0 ;
3073  //LOG(WARN,"Stop Comma at the very end") ;
3074  return 1 ;
3075  }
3076  else LOG(NOTE,"%d: no end-comma %d %d = 0x%08X!",rdo_id,data_end-data,words,data[-1]) ;
3077 
3078  return 1 ;
3079 
3080 
3081 
3082 }
3083 
3084 
3085 
3086 /* Tonko: received from Arild on 16 Nov 2017
3087 
3088 buffer[0] -- first 30 bits of 50 bit word
3089 buffer[1] -- last 20 bits of 50 bit word
3090 
3091 */
3092 
3093 typedef unsigned char uint8_t ;
3094 
3095 static void hammingdecode(unsigned int buffer[2], bool& error, bool& uncorrectable, bool fix_data) // Least efficient hamming decoder ever
3096 {
3097 
3098  // header split
3099  bool parityreceived[6];
3100  bool data_in[43];
3101  bool overallparity;
3102 
3103  for (int i = 0; i < 6; i++)
3104  parityreceived[i] = (buffer[0] >> i) & 0x1;
3105 
3106  overallparity = (buffer[0] >> 6) & 0x1;
3107 
3108  //for (int i = 0; i < 43; i++)
3109  // data_in[i] = (header_in >> (i + 7)) & 0x1;
3110 
3111  for (int i = 7; i < 30; i++)
3112  data_in[i-7] = (buffer[0] >> i) & 0x1;
3113 
3114  for (int i = 30; i < 50; i++)
3115  data_in[i-7] = (buffer[1] >> (i - 30)) & 0x1;
3116 
3117  //calculated values
3118  bool corrected_out[43];
3119  bool overallparitycalc = 0;
3120  bool overallparity_out = 0;
3121  bool paritycalc[6];
3122  bool paritycorreced_out[6];
3123 
3125  // calculate parity
3126  paritycalc[0] = data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^
3127  data_in[8] ^ data_in[10] ^ data_in[11] ^ data_in[13] ^ data_in[15] ^
3128  data_in[17] ^ data_in[19] ^ data_in[21] ^ data_in[23] ^ data_in[25] ^
3129  data_in[26] ^ data_in[28] ^ data_in[30] ^ data_in[32] ^ data_in[34] ^
3130  data_in[36] ^ data_in[38] ^ data_in[40] ^ data_in[42];
3131 
3132  paritycalc[1] = data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^
3133  data_in[9] ^ data_in[10] ^ data_in[12] ^ data_in[13] ^ data_in[16] ^
3134  data_in[17] ^ data_in[20] ^ data_in[21] ^ data_in[24] ^ data_in[25] ^
3135  data_in[27] ^ data_in[28] ^ data_in[31] ^ data_in[32] ^ data_in[35] ^
3136  data_in[36] ^ data_in[39] ^ data_in[40] ;
3137 
3138  paritycalc[2] = data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[7] ^ data_in[8] ^
3139  data_in[9] ^ data_in[10] ^ data_in[14] ^ data_in[15] ^ data_in[16] ^
3140  data_in[17] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^
3141  data_in[29] ^ data_in[30] ^ data_in[31] ^ data_in[32] ^ data_in[37] ^
3142  data_in[38] ^ data_in[39] ^ data_in[40] ;
3143 
3144  paritycalc[3] = data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7] ^ data_in[8] ^
3145  data_in[9] ^ data_in[10] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^
3146  data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^
3147  data_in[33] ^ data_in[34] ^ data_in[35] ^ data_in[36] ^ data_in[37] ^
3148  data_in[38] ^ data_in[39] ^ data_in[40] ;
3149 
3150  paritycalc[4] = data_in[11] ^ data_in[12] ^ data_in[13] ^ data_in[14] ^ data_in[15] ^
3151  data_in[16] ^ data_in[17] ^ data_in[18] ^ data_in[19] ^ data_in[20] ^
3152  data_in[21] ^ data_in[22] ^ data_in[23] ^ data_in[24] ^ data_in[25] ^
3153  data_in[41] ^ data_in[42] ;
3154 
3155  paritycalc[5] = data_in[26] ^ data_in[27] ^ data_in[28] ^ data_in[29] ^ data_in[30] ^
3156  data_in[31] ^ data_in[32] ^ data_in[33] ^ data_in[34] ^ data_in[35] ^
3157  data_in[36] ^ data_in[37] ^ data_in[38] ^ data_in[39] ^ data_in[40] ^
3158  data_in[41] ^ data_in[42] ;
3160 
3161  uint8_t syndrome = 0;
3162 
3163  for (int i = 0; i < 6; i++)
3164  syndrome |= (paritycalc[i]^parityreceived[i]) << i;
3165 
3166  bool data_parity_interleaved[64];
3167  bool syndromeerror;
3168 
3169  //data_parity_interleaved[0] = 0;
3170  data_parity_interleaved[1] = parityreceived[0];
3171  data_parity_interleaved[2] = parityreceived[1];
3172  data_parity_interleaved[3] = data_in[0];
3173  data_parity_interleaved[4] = parityreceived[2];
3174  for (int i = 1; i <= 3; i++)
3175  data_parity_interleaved[i+5-1] = data_in[i];
3176  data_parity_interleaved[8] = parityreceived[3];
3177  for (int i = 4; i <= 10; i++)
3178  data_parity_interleaved[i+9-4] = data_in[i];
3179  data_parity_interleaved[16] = parityreceived[4];
3180  for (int i = 11; i <= 25; i++)
3181  data_parity_interleaved[i+17-11] = data_in[i];
3182  data_parity_interleaved[32] = parityreceived[5];
3183  for (int i = 26; i <= 42; i++)
3184  data_parity_interleaved[i+33-26] = data_in[i];
3185  //for (int i = 50; i <= 63; i++)
3186  // data_parity_interleaved[i] = 0;
3187 
3188  data_parity_interleaved[syndrome] = !data_parity_interleaved[syndrome]; // correct the interleaved
3189 
3190  paritycorreced_out[0] = data_parity_interleaved[1];
3191  paritycorreced_out[1] = data_parity_interleaved[2];
3192  corrected_out[0] = data_parity_interleaved[3];
3193  paritycorreced_out[2] = data_parity_interleaved[4];
3194  for (int i = 1; i <= 3; i++)
3195  corrected_out[i] = data_parity_interleaved[i+5-1];
3196  paritycorreced_out[3] = data_parity_interleaved[8];
3197  for (int i = 4; i <= 10; i++)
3198  corrected_out[i] = data_parity_interleaved[i+9-4];
3199  paritycorreced_out[4] = data_parity_interleaved[16];
3200  for (int i = 11; i <= 25; i++)
3201  corrected_out[i] = data_parity_interleaved[i+17-11];
3202  paritycorreced_out[5] = data_parity_interleaved[32];
3203  for (int i = 26; i <= 42; i++)
3204  corrected_out[i] = data_parity_interleaved[i+33-26];
3205 
3206  // now we have the "corrected" data -> update the flags
3207 
3208  bool wrongparity;
3209  for (int i = 0; i < 43; i++)
3210  overallparitycalc ^=data_in[i];
3211  for (int i = 0; i < 6; i++)
3212  overallparitycalc ^= parityreceived[i];
3213  syndromeerror = (syndrome > 0) ? 1 : 0; // error if syndrome larger than 0
3214  wrongparity = (overallparitycalc != overallparity);
3215  overallparity_out = !syndromeerror && wrongparity ? overallparitycalc : overallparity; // If error was in parity fix parity
3216  error = syndromeerror | wrongparity;
3217  uncorrectable = (syndromeerror && (!wrongparity));
3218 
3219 
3220  //header_out = 0;
3221  //for (int i = 0; i < 43; i++)
3222  // header_out |= corrected_out[i] << (i + 7);
3223  //header_out |= overallparity_out << 6;
3224  //for (int i = 0; i < 6; i++)
3225  // header_out |= paritycorreced_out[i] << i;
3226  if (fix_data)
3227  {
3228  for (int i = 0; i < 6; i++)
3229  buffer[0] = (buffer[0] & ~(1 << i)) | (paritycorreced_out[i] << i);
3230  buffer[0] = (buffer[0] & ~(1 << 6)) | (overallparity_out << 6);
3231  for (int i = 7; i < 30; i++)
3232  buffer[0] = (buffer[0] & ~(1 << i)) | (corrected_out[i - 7] << i);
3233  for (int i = 30; i < 50; i++)
3234  buffer[1] = (buffer[1] & ~(1 << (i - 30))) | (corrected_out[i - 7] << (i - 30));
3235  }
3236 }
Definition: rb.hh:21