00001 #include "ConfigurationUtility.h"
00002 #include "SctApiException.h"
00003 #include "primParams.h"
00004
00005 namespace SctApi{
00006 #define fToInt(val) ((int)((val)+0.5))
00007
00008 const static short tokens[20]={0x01, 0x03, 0x05, 0x07, 0x0b,
00009 0x0d, 0x0f, 0x15, 0x17, 0x1b,
00010 0x1d, 0x1f, 0x2b, 0x2d, 0x2f,
00011 0x35, 0x37, 0x3b, 0x3d, 0x3f};
00012
00013 const char *chipRoles[] = {"MISSING", "DEAD", "END", "MASTER", "SLAVE", "LONELY", "PARANOID"};
00014
00015 void ConfigUtility::setToken(ABCDModule* module, unsigned token, int link0, int link1) {
00016
00017 for(unsigned int theChip=0; theChip<N_SCT_CHIPS; theChip++){
00018 module->chip[theChip].basic.config.outputBypass = 0;
00019 module->chip[theChip].basic.config.inputBypass = 0;
00020 module->chip[theChip].basic.config.master = 1;
00021 module->chip[theChip].basic.config.end = 0;
00022 module->chip[theChip].basic.config.feedThrough = 1;
00023 }
00024
00025 for(unsigned int theChip=0; theChip<N_SCT_CHIPS; theChip++){
00026
00027 if( (token >> theChip) & 0x1 ) {
00028
00029 if(theChip==0) {
00030 if(link0) {
00031 if((token&0x003F)==0x0001) {
00032 setChipRole(module,theChip,LONELY);
00033 } else {
00034 setChipRole(module,theChip,MASTER);
00035 }
00036 } else {
00037 setChipRole(module,theChip,END);
00038 }
00039
00040 } else if(theChip==6) {
00041 if (link1) {
00042 if((token&0x0FC0)==0x0040) {
00043 setChipRole(module,theChip,LONELY);
00044 } else {
00045 setChipRole(module,theChip,MASTER);
00046 }
00047 } else {
00048 setChipRole(module,theChip,END);
00049 }
00050
00051 } else if(theChip<6) {
00052
00053 if( (link0<2) && (1<<(theChip+1)>(token&0x3F)) ) {
00054 setChipRole(module,theChip,END);
00055 } else {
00056 setChipRole(module,theChip,SLAVE);
00057 }
00058
00059 } else {
00060
00061 if( (link1<2) && (1<<(theChip+1)>token) ) {
00062 setChipRole(module,theChip,END);
00063 } else {
00064 setChipRole(module,theChip,SLAVE);
00065 }
00066 }
00067
00068 } else {
00069 setChipRole(module,theChip,DEAD);
00070 }
00071 }
00072 return;
00073 }
00074
00075 void ConfigUtility::modifyVar(ABCDModule* p_module, UINT32 typ, FLOAT32 val){
00076 ConfigVarType variable_type=variableType(typ);
00077 if ( !isModuleRegister(variable_type) ) return;
00078 if (!p_module) throw SctApiException("Null pointer exception in ConfigUtililty::modifyVar");
00079 ABCDModule &module = *p_module;
00080
00081 switch (typ){
00082 case ST_TOKEN:
00083 {
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 int myVal = fToInt(val);
00118
00119 if(myVal<20) {
00120 setToken(&module, (tokens[myVal] + (tokens[myVal] << 6)),1,1);
00121
00122 } else if(myVal<36) {
00123 if(!((int)myVal%2)) {
00124 setToken(&module, (tokens[(myVal-20)/2+12] + (0x1 << 7)),2,0);
00125 } else {
00126 setToken(&module, (0x2 + (tokens[(myVal-21)/2+12] << 6)),0,2);
00127 }
00128 } else {
00129 if(!(myVal%2)) {
00130 setToken(&module, (tokens[((myVal-36)/2+7)] + (1 << 6)),2,0);
00131 } else {
00132 setToken(&module, (0x1 + (tokens[((myVal-37)/2+7)] << 6)),0,2);
00133 }
00134 }
00135 break;
00136 }
00137 case MVAR_GROUP_ID:
00138 {
00139 module.groupId = fToInt(val);
00140 break;
00141 }
00142 case MVAR_ACTIVE:
00143 {
00144 module.active = fToInt(val);
00145 break;
00146 }
00147 case MVAR_SELECT:
00148 {
00149 module.select = fToInt(val);
00150
00151 if(module.select) {
00152 for(int c=0; c<12; c++) {
00153 module.chip[c].address |= 0x10;
00154 }
00155 } else {
00156 for(int c=0; c<12; c++) {
00157 module.chip[c].address &= ~0x10;
00158 }
00159 }
00160 break;
00161 }
00162 default:
00163 if (variable_type==MODULE_CHIP_CONFIG_VAR) {
00164 for(int ichip=0; ichip<12; ichip++) {
00165 modifyVar(p_module, ichip, typ, val);
00166 }
00167 break;
00168 }else{
00169 std::cerr << "ERROR I don't know how to deal with variable " << typ << " of type " << variable_type << std::endl;
00170 }
00171 }
00172 }
00173
00174 void ConfigUtility::modifyVar(ABCDModule* module, unsigned ichip, UINT32 typ, FLOAT32 val){
00175 if (ichip==ALL_CHIPS) {
00176 modifyVar(module, typ, val);
00177 return;
00178 }
00179 if (ichip>=12) {
00180 std::ostringstream oss;
00181 oss << "Chip ["<<ichip<<"] out of range in ConfigurationUtility::modifyVar\n";
00182 oss << "was expecting {0->12} or " << ALL_CHIPS;
00183 throw SctApiException(oss.str());
00184 }
00185 if (!module) throw SctApiException("Null pointer exception in ConfigUtililty::modifyVar");
00186 ABCDChip &chip = module->chip[ichip];
00187 ConfigVarType variable_type = variableType(typ);
00188 if (variable_type != MODULE_CHIP_CONFIG_VAR && variable_type != MODULE_CHANNEL_CONFIG_VAR) return;
00189
00190 switch(typ) {
00191 case ST_ELAPSED:
00192
00193 break;
00194 case ST_VTHR:
00195 chip.basic.vthr = (char) fToInt(val/2.5);
00196 break;
00197 case ST_VCAL:
00198 chip.basic.vcal = (char) fToInt(val/0.625);
00199 break;
00200 case ST_STROBE_DELAY:
00201 chip.basic.delay = (char) fToInt(val);
00202 break;
00203 case ST_PREAMP:
00204 chip.basic.preamp = (char) fToInt(val/9.2);
00205 break;
00206 case ST_SHAPER:
00207 chip.basic.shaper = (char) fToInt(val/1.2);
00208 break;
00209 case ST_TRIM:
00210 for(int i=0; i<128; i++) {
00211 chip.trim[i] = (char) fToInt(val);
00212 }
00213 break;
00214 case ST_MASK:
00215 {
00216 UINT32 myval = (UINT32) fToInt(val);
00217 UINT32 mask = myval;
00218 for(int i=0; i<16; i++) {
00219 mask = (mask << 2) + myval;
00220 }
00221
00222 for(int i=0; i<4; i++) {
00223 chip.basic.mask[i] = mask;
00224 }
00225 }
00226 break;
00227 case ST_ROLE:
00228 switch(fToInt(val)) {
00229 case END:
00230 chip.basic.config.master = 1;
00231 chip.basic.config.end = 1;
00232 chip.basic.config.feedThrough = 1;
00233 break;
00234 case MASTER:
00235 chip.basic.config.master = 0;
00236 chip.basic.config.end = 0;
00237 chip.basic.config.feedThrough = 1;
00238 break;
00239 case SLAVE:
00240 chip.basic.config.master = 1;
00241 chip.basic.config.end = 0;
00242 chip.basic.config.feedThrough = 1;
00243 break;
00244 case LONELY:
00245 chip.basic.config.master = 0;
00246 chip.basic.config.end = 1;
00247 chip.basic.config.feedThrough = 1;
00248 break;
00249 case PARANOID:
00250 chip.basic.config.master = 0;
00251 chip.basic.config.end = 1;
00252 chip.basic.config.feedThrough = 1;
00253 case DEAD:
00254 default:
00255 module->chip[(ichip+1)%12].basic.config.outputBypass = 1;
00256 module->chip[(ichip+11)%12].basic.config.inputBypass = 1;
00257 case MISSING:
00258 break;
00259 }
00260
00261 case ST_NMASK:
00262 {
00263 int channels = fToInt(val);
00264 if(channels > 128) channels = 128;
00265
00266 for(int i=0; i<4; i++) {
00267
00268 int chan = channels - i*32;
00269 if(chan >= 32) {
00270 chip.basic.mask[i] = 0x00000000;
00271 } else {
00272 int value = 0;
00273 for(int b=0; b<chan; b++) {
00274 value <<= 1;
00275 value ++;
00276 }
00277 chip.basic.mask[i] = ~value;
00278 }
00279 }
00280 }
00281 break;
00282 case ST_CAL_MODE:
00283 chip.basic.config.calibMode = fToInt(val);
00284 break;
00285 case ST_COMPRESSION:
00286 chip.basic.config.readoutMode = fToInt(val);
00287 break;
00288 case ST_TRIM_RANGE:
00289 chip.basic.config.trimRange = fToInt(val);
00290 break;
00291 case ST_EDGE_DETECT:
00292 chip.basic.config.edgeDetect = fToInt(val);
00293 break;
00294 case ST_SEND_MASK:
00295 chip.basic.config.mask = fToInt(val)?1:0;
00296 break;
00297 case ST_ACCUMULATE:
00298 chip.basic.config.accumulate = fToInt(val)?1:0;
00299 break;
00300 case ST_FEEDTHROUGH:
00301 chip.basic.config.feedThrough = fToInt(val)?1:0;
00302 break;
00303 case ST_ACTIVE:
00304 chip.active = fToInt(val)?1:0;
00305 break;
00306
00307 #ifdef DO_TOKENS_BY_CHIP
00308 case ST_BYPASS:
00309 {
00310
00311
00312
00313
00314
00315 UINT8 int_val = (UINT8)((val+0.5)/1.0);
00316 switch(int_val){
00317 case 0:
00318 setToken(module, 0x03 +(0x03<<6),1,1);
00319 break;
00320 case 1:
00321 setToken(module, 0x07 +(0x07<<6),1,1);
00322 break;
00323 case 2:
00324 setToken(module, 0x0F +(0x0F<<6),1,1);
00325 break;
00326 case 3:
00327 setToken(module, 0x1F +(0x1F<<6),1,1);
00328 break;
00329
00330 case 5:
00331 setToken(module, 0x05 +(0x05<<6),1,1);
00332 break;
00333 case 6:
00334 setToken(module, 0x0b +(0x0b<<6),1,1);
00335 break;
00336 case 7:
00337 setToken(module, 0x17 +(0x17<<6),1,1);
00338 break;
00339 case 8:
00340 setToken(module, 0x2f +(0x2f<<6),1,1);
00341 break;
00342 case 9:
00343 setToken(module, 0x3f +(0x3e<<6),2,0);
00344 break;
00345 case 10:
00346 setToken(module, 0x3e +(0x3F<<6),0,2);
00347 break;
00348 case 11:
00349 setToken(module, 0x3f +(0x3f<<6),2,0);
00350 break;
00351 case 12:
00352 setToken(module, 0x3f +(0x3F<<6),0,2);
00353 break;
00354 default:
00355 setToken(module, 0x3F +(0x3F<<6),1,1);
00356 break;
00357 }
00358 break;
00359 }
00360
00361 case ST_TOKEN:
00362 {
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 int myVal = fToInt(val);
00398
00399 if(myVal<20) {
00400 setToken(module, (tokens[(int)myVal] + (tokens[(int)myVal] << 6)),1,1);
00401 } else if(myVal<36) {
00402 if(!((int)myVal%2)) {
00403 setToken(module, (tokens[(int)(myVal-20)/2+12] + (0x1 << 7)),2,0);
00404 } else {
00405 setToken(module, (0x2 + (tokens[((int)myVal-21)/2+12] << 6)),0,2);
00406 }
00407 } else {
00408 if(!((int)myVal%2)) {
00409 setToken(module, (tokens[(int)((myVal-36)/2+7)] + (1 << 6)),2,0);
00410 } else {
00411 setToken(module, (0x1 + (tokens[(int)((myVal-37)/2+7)] << 6)),0,2);
00412 }
00413 }
00414 break;
00415 }
00416 #endif
00417 case ST_QTHR:
00418 {
00419 ABCDCaldata &calPtr = chip.caldata;
00420 float v, vv;
00421
00422 switch(calPtr.rc_function){
00423 case 1:
00424 v = calPtr.rc_params[0] +
00425 val * (calPtr.rc_params[1] +
00426 (val * calPtr.rc_params[2]) );
00427 break;
00428 case 2:
00429 if((val==0)|| (calPtr.rc_params[1]==0))
00430 vv = 0;
00431 else
00432 vv = calPtr.rc_params[2] /
00433 (calPtr.rc_params[1] *val);
00434 v = calPtr.rc_params[0] +
00435 calPtr.rc_params[2] / (float) sqrt(1+(vv*vv));
00436 break;
00437 case 3:
00438 if(calPtr.rc_params[1]==0)
00439 v = 0;
00440 else
00441 v = calPtr.rc_params[2] +
00442 calPtr.rc_params[0]/(1+ (float)exp(-val/calPtr.rc_params[1]));
00443 break;
00444 case 4:
00445 v = calPtr.rc_params[0] +
00446 (val * calPtr.rc_params[1]);
00447 break;
00448 default:
00449 v = 0;
00450 break;
00451 }
00452
00453 UINT8 int_val = ((UINT8)((v+1.25)/(float)2.5));
00454 chip.basic.vthr = int_val;
00455 break;
00456 }
00457
00458 case ST_QCAL:
00459
00460
00461
00462
00463
00464 {
00465 FLOAT32 step = (float) 0.0625 * chip.caldata.c_factor;
00466 UINT8 int_val = (UINT8)((val+(step/2))/step);
00467 chip.basic.vcal = int_val;
00468 break;
00469 }
00470 case ST_TARGET:
00471 {
00472
00473
00474
00475
00476 UINT8 int_val = ((UINT8)((val+1.25)/(float)2.5));
00477
00478
00479
00480
00481
00482 chip.target = int_val;
00483 break;
00484 }
00485
00486 case ST_TTHR:
00487 {
00488
00489
00490
00491
00492 UINT8 int_val = ((UINT8)((val+1.25)/(float)2.5));
00493 int_val += chip.target;
00494
00495
00496
00497
00498
00499 chip.basic.vthr = int_val;
00500 break;
00501 }
00502
00503 default:
00504 break;
00505 }
00506
00507 }
00508
00509 INT32 ConfigUtility::setChipRole(ABCDModule *module, UINT32 theChip, ABCD_ROLES role){
00510
00511
00512 ABCDChip* chipPtr;
00513 ABCDConfig* configPtrLast;
00514 ABCDConfig* configPtr;
00515 ABCDConfig* configPtrNext;
00516
00517 UINT32 lastChip, nextChip;
00518
00519 if(theChip>N_SCT_CHIPS-1) return -1;
00520 if(module->active==0) return -2;
00521
00522 chipPtr = &module->chip[theChip];
00523 if(chipPtr->active==0) return -3;
00524
00525 lastChip = theChip-1;
00526 nextChip = theChip+1;
00527
00528 if(theChip==0) lastChip = 11;
00529 if(theChip==11) nextChip = 0;
00530
00531 configPtrLast = &module->chip[lastChip].basic.config;
00532 configPtr = &module->chip[theChip].basic.config;
00533 configPtrNext = &module->chip[nextChip].basic.config;
00534
00535 switch(role){
00536 case MISSING:
00537
00538 break;
00539 case DEAD:
00540 configPtrNext->outputBypass = 1;
00541 configPtrLast->inputBypass = 1;
00542 break;
00543 case END:
00544 configPtr->master = 1;
00545 configPtr->end = 1;
00546 configPtr->feedThrough = 1;
00547 break;
00548 case MASTER:
00549 configPtr->master = 0;
00550 configPtr->end = 0;
00551 configPtr->feedThrough = 1;
00552 break;
00553 case SLAVE:
00554 configPtr->master = 1;
00555 configPtr->end = 0;
00556 configPtr->feedThrough = 1;
00557 break;
00558 case LONELY:
00559 configPtr->master = 0;
00560 configPtr->end = 1;
00561 configPtr->feedThrough = 1;
00562 break;
00563 case PARANOID:
00564 configPtrNext->outputBypass = 1;
00565 configPtrLast->inputBypass = 1;
00566 configPtr->master = 0;
00567 configPtr->end = 1;
00568 configPtr->feedThrough = 1;
00569 break;
00570 default:
00571 break;
00572 }
00573
00574 return 0;
00575 }
00576
00577 ConfigUtility::ConfigVarType ConfigUtility::variableType(UINT32 typ){
00578 switch(typ) {
00579 case ST_RX_DELAY:
00580 case ST_RX_DELAY0:
00581 case ST_RX_DELAY1:
00582 case ST_RX_THRESHOLD:
00583 case ST_RX_THRESHOLD0:
00584 case ST_RX_THRESHOLD1:
00585 case ST_TX_CURRENT:
00586 case ST_TX_MARKSPACE:
00587 case ST_TX_DELAY:
00588 case ST_TX_COARSE:
00589 case ST_TX_FINE:
00590 return BOC_CHANNEL_CONFIG_VAR;
00591 case SCT_SCAN_BOC_BPM_PHASE:
00592 case SCT_SCAN_BOC_BREG_PHASE:
00593 case SCT_SCAN_BOC_V0_PHASE:
00594 case SCT_SCAN_BOC_V1_PHASE:
00595 case SCT_SCAN_BOC_V_PHASES:
00596 case SCT_SCAN_BOC_VRN_FINE:
00597 case SCT_SCAN_TX_CHANNELS:
00598 case SCT_SCAN_RAW_TX_CHANNELS:
00599 return BOC_GLOBAL_CONFIG_VAR;
00600 case ST_TOKEN:
00601
00602 case MVAR_GROUP_ID:
00603 case MVAR_ACTIVE:
00604 case MVAR_SELECT:
00605 return MODULE_GLOBAL_CONFIG_VAR;
00606 case ST_VTHR:
00607 case ST_VCAL:
00608 case ST_STROBE_DELAY:
00609 case ST_PREAMP:
00610 case ST_SHAPER:
00611 case ST_TRIM:
00612 case ST_MASK:
00613 case ST_ROLE:
00614 case ST_NMASK:
00615 case ST_CAL_MODE:
00616 case ST_COMPRESSION:
00617 case ST_TRIM_RANGE:
00618 case ST_EDGE_DETECT:
00619 case ST_SEND_MASK:
00620 case ST_ACCUMULATE:
00621 case ST_FEEDTHROUGH:
00622 case ST_ACTIVE:
00623
00624 case ST_QTHR:
00625 case ST_QCAL:
00626 case ST_TARGET:
00627 case ST_TTHR:
00628 return MODULE_CHIP_CONFIG_VAR;
00629 return MODULE_CHANNEL_CONFIG_VAR;
00630 case SCT_TIM_PRE_TRIGGER_DELAY:
00631 case SCT_TIM_CLOCK_DELAY:
00632 return TIM_CONFIG_VAR;
00633 case ST_TRIG_DELAY1:
00634 case ST_TRIG_DELAY2:
00635 return TRIGGER_VAR;
00636 default:
00637 return UNKNOWN_CONFIG_VAR;
00638 }
00639 }
00640
00641 }