00001 #include <assert.h>
00002 #include <sys/types.h>
00003 #include <errno.h>
00004
00005 #include <rtsLog.h>
00006 #include <rtsSystems.h>
00007
00008 #include <SFS/sfs_index.h>
00009
00010 #include <DAQ_READER/daqReader.h>
00011 #include <DAQ_READER/daq_dta.h>
00012
00013 #include "daq_mtd.h"
00014
00015
00016
00017
00018
00019
00020 const char *daq_mtd::help_string = "\
00021 \n\
00022 MTD Help: \n\
00023 Supported Banks: \n\
00024 raw returns=ptr of start of DDL data; c1=sector[1..1]; c2=rdo[1..4]; \n\
00025 legacy returns=ptr to struct mtd_t; \n\
00026 \n\
00027 \n\
00028 " ;
00029
00030 class daq_det_mtd_factory : public daq_det_factory
00031 {
00032 public:
00033 daq_det_mtd_factory() {
00034 daq_det_factory::det_factories[MTD_ID] = this ;
00035 }
00036
00037 daq_det *create() {
00038 return new daq_mtd ;
00039 }
00040 } ;
00041
00042 static daq_det_mtd_factory mtd_factory ;
00043
00044
00045
00046 daq_mtd::daq_mtd(daqReader *rts_caller)
00047 {
00048 rts_id = MTD_ID ;
00049 name = rts2name(rts_id) ;
00050 sfs_name = "mtd" ;
00051 caller = rts_caller ;
00052 if(caller) caller->insert(this, rts_id) ;
00053
00054 raw = new daq_dta ;
00055 legacy = new daq_dta ;
00056
00057
00058
00059 LOG(DBG,"%s: constructor: caller %p",name,rts_caller) ;
00060 return ;
00061 }
00062
00063 daq_mtd::~daq_mtd()
00064 {
00065 LOG(DBG,"%s: DEstructor",name) ;
00066
00067 delete raw ;
00068 delete legacy ;
00069
00070 return ;
00071 }
00072
00073
00074
00075 daq_dta *daq_mtd::get(const char *bank, int sec, int row, int pad, void *p1, void *p2)
00076 {
00077 Make() ;
00078
00079 if(present==0) return 0 ;
00080
00081 LOG(DBG,"%s: looking for bank %s",name,bank) ;
00082
00083 if(strcmp(bank,"*")==0) bank = "legacy" ;
00084
00085
00086
00087 if(strcasecmp(bank,"raw")==0) {
00088 if((present & DET_PRESENT_SFS)==0) return 0 ;
00089 return handle_raw(sec,row) ;
00090 }
00091 else if(strcasecmp(bank,"legacy")==0) {
00092 if((present & DET_PRESENT_SFS)==0) return 0 ;
00093 return handle_legacy() ;
00094 }
00095 else {
00096 LOG(ERR,"%s: unknown bank type \"%s\"",name,bank) ;
00097 }
00098
00099 return 0 ;
00100 }
00101
00102
00103 daq_dta *daq_mtd::handle_legacy()
00104 {
00105 assert(caller) ;
00106
00107 legacy->create(1,"mtd_t",rts_id,DAQ_DTA_STRUCT(mtd_t)) ;
00108
00109
00110 mtd_t *mtd_p = (mtd_t *) legacy->request(1) ;
00111
00112
00113 memset(mtd_p->ddl_words,0,sizeof(mtd_p->ddl_words)) ;
00114
00115 mtd_p->mode = 1 ;
00116 mtd_p->channels = 0 ;
00117 mtd_p->max_channels = 0 ;
00118
00119
00120 for(int r=1;r<=MAX_RDO;r++) {
00121 daq_dta *dd = handle_raw(0,r) ;
00122 if(dd && dd->iterate()) {
00123 u_int *tmp = (u_int *)dd->Void ;
00124
00125 u_int words = dd->ncontent/4 ;
00126
00127 LOG(DBG,"MTD: RDO %d: bytes %d (max %d)",r,dd->ncontent,sizeof(mtd_p->ddl[0])) ;
00128
00129 if(words > (sizeof(mtd_p->ddl[0])/4)) {
00130 LOG(ERR,"MTD: Huge event in RDO %d: %d words -- clipping to %d words",
00131 r,words,sizeof(mtd_p->ddl[0])/4) ;
00132
00133 words = sizeof(mtd_p->ddl[0])/4 ;
00134 }
00135
00136
00137 mtd_p->ddl_words[r-1] = words ;
00138
00139
00140 for(u_int i=0;i<words;i++) {
00141 mtd_p->ddl[r-1][i] = l2h32(*tmp) ;
00142 tmp++ ;
00143 }
00144
00145 }
00146
00147 }
00148
00149
00150 legacy->finalize(1,1,0,0) ;
00151 legacy->rewind() ;
00152
00153 return legacy ;
00154 }
00155
00156
00157 daq_dta *daq_mtd::handle_raw(int sec, int rdo)
00158 {
00159 char str[128] ;
00160 int tot_bytes ;
00161 int min_rdo, max_rdo ;
00162 int min_sec, max_sec ;
00163 struct {
00164 int sec ;
00165 int rb ;
00166 u_int bytes ;
00167 } obj[MAX_SEC*MAX_RDO] ;
00168
00169
00170 sec = 1 ;
00171 min_sec = max_sec = sec ;
00172
00173 if(rdo==-1) {
00174 min_rdo = 1 ;
00175 max_rdo = MAX_RDO ;
00176 }
00177 else if((rdo<1) || (rdo>MAX_RDO)) return 0 ;
00178 else {
00179 min_rdo = max_rdo = rdo ;
00180 }
00181
00182
00183 assert(caller) ;
00184
00185
00186 tot_bytes = 0 ;
00187 int o_cou = 0 ;
00188 for(int s=min_sec;s<=max_sec;s++) {
00189 for(int r=min_rdo;r<=max_rdo;r++) {
00190
00191 sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, s, r) ;
00192 char *full_name = caller->get_sfs_name(str) ;
00193
00194 LOG(DBG,"%s: trying sfs on \"%s\"",name,str) ;
00195 if(full_name == 0) continue ;
00196
00197 int size = caller->sfs->fileSize(full_name) ;
00198
00199 LOG(DBG,"Got %d",size) ;
00200
00201 if(size <= 0) {
00202 LOG(DBG,"%s: %s: not found in this event",name,str) ;
00203 continue ;
00204 }
00205 else {
00206 obj[o_cou].sec = s ;
00207 obj[o_cou].rb = r ;
00208 obj[o_cou].bytes = size ;
00209
00210 o_cou++ ;
00211
00212 tot_bytes += size ;
00213 LOG(DBG,"%s: %s: reading in \"%s\": bytes %d",name,str,"raw", size) ;
00214 }
00215 }
00216 }
00217
00218 raw->create(tot_bytes,"mtd_raw",rts_id,DAQ_DTA_STRUCT(u_char)) ;
00219
00220 for(int i=0;i<o_cou;i++) {
00221
00222 sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, obj[i].sec, obj[i].rb) ;
00223 char *full_name = caller->get_sfs_name(str) ;
00224 if(full_name == 0) continue ;
00225
00226 char *st = (char *) raw->request(obj[i].bytes) ;
00227
00228 int ret = caller->sfs->read(full_name, st, obj[i].bytes) ;
00229
00230 if(ret != (int)obj[i].bytes) {
00231 LOG(ERR,"%s: %s: read failed, expect %d, got %d [%s]",name,str,
00232 obj[i].bytes,ret,strerror(errno)) ;
00233 }
00234
00235 else {
00236 LOG(NOTE,"%s: %s read %d bytes",name,str,ret) ;
00237
00238 }
00239
00240 raw->finalize(obj[i].bytes,obj[i].sec,obj[i].rb,0) ;
00241
00242 }
00243
00244 raw->rewind() ;
00245 return raw ;
00246 }
00247
00248
00249
00250 int daq_mtd::get_token(char *addr, int words)
00251 {
00252 int cou ;
00253 struct daq_trg_word trg[128] ;
00254
00255 cou = get_l2(addr,words,trg,1) ;
00256
00257 if(cou==0) return -1000 ;
00258 if(trg[0].t==0) return -ENOSYS ;
00259
00260 return trg[0].t ;
00261 }
00262
00263
00264 int daq_mtd::get_l2(char *addr, int words, struct daq_trg_word *trg, int rdo)
00265 {
00266 u_int *w ;
00267 int cou = 0 ;
00268 int t_cou = 0 ;
00269 int in_words = words ;
00270
00271 int err = 0 ;
00272 int trg_start ;
00273
00274 w = (u_int *)addr ;
00275 words-- ;
00276
00277
00278 LOG(DBG,"First words 0x%08X 0x%08X 0x%08X, last words 0x%08X 0x%08X 0x%08X [+0x%08X], %u",
00279 w[0],w[1],w[2],w[words-2],w[words-1],w[words],w[words+1],words+1) ;
00280
00281
00282
00283
00284
00285
00286 trg[t_cou].t = w[0] & 0xFFF ;
00287 trg[t_cou].daq = (w[0]>>12) & 0xF ;
00288 trg[t_cou].trg = (w[0]>>16) & 0xF ;
00289 trg[t_cou].rhic = 0 ;
00290 trg[t_cou].rhic_delta = 0 ;
00291 t_cou++ ;
00292
00293
00294
00295
00296
00297 LOG(NOTE,"prompt: T %4d, trg %d, daq %d [0x%08X]: words %d",trg[0].t,trg[0].trg,trg[0].daq,w[0],in_words) ;
00298
00299 if(in_words < 2) {
00300 err |= 1 ;
00301 LOG(ERR,"[%d] bad word count %d < 2",rdo,in_words);
00302 }
00303
00304
00305 if(w[0] == 0xA0000000) {
00306 trg[0].t = 4097;
00307 }
00308 else {
00309 if(in_words < 3) {
00310 err |= 1 ;
00311 LOG(ERR,"[%d] bad word count %d <= 3",rdo,in_words);
00312 }
00313
00314 if(trg[0].t == 0) {
00315 err |= 2 ;
00316 LOG(ERR,"[%d] token 0",rdo);
00317 trg[0].t = 4097 ;
00318 }
00319
00320 if(trg[0].trg != 4) {
00321 err |= 2 ;
00322 LOG(ERR,"[%d] bad trg_cmd %d != 4",rdo,trg[0].trg);
00323 }
00324
00325 if(w[1] != 0xDEADFACE) {
00326 err |= 1 ;
00327 LOG(ERR,"[%d] bad DEADCODE 0x%08X",rdo,w[1]);
00328 }
00329
00330
00331 }
00332
00333 if((w[0] >> 20) != 0xA00) {
00334 err |= 1 ;
00335 LOG(ERR,"[%d] bad first word 0x%08X doesn't start with 0xA00",rdo,w[0]);
00336 trg[0].t = 4097 ;
00337 }
00338
00339
00340
00341 while(words) {
00342 if((w[words] >> 28)==0xA) {
00343 words-- ;
00344 cou++ ;
00345 }
00346 else {
00347 break ;
00348 }
00349 }
00350
00351 if(cou==0) {
00352 err |= 1 ;
00353 LOG(ERR,"[%d] No Trigger FIFO contribution??",rdo);
00354 }
00355
00356 words++ ;
00357
00358 trg_start = words ;
00359
00360
00361 for(int i=0;i<cou;i++) {
00362 int l_err = 0 ;
00363
00364 trg[t_cou].t = w[words+i] & 0xFFF ;
00365 trg[t_cou].daq = (w[words+i]>>12) & 0xF ;
00366 trg[t_cou].trg = (w[words+i]>>16) & 0xF ;
00367 trg[t_cou].rhic = i+1 ;
00368 trg[t_cou].rhic_delta = i+1 ;
00369
00370 if(trg[t_cou].t == 0) l_err = 1 ;
00371
00372
00373 switch(trg[t_cou].trg) {
00374 case 4 :
00375 continue ;
00376 case 13 :
00377 case 15 :
00378 break ;
00379 default :
00380 l_err = 1 ;
00381 break ;
00382 }
00383
00384 if(l_err) {
00385 LOG(ERR,"[%d] bad FIFO trg (%d.): T %4d, trg %d, daq %d [0x%08X]",rdo,words+i,trg[t_cou].t,trg[t_cou].trg,trg[t_cou].daq,w[words+i]);
00386 err |= 2 ;
00387 continue ;
00388 }
00389
00390 t_cou++ ;
00391
00392 if(t_cou >=120) {
00393 err |= 2 ;
00394 LOG(ERR,"[%d] Too many trigger contributions %d >= 120",rdo,t_cou) ;
00395 break ;
00396 }
00397 }
00398
00399
00400 if(err) {
00401 LOG(ERR,"[%d] Bad Event: T %4d: words %d, trg_words %d (start at %d) : 0x%08X 0x%08X 0x%08X",
00402 rdo,trg[0].t,in_words,cou,trg_start,w[0],w[1],w[2]) ;
00403
00404
00405
00406
00407 }
00408
00409 if(err & 1) {
00410 return -1 ;
00411 }
00412
00413 return t_cou ;
00414 }