StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fcs_trg_base.cxx
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <string.h>
4 
5 #include <rtsLog.h>
6 #include <DAQ_FCS/fcs_data_c.h>
7 
8 #include "fcs_trg_base.h"
9 
10 // statics
11 fcs_trg_base::marker_t fcs_trg_base::marker ;
12 
13 u_int fcs_trg_base::stage_version[4] ;
14 
15 u_short fcs_trg_base::stage_params[4][32] ;
16 
17 ped_gain_t fcs_trg_base::p_g[NS_COU][ADC_DET_COU][DEP_COU][32] ;
18 u_short fcs_trg_base::ht_threshold[ADC_DET_COU] ;
19 
20 
21 unsigned long long fcs_trg_base::s2_ch_mask[NS_COU] ;
22 u_char fcs_trg_base::s2_ch_phase[NS_COU][34] ;
23 
24 u_char fcs_trg_base::s3_ch_mask ;
25 u_char fcs_trg_base::s3_ch_phase[4] ;
26 u_char fcs_trg_base::s3_out_phase ;
27 
28 int fcs_trg_base::fcs_trgDebug ;
29 int fcs_trg_base::fcs_readPresMaskFromText;
30 u_int fcs_trg_base::PRES_MASK[15][9][6];
31 
32 u_short fcs_trg_base::EM_HERATIO_THR ;
33 u_short fcs_trg_base::HAD_HERATIO_THR ;
34 u_short fcs_trg_base::EMTHR0 ;
35 u_short fcs_trg_base::EMTHR1 ;
36 u_short fcs_trg_base::EMTHR2 ;
37 u_short fcs_trg_base::EMTHR3 ; //obsolete for 202207
38 u_short fcs_trg_base::ELETHR0 ;
39 u_short fcs_trg_base::ELETHR1 ;
40 u_short fcs_trg_base::ELETHR2 ;
41 u_short fcs_trg_base::HADTHR0 ;
42 u_short fcs_trg_base::HADTHR1 ;
43 u_short fcs_trg_base::HADTHR2 ;
44 u_short fcs_trg_base::HADTHR3 ; //obsolete for 202207
45 u_short fcs_trg_base::JETTHR1 ; //obsolete for 202207
46 u_short fcs_trg_base::JETTHR2 ; //obsolete for 202207
47 u_short fcs_trg_base::JPATHR2 ;
48 u_short fcs_trg_base::JPATHR1 ;
49 u_short fcs_trg_base::JPATHR0 ;
50 u_short fcs_trg_base::JPBCTHR2 ;
51 u_short fcs_trg_base::JPBCTHR1 ;
52 u_short fcs_trg_base::JPBCTHR0 ;
53 u_short fcs_trg_base::JPBCTHRD ;
54 u_short fcs_trg_base::JPDETHR2 ;
55 u_short fcs_trg_base::JPDETHR1 ;
56 u_short fcs_trg_base::JPDETHR0 ;
57 u_short fcs_trg_base::JPDETHRD ;
58 u_short fcs_trg_base::ETOTTHR ;
59 u_short fcs_trg_base::HTOTTHR ;
60 u_short fcs_trg_base::EHTTHR ;
61 u_short fcs_trg_base::HHTTHR ;
62 u_short fcs_trg_base::PHTTHR ;
63 
64 u_int fcs_trg_base::data_format ;
65 
66 int fcs_trg_base::run_type ;
67 
68 
69 fcs_trg_base::fcs_trg_base()
70 {
71 // LOG(TERR,"%s (sizeof class %u)",__PRETTY_FUNCTION__,sizeof(*this)) ;
72 
73  log_level = 0 ;
74  realtime = 0 ;
75  id = 0 ;
76  sim_mode = 0 ;
77  data_format = 1 ;
78 
79  run_type = 3 ; // assume normal
80 
81  trg_xing = 5 ;
82 
83  want_stage_2_io = 0 ;
84  want_stage_3_io = 0 ;
85  want_stage_1_sim = 1 ;
86 }
87 
88 
89 fcs_trg_base::~fcs_trg_base()
90 {
91 // LOG(TERR,"%s",__PRETTY_FUNCTION__) ;
92 }
93 
94 u_int fcs_trg_base::get_version()
95 {
96  return 0x21000000 ; //YY,MM,DD,HH in BCD; 0 for base class
97 } ;
98 
99 
100 void fcs_trg_base::init(const char* fname)
101 {
102  if(id != 0) return ; // just one guy
103 
104 
105  // zap input params
106 
107  memset(stage_params,0,sizeof(stage_params)) ;
108  memset(p_g,0,sizeof(p_g)) ;
109 
110  memset(s2_ch_phase,0,sizeof(s2_ch_phase)) ;
111  memset(s2_ch_mask,0,sizeof(s2_ch_mask)) ;
112 
113  memset(s3_ch_phase,0,sizeof(s3_ch_phase)) ;
114  s3_ch_mask = 0 ;
115  s3_out_phase = 0 ;
116 
117  // and then set all gains to 1
118  for(int i=0;i<NS_COU;i++) {
119  for(int j=0;j<ADC_DET_COU;j++) {
120  for(int k=0;k<DEP_COU;k++) {
121  for(int c=0;c<32;c++) {
122  p_g[i][j][k][c].gain = (1<<8) ; // new for FY22
123 
124  }}}}
125 
126 
127  // thresholds to defaults
128  ht_threshold[0] = 90 ; // ecal
129  ht_threshold[1] = 90 ; // hcal
130  ht_threshold[2] = 45 ; // fpRE in FY19
131 
132  // since I can use fcs_trg_base in realtime, all the stuff below is already loaded
133  // if(!realtime && !sim_mode) {
134  if(!realtime) {
135  LOG(INFO,"init: not realtime -- loading stuff from files") ;
136 
137  memset(fcs_data_c::ped,0,sizeof(fcs_data_c::ped)) ;
138 
139  char rdomap[128];
140  sprintf(rdomap,"%s/fcs_daq_map.txt",fname);
141  fcs_data_c::load_rdo_map(rdomap) ;
142  fcs_data_c::gain_from_cache(fname) ;
143 
144  if(!sim_mode){ //no need for pedestal in sim_mode
145  for(int s=1;s<=1;s++) {
146  for(int r=1;r<=6;r++) {
147  char fname[256] ;
148  sprintf(fname,"/net/fcs%02d/RTScache/fcs_pedestals_s%02d_r%d.txt",s,s,r) ;
149  fcs_data_c::ped_from_cache(fname) ;
150  }
151  }
152  }
153 
154 
155  }
156  else if(!sim_mode) {
157 // LOG(TERR,"init:realtime: ht_threshold is %d",fcs_data_c::ht_threshold) ;
158 
159  for(int i=0;i<3;i++) { // known in realtime
160  ht_threshold[i] = fcs_data_c::ht_threshold ;
161  }
162  }
163 
164  for(int i=0;i<NS_COU;i++) {
165  for(int j=0;j<ADC_DET_COU;j++) {
166  for(int k=0;k<DEP_COU;k++) {
167 
168  int sec = fcs_data_c::det_map[j][i][k].sector - 1 ;
169  int rdo = fcs_data_c::det_map[j][i][k].rdo - 1 ;
170 
171  if(sec<0 || rdo<0) continue ; // protection against bad load
172 
173  for(int c=0;c<32;c++) {
174  u_short p = fcs_data_c::ped[sec][rdo].i_ped[c] ;
175  u_short g = fcs_data_c::ped[sec][rdo].i_gain[c] ;
176 
177  if(p && log_level>5 && c==0) { // just a sample, to check sanity
178  LOG(TERR,"S%d:%d: %d:%d:%d: ch %d = i_ped %d, i_gain %d",sec+1,rdo+1,j,i,k,c,p,g) ;
179  }
180 
181  //u_int mask = fcs_data_c::rdo_map[sec][rdo].ch_mask & 0xFFFFFFFFll ;
182 
183 
184  p_g[i][j][k][c].gain = fcs_data_c::ped[sec][rdo].i_gain[c] ;
185  p_g[i][j][k][c].ped = fcs_data_c::ped[sec][rdo].i_ped[c] ;
186  }
187  }}}
188 
189 
190  // BELOW depends on the length of processing so don't change!
191  // Set by Tonko
192 
193  // concrete values at e.g. 09-Dec-2021
194  marker.last_xing = 7 ; // this depends on the post setting and should be calculable
195 
196  marker.adc_start = 7 ; // fixed during board configuration
197  marker.s1_out_start = marker.adc_start + 11 ; // depends on stage_0/1 algo but pretty much fixed
198 
199  marker.s2_in_start = marker.s1_out_start + 2 ; // depends on the cable length from 1-to-2 put pretty much fixed
200  marker.s2_to_s3_start = marker.s2_in_start + 15 ; // depends on stage_2 algo?
201 
202 
203  marker.s3_in_start = marker.s2_to_s3_start + 8 ; // depends on cable length from 2-to-3; 0 in FY19
204  marker.dsm_out_start = marker.s3_in_start + 14 ; // depends on stage_3 algo
205 
206 
207  if(log_level>0) LOG(INFO,"init markers: last xing %d, ADC %d, s1_out %d, s2_in %d, s2_to_s3 %d, s3_in %d, dsm_out %d",
208  marker.last_xing,
209  marker.adc_start,
210  marker.s1_out_start,
211  marker.s2_in_start,
212  marker.s2_to_s3_start,
213  marker.s3_in_start,
214  marker.dsm_out_start) ;
215 
216 
217  // for Akio's code
218  fcs_trgDebug = 0 ;
219  fcs_readPresMaskFromText=0;
220 
221  // stage2 params (defaults are from Akio's code)
222  EM_HERATIO_THR = 32 ; // or 128*(1/4)
223  HAD_HERATIO_THR = 32 ;
224 
225  EMTHR3 = 128 ; //obsolete for 202207
226  HADTHR3 = 169 ; //obsolete for 202207
227  JETTHR2 = 128 ; //obsolete for 202207
228  JETTHR1 = 64 ; //obsolete for 202207
229 
230  //original default
231  EMTHR2 = 192 ;
232  EMTHR1 = 128 ;
233  EMTHR0 = 64 ;
234 
235  ELETHR2 = 32 ;
236  ELETHR1 = 22 ;
237  ELETHR0 = 25 ;
238 
239  HADTHR2 = 192 ;
240  HADTHR1 = 128 ;
241  HADTHR0 = 64 ;
242 
243  JPATHR2 = 254 ;
244  JPATHR1 = 192 ;
245  JPATHR0 = 128 ;
246  JPBCTHR2 = 254 ;
247  JPBCTHR1 = 192 ;
248  JPBCTHR0 = 128 ;
249  JPBCTHRD = 160 ;
250  JPDETHR2 = 254 ;
251  JPDETHR1 = 192 ;
252  JPDETHR0 = 128 ;
253  JPDETHRD = 160 ;
254 
255  ETOTTHR = 32 ;
256  HTOTTHR = 32 ;
257  EHTTHR = 50 ;
258  HHTTHR = 50 ;
259  PHTTHR = 100 ; //stage1
260 
261  if(sim_mode){
262  ht_threshold[0]=EHTTHR;
263  ht_threshold[1]=HHTTHR;
264  ht_threshold[2]=PHTTHR;
265  }
266 
267  // IMPORTANT: Requested Stage_x versions defaults
268  // Either set by the user to her/his wishes or picked up from the DAQ file
269  stage_version[0] = 2 ;
270  stage_version[1] = 1 ;
271  stage_version[2] = 7 ;
272  stage_version[3] = 7 ;
273 
274  // DEP/Trigger masks
275  //s3_ch_mask = (1<<2) ; // South 0
276  //s2_ch_mask[0] = 0 ; // Nothing in North
277  //s2_ch_mask[1] = (1<<3) ; // just 1 fPRE channel in South for early FY19
278 }
279 
280 
281 void fcs_trg_base::run_start(u_int run)
282 {
283  run_number = run ;
284  evts = 0 ;
285 
286  memset(&errs,0,sizeof(errs)) ;
287  memset(&good,0,sizeof(good)) ;
288  memset(&statistics,0,sizeof(statistics)) ;
289 
290  // cleanup, just in case
291  memset(d_in,0,sizeof(d_in));
292  memset(&d_out,0,sizeof(d_out));
293 
294  start_event() ; // just in case
295 
296  if(sim_mode) {
297  marker.adc_start = 0 ;
298  marker.last_xing = 1 ;
299  }
300 
301  LOG(INFO,"%d: starting run %08u, realtime %d, sim_mode %d",id,run_number,realtime,sim_mode) ;
302 
303  return ;
304 }
305 
306 
307 void fcs_trg_base::start_event()
308 {
309  got_one = 0 ;
310 
311  memset(tb_cou,0,sizeof(tb_cou)) ;
312 
313  if(sim_mode) { // only for simulated data
314  memset(d_in,0,sizeof(d_in)); //akio?
315  }
316 } ;
317 
318 
319 void fcs_trg_base::fill_event(int det, int ns, int dep, int c, u_short *d16, int t_cou)
320 {
321 
322  if(t_cou) {
323  if(got_one==0) {
324  evts++ ;
325  got_one = 1 ;
326  }
327  }
328  else return ;
329 
330  //printf("... tb_cou %d %d %d: %d\n",ns,det,dep,t_cou) ;
331 
332  tb_cou[ns][det][dep] = t_cou ;
333 
334  // various markers
335  int is_self = -1 ;
336  int is_tcd = -1 ;
337 
338  for(int t=0;t<t_cou;t++) {
339  int dta = d16[t] & 0xFFF ;
340  int fla = d16[t] >> 12 ;
341 
342  int xing ;
343  int xou ;
344  int tix ;
345 
346  if(log_level>100) printf("%d:%d:%d ch %d: tb %d: ADC %d, fla %d\n",
347  ns,det,dep,c,t,dta,fla) ;
348 
349  if(det != 3) { // DEP/ADC
350  if(c==32) { // stage_1 out data
351  tix = t - marker.s1_out_start ;
352  xing = tix/8 ;
353  xou = tix%8 ;
354 
355  if(dta && log_level>10) {
356  printf("s1 out: %d:%d:%d -- at xing %d:%d(%d) = %d\n",ns,det,dep,xing,xou,t,dta) ;
357  }
358 
359  if(tix>=0 && xing<XING_COU) {
360  // data stage_1 out
361  d_in[xing].s1[ns][det][dep].s1_to_s2.d[xou] = dta ;
362  }
363  }
364  else { // raw ADC data
365  tix = t - marker.adc_start ;
366  xing = tix/8 ;
367  xou = tix%8 ;
368 
369  if(tix>=0 && xing<XING_COU) {
370  // actual ADC data
371  d_in[xing].s1[ns][det][dep].adc[c].d[xou] = dta ;
372  }
373 
374  switch(data_format) {
375  case 0 : // some old shit -- ignore
376  if(c==0 && (fla & 0x1)) {
377 
378 
379  if(is_tcd < 0) is_tcd = t ;
380 
381  if(log_level > 101) {
382  printf("ADC tcd_marker -- at xing %d:%d(%d)\n",xing,xou,t) ;
383  }
384 
385  }
386 
387  if(c==0 && (fla & 0x2)) {
388 
389  if(is_self < 0) is_self = t ;
390 
391  if(log_level>101) {
392  printf("ADC self_trg -- at xing %d:%d(%d)\n",xing,xou,t) ;
393  }
394  }
395 
396  break ;
397  case 1 : //FY21
398 
399  if(c==3 && (fla&4)) {
400 
401  if(is_tcd < 0) is_tcd = t ;
402 
403  if(log_level > 101) {
404  printf("ADC tcd_marker -- at xing %d:%d(%d)\n",xing,xou,t) ;
405  }
406 
407  }
408 
409  if(c==1 && (fla&4)) {
410  if(is_self < 0) is_self = t ;
411 
412  if(log_level>101) {
413  printf("ADC self_trg -- at xing %d:%d(%d)\n",xing,xou,t) ;
414  }
415  }
416 
417 
418  break ;
419  }
420 
421  }
422  }
423  else if(dep==0) { // FY21 stage 3
424  switch(c) {
425  case 4 : // dsm out lo 8 bits
426  tix = t - marker.dsm_out_start ;
427 
428  xing = tix/8 ;
429  xou = tix%8 ;
430 
431  if(tix>=0 && xing<XING_COU) {
432  d_in[xing].s3.dsm_out.d[xou] = dta & 0xFF ; // link
433  }
434  break ;
435  case 5 : // DSM out hi 8 bits
436  tix = t - marker.dsm_out_start ;
437 
438  xing = tix/8 ;
439  xou = tix%8 ;
440 
441 
442  if(tix>=0 && xing<XING_COU) {
443  d_in[xing].s3.dsm_out.d[xou] |= (dta & 0xFF)<<8 ;
444  }
445  break ;
446  default :
447  tix = t - marker.s3_in_start ;
448 
449  xing = tix/8 ;
450  xou = tix%8 ;
451 
452  if(tix>=0 && xing<XING_COU) {
453  d_in[xing].s3.s3_from_s2[c].d[xou] = dta & 0xFF ;
454  }
455 
456 
457  break ;
458  }
459  }
460  else { // Stage 2
461  switch(c) {
462  case 34 : // s2_to_s3
463  case 35 :
464  tix = t - marker.s2_to_s3_start ;
465 
466  xing = tix/8 ;
467  xou = tix%8 ;
468 
469  if(tix>=0 && xing<XING_COU) {
470  // I had to remap this because the stage3 input is _swapped_
471  // S6:34 is S5:1
472  // S6:35 is S5:0
473  // S7:34 is S5:3
474  // S7:35 is S5:2
475  //int cc = (c==34?1:0) ;
476  //d_in[xing].s2[ns].s2_to_s3[cc].d[xou] = dta & 0xFF ;
477 
478  d_in[xing].s2[ns].s2_to_s3[c-34].d[xou] = dta & 0xFF ;
479  }
480  break ;
481  case 36 : // new in FY22
482  //tix = t - (marker.s2_to_s3_start - 1) ; // adjusted by hand!
483  tix = t - marker.dsm_out_start ; // same as S3 to DSM!
484 
485  xing = tix/8 ;
486  xou = tix%8 ;
487 
488  if(tix>=0 && xing<XING_COU) {
489  d_in[xing].s2[ns].s2_to_dsm.d[xou] = dta & 0xFF ;
490  }
491  break ;
492 
493  break ; // for now
494  default :
495  tix = t - marker.s2_in_start ;
496 
497  xing = tix/8 ;
498  xou = tix%8 ;
499 
500  if(tix>=0 && xing<XING_COU) {
501  d_in[xing].s2[ns].s2_from_s1[c].d[xou] = dta & 0xFF ;
502  }
503 
504  break ;
505  }
506  }
507  }
508 
509  // this generally is nonsense because we have many boards...
510  if(is_self>0) {
511  statistics.self_trgs++ ;
512  statistics.self_trg_marker = is_self ;
513  }
514 
515  if(is_tcd > 0) {
516  statistics.tcd_marker = is_tcd ;
517  }
518 
519 } ;
520 
521 int fcs_trg_base::end_event()
522 {
523  event_bad = 0 ;
524 
525  s2_io_ns_bad = 0 ;
526  s2_io_ch_bad = 0 ;
527 
528  s3_io_ch_bad = 0 ;
529 
530  s1_dep_bad = 0 ;
531  s1_det_bad = 0 ;
532  s1_ns_bad = 0 ;
533 
534  s2_ns_bad = 0 ;
535  s2_ch_bad = 0 ;
536 
537  s3_to_dsm = s2_to_dsm[0] = s2_to_dsm[1] = 0 ;
538 
539  if(!got_one) return 0 ; // nothing to do; let's not waste time
540 
541  verify_event_io() ; // verify interconnectivity
542 
543  self_trigger = 0 ;
544 
545  s3_to_dsm = d_in[trg_xing].s3.dsm_out.d[0] ;
546  s2_to_dsm[0] = d_in[trg_xing].s2[0].s2_to_dsm.d[0] ;
547  s2_to_dsm[1] = d_in[trg_xing].s2[1].s2_to_dsm.d[0] ;
548 
549  for(int xing=0;xing<marker.last_xing;xing++) {
550  if(log_level>1) {
551  LOG(NOTE,"run_event_sim: xing %d",xing) ;
552  }
553 
554  dsmout = run_event_sim(xing,sim_mode) ;
555 
556  if(sim_mode) { // when running offline
557  dump_event_sim(xing) ;
558  }
559  else {
560  verify_event_sim(xing) ;
561  }
562  }
563 
564  return dsmout;
565 }
566 
567 int fcs_trg_base::run_stop()
568 {
569  int err = 0 ;
570 
571  for(int i=0;i<4;i++) {
572  if(errs.io_s1_to_s2[i]) err |= 1 ;
573  }
574 
575  if(errs.io_s2_to_s3) err |= 1 ;
576 
577  if(errs.sim_s1 || errs.sim_s2 || errs.sim_s3) {
578  err |= 2 ;
579  }
580 
581  LOG(INFO,"thread %d: self_trg_marker %d, tcd_marker %d",id,statistics.self_trg_marker,statistics.tcd_marker) ;
582 
583  if(err) {
584  if(run_type==3 || (err&1)) { // normal run or IO
585  LOG(ERR,"thread %d: %d/%d events in run %d: errs sim %u %u %u; io [%u %u %u %u] %u",id,
586  statistics.self_trgs,
587  evts,run_number,
588  errs.sim_s1,
589  errs.sim_s2,
590  errs.sim_s3,
591  errs.io_s1_to_s2[0],errs.io_s1_to_s2[1],errs.io_s1_to_s2[2],errs.io_s1_to_s2[3],
592  errs.io_s2_to_s3) ;
593  }
594  else {
595  LOG(WARN,"thread %d: %d/%d events in run %d: errs sim %u %u %u; io [%u %u %u %u] %u",id,
596  statistics.self_trgs,
597  evts,run_number,
598  errs.sim_s1,
599  errs.sim_s2,
600  errs.sim_s3,
601  errs.io_s1_to_s2[0],errs.io_s1_to_s2[1],errs.io_s1_to_s2[2],errs.io_s1_to_s2[3],
602  errs.io_s2_to_s3) ;
603 
604  }
605 
606  }
607 
608  LOG(INFO,"thread %d: %d/%d events in run %d: good sim %u %u %u; io [%u %u %u %u] %u",id,
609  statistics.self_trgs,
610  evts,run_number,
611  good.sim_s1,
612  good.sim_s2,
613  good.sim_s3,
614  good.io_s1_to_s2[0],good.io_s1_to_s2[1],good.io_s1_to_s2[2],good.io_s1_to_s2[3],
615  good.io_s2_to_s3) ;
616 
617 
618  return 0 ;
619 }
620 
621 // verify the IO parts of the event, various links
622 int fcs_trg_base::verify_event_io()
623 {
624  int printed = 0 ;
625  int bad = 0 ;
626 
627  // Stage 1 to Stage 2 DEPs: but ONLY if I have the whole event!!!
628  if(!want_stage_2_io) goto stage_3 ;
629 
630 
631  for(int x=0;x<marker.last_xing;x++) {
632  for(int t=0;t<8;t++) {
633  for(int ns=0;ns<2;ns++) {
634  int s2_from_s1[34] ;
635  int s1_to_s2[34] ;
636  int ix = 0 ;
637 
638  long mask = 0 ;
639 
640  int cns ;
641 
642  if(ns==0) cns='N' ;
643  else cns = 'S' ;
644 
645  //LOG(TERR,"xing %d, t %d, ns %d = %d",x,t,ns,tb_cou[ns][3][1]) ;
646 
647  //watch it!
648  //if(tb_cou[ns][3][1]==0) continue ; // no stage_2
649 
650  for(int i=0;i<34;i++) {
651  s2_from_s1[i] = d_in[x].s2[ns].s2_from_s1[i].d[t] ;
652  }
653 
654 
655  // ECAL
656  //LOG(TERR," %d %d %d %d",
657  // tb_cou[ns][0][0],
658  // tb_cou[ns][0][0],
659  // tb_cou[ns][0][0],
660  // tb_cou[ns][0][0]) ;
661 
662  for(int d=0;d<20;d++) {
663  if(tb_cou[ns][0][d]) mask |= (1ll<<ix) ;
664  s1_to_s2[ix] = d_in[x].s1[ns][0][d].s1_to_s2.d[t] ;
665  ix++ ;
666  }
667 
668  // HCAL
669  for(int d=0;d<8;d++) {
670  if(tb_cou[ns][1][d]) mask |= (1ll<<ix) ;
671  s1_to_s2[ix] = d_in[x].s1[ns][1][d].s1_to_s2.d[t] ;
672  ix++ ;
673  }
674 
675  // FPRE
676  for(int d=0;d<6;d++) {
677  if(tb_cou[ns][2][d]) mask |= (1ll<<ix) ;
678  s1_to_s2[ix] = d_in[x].s1[ns][2][d].s1_to_s2.d[t] ;
679  ix++ ;
680  }
681 
682 
683 
684 
685  if(mask != 0 && log_level>1) LOG(WARN,"xing %d:%d, ns %d: mask 0x%llX, ix %d",x,t,ns,mask,ix) ;
686 
687  for(int i=0;i<34;i++) {
688  // watch it!
689  //if(mask & (1ll<<i)) ;
690  //else continue ;
691 
692  // separate mask
693  if(s2_ch_mask[ns] & (1ll<<i)) continue ;
694 
695  if(s2_from_s1[i] || s1_to_s2[i]) {
696  //printf("... xing %d:%d, ns %d: %d: s2_in 0x%02X, s1_out 0x%02X\n",x,t,ns,i,s2_from_s1[i],s1_to_s2[i]) ;
697  }
698 
699  if(s2_from_s1[i] != s1_to_s2[i]) {
700  event_bad |= 0x10 ;
701 
702  s2_io_ns_bad = ns ;
703  s2_io_ch_bad = i ;
704 
705  if(log_level>0) LOG(ERR,"evt %d: S1_to_S2 IO: NS %c: ch %d: xing %d:%d: out 0x%02X, in 0x%02X",
706  evts,cns,i,x,t,s1_to_s2[i],s2_from_s1[i]) ;
707 
708  if(ns==0 && i<17) errs.io_s1_to_s2[0]++ ;
709  else if(ns==0) errs.io_s1_to_s2[1]++ ;
710  else if(ns==1 && i<17) errs.io_s1_to_s2[2]++ ;
711  else errs.io_s1_to_s2[3]++ ;
712 
713  }
714  else {
715  if(ns==0 && i<17) good.io_s1_to_s2[0]++ ;
716  else if(ns==0) good.io_s1_to_s2[1]++ ;
717  else if(ns==1 && i<17) good.io_s1_to_s2[2]++ ;
718  else good.io_s1_to_s2[3]++ ;
719 
720  }
721  }
722 
723  }
724  }
725  }
726 
727  stage_3:
728 
729  if(!want_stage_3_io) goto end ;
730 
731  // Stage 2 to Stage 3: but only if I have Stage_2 and Stage_3 DEPs in the data
732  for(int x=0;x<marker.last_xing;x++) {
733 
734  if(tb_cou[0][3][0]==0) continue ; // no stage_3 at all
735 
736  for(int c=0;c<4;c++) {
737  int cc = c%2 ;
738 
739  if(tb_cou[c/2][3][1]==0) continue ;
740  int err = 0 ;
741 
742 #if 0 // need to remap
743  switch(c) {
744  case 0 :
745  case 2 :
746  cc = 1 ;
747  break ;
748  case 1 :
749  case 3 :
750  cc = 0 ;
751  break ;
752  }
753 #endif
754  for(int t=0;t<8;t++) {
755  int s3_from_s2 = d_in[x].s3.s3_from_s2[c].d[t] ;
756  int s2_to_s3 = d_in[x].s2[c/2].s2_to_s3[cc].d[t] ;
757 
758  if(s2_to_s3 != s3_from_s2) {
759  event_bad |= 0x20 ;
760 
761  s3_io_ch_bad = c ;
762 
763  errs.io_s2_to_s3++ ;
764  err = 1 ;
765  }
766  else {
767  good.io_s2_to_s3++ ;
768  }
769  }
770 
771  if(err==1 && log_level>0) {
772  for(int t=0;t<8;t++) {
773  char ctmp ;
774 
775  int s3_from_s2 = d_in[x].s3.s3_from_s2[c].d[t] ;
776  int s2_to_s3 = d_in[x].s2[c/2].s2_to_s3[cc].d[t] ;
777 
778  if(s2_to_s3 != s3_from_s2) ctmp = '*' ;
779  else ctmp = ' ' ;
780 
781  LOG(ERR,"evt %d: S3 IO: ch %d: xing %d:%d: in S3 0x%02X, out of S2 0x%02X%c",
782  evts,c,x,t,
783  s3_from_s2,s2_to_s3,ctmp) ;
784  }
785 
786  }
787  }
788  }
789 
790  end:;
791 
792 
793  if(printed) fflush(stdout) ;
794 
795 
796 
797  return bad ;
798 }
799 
800 int fcs_trg_base::dump_event_sim(int xing)
801 {
802  // verify stage_1 data
803 
804  for(int i=0;i<NS_COU;i++) {
805  for(int j=0;j<ADC_DET_COU;j++) {
806  for(int k=0;k<DEP_COU;k++) {
807 
808  //if(tb_cou[i][j][k]==0) continue ; // not in the daat...
809 
810  for(int t=0;t<8;t++) {
811  int d_sim = d_out.s1[i][j][k].s1_to_s2.d[t] ;
812 
813  if(d_sim && fcs_trgDebug>0)
814  printf("S1 sim: %d:%d:%d - xing %d:%d, dta %d\n",
815  i,j,k,xing,t,d_sim) ;
816  }
817  }
818  }
819  }
820 
821 
822  // verify stage_2 data locally to stage_2 DEP
823  for(int i=0;i<NS_COU;i++) {
824  for(int j=0;j<2;j++) {
825 
826 
827  for(int t=0;t<8;t++) {
828  int d_sim = d_out.s2[i].s2_to_s3[j].d[t] ;
829 
830  if(fcs_trgDebug>0)
831  printf("S2 sim: %d:%d - xing %d:%d, dta 0x%03X\n",
832  i,j,xing,t,d_sim) ;
833  }
834  }
835  }
836 
837  //printf("S3 sim: to DSM 0x%04X\n",d_out.s3.dsm_out) ;
838 
839  return 0 ;
840 }
841 
842 
843 int fcs_trg_base::verify_event_sim(int xing)
844 {
845  int bad = 0 ;
846 
847  // class vars
848 
849  // verify stage_1 data
850 
851  int s1_failed = 0 ;
852  int s2_failed = 0 ;
853  int s3_failed = 0 ;
854 
855  if(!want_stage_1_sim) goto skip_stage1 ;
856 
857  for(int i=0;i<NS_COU;i++) {
858  int cns ;
859 
860  if(i==0) cns='N' ;
861  else cns='S' ;
862 
863  for(int j=0;j<ADC_DET_COU;j++) {
864  int cdet ;
865 
866  switch(j) {
867  case 0 :
868  cdet='E' ;
869  break ;
870  case 1 :
871  cdet='H' ;
872  break ;
873  case 2 :
874  cdet='F' ;
875  break ;
876  }
877 
878  for(int k=0;k<DEP_COU;k++) {
879  int want_print = 0 ;
880  int want_log = 0 ;
881 
882  if(tb_cou[i][j][k]==0) continue ; // not in the daat...
883 
884 
885  for(int t=0;t<8;t++) {
886  int d_sim = d_out.s1[i][j][k].s1_to_s2.d[t] ;
887  int d_i = d_in[xing].s1[i][j][k].s1_to_s2.d[t] ;
888 
889  if(d_sim != d_i) {
890  s1_failed = 1 ;
891  errs.sim_s1++ ;
892 
893  s1_dep_bad = k ;
894  s1_det_bad = j ;
895  s1_ns_bad = i ;
896 
897  want_log = 1 ;
898  bad++ ;
899  }
900  else {
901  good.sim_s1++ ;
902  }
903 
904  if(d_i || d_sim) {
905  want_print = 1 ;
906  }
907 
908  }
909 
910 
911  for(int t=0;t<8;t++) {
912  int d_sim = d_out.s1[i][j][k].s1_to_s2.d[t] ;
913  int d_i = d_in[xing].s1[i][j][k].s1_to_s2.d[t] ;
914 
915  if(want_log && log_level>0) {
916  LOG(ERR,"evt %d: S1 sim: %c:%c:%d - xing %d:%d: sim 0x%02X, dta 0x%02X %c",evts,cns,cdet,k,
917  xing,t,
918  d_sim,
919  d_i,d_sim!=d_i?'*':' ') ;
920  }
921 
922  if(want_print && log_level>3) {
923  printf("S1: %d:%d:%d - xing %d:%d: s1 sim %d, dta %d %s\n",i,j,k,
924  xing,t,
925  d_sim,
926  d_i,want_log?"ERROR":"") ;
927  }
928  }
929 
930  if(want_log && log_level>4) {
931  u_int s1_bits = 0 ;
932  for(int c=0;c<32;c++) {
933  int sum = 0 ;
934  for(int t=0;t<8;t++) {
935  sum += d_in[xing].s1[i][j][k].adc[c].d[t] ;
936  LOG(ERR,"ch %2d: t %d: dta %d",c,t,d_in[xing].s1[i][j][k].adc[c].d[t]) ;
937  }
938 
939  //LOG(ERR," sum %d, ped %d, sum-ped %d, ht thresh %d",sum,p_g[i][j][k][c].ped,sum-p_g[i][j][k][c].ped,ht_threshold[j]) ;
940  sum -= p_g[i][j][k][c].ped ;
941  if(sum > ht_threshold[j]) s1_bits |= (1<<c) ;
942  }
943  LOG(ERR," s1_bits 0x%08X",s1_bits) ;
944  }
945 
946  }}}
947 
948  skip_stage1: ;
949 
950  if(s1_failed) {
951  event_bad |= 1 ;
952  }
953 
954  // verify stage_2 data locally to stage_2 DEP
955  for(int i=0;i<NS_COU;i++) {
956 
957  int cns ;
958 
959  if(i==0) cns = 'N' ;
960  else cns = 'S' ;
961 
962 #if 1
963  // check S2-to-DSM
964  for(int j=0;j<1;j++) {
965  int want_print = 0 ;
966  int want_log = 0 ;
967 
968  if(tb_cou[i][3][1]==0) continue ; // no stage_2 in data
969 
970  for(int t=0;t<4;t++) { // just the first 4
971  int d_sim = d_out.s2[i].s2_to_dsm ;
972  int d_i = d_in[xing].s2[i].s2_to_dsm.d[t] ;
973 
974  if(d_sim != d_i) {
975  errs.sim_s2++ ;
976  s2_failed = 1 ;
977  event_bad |= 8 ;
978 
979  s2_ns_bad = i ;
980  s2_ch_bad = j ;
981 
982  want_log = 1 ;
983  bad++ ;
984  }
985  else {
986  good.sim_s2++ ;
987  }
988 
989  if(d_i || d_sim) {
990  want_print = 1 ;
991  }
992  }
993 
994  for(int t=0;t<4;t++) {
995  char ctmp = ' ' ;
996 
997  int d_sim = d_out.s2[i].s2_to_dsm ;
998  int d_i = d_in[xing].s2[i].s2_to_dsm.d[t] ;
999 
1000  if(d_sim != d_i) ctmp = '*' ;
1001 
1002  if(want_log && log_level>0) {
1003  LOG(ERR,"evt %d: S2_to_DSM sim: %c - xing %d:%d: sim 0x%02X, dta 0x%02X%c",evts,cns,
1004  xing,t,
1005  d_sim,
1006  d_i,ctmp) ;
1007  }
1008 
1009  if(want_print && log_level>3) {
1010  printf("evt %d: S2_to_DSM sim: %c: - xing %d:%d: sim %d, dta %d %s\n",evts,cns,
1011  xing,t,
1012  d_sim,
1013  d_i,want_log?"ERROR":"") ;
1014  }
1015  }
1016 
1017 
1018  }
1019 #endif
1020 
1021  for(int j=0;j<2;j++) {
1022  int want_print = 0 ;
1023  int want_log = 0 ;
1024 
1025  if(tb_cou[i][3][1]==0) continue ; // no stage_2 in data
1026 
1027  for(int t=0;t<7;t++) { // skip 0xABCD
1028  int d_sim = d_out.s2[i].s2_to_s3[j].d[t] ;
1029  int d_i = d_in[xing].s2[i].s2_to_s3[j].d[t] ;
1030 
1031  if(d_sim != d_i) {
1032  errs.sim_s2++ ;
1033  s2_failed = 1 ;
1034  event_bad |= 2 ;
1035 
1036  s2_ns_bad = i ;
1037  s2_ch_bad = j ;
1038 
1039  want_log = 1 ;
1040  bad++ ;
1041  }
1042  else {
1043  good.sim_s2++ ;
1044  }
1045 
1046  if(d_i || d_sim) {
1047  want_print = 1 ;
1048  }
1049  }
1050 
1051  for(int t=0;t<8;t++) {
1052  char ctmp = ' ' ;
1053 
1054  int d_sim = d_out.s2[i].s2_to_s3[j].d[t] ;
1055  int d_i = d_in[xing].s2[i].s2_to_s3[j].d[t] ;
1056 
1057  if(d_sim != d_i) ctmp = '*' ;
1058 
1059  if(want_log && log_level>0) {
1060  LOG(ERR,"evt %d: S2 sim: %c:%d - xing %d:%d: sim 0x%02X, dta 0x%02X%c",evts,cns,j,
1061  xing,t,
1062  d_sim,
1063  d_i,ctmp) ;
1064  }
1065 
1066  if(want_print && log_level>3) {
1067  printf("evt %d: S2 sim: %c:%d: - xing %d:%d: sim %d, dta %d %s\n",evts,cns,j,
1068  xing,t,
1069  d_sim,
1070  d_i,want_log?"ERROR":"") ;
1071  }
1072  }
1073 
1074 
1075  }}
1076 
1077 
1078 // if(s2_failed) {
1079 // event_bad |= 2 ;
1080 // }
1081 
1082  // verify stage_3 locally to stage_2 DEP
1083  if(tb_cou[0][3][0]==0) return bad ; // no stage_3 in data
1084 
1085 
1086 
1087  int want_log = 0 ;
1088  int want_print = 0 ;
1089 
1090  for(int t=0;t<4;t++) { // not that we look at only the first 4 timebins because the other 4 are 0 in FPGA
1091  int d_sim = d_out.s3.dsm_out ;
1092  int d_i = d_in[xing].s3.dsm_out.d[t] ;
1093 
1094 
1095  if(d_sim || d_i) want_print = 1 ;
1096 
1097  // 24-Feb-21 hack to remove the free-running bit
1098  //d_i &= 0xFFFB ;
1099 
1100  if(d_sim != d_i) {
1101  errs.sim_s3++ ;
1102  s3_failed = 1 ;
1103  bad++ ;
1104  want_log = 1 ;
1105  }
1106  else {
1107  good.sim_s3++ ;
1108  }
1109  }
1110 
1111  // in case I want printouts
1112  for(int t=0;t<4;t++) {
1113  int d_sim = d_out.s3.dsm_out ;
1114  int d_i = d_in[xing].s3.dsm_out.d[t] ;
1115 
1116  if(want_log && log_level>0) {
1117  LOG(ERR,"evt %d: S3 sim: xing %d:%d: sim 0x%04X, dta 0x%04X %s",evts,xing,t,
1118  d_sim,d_i,want_log?"ERROR":"") ;
1119 
1120  }
1121  if(want_print && log_level > 3) {
1122  printf("evt %d: S3 sim: xing %d:%d: sim 0x%04X, dta 0x%04X %s\n",evts,xing,t,
1123  d_sim,d_i,want_log?"ERROR":"") ;
1124  }
1125  }
1126 
1127 
1128  if(s3_failed) {
1129  event_bad |= 4 ;
1130  }
1131 
1132  return bad ;
1133 }
1134 
1135 // Main routine to run the simulations
1136 // type==0 if we only want to compare data from actual DAQ files
1137 // type==1 if this is a GEANT simulation and there are no actual DEP boards
1138 
1139 //u_short fcs_trg_base::run_event_sim(int xing, int type)
1140 u_int fcs_trg_base::run_event_sim(int xing, int type)
1141 {
1142  geom_t geo ;
1143 
1144  if(type) {
1145  memset(&d_out,0,sizeof(d_out)) ;
1146  }
1147 
1148  dbg_xing = xing ;
1149 
1150  for(int i=0;i<NS_COU;i++) { // NS
1151  geo.ns = i ;
1152 
1153  // for stage_2
1154  link_t ecal_in[DEP_ECAL_COU] ;
1155  link_t hcal_in[DEP_HCAL_COU] ;
1156  link_t fpre_in[DEP_PRE_COU] ;
1157 
1158  for(int j=0;j<ADC_DET_COU;j++) { // DET
1159  geo.det = j ;
1160 
1161  for(int k=0;k<DEP_COU;k++) { // DEP/ADC
1162  u_int s0_to_s1[32] ;
1163 
1164  if(tb_cou[i][j][k]==0) continue ; // this DEP/ADC wasn't filled
1165 
1166  geo.dep = k ;
1167 
1168  //if(realtime && (dep != k)) continue ;
1169 
1170  for(int c=0;c<32;c++) { // channel
1171  geo.ch = c ;
1172 
1173  u_int res ;
1174 
1175  stage_0(d_in[xing].s1[i][j][k].adc[c],geo,&(p_g[i][j][k][c]),&res) ;
1176 
1177  s0_to_s1[c] = res ;
1178 
1179  if(log_level>100) printf("... S0: xing %d: %d:%d:%d: ch %d = %d (ADC %d) (ped %d, gain %d) %s\n",xing,i,j,k,c,res,
1180  d_in[xing].s1[i][j][k].adc[c].d[0],
1181  p_g[i][j][k][c].ped,p_g[i][j][k][c].gain,
1182  res?"S1_HIT":"") ;
1183 
1184  if(log_level>101) {
1185  int sum = 0 ;
1186  for(int t=0;t<8;t++) {
1187  sum += d_in[xing].s1[i][j][k].adc[c].d[t] ;
1188  printf(" ADC %d = %d [sum %d, delta %d]\n",t,d_in[xing].s1[i][j][k].adc[c].d[t],sum,sum-p_g[i][j][k][c].ped) ;
1189  }
1190 
1191  printf("SSS0: %d %d %d %d %d\n",j,i,k,c,sum-p_g[i][j][k][c].ped) ;
1192  }
1193  }
1194 
1195  // so that we compare d_out.s1_to_s2 and d_in.s1_to_s2
1196  stage_1(s0_to_s1, geo, &d_out.s1[i][j][k].s1_to_s2) ;
1197 
1198  }
1199  }
1200 
1201  geo.det = 3 ;
1202  geo.dep = 1 ; // stage_2's
1203  geo.ch = 0 ; // ignored
1204 
1205  if(type==0) { // running in realtime or through DAQ file
1206  if(tb_cou[i][3][1]==0) continue ; // DEP/Stage_2 wasn't filled
1207 
1208  memset(ecal_in,0,sizeof(ecal_in)) ; //akio
1209  memset(hcal_in,0,sizeof(hcal_in)) ; //akio
1210  memset(fpre_in,0,sizeof(fpre_in)) ;
1211 
1212  for(int j=0;j<20;j++) {
1213  ecal_in[j] = d_in[xing].s2[i].s2_from_s1[j] ;
1214  }
1215  for(int j=0;j<8;j++) {
1216  hcal_in[j] = d_in[xing].s2[i].s2_from_s1[20+j] ;
1217  }
1218  for(int j=0;j<6;j++) {
1219  fpre_in[j] = d_in[xing].s2[i].s2_from_s1[28+j] ;
1220  }
1221 
1222  stage_2(ecal_in, hcal_in, fpre_in, geo, d_out.s2[i].s2_to_s3, &d_out.s2[i].s2_to_dsm) ;
1223  }
1224  else { // GEANT-like simulation
1225 
1226  for(int c=0;c<DEP_ECAL_COU;c++) {
1227  ecal_in[c] = d_out.s1[i][0][c].s1_to_s2 ;
1228  }
1229  for(int c=0;c<DEP_HCAL_COU;c++) {
1230  hcal_in[c] = d_out.s1[i][1][c].s1_to_s2 ; // FY19 fPRE
1231  }
1232  for(int c=0;c<DEP_PRE_COU;c++) {
1233  fpre_in[c] = d_out.s1[i][2][c].s1_to_s2 ; // FY19 fPRE
1234  }
1235 
1236  stage_2(ecal_in, hcal_in, fpre_in, geo, d_out.s2[i].s2_to_s3, &d_out.s2[i].s2_to_dsm) ;
1237  }
1238  }
1239 
1240 
1241  // stage_3
1242  geo.det = 3 ;
1243  geo.ns = 0 ;
1244  geo.dep = 0 ;
1245  geo.ch = 0 ;
1246 
1247  link_t l_in[4] ;
1248 
1249  if(type==0) { // from actual SFS file
1250  if(tb_cou[0][3][0]==0) return 0 ; // no stage_3 data present
1251 
1252  l_in[0] = d_in[xing].s3.s3_from_s2[0] ;
1253  l_in[1] = d_in[xing].s3.s3_from_s2[1] ;
1254  l_in[2] = d_in[xing].s3.s3_from_s2[2] ;
1255  l_in[3] = d_in[xing].s3.s3_from_s2[3] ;
1256 
1257  stage_3(l_in,&d_out.s3.dsm_out) ;
1258 
1259  }
1260  else {
1261 
1262 
1263  l_in[0] = d_out.s2[0].s2_to_s3[0] ;
1264  l_in[1] = d_out.s2[0].s2_to_s3[1] ;
1265  l_in[2] = d_out.s2[1].s2_to_s3[0] ;
1266  l_in[3] = d_out.s2[1].s2_to_s3[1] ;
1267 
1268  stage_3(l_in,&d_out.s3.dsm_out) ;
1269  }
1270 
1271  // return d_out.s3.dsm_out ; // not that the return is the _simulated_ DSM
1272  return d_out.s3.dsm_out
1273  + ((int)(d_out.s2[0].s2_to_dsm & 0xFF) << 16)
1274  + ((int)(d_out.s2[1].s2_to_dsm & 0xFF) << 24);
1275 
1276 }
1277 
1278 
1279 
1280 
1281 void fcs_trg_base::stage_0(adc_tick_t adc, geom_t geo, ped_gain_t *pg, u_int *dta_out)
1282 {
1283  switch(stage_version[0]) {
1284  case 0 :
1285  stage_0_201900(adc, geo, pg, dta_out) ;
1286  break ;
1287  case 1 :
1288  stage_0_202101(adc, geo, pg, dta_out) ;
1289  break ;
1290  case 2 :
1291  stage_0_202103(adc, geo, pg, dta_out) ;
1292  break ;
1293  case 3 : // current at start of FY22
1294  stage_0_202109(adc, geo, pg, dta_out) ;
1295  break ;
1296  default :
1297  *dta_out = 0 ;
1298  LOG(ERR,"stage_0: unknown version %d",stage_version[0]) ;
1299  }
1300 }
1301 
1302 
1303 
1304 
1305 void fcs_trg_base::stage_1(u_int s0[], geom_t geo, link_t *output)
1306 {
1307 
1308  switch(stage_version[1]) {
1309  case 0 :
1310  stage_1_201900(s0,geo,output) ;
1311  break ;
1312  case 1 : // at start of FY22
1313  stage_1_202201(s0,geo,output) ;
1314  break ;
1315  default :
1316  LOG(ERR,"Unknown stage_1 version %d",stage_version[1]) ;
1317  break ;
1318  }
1319 }
1320 
1321 
1322 // 2 links are output: lo & hi
1323 void fcs_trg_base::stage_2(link_t ecal[], link_t hcal[], link_t pres[], geom_t geo, link_t output[2], u_short* s2_to_dsm)
1324 {
1325  switch(stage_version[2]) {
1326  case 0 :
1327  stage_2_201900(ecal,hcal,pres,geo,output) ;
1328  break ;
1329  case 1 :
1330  stage_2_202201(ecal,hcal,pres,geo,output) ;
1331  break ;
1332  case 2 :
1333  stage_2_TAMU_202202(ecal,hcal,pres,geo,output) ;
1334  break ;
1335  case 3 : // at start of FY22
1336  stage_2_202203(ecal,hcal,pres,geo,output) ;
1337  break ;
1338  case 4 :
1339  stage_2_JP6_202204(ecal,hcal,pres,geo,output) ;
1340  break ;
1341  case 5 :
1342  stage_2_JP6Carl_202205(ecal,hcal,pres,geo,output) ;
1343  break ;
1344  case 6 :
1345  stage_2_JP5_202206(ecal,hcal,pres,geo,output) ;
1346  break ;
1347  case 7 : // for FY22
1348  stage_2_202207(ecal,hcal,pres,geo,output,s2_to_dsm) ;
1349  break ;
1350 
1351  // debugging versions below
1352  case 0xFF210201 :
1353  stage_2_tonko_202101(ecal,hcal,pres,geo,output) ;
1354  break ;
1355  case 0xFF210204 :
1356  stage_2_tonko_202104(ecal,hcal,pres,geo,output) ;
1357  break ;
1358  default :
1359  LOG(ERR,"Unknown stage_2 version %d",stage_version[2]) ;
1360  break ;
1361  }
1362 
1363 }
1364 
1365 
1366 // VERSION 0x0
1367 void fcs_trg_base::stage_3(link_t link[4], u_short *dsm_out)
1368 {
1369 
1370  switch(stage_version[3]) {
1371  case 0 :
1372  stage_3_201900(link,dsm_out) ;
1373  break ;
1374  case 1 :
1375  stage_3_202201(link,dsm_out) ;
1376  break ;
1377  case 3 : // at start of FY22
1378  stage_3_202203(link,dsm_out) ;
1379  break ;
1380  case 7 : // for FY22
1381  stage_3_202207(link,dsm_out) ;
1382  break ;
1383  // debugging versions below
1384  case 0xFF210201 :
1385  stage_3_tonko_202101(link, dsm_out) ;
1386  break ;
1387 
1388  default :
1389  LOG(ERR,"Unknown stage_3 version %d",stage_version[3]) ;
1390  break ;
1391  }
1392 
1393 }
1394