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 if (isBOCRegister(typ)) return;
00077 if (!p_module) throw SctApiException("Null pointer exception in ConfigUtililty::modifyVar");
00078 ABCDModule &module = *p_module;
00079
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 #warning "Suggest using variableType to check for known module level variable"
00164 {
00165
00166 for(int ichip=0; ichip<12; ichip++) {
00167 modifyVar(p_module, ichip, typ, val);
00168 }
00169 }
00170 break;
00171 }
00172 }
00173
00174 void ConfigUtility::modifyVar(ABCDModule* module, unsigned ichip, UINT32 typ, FLOAT32 val){
00175 if (!module) throw SctApiException("Null pointer exception in ConfigUtililty::modifyVar");
00176 ABCDChip &chip = module->chip[ichip];
00177
00178 #warning "Suggest using variableType to check that typ is known chip level variable"
00179
00180 switch(typ) {
00181 case ST_ELAPSED:
00182
00183 break;
00184 case ST_VTHR:
00185 chip.basic.vthr = (char) fToInt(val/2.5);
00186 break;
00187 case ST_VCAL:
00188 chip.basic.vcal = (char) fToInt(val/0.625);
00189 break;
00190 case ST_STROBE_DELAY:
00191 chip.basic.delay = (char) fToInt(val);
00192 break;
00193 case ST_PREAMP:
00194 chip.basic.preamp = (char) fToInt(val/9.2);
00195 break;
00196 case ST_SHAPER:
00197 chip.basic.shaper = (char) fToInt(val/1.2);
00198 break;
00199 case ST_TRIM:
00200 for(int i=0; i<128; i++) {
00201 chip.trim[i] = (char) fToInt(val);
00202 }
00203 break;
00204 case ST_MASK:
00205 {
00206 UINT32 myval = (UINT32) fToInt(val);
00207 UINT32 mask = myval;
00208 for(int i=0; i<16; i++) {
00209 mask = (mask << 2) + myval;
00210 }
00211
00212 for(int i=0; i<4; i++) {
00213 chip.basic.mask[i] = mask;
00214 }
00215 }
00216 break;
00217 case ST_ROLE:
00218 switch(fToInt(val)) {
00219 case END:
00220 chip.basic.config.master = 1;
00221 chip.basic.config.end = 1;
00222 chip.basic.config.feedThrough = 1;
00223 break;
00224 case MASTER:
00225 chip.basic.config.master = 0;
00226 chip.basic.config.end = 0;
00227 chip.basic.config.feedThrough = 1;
00228 break;
00229 case SLAVE:
00230 chip.basic.config.master = 1;
00231 chip.basic.config.end = 0;
00232 chip.basic.config.feedThrough = 1;
00233 break;
00234 case LONELY:
00235 chip.basic.config.master = 0;
00236 chip.basic.config.end = 1;
00237 chip.basic.config.feedThrough = 1;
00238 break;
00239 case PARANOID:
00240 chip.basic.config.master = 0;
00241 chip.basic.config.end = 1;
00242 chip.basic.config.feedThrough = 1;
00243 case DEAD:
00244 default:
00245 module->chip[(ichip+1)%12].basic.config.outputBypass = 1;
00246 module->chip[(ichip+11)%12].basic.config.inputBypass = 1;
00247 case MISSING:
00248 break;
00249 }
00250
00251 case ST_NMASK:
00252 {
00253 int channels = fToInt(val);
00254 if(channels > 128) channels = 128;
00255
00256 for(int i=0; i<4; i++) {
00257
00258 int chan = channels - i*32;
00259 if(chan >= 32) {
00260 chip.basic.mask[i] = 0x00000000;
00261 } else {
00262 int value = 0;
00263 for(int b=0; b<chan; b++) {
00264 value <<= 1;
00265 value ++;
00266 }
00267 chip.basic.mask[i] = ~value;
00268 }
00269 }
00270 }
00271 break;
00272 case ST_CAL_MODE:
00273 chip.basic.config.calibMode = fToInt(val);
00274 break;
00275 case ST_COMPRESSION:
00276 chip.basic.config.readoutMode = fToInt(val);
00277 break;
00278 case ST_TRIM_RANGE:
00279 chip.basic.config.trimRange = fToInt(val);
00280 break;
00281 case ST_EDGE_DETECT:
00282 chip.basic.config.edgeDetect = fToInt(val);
00283 break;
00284 case ST_SEND_MASK:
00285 chip.basic.config.mask = fToInt(val)?1:0;
00286 break;
00287 case ST_ACCUMULATE:
00288 chip.basic.config.accumulate = fToInt(val);
00289 break;
00290 case ST_FEEDTHROUGH:
00291 chip.basic.config.feedThrough = fToInt(val);
00292 break;
00293 case ST_ACTIVE:
00294 chip.active = fToInt(val);
00295 break;
00296
00297 #ifdef DO_TOKENS_BY_CHIP
00298 case ST_BYPASS:
00299 {
00300
00301
00302
00303
00304
00305 UINT8 int_val = (UINT8)((val+0.5)/1.0);
00306 switch(int_val){
00307 case 0:
00308 setToken(module, 0x03 +(0x03<<6),1,1);
00309 break;
00310 case 1:
00311 setToken(module, 0x07 +(0x07<<6),1,1);
00312 break;
00313 case 2:
00314 setToken(module, 0x0F +(0x0F<<6),1,1);
00315 break;
00316 case 3:
00317 setToken(module, 0x1F +(0x1F<<6),1,1);
00318 break;
00319
00320 case 5:
00321 setToken(module, 0x05 +(0x05<<6),1,1);
00322 break;
00323 case 6:
00324 setToken(module, 0x0b +(0x0b<<6),1,1);
00325 break;
00326 case 7:
00327 setToken(module, 0x17 +(0x17<<6),1,1);
00328 break;
00329 case 8:
00330 setToken(module, 0x2f +(0x2f<<6),1,1);
00331 break;
00332 case 9:
00333 setToken(module, 0x3f +(0x3e<<6),2,0);
00334 break;
00335 case 10:
00336 setToken(module, 0x3e +(0x3F<<6),0,2);
00337 break;
00338 case 11:
00339 setToken(module, 0x3f +(0x3f<<6),2,0);
00340 break;
00341 case 12:
00342 setToken(module, 0x3f +(0x3F<<6),0,2);
00343 break;
00344 default:
00345 setToken(module, 0x3F +(0x3F<<6),1,1);
00346 break;
00347 }
00348 break;
00349 }
00350
00351 case ST_TOKEN:
00352 {
00353
00354
00355
00356
00357
00358
00359
00360
00361
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 int myVal = fToInt(val);
00388
00389 if(myVal<20) {
00390 setToken(module, (tokens[(int)myVal] + (tokens[(int)myVal] << 6)),1,1);
00391 } else if(myVal<36) {
00392 if(!((int)myVal%2)) {
00393 setToken(module, (tokens[(int)(myVal-20)/2+12] + (0x1 << 7)),2,0);
00394 } else {
00395 setToken(module, (0x2 + (tokens[((int)myVal-21)/2+12] << 6)),0,2);
00396 }
00397 } else {
00398 if(!((int)myVal%2)) {
00399 setToken(module, (tokens[(int)((myVal-36)/2+7)] + (1 << 6)),2,0);
00400 } else {
00401 setToken(module, (0x1 + (tokens[(int)((myVal-37)/2+7)] << 6)),0,2);
00402 }
00403 }
00404 break;
00405 }
00406 #endif
00407 case ST_QTHR:
00408 {
00409 ABCDCaldata &calPtr = chip.caldata;
00410 float v, vv;
00411
00412 switch(calPtr.rc_function){
00413 case 1:
00414 v = calPtr.rc_params[0] +
00415 val * (calPtr.rc_params[1] +
00416 (val * calPtr.rc_params[2]) );
00417 break;
00418 case 2:
00419 if((val==0)|| (calPtr.rc_params[1]==0))
00420 vv = 0;
00421 else
00422 vv = calPtr.rc_params[2] /
00423 (calPtr.rc_params[1] *val);
00424 v = calPtr.rc_params[0] +
00425 calPtr.rc_params[2] / (float) sqrt(1+(vv*vv));
00426 break;
00427 case 3:
00428 if(calPtr.rc_params[1]==0)
00429 v = 0;
00430 else
00431 v = calPtr.rc_params[2] +
00432 calPtr.rc_params[0]/(1+ (float)exp(-val/calPtr.rc_params[1]));
00433 break;
00434 case 4:
00435 v = calPtr.rc_params[0] +
00436 (val * calPtr.rc_params[1]);
00437 break;
00438 default:
00439 v = 0;
00440 break;
00441 }
00442
00443 UINT8 int_val = ((UINT8)((v+1.25)/(float)2.5));
00444 chip.basic.vthr = int_val;
00445 break;
00446 }
00447
00448 case ST_QCAL:
00449
00450
00451
00452
00453
00454 {
00455 FLOAT32 step = (float) 0.0625 * chip.caldata.c_factor;
00456 UINT8 int_val = (UINT8)((val+(step/2))/step);
00457 chip.basic.vcal = int_val;
00458 break;
00459 }
00460 case ST_TARGET:
00461 {
00462
00463
00464
00465
00466 UINT8 int_val = ((UINT8)((val+1.25)/(float)2.5));
00467
00468
00469
00470
00471
00472 chip.target = int_val;
00473 break;
00474 }
00475
00476 case ST_TTHR:
00477 {
00478
00479
00480
00481
00482 UINT8 int_val = ((UINT8)((val+1.25)/(float)2.5));
00483 int_val += chip.target;
00484
00485
00486
00487
00488
00489 chip.basic.vthr = int_val;
00490 break;
00491 }
00492
00493 default:
00494 break;
00495 }
00496
00497 }
00498
00499 INT32 ConfigUtility::setChipRole(ABCDModule *module, UINT32 theChip, ABCD_ROLES role){
00500
00501
00502 ABCDChip* chipPtr;
00503 ABCDConfig* configPtrLast;
00504 ABCDConfig* configPtr;
00505 ABCDConfig* configPtrNext;
00506
00507 UINT32 lastChip, nextChip;
00508
00509 if(theChip>N_SCT_CHIPS-1) return -1;
00510 if(module->active==0) return -2;
00511
00512 chipPtr = &module->chip[theChip];
00513 if(chipPtr->active==0) return -3;
00514
00515 lastChip = theChip-1;
00516 nextChip = theChip+1;
00517
00518 if(theChip==0) lastChip = 11;
00519 if(theChip==11) nextChip = 0;
00520
00521 configPtrLast = &module->chip[lastChip].basic.config;
00522 configPtr = &module->chip[theChip].basic.config;
00523 configPtrNext = &module->chip[nextChip].basic.config;
00524
00525 switch(role){
00526 case MISSING:
00527
00528 break;
00529 case DEAD:
00530 configPtrNext->outputBypass = 1;
00531 configPtrLast->inputBypass = 1;
00532 break;
00533 case END:
00534 configPtr->master = 1;
00535 configPtr->end = 1;
00536 configPtr->feedThrough = 1;
00537 break;
00538 case MASTER:
00539 configPtr->master = 0;
00540 configPtr->end = 0;
00541 configPtr->feedThrough = 1;
00542 break;
00543 case SLAVE:
00544 configPtr->master = 1;
00545 configPtr->end = 0;
00546 configPtr->feedThrough = 1;
00547 break;
00548 case LONELY:
00549 configPtr->master = 0;
00550 configPtr->end = 1;
00551 configPtr->feedThrough = 1;
00552 break;
00553 case PARANOID:
00554 configPtrNext->outputBypass = 1;
00555 configPtrLast->inputBypass = 1;
00556 configPtr->master = 0;
00557 configPtr->end = 1;
00558 configPtr->feedThrough = 1;
00559 break;
00560 default:
00561 break;
00562 }
00563
00564 return 0;
00565 }
00566
00567 ConfigUtility::ConfigVarType ConfigUtility::variableType(UINT32 typ){
00568 switch(typ) {
00569 case ST_RX_DELAY:
00570 case ST_RX_DELAY0:
00571 case ST_RX_DELAY1:
00572 case ST_RX_THRESHOLD:
00573 case ST_RX_THRESHOLD0:
00574 case ST_RX_THRESHOLD1:
00575 case ST_TX_CURRENT:
00576 case ST_TX_MARKSPACE:
00577 case ST_TX_DELAY:
00578 case ST_TX_COARSE:
00579 case ST_TX_FINE:
00580 return BOC_CHANNEL_CONFIG_VAR;
00581 case SCT_SCAN_BOC_BPM_PHASE:
00582 case SCT_SCAN_BOC_BREG_PHASE:
00583 case SCT_SCAN_BOC_V0_PHASE:
00584 case SCT_SCAN_BOC_V1_PHASE:
00585 case SCT_SCAN_BOC_V_PHASES:
00586 case SCT_SCAN_BOC_VRN_FINE:
00587 case SCT_SCAN_TX_CHANNELS:
00588 case SCT_SCAN_RAW_TX_CHANNELS:
00589 return BOC_GLOBAL_CONFIG_VAR;
00590 case ST_TOKEN:
00591
00592 case MVAR_GROUP_ID:
00593 case MVAR_ACTIVE:
00594 case MVAR_SELECT:
00595 return MODULE_GLOBAL_CONFIG_VAR;
00596 case ST_VTHR:
00597 case ST_VCAL:
00598 case ST_STROBE_DELAY:
00599 case ST_PREAMP:
00600 case ST_SHAPER:
00601 case ST_TRIM:
00602 case ST_MASK:
00603 case ST_ROLE:
00604 case ST_NMASK:
00605 case ST_CAL_MODE:
00606 case ST_COMPRESSION:
00607 case ST_TRIM_RANGE:
00608 case ST_EDGE_DETECT:
00609 case ST_SEND_MASK:
00610 case ST_ACCUMULATE:
00611 case ST_FEEDTHROUGH:
00612 case ST_ACTIVE:
00613
00614 case ST_QTHR:
00615 case ST_QCAL:
00616 case ST_TARGET:
00617 case ST_TTHR:
00618 return MODULE_CHIP_CONFIG_VAR;
00619 return MODULE_CHANNEL_CONFIG_VAR;
00620 default:
00621 return UNKNOWN_CONFIG_VAR;
00622 }
00623 }
00624
00625 }