Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

SctApiModify.cxx

00001 
00008 #include <iostream>
00009 #include <cmath>
00010 
00011 #include "processor.h"
00012 
00013 #include "ABCD/ABCDscans.h"
00014 #include "primParams.h"     // This has MVAR variables which are shared with PIXEL
00015 #include "ABCD/ABCDchip.h"
00016 
00017 #include "SctApi.h"
00018 #include "crate.h"
00019 #include "utility.h"
00020 
00021 #include "extraScans.h"
00022 
00023 using namespace std;
00024 
00025 const static short tokens[20]={0x01, 0x03, 0x05, 0x07, 0x0b,
00026                                0x0d, 0x0f, 0x15, 0x17, 0x1b,
00027                                0x1d, 0x1f, 0x2b, 0x2d, 0x2f,
00028                                0x35, 0x37, 0x3b, 0x3d, 0x3f};
00029 
00030 const char *chipRoles[] = {"MISSING", "DEAD", "END", "MASTER", "SLAVE", "LONELY", "PARANOID"};
00031 
00032 static INT32 setChipRole(ABCDModule *module, UINT32 theChip, ABCD_ROLES role){
00033 //   cout << "Set chip " << theChip << " role to " << chipRoles[role] << endl;
00034 
00035   ABCDChip*   chipPtr;
00036   ABCDConfig* configPtrLast;  /* chip (n-1) */ 
00037   ABCDConfig* configPtr;      /* chip n     */
00038   ABCDConfig* configPtrNext;  /* chip (n+1) */
00039 
00040   UINT32 lastChip, nextChip;
00041 
00042   if(theChip>N_SCT_CHIPS-1) return -1;  /* chip out of range */
00043   if(module->active==0) return -2;  /* module inactive */
00044 
00045   chipPtr = &module->chip[theChip];
00046   if(chipPtr->active==0) return -3; /* chip inactive */
00047 
00048   lastChip = theChip-1;
00049   nextChip = theChip+1;
00050 
00051   if(theChip==0)  lastChip = 11;
00052   if(theChip==11) nextChip =  0;
00053 
00054   configPtrLast = &module->chip[lastChip].basic.config;
00055   configPtr     = &module->chip[theChip].basic.config;
00056   configPtrNext = &module->chip[nextChip].basic.config;
00057 
00058   switch(role){
00059     case MISSING:
00060       /* who cares! */
00061       break;
00062     case DEAD:
00063       configPtrNext->outputBypass = 1;
00064       configPtrLast->inputBypass  = 1;
00065       break;
00066     case END:
00067       configPtr->master = 1;
00068       configPtr->end    = 1;
00069       configPtr->feedThrough = 1;
00070       break;
00071     case MASTER:
00072       configPtr->master = 0;
00073       configPtr->end    = 0;
00074       configPtr->feedThrough = 1;  /* active low */
00075       break;
00076     case SLAVE:
00077       configPtr->master = 1;
00078       configPtr->end    = 0;
00079       configPtr->feedThrough = 1;
00080       break;
00081     case LONELY:
00082       configPtr->master = 0;
00083       configPtr->end    = 1;
00084       configPtr->feedThrough = 1;
00085       break;
00086     case PARANOID:
00087       configPtrNext->outputBypass = 1;
00088       configPtrLast->inputBypass  = 1;
00089       configPtr->master = 0;
00090       configPtr->end    = 1;
00091       configPtr->feedThrough = 1;
00092       break;
00093     default:
00094       break;
00095   }
00096 
00097   return 0;
00098 }
00099 
00100 static void setToken(ABCDModule* module, unsigned token, int link0, int link1) {
00101   cout << "Set token to 0x" << hex << token << dec << ": " << link0 << " " << link1 << endl;
00102 
00103   // Set up defaults...
00104   for(unsigned int theChip=0; theChip<N_SCT_CHIPS; theChip++){
00105        module->chip[theChip].basic.config.outputBypass = 0;
00106        module->chip[theChip].basic.config.inputBypass = 0;
00107        module->chip[theChip].basic.config.master = 1;        /* active low */
00108        module->chip[theChip].basic.config.end = 0;           /* active high */
00109        module->chip[theChip].basic.config.feedThrough  = 1;  /* active low  */
00110   }
00111 
00112   for(unsigned int theChip=0; theChip<N_SCT_CHIPS; theChip++){
00113     
00114     if( (token >> theChip) & 0x1 ) { /* chip to be read out */
00115 
00116       if(theChip==0) {
00117         if(link0) {
00118           if((token&0x003F)==0x0001) { /* only M0 in use */
00119             setChipRole(module,theChip,LONELY);
00120           } else {
00121             setChipRole(module,theChip,MASTER);
00122           }
00123         } else {
00124           setChipRole(module,theChip,END);
00125         }
00126 
00127       } else if(theChip==6) {
00128         if (link1) { 
00129           if((token&0x0FC0)==0x0040) { /* only M8 in use */
00130             setChipRole(module,theChip,LONELY);
00131           } else {
00132             setChipRole(module,theChip,MASTER);
00133           }
00134         } else {
00135           setChipRole(module,theChip,END);
00136         }
00137 
00138       } else if(theChip<6) {
00139         /* if( (link0<2) && (pow(2,(theChip+1))>(token&0x3F)) ) { dpsf */
00140         if( (link0<2) && (1<<(theChip+1)>(token&0x3F)) ) {
00141           setChipRole(module,theChip,END);
00142         } else {
00143           setChipRole(module,theChip,SLAVE);
00144         }
00145 
00146       } else {
00147         /* if( (link1<2) && (pow(2,(theChip+1))>token) ) {  dpsf */
00148         if( (link1<2) && (1<<(theChip+1)>token) ) {
00149           setChipRole(module,theChip,END);
00150         } else {
00151           setChipRole(module,theChip,SLAVE);
00152         }
00153       }
00154 
00155     } else {
00156       setChipRole(module,theChip,DEAD);
00157     }
00158   }
00159 
00160 //   if(debugLevel > 1) {
00161     for(unsigned int theChip=0; theChip<N_SCT_CHIPS; theChip++){
00162       cout << " OB: " << module->chip[theChip].basic.config.outputBypass;
00163       cout << " IB: " << module->chip[theChip].basic.config.inputBypass;
00164       cout << " bM: " << module->chip[theChip].basic.config.master;    
00165       cout << " END: " << module->chip[theChip].basic.config.end;       
00166       cout << " FT: " << module->chip[theChip].basic.config.feedThrough;
00167       cout << endl;
00168     }
00169 //   }
00170 
00171   return;
00172 }
00173 
00174 namespace SctApi {
00175 
00176 void SctApi::modifyABCDMask(UINT32 mid, UINT32* mask) {
00177   {
00178     boost::mutex::scoped_lock lock(logMutex);
00179     log << "modifyABCDMask on " << mid << "\n";
00180   }
00181 
00182   ABCDModule *module = lookupConfig(mid);
00183 
00184   if(module) {
00185     for(int c=0; c<12; c++) {
00186       for(int m=0; m<4; m++) {
00187         module->chip[c].basic.mask[m] = mask[c*4+m];
00188       }
00189     }
00190   } 
00191 }
00192 
00193 void SctApi::modifyABCDRC(UINT32 mid, UINT32 chip, UINT16 index, FLOAT32 p0, FLOAT32 p1, FLOAT32 p2){
00194   {
00195     boost::mutex::scoped_lock lock(logMutex);
00196     log << "modifyABCDRC on " << mid << " " << chip << "\n";
00197   }
00198   ABCDModule *module = lookupConfig(mid);
00199 
00200   if(module) {
00201     module->chip[chip].caldata.rc_function = index;
00202     module->chip[chip].caldata.rc_params[0]=p0;
00203     module->chip[chip].caldata.rc_params[1]=p1;
00204     module->chip[chip].caldata.rc_params[2]=p2;
00205   }
00206 }
00207 
00208 void SctApi::modifyABCDTrims(UINT32 mid, UINT8* trims) {
00209   {
00210     boost::mutex::scoped_lock lock(logMutex);
00211     log << "modifyABCDTrims on " << mid << "\n";
00212   }
00213 
00214   ABCDModule *module = lookupConfig(mid);
00215 
00216   if(module) {
00217     for(int c=0; c<12; c++) {
00218       for(int t=0; t<128; t++) {
00219         module->chip[c].trim[t] = trims[c*128+t];
00220       }
00221     }
00222   }
00223 }
00224 
00225 #define fToInt(val) ((int)((val)+0.5))
00226 
00227 void SctApi::modifyABCDVar(UINT32 typ, FLOAT32 val) {
00228   {
00229     boost::mutex::scoped_lock lock(logMutex);
00230     log << "modifyABCDVar (all)\n";
00231   }
00232 
00233   cout << "Modify var on all modules: setting " << typ << " to " << val << endl;
00234 
00235   switch(typ) {
00236     // Global BOC registers
00237   case SCT_SCAN_BOC_BPM_PHASE:
00238   case SCT_SCAN_BOC_BREG_PHASE:
00239   case SCT_SCAN_BOC_V0_PHASE:
00240   case SCT_SCAN_BOC_V1_PHASE:
00241   case SCT_SCAN_BOC_V_PHASES:
00242   case SCT_SCAN_BOC_VRN_FINE:
00243 
00244   case SCT_SCAN_TX_CHANNELS:
00245   case SCT_SCAN_RAW_TX_CHANNELS:
00246     {
00247       cout << "Calling modifyBOCParam on all crates for " << typ << " " << val << endl;
00248 
00249       try {
00250         for(list<RodLabel>::const_iterator rl = rodList.begin();
00251             rl!=rodList.end();
00252             rl++){
00253           getCrate(rl->partition, rl->crate)->modifyBOCParam(typ, fToInt(val), false);
00254         }
00255       } catch(CrateException &c) {
00256         cout << "CrateException: " << c.what() << endl;
00257       }
00258       break;
00259     }
00260 
00261   default:
00262     // Module level parameters
00263     for(map<UINT32, ABCDModule>::const_iterator iter = moduleMap.begin();
00264         iter != moduleMap.end();
00265         iter ++) {
00266       modifyABCDVar(iter->first, typ, val);
00267     }
00268     break;
00269   }
00270 }
00271 
00272 void SctApi::modifyABCDVar(UINT32 mid, UINT32 typ, FLOAT32 val) {
00273   {
00274     boost::mutex::scoped_lock lock(logMutex);
00275     log << "modifyABCDVar (module " << mid << ") " << typ << " " << val << "\n";
00276   }
00277 
00278   switch(typ) {
00279     // First some module parameters (BOC)
00280   case ST_RX_DELAY:
00281   case ST_RX_DELAY0:
00282   case ST_RX_DELAY1:
00283   case ST_RX_THRESHOLD:
00284   case ST_RX_THRESHOLD0:
00285   case ST_RX_THRESHOLD1:
00286   case ST_TX_CURRENT:
00287   case ST_TX_MARKSPACE:
00288   case ST_TX_DELAY:
00289   case ST_TX_COARSE:
00290   case ST_TX_FINE:
00291 
00292     // Global BOC registers
00293   case SCT_SCAN_BOC_BPM_PHASE:
00294   case SCT_SCAN_BOC_BREG_PHASE:
00295   case SCT_SCAN_BOC_V0_PHASE:
00296   case SCT_SCAN_BOC_V1_PHASE:
00297   case SCT_SCAN_BOC_V_PHASES:
00298   case SCT_SCAN_BOC_VRN_FINE:
00299 
00300   case SCT_SCAN_TX_CHANNELS:
00301   case SCT_SCAN_RAW_TX_CHANNELS:
00302     {
00303       unsigned int partition, crate, rod, channel;
00304       Utility::getpcrc(mid, partition, crate, rod, channel);
00305 
00306       cout << "Calling BOCCard method for module " << mid << " " << typ << " " << val << endl;
00307 
00308       try {
00309         // Do channel mapping
00310         getCrate(partition, crate)->modifyBOCParam(rod, channel, typ, fToInt(val), false);
00311       } catch(CrateException &c) {
00312         cout << "CrateException: " << c.what() << endl;
00313       }
00314       break;
00315     }
00316 
00317     // Some module wide parameters
00318 
00319    case ST_BYPASS:
00320      {
00321        // If more then could be more general
00322        ABCDModule *mConf = lookupConfig(mid);
00323 
00324        if(!mConf) {
00325          cout << "No module configuration to change\n";
00326          return;
00327        }
00328 
00329        ABCDModule &module = *mConf;
00330 
00331        /*
00332         * A method used to select certain predetermined bypass configurations.
00333         * Made obsolete by ST_TOKEN (below) but included here for reasons of
00334         * backward compatibility. Recoded to use setToken function.
00335         */
00336        UINT8 int_val = (UINT8)((val+0.5)/1.0);
00337        switch(int_val){
00338        case 0: /* ME---- ME---- */
00339          setToken(&module, 0x03 +(0x03<<6),1,1);
00340          break;
00341        case 1: /* MSE--- MSE--- */
00342          setToken(&module, 0x07 +(0x07<<6),1,1);
00343          break;
00344        case 2: /* MSSE-- MSSE-- */
00345          setToken(&module, 0x0F +(0x0F<<6),1,1);
00346          break;
00347        case 3: /* MSSSE- MSSSE- */
00348          setToken(&module, 0x1F +(0x1F<<6),1,1);
00349          break;
00350          /* case 4 is the default configuration */
00351        case 5: /* MDE--- MDE--- */
00352          setToken(&module, 0x05 +(0x05<<6),1,1);
00353          break;
00354        case 6: /* MSDE-- MSDE-- */
00355          setToken(&module, 0x0b +(0x0b<<6),1,1);
00356          break;
00357        case 7: /* MSSDE- MSSDE- */
00358          setToken(&module, 0x17 +(0x17<<6),1,1);
00359          break;
00360        case 8: /* MSSSDE MSSSDE */
00361          setToken(&module, 0x2f +(0x2f<<6),1,1);
00362          break;
00363        case 9: /* MSSSSS DSSSSE */
00364          setToken(&module, 0x3f +(0x3e<<6),2,0);
00365          break;
00366        case 10: /* DSSSSE MSSSSS */
00367          setToken(&module, 0x3e +(0x3F<<6),0,2);
00368          break;
00369        case 11: /* MSSSSS SSSSSE */
00370          setToken(&module, 0x3f +(0x3f<<6),2,0);
00371          break;
00372        case 12: /* SSSSSE MSSSSS */
00373          setToken(&module, 0x3f +(0x3F<<6),0,2);
00374          break;
00375        default: /* MSSSSE MSSSSE */
00376          setToken(&module, 0x3F +(0x3F<<6),1,1);
00377          break;
00378        }
00379        break;
00380      }
00381 
00382   case ST_TOKEN:
00383      {
00384        // If more then could be more general
00385        ABCDModule *mConf = lookupConfig(mid);
00386 
00387        if(!mConf) {
00388          cout << "No module configuration to change\n";
00389          return;
00390        }
00391 
00392        ABCDModule &module = *mConf;
00393 
00394        /*
00395         * This variable iterates over a set of token/data passing
00396         * schemes to determine the functionality of each token link.
00397         * The sequence sets all the combinations to read-out
00398         * n chips by first testing the bypass token (chip n-2 to n) 
00399         * for all combinations of (n-2) chips. Secondly trying the 
00400         * direct token (n-1 to n) for all combinations of (n-1) chips.
00401         *
00402         * For configurations 0-19, both datalinks are exercised at once.
00403         * For the remaining configurations, only one datalink is
00404         * used at once, as outlined below:
00405         *
00406         * o Even Configurations 20-34 read out chip S9 via datalink 0
00407         *   using the bypass link between E5 and S9.
00408         * 
00409         * o Odd  Configurations 21-35 read out chip S1 via datalink 1
00410         *   using the bypass link between E13 and S1.
00411         *
00412         * o Even configurations 36-60 read out chip M8 via datalink 0
00413         *   using first the bypass link between S4 and M8 and then
00414         *   the direct link between E5 and M8.
00415         *
00416         * o Odd  configurations 37-61 read out chip M0 via datalink 1
00417         *   using first the bypass link between S12 and M0 and then
00418         *   the direct link between E13 and M0.
00419         *
00420         * Only cases 0-35 have been implememted in the design of the
00421         * barrel hybrid. The logical inconsistency in the order between 
00422         * cases 20-35 and 36-61 is done such that the subset of the 
00423         * schemes used by the barrel design form a consecutive series.
00424         *
00425         * Orignal code by Lars Eklund, March 2001
00426         */
00427 
00428        int myVal = fToInt(val);
00429 
00430        if(myVal<20) {              /* use both datalinks */
00431          setToken(&module, (tokens[myVal] + (tokens[myVal] << 6)),1,1);
00432 
00433        } else if(myVal<36) {       /* use datalink 0 */
00434          if(!((int)myVal%2)) {
00435            setToken(&module, (tokens[(myVal-20)/2+12] + (0x1 << 7)),2,0);
00436          } else {                /* use datalink 1 */
00437            setToken(&module, (0x2 + (tokens[(myVal-21)/2+12] << 6)),0,2);
00438          }
00439        } else { // only possible for forward modules
00440          if(!(myVal%2)) {
00441            setToken(&module, (tokens[((myVal-36)/2+7)] + (1 << 6)),2,0);
00442          } else {
00443            setToken(&module, (0x1 + (tokens[((myVal-37)/2+7)] << 6)),0,2);
00444          }
00445        }
00446        break;
00447    }
00448 
00449   case MVAR_GROUP_ID:
00450     {
00451       // If more then could be more general
00452       ABCDModule *mConf = lookupConfig(mid);
00453 
00454       if(!mConf) {
00455         cout << "No module configuration to change\n";
00456         return;
00457       }
00458 
00459       mConf->groupId = fToInt(val);
00460       break;
00461     }
00462 
00463   case MVAR_ACTIVE:
00464     {
00465       // If more then could be more general
00466       ABCDModule *mConf = lookupConfig(mid);
00467 
00468       if(!mConf) {
00469         cout << "No module configuration to change\n";
00470         return;
00471       }
00472 
00473       mConf->active = fToInt(val);
00474       break;
00475     }
00476 
00477   case MVAR_SELECT:
00478     {
00479        // If more then could be more general
00480        ABCDModule *mConf = lookupConfig(mid);
00481 
00482        if(!mConf) {
00483          cout << "No module configuration to change\n";
00484          return;
00485        }
00486 
00487        mConf->select = fToInt(val);
00488 
00489        if(mConf->select) {
00490          for(int c=0; c<12; c++) {
00491            mConf->chip[c].address |= 0x10;
00492         }
00493        } else {
00494          for(int c=0; c<12; c++) {
00495            mConf->chip[c].address &= ~0x10;
00496          }
00497        }
00498 
00499        break;
00500     }
00501 
00502   default:
00503     {
00504       // The rest are chip parameters
00505       for(int c=0; c<12; c++) {
00506         modifyABCDVar(mid, c, typ, val);
00507       }
00508     }
00509     break;
00510   }
00511 }
00512 
00513 void SctApi::modifyABCDVar(UINT32 mid, UINT32 c, UINT32 typ, FLOAT32 val) {
00514   {
00515     boost::mutex::scoped_lock lock(logMutex);
00516     log << "modifyABCDVar (module " << mid << ": chip " << c  << ") " << typ << " " << val << "\n";
00517   }
00518 
00519   ABCDModule *mConf = lookupConfig(mid);
00520 
00521   if(!mConf) {
00522     cout << "No module configuration to change\n";
00523     return;
00524   }
00525 
00526   ABCDModule &module = *mConf;
00527 
00528   ABCDChip &chip = module.chip[c];
00529 
00530   switch(typ) {
00531   case ST_ELAPSED: 
00532     // Do nothing
00533     break;
00534   case ST_VTHR: 
00535     chip.basic.vthr = (char) fToInt(val/2.5);
00536     break;
00537   case ST_VCAL:
00538     chip.basic.vcal = (char) fToInt(val/0.625);
00539     break;
00540   case ST_STROBE_DELAY:
00541     chip.basic.delay = (char) fToInt(val);
00542     break;
00543   case ST_PREAMP:
00544     chip.basic.preamp = (char) fToInt(val/9.2);
00545     break;
00546   case ST_SHAPER:
00547     chip.basic.shaper = (char) fToInt(val/1.2);
00548     break;
00549   case ST_TRIM:
00550     for(int i=0; i<128; i++) {
00551       chip.trim[i] = (char) fToInt(val);
00552     }
00553     break;
00554   case ST_MASK:
00555     {
00556       UINT32 myval = (UINT32) fToInt(val);
00557       UINT32 mask = myval;
00558       for(int i=0; i<16; i++) {
00559         mask = (mask << 2) + myval;
00560       }
00561 
00562       for(int i=0; i<4; i++) {
00563         chip.basic.mask[i] = mask;
00564       }
00565     }
00566     break;
00567   case ST_ROLE:
00568     switch(fToInt(val)) {
00569     case END:
00570       chip.basic.config.master = 1;  // active low
00571       chip.basic.config.end = 1;     // active high
00572       chip.basic.config.feedThrough = 1; // active low
00573       break;
00574     case MASTER:
00575       chip.basic.config.master = 0;  // active low
00576       chip.basic.config.end = 0;     // active high
00577       chip.basic.config.feedThrough = 1;
00578       break;
00579     case SLAVE:
00580       chip.basic.config.master = 1;  // active low
00581       chip.basic.config.end = 0;     // active high
00582       chip.basic.config.feedThrough = 1;
00583       break;
00584     case LONELY:
00585       chip.basic.config.master = 0;  // active low
00586       chip.basic.config.end = 1;     // active high
00587       chip.basic.config.feedThrough = 1;
00588       break;
00589     case PARANOID:
00590       chip.basic.config.master = 0;  // active low
00591       chip.basic.config.end = 1;     // active high
00592       chip.basic.config.feedThrough = 1;
00593     case DEAD:
00594     default:
00595       module.chip[(c+1)%12].basic.config.outputBypass = 1;
00596       module.chip[(c+11)%12].basic.config.inputBypass = 1;
00597     case MISSING:
00598       break;
00599     } // End switch role
00600 
00601   case ST_NMASK:
00602     {
00603       int channels = fToInt(val);
00604       if(channels > 128) channels = 128;
00605 
00606       for(int i=0; i<4; i++) {
00607         // How many channels in this group
00608         int chan = channels - i*32;
00609         if(chan >= 32) {
00610           chip.basic.mask[i] = 0x00000000;
00611         } else {
00612           int value = 0;
00613           for(int b=0; b<chan; b++) {
00614             value <<= 1;
00615             value ++;
00616           }
00617           chip.basic.mask[i] = ~value;
00618         }
00619       }
00620     }
00621     break;
00622   case ST_CAL_MODE:
00623     chip.basic.config.calibMode = fToInt(val);
00624     break;
00625   case ST_COMPRESSION:
00626     chip.basic.config.readoutMode = fToInt(val);
00627     break;
00628   case ST_TRIM_RANGE:
00629     chip.basic.config.trimRange = fToInt(val);
00630     break;
00631   case ST_EDGE_DETECT:
00632     chip.basic.config.edgeDetect = fToInt(val);
00633     break;
00634   case ST_SEND_MASK:
00635     chip.basic.config.mask = fToInt(val)?1:0;
00636     break;
00637   case ST_ACCUMULATE:
00638     chip.basic.config.accumulate = fToInt(val);
00639     break;
00640   case ST_FEEDTHROUGH:
00641     chip.basic.config.feedThrough = fToInt(val);
00642     break;
00643   case ST_ACTIVE:
00644     chip.active = fToInt(val);
00645     break;
00646 
00647     //  Can't be set on a chip by chip basis!
00648 //    case ST_BYPASS:
00649 //    case ST_TOKEN:
00650 
00651 #ifdef DO_TOKENS_BY_CHIP
00652   case ST_BYPASS:
00653     {
00654       /*
00655        * A method used to select certain predetermined bypass configurations.
00656        * Made obsolete by ST_TOKEN (below) but included here for reasons of
00657        * backward compatibility. Recoded to use setToken function.
00658        */
00659       UINT8 int_val = (UINT8)((val+0.5)/1.0);
00660       switch(int_val){
00661       case 0: /* ME---- ME---- */
00662         setToken(&module, 0x03 +(0x03<<6),1,1);
00663         break;
00664       case 1: /* MSE--- MSE--- */
00665         setToken(&module, 0x07 +(0x07<<6),1,1);
00666         break;
00667       case 2: /* MSSE-- MSSE-- */
00668         setToken(&module, 0x0F +(0x0F<<6),1,1);
00669         break;
00670       case 3: /* MSSSE- MSSSE- */
00671         setToken(&module, 0x1F +(0x1F<<6),1,1);
00672         break;
00673         /* case 4 is the default configuration */
00674       case 5: /* MDE--- MDE--- */
00675         setToken(&module, 0x05 +(0x05<<6),1,1);
00676         break;
00677       case 6: /* MSDE-- MSDE-- */
00678         setToken(&module, 0x0b +(0x0b<<6),1,1);
00679         break;
00680       case 7: /* MSSDE- MSSDE- */
00681         setToken(&module, 0x17 +(0x17<<6),1,1);
00682         break;
00683       case 8: /* MSSSDE MSSSDE */
00684         setToken(&module, 0x2f +(0x2f<<6),1,1);
00685         break;
00686       case 9: /* MSSSSS DSSSSE */
00687         setToken(&module, 0x3f +(0x3e<<6),2,0);
00688         break;
00689       case 10: /* DSSSSE MSSSSS */
00690         setToken(&module, 0x3e +(0x3F<<6),0,2);
00691         break;
00692       case 11: /* MSSSSS SSSSSE */
00693         setToken(&module, 0x3f +(0x3f<<6),2,0);
00694         break;
00695       case 12: /* SSSSSE MSSSSS */
00696         setToken(&module, 0x3f +(0x3F<<6),0,2);
00697         break;
00698       default: /* MSSSSE MSSSSE */
00699         setToken(&module, 0x3F +(0x3F<<6),1,1);
00700         break;
00701       }
00702       break;
00703     }
00704 
00705   case ST_TOKEN:
00706     {
00707       /*
00708        * This variable iterates over a set of token/data passing
00709        * schemes to determine the functionality of each token link.
00710        * The sequence sets all the combinations to read-out
00711        * n chips by first testing the bypass token (chip n-2 to n) 
00712        * for all combinations of (n-2) chips. Secondly trying the 
00713        * direct token (n-1 to n) for all combinations of (n-1) chips.
00714        *
00715        * For configurations 0-19, both datalinks are exercised at once.
00716        * For the remaining configurations, only one datalink is
00717        * used at once, as outlined below:
00718        *
00719        * o Even Configurations 20-34 read out chip S9 via datalink 0
00720        *   using the bypass link between E5 and S9.
00721        * 
00722        * o Odd  Configurations 21-35 read out chip S1 via datalink 1
00723        *   using the bypass link between E13 and S1.
00724        *
00725        * o Even configurations 36-60 read out chip M8 via datalink 0
00726        *   using first the bypass link between S4 and M8 and then
00727        *   the direct link between E5 and M8.
00728        *
00729        * o Odd  configurations 37-61 read out chip M0 via datalink 1
00730        *   using first the bypass link between S12 and M0 and then
00731        *   the direct link between E13 and M0.
00732        *
00733        * Only cases 0-35 have been implememted in the design of the
00734        * barrel hybrid. The logical inconsistency in the order between 
00735        * cases 20-35 and 36-61 is done such that the subset of the 
00736        * schemes used by the barrel design form a consecutive series.
00737        *
00738        * Orignal code by Lars Eklund, March 2001
00739        */
00740 
00741       int myVal = fToInt(val);
00742 
00743       if(myVal<20) {              /* use both datalinks */
00744         setToken(&module, (tokens[(int)myVal] + (tokens[(int)myVal] << 6)),1,1);
00745       } else if(myVal<36) {       /* use datalink 0 */
00746         if(!((int)myVal%2)) {
00747           setToken(&module, (tokens[(int)(myVal-20)/2+12] + (0x1 << 7)),2,0);
00748         } else {                /* use datalink 1 */
00749           setToken(&module, (0x2 + (tokens[((int)myVal-21)/2+12] << 6)),0,2);
00750         }
00751       } else { // only possible for forward modules
00752         if(!((int)myVal%2)) {
00753           setToken(&module, (tokens[(int)((myVal-36)/2+7)] + (1 << 6)),2,0);
00754         } else {
00755           setToken(&module, (0x1 + (tokens[(int)((myVal-37)/2+7)] << 6)),0,2);
00756         }
00757       }
00758       break;
00759     }
00760 #endif
00761   case ST_QTHR: 
00762     {
00763       ABCDCaldata &calPtr = chip.caldata;
00764       float v, vv;
00765 
00766       switch(calPtr.rc_function){
00767       case 1: /* polynomial */
00768         v = calPtr.rc_params[0] + 
00769           val * (calPtr.rc_params[1] + 
00770                  (val * calPtr.rc_params[2]) );
00771         break; 
00772       case 2: /* grillo */
00773         if((val==0)|| (calPtr.rc_params[1]==0))
00774           vv = 0;
00775         else
00776           vv = calPtr.rc_params[2] / 
00777             (calPtr.rc_params[1] *val);
00778         v  = calPtr.rc_params[0] + 
00779           calPtr.rc_params[2] / (float) sqrt(1+(vv*vv)); 
00780         break; 
00781       case 3: /* exp */
00782         if(calPtr.rc_params[1]==0)
00783           v = 0;
00784         else
00785           v = calPtr.rc_params[2] + 
00786             calPtr.rc_params[0]/(1+ (float)exp(-val/calPtr.rc_params[1]));
00787         break;  
00788       case 4: /* linear fit */
00789         v = calPtr.rc_params[0] + 
00790           (val * calPtr.rc_params[1]);
00791         break; 
00792       default:
00793         v = 0;
00794         break;
00795       }
00796 
00797       UINT8 int_val = ((UINT8)((v+1.25)/(float)2.5));  /* 2.5mV / DAC bit */
00798       chip.basic.vthr = int_val;
00799       break;
00800     }
00801 
00802   case ST_QCAL:
00803     /*
00804      * calculate the actual vcal step size taking into
00805      * account the capacitor correction factor:
00806      * step size = (c_factor * 0.0625) fC / DAC bit 
00807      */
00808     {
00809       FLOAT32 step = (float) 0.0625 * chip.caldata.c_factor;
00810       UINT8 int_val = (UINT8)((val+(step/2))/step);
00811       chip.basic.vcal = int_val;
00812       break;
00813     }
00814   case ST_TARGET:
00815     {
00816       /*
00817        * record the target to which the chip has been trimmed
00818        * added PWP 07.01.03
00819        */
00820       UINT8 int_val = ((UINT8)((val+1.25)/(float)2.5));  /* 2.5mV / DAC bit */
00821 
00822       /* int_val must be in range if declared UINT8
00823          if(int_val<0x00) int_val = 0x00;
00824          if(int_val>0xff) int_val = 0xff;
00825       */
00826       chip.target = int_val;
00827       break;
00828     }
00829 
00830   case ST_TTHR:
00831     {
00832       /*
00833        * set the threshold in mV wrt the trim target
00834        * added PWP 07.01.03
00835        */
00836       UINT8 int_val = ((UINT8)((val+1.25)/(float)2.5));  /* 2.5mV / DAC bit */
00837       int_val += chip.target;
00838 
00839       /*
00840         if(int_val<0x00) int_val = 0x00;
00841         if(int_val>0xff) int_val = 0xff;
00842       */
00843       chip.basic.vthr = int_val;
00844       break;
00845     }
00846 
00847   case ST_RX_DELAY:
00848   case ST_RX_DELAY0:
00849   case ST_RX_DELAY1:
00850   case ST_RX_THRESHOLD:
00851   case ST_RX_THRESHOLD0:
00852   case ST_RX_THRESHOLD1:
00853   case ST_TX_CURRENT:
00854   case ST_TX_MARKSPACE:
00855   case ST_TX_DELAY:
00856   case ST_TX_COARSE:
00857   case ST_TX_FINE:
00858     {
00859       unsigned int partition, crate, rod, channel;
00860       Utility::getpcrc(mid, partition, crate, rod, channel);
00861 
00862       cout << "Calling BOCCard method for module " << channel << " " << typ << " " << val << endl;
00863 
00864       // Do channel mapping
00865       getCrate(partition, crate)->modifyBOCParam(rod, channel, typ, fToInt(val), false);
00866       break;
00867     }
00868 
00869   default:
00870     cout << "Unknown variable type " << typ << "\n";
00871     break;
00872   } // End switch var
00873 }
00874 }

Generated on Thu Feb 10 02:40:16 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5