SctApiMConf.cxx

00001 
00013 #include "primListWrapper.h"
00014 #include "PrimBuilder.h"
00015 #include "SctApi.h"
00016 #include "SctApiRodInfo.h"
00017 #include "crate.h"
00018 #include "utility.h"
00019 #include "SctApiDebug.h"
00020 
00021 #include "CommonWithDsp/primParams.h"
00022 #include "CommonWithDsp/registerIndices.h"
00023 #include <boost/timer.hpp>
00024 #include "Sct/FibreNumberConverters.h"
00025 #include "ConfigurationUtility.h"
00026 #include "sctConf/configuration.h"
00027 #include "SctApiException.h"
00028 
00029 using namespace std;
00030 using namespace SctPixelRod;
00031 
00032 namespace SctApi {
00033 
00034 void SctApi::getABCDModules(BankType bank_type) {
00035   {
00036     boost::mutex::scoped_lock lock(log().mutex());
00037     log() << "getABCDModule (all). Bank: " << bank_type << endl;
00038   }
00039   for(map<UINT32, ABCDModule> ::const_iterator iter = moduleMap.begin();
00040       iter != moduleMap.end();
00041       iter ++) {
00042     getABCDModule(iter->first, bank_type);
00043   }
00044 }
00045 
00046 
00047 void SctApi::getABCDModule(UINT32 mid, BankType bank_type) {
00048   unsigned int partition, crate, rod, channel;
00049   Utility::getpcrc(mid, partition, crate, rod, channel);
00050 
00051   if(checkDebugOption(DEBUG_MODULE_CONFIG)) std::cout << "AJB getABCDModule mid " << mid << " bank " << bank_type << std::endl;
00052   boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00053   if (!the_banks.get()) {
00054     if(mrs) {
00055       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00056            << MRS_PARAM<int>("mid", mid)
00057            << MRS_TEXT("Cant return cache for non-existant MID") << ENDM;
00058     }else{
00059       cerr << "Non-existant module mid=" << mid << std::endl; 
00060     }
00061     return;
00062   }
00063   boost::shared_ptr<ABCDModule> cached_config = the_banks->get(bank_type);
00064   if (!cached_config.get()){
00065     if(mrs) {
00066       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00067            << MRS_PARAM<int>("mid", mid)
00068            << MRS_PARAM<int>("bank", bank_type)
00069            << MRS_TEXT("Cant return cache for non-existant BANK") << ENDM;
00070     }else{
00071       cerr << "Non-existant bank, mid=" << mid 
00072        << "api bank = " << bank_type << std::endl; 
00073     }
00074     if(checkDebugOption(DEBUG_API_CONFIG_CACHE_CHECK)){
00075       std::cout << "Bravely persisting to try to read unset bank... (but printing, not storing the results)";
00076       boost::shared_ptr<ABCDModule> rod_config = getABCDModuleRaw(rod, channel, bank_type);
00077       std::cout << config->printModuleConfig(*rod_config) << std::endl;
00078     }
00079     return;
00080   }
00081 
00082   ABCDModule *previous = lookupConfig(mid);
00083   if(previous) {
00084     *previous = *cached_config;
00085   } else {
00086     std::cout << "WARNING - no previous configuration existed for mid " << mid 
00087           << " BANK "<< bank_type << std::endl;
00088     moduleMap.insert(make_pair(mid, *cached_config));
00089   }
00090 
00091   // option to test cache of this bank against the real ROD bank:
00092   if(checkDebugOption(DEBUG_API_CONFIG_CACHE_CHECK)){
00093     if (ConfigUtility::diff(*previous, *cached_config)){
00094       std::cerr << "ERROR in setting equality " << __FILE__ << ":" << __LINE__ << std::endl;
00095     }
00096     boost::shared_ptr<ABCDModule> rod_config = getABCDModuleRaw(rod, channel, bank_type);
00097     
00098     // get bit-field of difference types
00099     unsigned differences=ConfigUtility::diff(*rod_config, *cached_config);
00100     if (differences){
00101       string diff_as_string = ConfigUtility::apiBitFieldToString(differences);
00102       if (mrs){
00103     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_WARNING << MRS_QUALIF("SCTAPI") 
00104          << MRS_PARAM<int>("module", mid)
00105          << MRS_TEXT("DEBUG error - configuration in CACHE and ROD differ!")             
00106          << MRS_PARAM<const char*>("diff bitfield", diff_as_string.c_str())
00107              << ENDM;
00108       }
00109       cout << "ERROR on module configuration cache:"
00110        << " mid " <<  mid << " bank " << bank_type
00111        << " differences:" << diff_as_string << endl;
00112       cout << "=====>>> MID:" << mid << " CACHE config" << endl;
00113       if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
00114     cout << config->printModuleConfig(*cached_config);
00115       }
00116       cout << "=====>>> differs from MID:" << mid << " ROD config" << endl;
00117       if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
00118     cout << config->printModuleConfig(*rod_config);
00119       }
00120       std::cout << "\tCache\tRod" << std::endl;
00121       ConfigUtility::diff(*cached_config, *rod_config, true);
00122     }else{
00123       if(checkDebugOption(DEBUG_MODULE_CONFIG)) std::cout << "Checked differences - ok for mid " << mid << " bank " << bank_type << std::endl;
00124     }
00125   }
00126 }
00127 
00128 void printBanks(list<BankType> banks, ostream& os){
00129    for (list<BankType>::const_iterator i=banks.begin(); i!=banks.end(); ++i){
00130       if (i!=banks.begin()) os << ",";
00131       switch (*i) {
00132       case 0 : os << "PHYSICS"; break; 
00133       case 1 : os << "SCAN"; break;
00134       case 2 : os << "CALIBRATION"; break;
00135       default : os << "UNKNOWN-BANK-TYPE!"; break;
00136       }
00137    }
00138    if (banks.begin()==banks.end()) os << "NONE!";
00139 }
00140 
00141 void SctApi::copyABCDModules(BankType source, list<BankType> to){
00142   if (to.empty()){
00143     std::cout << "ERROR - request to copy modules from " << source << "to empty bank list" << std::endl;
00144     return;
00145   }
00146   if(checkDebugOption(DEBUG_MODULE_CONFIG)) std::cout << "AJB copyABCDModules (all) from " << source << " to ";
00147   printBanks(to, cout); 
00148   std::cout << std::endl;
00149 
00150 #if (R_RW_MODULE_DATA<103)
00151   if (true){
00152 #else
00153   if (checkDebugOption(DEBUG_API_CONFIG_NO_COPY)){
00154 #endif
00155     std::cout << " USING OLD get/set METHODS!" << endl;
00156     getABCDModules(source);
00157     setABCDModules(to);
00158   }else{
00159     boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00160     UINT32 bank_bits = Utility::translateApiBanksToRodCfgBitSet(to);
00161     PrimBuilder::instance().copyModuleData(primList, source, bank_bits, ALL_MODULES);
00162 
00163     if (synchSendPrimListAll(primList, 3)!=0){
00164       if (mrs){
00165     *mrs << "COPY_BANKS" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00166          << MRS_TEXT("Copy of all module configuration data failed") << ENDM;   
00167       }else{
00168     std::cout << "ERROR : copy all modules primitives from " << source << " to ";
00169     printBanks(to, std::cout);
00170     std::cout << " failed" << std::endl;
00171       }
00172     }else{
00173       std::cout << "synch send returned sucessfully" << std::endl;
00174     }
00175   }
00176   module_cache.copyAllModules(source, to);
00177 } 
00178 
00179 void SctApi::copyABCDModule(UINT32 mid, BankType source, list<BankType> to){
00180   if (to.empty()){
00181     std::cout << "ERROR - request to copy modules from " << source << "to empty bank list" << std::endl;
00182     return;
00183   }
00184   {
00185     boost::mutex::scoped_lock lock(log().mutex());
00186     log() << "ERROR - request to copy modules from " << source << "to ";
00187     printBanks(to, log()); 
00188     log() << std::endl;
00189   }
00190   
00191   if (checkDebugOption(DEBUG_MODULE_CONFIG)) {
00192     std::cout << "copyABCDModules (all) from " << source << " to ";
00193     printBanks(to, cout); 
00194     std::cout << std::endl;
00195   }
00196 
00197 #if (R_RW_MODULE_DATA<103)
00198   if (true){
00199 #else
00200   if (checkDebugOption(DEBUG_API_CONFIG_NO_COPY)){
00201 #endif
00202     std::cout << " USING OLD get/set METHODS!" << endl;
00203     getABCDModule(mid, source);
00204     setABCDModule(mid, to);  
00205   }else{
00206      if(checkDebugOption(DEBUG_MODULE_CONFIG)){
00207        cout << "copyABCDModule mid=" << mid << " from " << source << " to ";
00208        printBanks(to, cout);
00209        cout << endl;
00210      }
00213     unsigned int partition, crate, rod, channel;
00214     Utility::getpcrc(mid, partition, crate, rod, channel);
00215     
00216     boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00217     
00218     UINT32 bank_bits =  Utility::translateApiBanksToRodCfgBitSet(to);
00219     PrimBuilder::instance().copyModuleData(primList, source, bank_bits, channel);
00220 
00221     sendPrimList(rod, primList);
00222     if(awaitResponse(rod, 4)!=0) {
00223       if (mrs){
00224     *mrs << "COPY_BANKS" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00225          << MRS_PARAM<int>("mid", mid)
00226          << MRS_TEXT("Copy of module configuration data failed") << ENDM;   
00227       }else{
00228     cout << "ERROR - copy module unsuccessful!\n";
00229       }
00230       return;
00231     }else{
00232        if(checkDebugOption(DEBUG_MODULE_CONFIG)) std::cout << "sucessful" << std::endl;
00233     }
00234     boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00235     if (the_banks.get()){
00236       the_banks->copy(source, to);
00237     }else{
00238       if (mrs){
00239     *mrs << "COPY_BANKS" << MRS_ERROR << MRS_QUALIF("SCTAPI")
00240          << MRS_PARAM<int>("mid", mid)
00241          << MRS_TEXT("Configuration not found in cache") << ENDM;
00242       }else{
00243     cout << "ERROR - cache not found" << std::endl;
00244       }
00245     }
00246   }
00247 }
00248 
00249 void SctApi::setABCDModule(UINT32 mid, list<BankType> bank_list) {
00250   UINT32 all_differences=0;
00251    if(checkDebugOption(DEBUG_MODULE_CONFIG)){
00252      cout << "setABCDModule mid=" << mid << " banks=";
00253      printBanks(bank_list, cout);
00254      cout << endl;
00255   }
00256   using boost::shared_ptr;
00257   ABCDModule* lookup=lookupConfig(mid);
00258   if (!lookup) {
00259     cerr << "setABCDModule : Could not find module config for mid = " << mid << endl;
00260     return;
00261   }
00262 
00263   shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00264 
00265   // get cache of banks for this mid, or create it (in which case the config must be sent)
00266   if (!the_banks.get()) {
00267     //std::cout << "New module config to rod MID " << mid << std::endl;
00268     the_banks=shared_ptr<SctApiConfigCache::ModuleBanks>(new SctApiConfigCache::ModuleBanks);    
00269     module_cache.set(mid, the_banks);
00270     all_differences |= 1 << SCTAPI_CONFIG_ALL;
00271   }
00272   
00273   list<BankType> modified_bank_list;
00274   for (list<BankType>::const_iterator bank_iterator=bank_list.begin(); 
00275        bank_iterator!=bank_list.end(); ++bank_iterator){
00276     BankType bank_type=*bank_iterator;
00277     shared_ptr<ABCDModule> current_cache=the_banks->get(bank_type);
00278     
00279     // get ABCDModule for this bank, or create it (in which case the config must be sent)
00280     if (!current_cache.get()) {
00281       current_cache = shared_ptr<ABCDModule>(ConfigUtility::clone(*lookupConfig(mid)).release());
00282       the_banks->set(bank_type, current_cache);
00283       modified_bank_list.push_back(bank_type);
00284       if(checkDebugOption(DEBUG_MODULE_CONFIG)) std::cout << "  MID " << mid << " adding cache for bank " << bank_type << std::endl;
00285       all_differences |= 1 << SCTAPI_CONFIG_ALL;
00286     }else{
00287       /*
00288     Get bit-field of all differences between local config and ROD cache.
00289     1/3/2005 AJB has set the conditional below because at the end of the scan 
00290     the SCAN bank is in an odd state, hence we always should copy the scan bank,
00291     if that has been explicitly requested
00292       */
00293       unsigned differences=ConfigUtility::diff(*current_cache, *lookup);
00294       // gather up differences
00295       all_differences |= differences;
00296       if (differences){
00297     *current_cache = *lookup;
00298     modified_bank_list.push_back(bank_type);
00299     if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
00300         std::cout << "  MID " << mid << " bank " << bank_type << " modifications: " 
00301           << ConfigUtility::apiBitFieldToString(differences) << std::endl;
00302         }
00303       }else{
00304     if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
00305       cout << "No need to set ABCDModule type " << bank_type
00306            << " for mid = " << mid
00307            << " and bank_type  = " << bank_type
00308            << " as configuration hasnt changed, " << endl;
00309     }
00310     if(checkDebugOption(DEBUG_API_CONFIG_CACHE_SEND)){
00311       cout << "Debug option set so sending module configuration ANYWAY!" << endl;
00312       modified_bank_list.push_back(bank_type);
00313       differences |= SCTAPI_CONFIG_ALL;
00314     }
00315       }
00316     }
00317   }
00318   if (modified_bank_list.empty()){
00319     cout << ucid() << " mid " << mid << " no banks need setting" << endl;
00320   }else{
00321     really_setABCDModule(mid, modified_bank_list, all_differences);
00322   }
00323 }
00324 
00325 #warning "This isn't called from anywhere!"
00326 void SctApi::really_getABCDModule(UINT32 mid, BankType bank_type) {
00327   {
00328     boost::mutex::scoped_lock lock(log().mutex());
00329     log() << "getABCDModule " << mid << " Bank: " << bank_type << endl;
00330   }
00331 
00332   // Find module channel in ROD
00333   unsigned int partition, crate, rod, channel;
00334   Utility::getpcrc(mid, partition, crate, rod, channel);
00335 
00336   // Which bank id to use
00337   int realBank = Utility::translateBank(bank_type);
00338 
00339   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00340   PrimBuilder::instance().readModuleData(primList, realBank, channel);
00341 
00342   sendPrimList(rod, primList);
00343 
00344   int responseCode = awaitResponse(rod, 5);
00345 
00346   unsigned long length;
00347   unsigned long *outBody = 0;
00348   if(responseCode == 0) {
00349     outBody = getResponse(rod, length);
00350   }
00351 
00352   if(outBody) {
00353 //      unsigned long outLength = outBody[0];
00354 //      unsigned long outIndex = outBody[1];
00355     unsigned long outNumPrims = outBody[2];
00356 //      unsigned long outPrimVersion = outBody[3];
00357 
00358     if(outNumPrims == 1) {
00359       unsigned long primLength = outBody[4];
00360 //        unsigned long primIndex = outBody[5];
00361       unsigned long primID = outBody[6];
00362 //        unsigned long primVersion = outBody[7];
00363 
00364       if(primID == RW_MODULE_DATA) {
00365         if(primLength != (sizeof(ABCDModule)/sizeof(UINT32) + 4)) { // Prim length includes header
00366           cout << "Output primitive was " << primLength << " not " << sizeof(ABCDModule)/sizeof(UINT32) << endl;
00367         }
00368 
00369         // Data is at outBody[8]
00370         ABCDModule result;
00371 
00372         // Copy data
00373         for(unsigned int i=0; i<sizeof(ABCDModule)/sizeof(UINT32); i++) {
00374           ((unsigned long *)&result)[i] = outBody[8 + i];
00375         }
00376 
00377         ABCDModule *previous = lookupConfig(mid);
00378 
00379         if(previous) {
00380           cout << "Replacing previous module config\n";
00381 
00382           *previous = result;
00383         } else {
00384           cout << "New module config inserted\n";
00385           moduleMap.insert(make_pair(mid, result));
00386         }
00387       } else {
00388         cout << "Returned primitive was not RW_MODULE_DATA\n";
00389       }
00390     } else {
00391       cout << "Too many primitives in output list\n";
00392     }
00393 
00394     delete [] outBody;
00395   } else {
00396     cout << "No response to primitive list!\n";
00397   }
00398 }
00399 
00400 boost::shared_ptr<ABCDModule> SctApi::getABCDModuleRaw(unsigned int rod, 
00401                                                        UINT32 slot, BankType bank_type) {
00402   {
00403     boost::mutex::scoped_lock lock(log().mutex());
00404     log() << "getABCDModuleRaw Slot: " << slot << " Bank: " << bank_type << endl;
00405   }
00406 
00407   boost::shared_ptr<ABCDModule> result;
00408 
00409   // Which bank id to use
00410   int realBank = Utility::translateBank(bank_type);
00411 
00412   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00413   PrimBuilder::instance().readModuleData(primList, realBank, slot);
00414   sendPrimList(rod, primList);
00415 
00416   int responseCode = awaitResponse(rod, 5);
00417 
00418   unsigned long length;
00419   unsigned long *outBody = 0;
00420   if(responseCode == 0) {
00421     outBody = getResponse(rod, length);
00422   }
00423 
00424   if(outBody) {
00425     unsigned long outNumPrims = outBody[2];
00426 
00427     if(outNumPrims == 1) {
00428       unsigned long primLength = outBody[4];
00429       unsigned long primID = outBody[6];
00430 
00431       if(primID == RW_MODULE_DATA) {
00432         unsigned int expectedSize = (sizeof(ABCDModule)/sizeof(UINT32) + 4);
00433         if(primLength != expectedSize) { // Prim length includes header
00434           cout << "Output primitive was " << primLength << " not " << expectedSize << endl;
00435         }
00436 
00437         result.reset(new ABCDModule);
00438 
00439         // Data is at outBody[8]
00440         // Copy data
00441         for(unsigned int i=0; i<sizeof(ABCDModule)/sizeof(UINT32); i++) {
00442           ((unsigned long *)result.get())[i] = outBody[8 + i];
00443         }
00444       } else {
00445         cout << "Returned primitive was not RW_MODULE_DATA\n";
00446       }
00447     } else {
00448       cout << "Too many primitives in output list\n";
00449     }
00450 
00451     delete [] outBody;
00452   } else {
00453     cout << "No response to primitive list!\n";
00454   }
00455 
00456   return result;
00457 }
00458 
00459 /* Store config in ROD */
00460 void SctApi::setABCDModules(list<BankType> banks) {
00461   boost::timer set_modules_timer;
00462   cout << "setABCDModules (all) banks=";
00463   printBanks(banks, cout);
00464   cout << endl;
00465   {
00466     boost::mutex::scoped_lock lock(log().mutex());
00467     log() << "setABCDModule called for all modules. Banks : ";
00468     for (list<BankType>::const_iterator it=banks.begin(); it!=banks.end(); ++it){
00469       log() << *it <<",";
00470     }
00471     log() << endl;
00472   }
00473   for(map<UINT32, ABCDModule>::const_iterator iter = moduleMap.begin();
00474       iter != moduleMap.end();
00475       iter ++) {
00476     setABCDModule(iter->first, banks);
00477   }
00478   
00479   /* AJB commented out following bruces changes in R4-updated of 29-6-2005 
00480   // Off-ROD modules need to be sent from the "wrong" ROD
00481   for(list<RodLabel>::const_iterator rl = rodList.begin();
00482       rl!=rodList.end();
00483       rl++){
00484     RodInfo info = getRodInfo(*rl);
00485 
00486     for(map<unsigned long, unsigned long>::const_iterator iter = info.offRODRX.begin();
00487         iter != info.offRODRX.end(); iter++) {
00488       cout << "Set config " << hex << iter->first << " (off ROD pair of " << iter->second << ")" << dec << endl;
00489       setABCDModule(iter->first, banks);
00490     }
00491   }
00492   */
00493 
00494   std::cout << "set all modules in " << set_modules_timer.elapsed() << " seconds" << std::endl;
00495   return;
00496 }
00497 
00498 /* Store config in ROD */
00499 void SctApi::really_setABCDModule(UINT32 mid, list<BankType> bank_list, UINT32 api_cfg_type_bitfield) {
00500   if(checkDebugOption(DEBUG_MODULE_CONFIG)) {
00501     cout << "really_setABCDModule mid=" << mid << " banks=";
00502     printBanks(bank_list, cout);
00503     cout << " cfgbits=" << api_cfg_type_bitfield << endl;
00504   }
00505   if(mid==0xffffffff){
00506     cout << "setABCDModule with 0xffffffff\n";
00507     throw SctApiException("mid out of range");
00508   }
00509 
00510   string moduleName;
00511   ABCDModule *moduleConfig;
00512   
00513   moduleConfig = lookupConfig(mid);
00514   
00515   if(!moduleConfig) {
00516     if(mrs) {
00517       *mrs << "ROD_BANKS" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00518        << MRS_PARAM<int>("module", mid)
00519        << MRS_TEXT("Cant send module configuration - module not in configuration") << ENDM;
00520     }
00521     cout << "ERROR - NO module configuration for mid = " << mid << " in set module" << endl;
00522     return;
00523   }
00524   
00525   cout << "Module config: ";
00526   cout << " primary channel " << (int)moduleConfig->pTTC 
00527        << " red channel " << (int)moduleConfig->rTTC 
00528        << " group " << (int)moduleConfig->groupId
00529        << " select " << (int)moduleConfig->select 
00530        << " apicfgbits=" << api_cfg_type_bitfield << endl;
00531 
00532   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00533 
00534   unsigned int partition, crate, rod, channel;
00535   Utility::getpcrc(mid, partition, crate, rod, channel);
00536   UINT32 bank_bits       = Utility::translateApiBanksToRodCfgBitSet(bank_list);
00537   UINT32 module_bits     = Utility::translateConfigTypeBitset(api_cfg_type_bitfield);
00538   UINT32 setablecfgtype = Utility::getSetableConfigType(module_bits, true);  
00539   PrimBuilder::instance().writeModuleData(primList, moduleConfig, bank_bits, channel, setablecfgtype);
00540 
00541 #if USE_DUAL_PORTS
00542   // Set up module masks so config can be sent using both serial ports
00543   setupModuleMask(SP_BOTH, 0xf, primList);
00544 #else
00545   // This will be a null op if it doesn't exist
00546 #ifdef CMD_BUFFER_0
00547 #warning "Use of old header files detected"
00548   setupModuleMask(CMD_BUFFER_0, 0xf, primList);
00549 #else
00550   setupModuleMask(SP0, 0xf, primList);
00551 #endif
00552 #endif
00553   sendPrimList(rod, primList);
00554   
00555   int responseCode = awaitResponse(rod, 10);
00556   
00557   if(responseCode!=0) {
00558     if (mrs) {
00559       *mrs << "SctApi" << MRS_WARNING << MRS_TEXT("set module unsucessful") 
00560        << MRS_PARAM<long>("MID",mid) 
00561        << MRS_PARAM<const char*>("serial number",moduleConfig->serialNumber)
00562        << ENDM;
00563     } else {
00564       cout << "SctApi: ERROR : set module unsucessful" << endl;
00565       return;
00566     }
00567   }
00568 }
00569 
00570 void SctApi::setErrorMasks(){
00571   std::string errorText="";
00572   // first set them all to zero:
00573   {
00574     unsigned efb_value = 0x0;
00575     boost::shared_ptr<PrimListWrapper> zeroMasksList(new PrimListWrapper(1));
00576     for(int i=0; i<48; i++) {
00577       PrimBuilder::instance().writeRegister(zeroMasksList, Utility::EfbErrorMask(0, i), 0, 12, efb_value);
00578       PrimBuilder::instance().writeRegister(zeroMasksList, Utility::EfbErrorMask(1, i), 0, 12, efb_value);
00579     }
00580     //std::cout << "Setting all error masks to 0x" << hex << efb_value << dec << std::endl;
00581     if (synchSendPrimListAll(zeroMasksList, 5)!=0) errorText+="Error zeroing module error masks\n";
00582   }
00583   
00584   // now set non-zero values for special cases.
00585   // build up prim list for each rod
00586   map<int, boost::shared_ptr<PrimListWrapper> > primlists;
00587   
00588   for (std::map<RodLabel, RodInfo>::const_iterator ri=rodInfoList.begin(); ri!=rodInfoList.end(); ++ri){
00589     for(int l=0; l<96; l++) {
00590       const unsigned int val = ri->second.linkErrorMasks[l];
00591       if (val!=0){
00592     // make the list if necessary:
00593     if (primlists.find(ri->first.rod)==primlists.end()){
00594       primlists[ri->first.rod]=boost::shared_ptr<PrimListWrapper>(new PrimListWrapper(1));
00595     }
00596     PrimBuilder::instance().writeRegister(primlists[ri->first.rod], Utility::EfbErrorMask(l/48, l%48), 0, 12, val);
00597       }
00598     }
00599   }
00600   if (primlists.empty()){
00601     std::cout << "No need to set any special values for error masks" << std::endl;
00602   }
00603   for (map<int, boost::shared_ptr<PrimListWrapper> >::const_iterator ri = primlists.begin(); 
00604        ri!= primlists.end(); ++ri){
00605     const unsigned rod=ri->first;
00606     std::cout << "sending error mask prim list to rod " << rod << std::endl;
00607     sendPrimList(rod, ri->second);
00608     if (awaitResponse(rod, 3)!=0){
00609       errorText += "\nError sending error mask prim list to rod ";
00610       errorText += rod;
00611     }
00612   }
00613   if (errorText!=""){
00614     if (mrs){
00615       *mrs << "SctApi" << MRS_WARNING << MRS_TEXT(errorText) << ENDM;
00616     }else{
00617       cout << errorText << std::endl;
00618     }
00619   }
00620 }
00621 
00622 void SctApi::sendAllABCDModules(BankType bank_type,
00623                                 ConfigType config_type,
00624                                 const bool enableDataMode /* enableDataMode should have default value true to ensure compatibility with old code*/) {
00625 
00626   cout << "AJB AJB sendAllABCDModules bank=" << bank_type << " config_type="
00627             << config_type << " enableDataMode=" << enableDataMode << endl;
00628   {
00629     boost::mutex::scoped_lock lock(log().mutex());
00630     log() << "sendABCDModule called for all modules. Bank: " << bank_type << endl;
00631   }
00632 
00633   /*
00634     This method is far too long...
00635 
00636     1) Change to ROD mode that allows configuration to be sent to the modules
00637     2) Check the BOC isn't interlocked
00638     3) Build and send a primitive list
00639      a) Disable trigger decoder
00640      b) Disable formatters
00641      c) Send configuration
00642      d) Reenable trigger decoder
00643     4) Change "back" to CALIBRATION_MODE
00644 
00645     option 2 (for early versions of the DSP code, probably not every stage necessary)
00646     1) Disable formatters
00647     2) Send configuration for each module in turn using sendABCDModule
00648     3) Setup module masks
00649     4) Reset some FIFOs...
00650 
00651 */
00652 
00653   cout << "Send config to all modules\n";
00654 
00655   PrimBuilder &builder = PrimBuilder::instance();
00656 
00657   // Set ROD mode to something appropriate (may be in TIM mode!)
00658   boost::shared_ptr<PrimListWrapper> rodModeList1(new PrimListWrapper(1));
00659   // Should CALIBRATION_SLINK_OVERRIDE_MODE be added to this (it works without!)
00660   builder.rodMode(rodModeList1, CALIBRATION_MODE, 0, 1, 1, 1, 1);
00661 
00662   synchSendPrimListAll(rodModeList1);
00663 
00664 
00665   // If new primitive use it instead of doing a loop
00666 #if (R_SEND_CONFIG >= 104)
00667   {
00668     boost::mutex::scoped_lock lock(log().mutex());
00669     log() << "\tUsing one SEND_CONFIG primitive\n";
00670   }
00671 
00672   {
00673     for(list<RodLabel>::const_iterator rl = rodList.begin();
00674         rl!=rodList.end();
00675         rl++){
00676       if(!getCrate()->checkBOCLasersOn(rl->rod)) {
00677         cout << "Trying to send module configuration using BOC that has its lasers cut out\n";
00678         if(mrs) {
00679           *mrs << "BOC_INTERLOCKED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00680                << MRS_PARAM<int>("crate", rl->crate) 
00681                << MRS_PARAM<int>("rod", rl->rod)
00682                << MRS_TEXT("Can't send all module config (BOC interlocked)") << ENDM;
00683         }
00684 
00685         throw SctApiException("Send modules aborted due to interlock status");
00686       }
00687     }
00688   }
00689 
00690   boost::shared_ptr<PrimListWrapper> sendConfigList(new PrimListWrapper(1));
00691 
00692   // Write "Disable trigger decoder" to primList
00693 #ifdef RRIF_CMND_1
00694   builder.writeRegister(sendConfigList, RRIF_CMND_1, 18, 1, 0);
00695 #else
00696 #error "Unsupported no registers"
00697 #endif   // RRIF_CMND_1
00698 
00699   // Disable all formatters
00700 #ifdef FMT_LINK_EN
00701   for(int i=0; i<8; i++) {
00702     builder.writeRegister(sendConfigList, FMT_LINK_EN(i), 0, 32, 0);
00703   }
00704 #else
00705 #warning "Probably don't need to turn off formatters!?"
00706 #endif // FMT_LINK_EN
00707 
00708   int realBank = Utility::translateBank(bank_type);
00709   int realConfig = Utility::translateConfigTypeForSendPrimitive(config_type);
00710   
00711   //#warning "AJB Line below added for *debugging*" 
00712   //realConfig = CONFIG_MODULE_ALL;
00713 
00714   //@todo SP_BOTH doesn't work with current DSP code
00715 #if USE_DUAL_PORTS
00716   // Send module configuration from both serial ports (ie two modules at a time)
00717   builder.sendConfig(sendConfigList, SP_BOTH, 0, ALL_MODULES, ALL_MODULES, ALL_CHIPS, 1, 1,
00718                      realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00719 #else
00720   builder.sendConfig(sendConfigList, SP0, 0, ALL_MODULES, ALL_MODULES, ALL_CHIPS, 1, 1,
00721                      realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00722 #endif
00723 
00724   // Write "Re-enable trigger decoder" to primList
00725 #ifdef RRIF_CMND_1
00726   builder.writeRegister(sendConfigList, RRIF_CMND_1, 18, 1, 1);
00727 #else
00728 #error "Unsupported no registers"
00729 #endif  // RRIF_CMND_1
00730 
00731   // setupModuleMask to reenable appropriate formatters??
00732 
00733   sendPrimListAll(sendConfigList);
00734   
00735   {
00736     int responseCode = awaitResponseAll(10);
00737     
00738     if(responseCode != 0) {
00739       cout << "Send modules unsuccessful\n";
00740     }
00741   }
00742 
00743   boost::shared_ptr<PrimListWrapper> rodModeList(new PrimListWrapper(1));
00744   // Should CALIBRATION_SLINK_OVERRIDE_MODE be added to this (it works without!)
00745   builder.rodMode(rodModeList, CALIBRATION_MODE, 0, 1, 1, 1, 1);
00746 
00747   sendPrimListAll(rodModeList);
00748 
00749   {
00750     int responseCode = awaitResponseAll(10);
00751     
00752     if(responseCode != 0) {
00753       cout << "Send modules rod mode unsuccessful\n";
00754     }
00755   }
00756 #else   // Use slow config (loop over modules)
00757   {
00758     boost::mutex::scoped_lock lock(log().mutex());
00759     log() << "\tUsing multiple SEND_CONFIG primitives\n";
00760   }
00761 
00762 #warning "Slow module sending"
00763 
00764   // Disable all formatters to avoid bus error!
00765 #ifdef FMT_LINK_EN
00766   boost::shared_ptr<PrimListWrapper> clearFormatList(new PrimListWrapper(1));
00767 
00768   for(int i=0; i<8; i++) {
00769     builder.writeRegister(clearFormatList, FMT_LINK_EN(i), 0, 32, 0);
00770   }
00771 
00772   sendPrimListAll(clearFormatList);
00773   
00774   {
00775     int responseCode = awaitResponseAll(10);
00776     
00777     if(responseCode != 0) {
00778       cout << "Clear formatters unsuccessful\n";
00779     }
00780   }
00781 #else
00782 #warning "Probably don't need to turn off formatters! (old version)"
00783 #endif   // FMT_LINK_EN
00784 
00785   for(map<UINT32, ABCDModule>::const_iterator iter = moduleMap.begin();
00786       iter != moduleMap.end();
00787       iter ++) {
00788     sendABCDModule(iter->first, bank_type, config_type, enableDataMode);
00789   }
00790 #endif   // End of slow config sending
00791 
00792   // Restore link masks etc
00793   boost::shared_ptr<PrimListWrapper> setupMasks(new PrimListWrapper(1));
00794 
00795 #if USE_DUAL_PORTS
00796   // Masks also have to be both serial ports
00797   setupModuleMask(SP_BOTH, 0xf, setupMasks);
00798 #else
00799 #ifdef CMD_BUFFER_0
00800   setupModuleMask(CMD_BUFFER_0, 0xf, setupMasks);
00801 #else
00802   setupModuleMask(SP0, 0xf, setupMasks);
00803 #endif   // CMD_BUFFER_0
00804 #endif
00805 
00806   sendPrimListAll(setupMasks);
00807   
00808   {
00809     int responseCode = awaitResponseAll(10);
00810     
00811     if(responseCode != 0) {
00812       cout << "Setup masks unsuccessful\n";
00813     }
00814   }
00815   // Reset everything so its not confused by the clk/2
00816   boost::shared_ptr<PrimListWrapper> resetList(new PrimListWrapper(1));
00817 
00818   cout << "Resetting front end interface\n";
00819 #ifdef RRIF_CMND_0
00820   builder.writeRegister(resetList, RRIF_CMND_0, 0, 8, 0xff);  // Reset everything
00821   builder.writeRegister(resetList, RRIF_CMND_0, 0, 8, 0x78);  // Leave debug FIFO in reset
00822 #else
00823 #error "Unsupported no registers"
00824 #endif   // RRIF_CMND_0
00825 
00826   sendPrimListAll(resetList);
00827 
00828   int responseCode = awaitResponseAll(10);
00829 
00830   if(responseCode != 0) {
00831       cout << "ROD front end reset unsuccessful\n";
00832   }
00833 
00834   return;
00835 }
00836 
00837 #warning "TODO: fix so send configuration using different ROD if necessary"
00838 void SctApi::sendABCDModule(UINT32 mid,
00839                 BankType bank_type, 
00840                 ConfigType config_type, 
00841                 const bool enableDataMode) {
00842 
00843   /* enableDataMode should have default value true to ensure compatibility with old code*/
00844   if(mid==0xffffffff){
00845     cout << "sendABCDModule with 0xffffffff\n";
00846     throw SctApiException("mid out of range");
00847   }
00848   
00849   int realConfig=Utility::translateConfigTypeForSendPrimitive(config_type);
00850 
00851   cout << "Send config to module " << mid << endl;
00852 
00853   {
00854     boost::mutex::scoped_lock lock(log().mutex());
00855     log() << "sendABCDModule: Mid: " << mid << " Bank: " << bank_type << " Type: " << config_type << endl;
00856   }
00857 
00858   unsigned int partition, crate, rod, channel;
00859   Utility::getpcrc(mid, partition, crate, rod, channel);
00860 
00861   if(!getCrate()) {
00862     cout << "Send module for non-existent crate " << partition << " " << crate << endl;
00863     return;
00864   }
00865 
00866   {
00867     boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks = module_cache.getFromMid(mid);
00868     if (!the_banks.get()){
00869       if(mrs) {
00870     *mrs << "SEND_CONFIG" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00871          << MRS_PARAM<int>("module", mid)
00872          << MRS_TEXT("No module configuration existant") << ENDM;
00873       }else{
00874     std::cerr << "ERROR - No module configuration existant" << std::endl;
00875       }
00876       return;
00877     }else if (!the_banks->get(bank_type)){
00878       if(mrs) {
00879     *mrs << "SEND_CONFIG" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00880          << MRS_PARAM<int>("module", mid)
00881          << MRS_PARAM<int>("bank", bank_type)
00882          << MRS_TEXT("No module configuration existant for this bank") << ENDM;
00883       }else{
00884     std::cerr << "ERROR - No module configuration existant for this bank" << std::endl;
00885       }
00886     }
00887   }
00888 
00889   if(!getCrate()->checkBOCLasersOn(rod)) {
00890     cout << "Trying to send module configuration using BOC that has its lasers cut out\n";
00891     if(mrs) {
00892       *mrs << "BOC_INTERLOCKED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00893            << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00894            << MRS_PARAM<int>("rod", rod)
00895            << MRS_TEXT("Can't send module config (BOC interlocked)") << ENDM;
00896     }
00897 
00898     return;
00899   }
00900 
00901   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00902   PrimBuilder &builder = PrimBuilder::instance();
00903 
00904   int realBank = Utility::translateBank(bank_type);
00905 
00906   // Write "Disable trigger decoder" to primList
00907 #ifdef RRIF_CMND_1
00908   builder.writeRegister(primList, RRIF_CMND_1, 18, 1, 0);
00909 #else
00910 #error "Unsupported no registers"
00911 #endif
00912 
00913   // Seeing as we're only sending one module, use only one serial port
00914   builder.sendConfig(primList, SP0, 0, channel, NO_MODULE, ALL_CHIPS, 1, 1,
00915                      realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00916 
00917   // Write "Re-enable trigger decoder" to primList
00918 #ifdef RRIF_CMND_1
00919   builder.writeRegister(primList, RRIF_CMND_1, 18, 1, 1);
00920 #else
00921 #error "Unsupported no registers"
00922 #endif
00923 
00924   sendPrimList(rod, primList);
00925 
00926   int responseCode = awaitResponse(rod, 10);
00927 
00928   if(responseCode != 0) {
00929     cout << "Send module unsuccessful\n";
00930   }
00931 }
00932 
00933 #warning "TODO: fix so send configuration using different ROD if necessary"
00934 void SctApi::modifyABCDVarROD(UINT32 mid, UINT32 chip, UINT32 type, FLOAT32 value, list<BankType> banks) {
00935   if (checkDebugOption(DEBUG_MODULE_CONFIG)){
00936     std::cout << "AJB modifyABCDVarROD type " << type << " value " << value << " banks ";
00937     printBanks(banks, std::cout);
00938     std::cout << endl;
00939   }
00940   {
00941     boost::mutex::scoped_lock lock(log().mutex());
00942     log() << "modifyABCDVarROD (module " << mid << ": chip " << chip  << ") " << type << " " << value << " banks";
00943     printBanks(banks, log());
00944     log() << endl;
00945   }
00946 
00947   unsigned int partition, crate, rod, channel;
00948   Utility::getpcrc(mid, partition, crate, rod, channel);
00949 
00950   if(!isRODPresent(rod)) {
00951     cout << "Trying to change module configuration on a non existant ROD\n";
00952     if(mrs) {
00953       *mrs << "ROD_UNCONFIGURED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00954            << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00955            << MRS_PARAM<int>("rod", rod)
00956            << MRS_TEXT("Can't modify module config (ROD non-existant)") << ENDM;
00957     }
00958 
00959     return;
00960   }
00961 
00962   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00963 
00964   UINT32 real_banks_bits = Utility::translateApiBanksToRodCfgBitSet(banks);
00965   UINT32 chipid = Utility::translateChip(chip);
00966   PrimBuilder::instance().writeModuleVariable(primList, real_banks_bits, MODULE_GROUP_ALL,
00967                           channel, chipid, type, value);
00968   sendPrimList(rod, primList);
00969   awaitResponse(rod, 5);
00970   
00971   // also update the cache!
00972   // update cache...
00973   boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00974   if (!the_banks.get()) {
00975     if(mrs) {
00976       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00977        << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00978        << MRS_PARAM<int>("rod", rod)
00979        << MRS_TEXT("Cant update cache for non-existant MID") << ENDM;
00980     }else{
00981       cout << "Cant update cache for non-existant MID "<< mid << std::endl;
00982     }
00983     return;
00984   }
00985   for (list<BankType>::const_iterator bank_iterator=banks.begin(); bank_iterator!=banks.end(); ++bank_iterator){
00986     boost::shared_ptr<ABCDModule> cached_config = the_banks->get(*bank_iterator);
00987     if (!cached_config.get()){
00988       if(mrs) {
00989     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00990          << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00991          << MRS_PARAM<int>("rod", rod)
00992          << MRS_PARAM<int>("bank", *bank_iterator)
00993          << MRS_TEXT("Cant update cache for non-existant BANK") << ENDM;
00994       }else{
00995     cout << "Cant update cache for non-existant BANK " << *bank_iterator << endl;
00996       }
00997       return;
00998     }
00999     ConfigUtility::modifyVar(cached_config.get(), chip, type, value);
01000   }
01001 }
01002  
01003 void SctApi::modifyABCDVarROD(UINT32 mid, UINT32 type, FLOAT32 value, list<BankType> banks) {
01004   modifyABCDVarROD(mid, ALL_CHIPS, type, value, banks);
01005 }
01006 
01007 
01008 void SctApi::modifyABCDVarROD(UINT32 type, FLOAT32 value, list<BankType> banks) {
01009   std::cout << "AJB modifyABCDVarROD type " << type << " value " << value << " banks ";
01010   printBanks(banks, std::cout);
01011   std::cout << endl;
01012   {
01013     boost::mutex::scoped_lock lock(log().mutex());
01014     log() << "modifyABCDVarROD (all modules, all chips) " << type << " " << value << " Banks: ";
01015     printBanks(banks, log());
01016     log() << endl;
01017   }
01018 
01019   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
01020 #if (R_RW_MODULE_DATA < 103 ) 
01021 #warning "older version of RwModuleVariable may be slower"
01022   std::cout << "using old version of RwModuleVariable - may be slower" << std::endl;
01023   for (list<BankType>::const_iterator bank_iterator=banks.begin(); bank_iterator!=banks.end(); ++bank_iterator){
01024     BankType bank_type=*bank_iterator;
01025     int realBank = Utility::translateBank(bank_type);    
01026     PrimBuilder::instance().writeModuleVariable(primList, realBank, MODULE_GROUP_ALL, 
01027                         ALL_MODULES, ALL_CHIPS, type, value);
01028   }
01029 #else
01030   UINT32 real_banks_bits = Utility::translateApiBanksToRodCfgBitSet(banks);
01031   PrimBuilder::instance().writeModuleVariable(primList, real_banks_bits, MODULE_GROUP_ALL,
01032                           ALL_MODULES, ALL_CHIPS, type, value);
01033   
01034 #endif
01035   for(list<RodLabel>::const_iterator rl = rodList.begin();
01036       rl!=rodList.end();
01037       rl++){
01038     
01039     unsigned int rod = rl->rod;
01040     
01041     if(!isRODPresent(rod)) {
01042       std::cout << "Trying to change module configuration on a non existant ROD\n";
01043       if(mrs) {
01044     *mrs << "ROD_UNCONFIGURED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
01045          << MRS_PARAM<int>("rod", rod)
01046          << MRS_TEXT("Can't modify module config (ROD non-existant)") << ENDM;
01047       }else{
01048     std::cout << "ERROR - Rod " << rod << " does not exist" << std::endl;
01049       } 
01050       return;
01051     }
01052     sendPrimList(rod, primList);
01053     if (awaitResponse(rod, 2)!=0){
01054       if (mrs){
01055     *mrs << "MODIFY_VAR_ERROR" << MRS_ERROR << MRS_QUALIF("SCTAPI")
01056          << MRS_PARAM<int>("rod",rod)
01057          << MRS_TEXT("Error setting ABCDVariable on all modules") << ENDM;
01058       }else{
01059     std::cout << "ERROR in response from ROD " << rod << " modifying variable all modules" << std::endl;
01060       }
01061       return;
01062     }
01063   }
01064 
01065   // update cache
01066   for(map<UINT32, ABCDModule>::const_iterator iter = moduleMap.begin(); iter != moduleMap.end(); iter ++) {
01067       UINT32 mid = iter->first;
01068       boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
01069       if (!the_banks.get()) {
01070     if(mrs) {
01071       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
01072            << MRS_PARAM<int>("mid", mid)
01073            << MRS_TEXT("Cant update cache for non-existant MID") << ENDM;
01074     }else{
01075       std::cout << "Cant update cache for non-existant MID "<< mid << endl;
01076     }
01077     return;
01078       }
01079       for (list<BankType>::const_iterator bank_iterator=banks.begin(); bank_iterator!=banks.end(); ++bank_iterator){
01080     boost::shared_ptr<ABCDModule> cached_config = the_banks->get(*bank_iterator);
01081     if (!cached_config.get()){
01082       if(mrs) {
01083         *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
01084          << MRS_PARAM<int>("mid", mid)
01085          << MRS_PARAM<int>("bank", *bank_iterator)
01086          << MRS_TEXT("Cant update cache for non-existant BANK") << ENDM;
01087       }else{
01088         std::cout << "Cant update cache for non-existant BANK " << *bank_iterator << endl;
01089       }
01090       return;
01091     }
01092     ConfigUtility::modifyVar(cached_config.get(), type, value); 
01093       }
01094   }
01095 }
01096 
01097 } // Close namespace
01098 

Generated on Mon Feb 6 14:01:29 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6