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

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 
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   boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00049   if (!the_banks.get()) {
00050     if(mrs) {
00051       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00052            << MRS_PARAM<int>("mid", mid)
00053            << MRS_TEXT("Cant return cache for non-existant MID") << ENDM;
00054     }
00055     return;
00056   }
00057   boost::shared_ptr<ABCDModule> cached_config = the_banks->get(bank_type);
00058   if (!cached_config.get()){
00059     if(mrs) {
00060       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00061            << MRS_PARAM<int>("mid", mid)
00062            << MRS_PARAM<int>("bank", bank_type)
00063            << MRS_TEXT("Cant return cache for non-existant BANK") << ENDM;
00064     }
00065     return;
00066   }
00067 
00068   ABCDModule *previous = lookupConfig(mid);
00069   if(previous) {
00070     *previous = *cached_config;
00071   } else {
00072     moduleMap.insert(make_pair(mid, *cached_config));
00073   }
00074 
00075   // option to test cache of this bank against the real ROD bank:
00076   if(checkDebugOption(DEBUG_API_CONFIG_CACHE_CHECK)){
00077     previous = lookupConfig(mid);
00078     if (!previous) throw SctApiException("SctApiMConf: null pointer error which should never happen");
00079     std::auto_ptr<ABCDModule> previous_clone = ConfigUtility::clone(*previous);
00080     really_getABCDModule(mid, bank_type);
00081 
00082     ABCDModule *current = lookupConfig(mid);
00083 
00084     // get bit-field of difference types
00085     unsigned differences=ConfigUtility::diff(*previous_clone, *current);
00086     if (differences){
00087       if (mrs){
00088     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_WARNING << MRS_QUALIF("SCTAPI") 
00089          << MRS_PARAM<int>("module", mid)
00090          << MRS_TEXT("DEBUG error - configuration in CACHE and ROD differ!")             << MRS_PARAM<int>("diff bitfield", differences)
00091              << ENDM;
00092       }
00093       boost::mutex::scoped_lock lock(log().mutex());
00094       log() << "ERROR on module configuration cache:"
00095         << " module" <<  mid << " bitfield of differences:" << std::hex << differences 
00096         << std::dec << std::endl;
00097       log() << "Printing CACHE and then ROD to configuration service output"<< std::endl;
00098       config->printModuleConfig(*previous_clone);
00099       config->printModuleConfig(*current);
00100     }
00101   }
00102 }
00103 
00104 void printBanks(std::list<BankType> banks, std::ostream& os){
00105    for (std::list<BankType>::const_iterator i=banks.begin(); i!=banks.end(); ++i){
00106       if (i!=banks.begin()) os << ",";
00107       os << *i;
00108    }
00109    if (banks.begin()==banks.end()) os << "NONE!";
00110 }
00111 
00112 void SctApi::copyABCDModules(BankType source, std::list<BankType> to){
00113 #warning "AJB - this should be changed to use multiple copyABCDModule when it changes"
00114   std::cout << "AJB AJB copyABCDModules from " << source << " to ";
00115   printBanks(to, std::cout); 
00116   std::cout << endl;
00117   getABCDModules(source);
00118   setABCDModules(to);
00119 }
00120 
00121 void SctApi::copyABCDModule(UINT32 mid, BankType source, std::list<BankType> to_banks){
00122 #warning "AJB - this should be changed to use the new ROD primitive ASAP!"
00123   std::cout << "Using non-primitive version of copyABCDModule" << std::endl;
00124   getABCDModule(mid, source);
00125   setABCDModule(mid, to_banks);  
00126   
00127   std::cout << "AJB AJB copyABCDModule mid=" << mid << " from " << source << " to ";
00128   printBanks(to_banks, std::cout);
00129   std::cout << endl;
00130   
00131   return;
00132   /*
00133     AJB - code below is awaiting a copy primitive ...
00134     until then the two methods above (get/set) simulate this
00135   */
00136 #warning "AJB awaiting a copy primitive"
00137   
00138   boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00139   if (!the_banks.get()) {
00140     if(mrs) {
00141       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00142        << MRS_PARAM<int>("mid", mid)
00143        << MRS_TEXT("Cant return cache for non-existant MID") << ENDM;
00144     }else{
00145       std::cout << "Cant return cache for non-existant MID " << mid << std::endl;
00146     }
00147     return;
00148   }
00149   boost::shared_ptr<ABCDModule> from_config = the_banks->get(source);
00150   if (!from_config.get()){
00151     if(mrs) {
00152       *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00153        << MRS_PARAM<int>("module", mid)
00154        << MRS_PARAM<int>("bank", source)
00155        << MRS_TEXT("Cant return cache for non-existant BANK") << ENDM;
00156     }else{
00157       std::cout << "Cant return cache for non-existant source BANK " << source << std::endl;
00158     }
00159     return;
00160   }
00161   std::list<BankType> modify_bank_list;
00162   for (std::list<BankType>::const_iterator bank_iterator=to_banks.begin(); 
00163        bank_iterator!=to_banks.end(); ++bank_iterator){
00164 
00165     BankType to_bank=*bank_iterator;
00166 
00167     boost::shared_ptr<ABCDModule> to_config = the_banks->get(to_bank);
00168     if (!to_config.get()){
00169       to_config=boost::shared_ptr<ABCDModule>(ConfigUtility::clone(*from_config).release());
00170       the_banks->set(to_bank, to_config);
00171       modify_bank_list.push_back(to_bank);
00172     }else{
00173       unsigned differences=ConfigUtility::diff(*from_config, *to_config);
00174       if (to_bank==SCTAPI_BANK_SCAN) differences = SCTAPI_CONFIG_ALL;
00175       if (differences) {
00176     *to_config=*from_config;
00177     modify_bank_list.push_back(to_bank);
00178       }
00179     }
00180   }
00181 
00184   unsigned int partition, crate, rod, channel;
00185   Utility::getpcrc(mid, partition, crate, rod, channel);
00186 
00187   for (list<BankType>::const_iterator bank_iterator=modify_bank_list.begin();
00188        bank_iterator!=modify_bank_list.end(); ++ bank_iterator){
00189     int realBank = Utility::translateBank(*bank_iterator);
00190     // add translation of bank to multi-bank thingy
00191   }
00192   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00193 
00194   sendPrimList(rod, primList);
00195 
00196   int responseCode = awaitResponse(rod, 10);
00197   
00198   if(responseCode!=0) {
00199     cout << "Copy module unsuccessful!\n";
00200   }
00201 }
00202 
00203 void SctApi::setABCDModule(UINT32 mid, std::list<BankType> bank_list) {
00204   std::cout << "AJB AJB setABCDModule mid=" << mid << " banks=";
00205   printBanks(bank_list, std::cout);
00206   std::cout << std::endl;
00207   bool config_is_new=false;
00208     
00209   using boost::shared_ptr;
00210   ABCDModule* lookup=lookupConfig(mid);
00211   if (!lookup) {
00212     std::cerr << "setABCDModule : Could not find module config for mid = " << mid << std::endl;
00213     return;
00214   }
00215 
00216 #warning "TODO: fix so send configuration using different ROD if necessary"
00217   /* Look up using offRODTTC to find ROD and virtual channel number
00218      this should already be in the module configuration cache */
00219 
00220   shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00221 
00222   // get cache of banks for this mid, or create it (in which case the config must be sent)
00223   if (!the_banks.get()) {
00224     config_is_new=true;
00225     the_banks=shared_ptr<SctApiConfigCache::ModuleBanks>(new SctApiConfigCache::ModuleBanks);
00226     module_cache.set(mid, the_banks);
00227   }
00228   
00229 
00230   std::list<BankType> modified_bank_list;
00231   for (std::list<BankType>::const_iterator bank_iterator=bank_list.begin(); 
00232        bank_iterator!=bank_list.end(); ++bank_iterator){
00233     BankType bank_type=*bank_iterator;
00234     std::cout << "AJB AJB on bank " << bank_type << std::endl;
00235     shared_ptr<ABCDModule> current_cache=the_banks->get(bank_type);
00236     
00237     // get ABCDModule for this bank, or create it (in which case the config must be sent)
00238     if (!current_cache.get()) {
00239       current_cache = shared_ptr<ABCDModule>(ConfigUtility::clone(*lookupConfig(mid)).release());
00240       the_banks->set(bank_type, current_cache);
00241       modified_bank_list.push_back(bank_type);
00242     }else{
00243       /*
00244     Get bit-field of all differences between local config and ROD cache.
00245     1/3/2005 AJB has set the conditional below because at the end of the scan 
00246     the SCAN bank is in an odd state, hence we always should copy the scan bank,
00247     if that has been explicitly requested
00248       */
00249       unsigned differences=ConfigUtility::diff(*current_cache, *lookup);
00250       if (bank_type==SCTAPI_BANK_SCAN) differences = SCTAPI_CONFIG_ALL;
00251       if (differences){
00252     *current_cache = *lookup;
00253     modified_bank_list.push_back(bank_type);
00254       }else{
00255     std::cout << "AJB AJB No need to set ABCDModule type " << bank_type
00256           << " for mid = " << mid
00257           << " and bank_type  = " << bank_type
00258           << " as configuration hasnt changed, " << endl;
00259     if(checkDebugOption(DEBUG_API_CONFIG_CACHE_SEND)){
00260       std::cout << "Debug option set so sending module configuration ANYWAY!" << std::endl;
00261       modified_bank_list.push_back(bank_type);
00262     }
00263       }
00264     }
00265   }
00266   really_setABCDModule(mid, modified_bank_list);
00267 }
00268 
00269 void SctApi::really_getABCDModule(UINT32 mid, BankType bank_type) {
00270   {
00271     boost::mutex::scoped_lock lock(log().mutex());
00272     log() << "getABCDModule " << mid << " Bank: " << bank_type << endl;
00273   }
00274 
00275   // Find module channel in ROD
00276   unsigned int partition, crate, rod, channel;
00277   Utility::getpcrc(mid, partition, crate, rod, channel);
00278 
00279   // Which bank id to use
00280   int realBank = Utility::translateBank(bank_type);
00281 
00282   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00283   PrimBuilder::instance().readModuleData(primList, realBank, channel);
00284 
00285   sendPrimList(rod, primList);
00286 
00287   int responseCode = awaitResponse(rod, 5);
00288 
00289   unsigned long length;
00290   unsigned long *outBody = 0;
00291   if(responseCode == 0) {
00292     outBody = getResponse(rod, length);
00293   }
00294 
00295   if(outBody) {
00296 //      unsigned long outLength = outBody[0];
00297 //      unsigned long outIndex = outBody[1];
00298     unsigned long outNumPrims = outBody[2];
00299 //      unsigned long outPrimVersion = outBody[3];
00300 
00301     if(outNumPrims == 1) {
00302       unsigned long primLength = outBody[4];
00303 //        unsigned long primIndex = outBody[5];
00304       unsigned long primID = outBody[6];
00305 //        unsigned long primVersion = outBody[7];
00306 
00307       if(primID == RW_MODULE_DATA) {
00308         if(primLength != (sizeof(ABCDModule)/sizeof(UINT32) + 4)) { // Prim length includes header
00309           cout << "Output primitive was " << primLength << " not " << sizeof(ABCDModule)/sizeof(UINT32) << endl;
00310         }
00311 
00312         // Data is at outBody[8]
00313         ABCDModule result;
00314 
00315         // Copy data
00316         for(unsigned int i=0; i<sizeof(ABCDModule)/sizeof(UINT32); i++) {
00317           ((unsigned long *)&result)[i] = outBody[8 + i];
00318         }
00319 
00320         ABCDModule *previous = lookupConfig(mid);
00321 
00322         if(previous) {
00323           cout << "Replacing previous module config\n";
00324 
00325           *previous = result;
00326         } else {
00327           cout << "New module config inserted\n";
00328           moduleMap.insert(make_pair(mid, result));
00329         }
00330       } else {
00331         cout << "Returned primitive was not RW_MODULE_DATA\n";
00332       }
00333     } else {
00334       cout << "Too many primitives in output list\n";
00335     }
00336 
00337     delete [] outBody;
00338   } else {
00339     cout << "No response to primitive list!\n";
00340   }
00341 }
00342 
00343 boost::shared_ptr<ABCDModule> SctApi::getABCDModuleRaw(unsigned int rod, 
00344                                                        UINT32 slot, BankType bank_type) {
00345   {
00346     boost::mutex::scoped_lock lock(log().mutex());
00347     log() << "getABCDModuleRaw Slot: " << slot << " Bank: " << bank_type << endl;
00348   }
00349 
00350   boost::shared_ptr<ABCDModule> result;
00351 
00352   // Which bank id to use
00353   int realBank = Utility::translateBank(bank_type);
00354 
00355   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00356   PrimBuilder::instance().readModuleData(primList, realBank, slot);
00357   sendPrimList(rod, primList);
00358 
00359   int responseCode = awaitResponse(rod, 5);
00360 
00361   unsigned long length;
00362   unsigned long *outBody = 0;
00363   if(responseCode == 0) {
00364     outBody = getResponse(rod, length);
00365   }
00366 
00367   if(outBody) {
00368     unsigned long outNumPrims = outBody[2];
00369 
00370     if(outNumPrims == 1) {
00371       unsigned long primLength = outBody[4];
00372       unsigned long primID = outBody[6];
00373 
00374       if(primID == RW_MODULE_DATA) {
00375         unsigned int expectedSize = (sizeof(ABCDModule)/sizeof(UINT32) + 4);
00376         if(primLength != expectedSize) { // Prim length includes header
00377           cout << "Output primitive was " << primLength << " not " << expectedSize << endl;
00378         }
00379 
00380         result.reset(new ABCDModule);
00381 
00382         // Data is at outBody[8]
00383         // Copy data
00384         for(unsigned int i=0; i<sizeof(ABCDModule)/sizeof(UINT32); i++) {
00385           ((unsigned long *)result.get())[i] = outBody[8 + i];
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   return result;
00400 }
00401 
00402 /* Store config in ROD */
00403 void SctApi::setABCDModules(std::list<BankType> banks) {
00404   std::cout << "setABCDModules (all) banks=";
00405   printBanks(banks, std::cout);
00406   std::cout << std::endl;
00407   {
00408     boost::mutex::scoped_lock lock(log().mutex());
00409     log() << "setABCDModule called for all modules. Banks : ";
00410     for (std::list<BankType>::const_iterator it=banks.begin(); it!=banks.end(); ++it){
00411       log() << *it <<",";
00412     }
00413     log() << endl;
00414   }
00415   for(map<UINT32, ABCDModule>::const_iterator iter = moduleMap.begin();
00416       iter != moduleMap.end();
00417       iter ++) {
00418     cout << "Set Config " << iter->first << endl;
00419     setABCDModule(iter->first, banks);
00420   }
00421 
00422   // Off-ROD modules are already in the moduleMap so get sent automatically
00423   return;
00424 }
00425 
00426 /* Store config in ROD */
00427 void SctApi::really_setABCDModule(UINT32 mid, std::list<BankType> bank_list) {
00428   std::cout << "really_setABCDModule mid=" << mid << " banks=";
00429   printBanks(bank_list, std::cout);
00430   std::cout << std::endl;
00431   if(mid==0xffffffff){
00432     cout << "setABCDModule with 0xffffffff\n";
00433     throw SctApiException("mid out of range");
00434   }
00435 
00436 
00437   std::string moduleName;
00438   ABCDModule *moduleConfig;
00439   
00440   moduleConfig = lookupConfig(mid);
00441   
00442   if(!moduleConfig) {
00443     cout << "*** NO module configuration for mid = " << mid << " in set module" << endl;
00444     return;
00445   }
00446   
00447   cout << "\nModule config\n";
00448   cout << " primary channel " << (int)moduleConfig->pTTC 
00449        << " red channel " << (int)moduleConfig->rTTC 
00450        << " group " << (int)moduleConfig->groupId
00451        << " select " << (int)moduleConfig->select << endl;
00452   cout << " target (chip 0) " << (int)moduleConfig->chip[0].target << endl;
00453 
00454   for (std::list<BankType>::const_iterator bank_iterator=bank_list.begin();
00455        bank_iterator!=bank_list.end(); ++bank_iterator){
00456     BankType bank_type=*bank_iterator; 
00457     {
00458       boost::mutex::scoped_lock lock(log().mutex());
00459       log() << "AJB AJB setABCDModule " << mid << " Bank: " << bank_type << endl;
00460     }
00461     std::cout << "AJB AJB setABCDModule " << mid << " Bank: " << bank_type << endl; 
00462     unsigned int partition, crate, rod, channel;
00463     Utility::getpcrc(mid, partition, crate, rod, channel);
00464     
00465     int realBank = Utility::translateBank(bank_type);
00466     
00467     boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00468     PrimBuilder::instance().writeModuleData(primList, moduleConfig, realBank, channel);
00469     
00470     RodLabel rl(partition, crate, rod);
00471     
00472     for(int l=0; l<2; l++) {
00473       const unsigned int zeroTo123Pos = moduleConfig->rx[l];
00474       // We check the values before using it, doing this here makes the next bit less confusing
00475       const unsigned int zeroTo95Pos = Sct::FibreNumberConverters::from124FormatTo96Format(zeroTo123Pos);
00476       if (zeroTo123Pos==DATA_LINK_OFF) {
00477     // Don't try to get non-existant value!
00478     //  but otherwise this is valid ... no problem
00479       } else if(zeroTo123Pos <= 123 && zeroTo95Pos < 96) {
00480     // This is already cached in cacheModuleConfig
00481     const unsigned int val = getRodInfo(rl).linkErrorMasks[zeroTo95Pos];
00482     PrimBuilder::instance().writeRegister(primList, ERROR_MASK(zeroTo95Pos/48, zeroTo95Pos%48), 0, 13, val);
00483         std::cout << "ERROR_MASK: writing value " << val  << " to " << ERROR_MASK(zeroTo95Pos/48, zeroTo95Pos%48) << endl; 
00484       } else {
00485     std::ostringstream os;
00486     os << "Bad fibre number for error mask values! Line " << __LINE__ << " of " << __FILE__ << " when 123pos = " << zeroTo123Pos <<" and 95pos = " << zeroTo95Pos;
00487     if (mrs) {
00488       *mrs << "SctApi" << MRS_ERROR << MRS_TEXT(os.str()) << ENDM;
00489     } else {
00490       std::cout << "SctApi: ERROR " << os.str() << std::endl;
00491       return;
00492     }
00493       }
00494     }
00495     
00496 #if USE_DUAL_PORTS
00497     // Set up module masks so config can be sent using both serial ports
00498     setupModuleMask(SP_BOTH, 0xf, primList);
00499 #else
00500     // This will be a null op if it doesn't exist
00501 #ifdef CMD_BUFFER_0
00502 #warning "Use of old header files detected"
00503     setupModuleMask(CMD_BUFFER_0, 0xf, primList);
00504 #else
00505     setupModuleMask(SP0, 0xf, primList);
00506 #endif
00507 #endif
00508     sendPrimList(rod, primList);
00509 
00510     int responseCode = awaitResponse(rod, 10);
00511 
00512     if(responseCode!=0) {
00513       cout << "Set module unsuccessful!\n";
00514     }
00515   }
00516 }
00517 
00518 
00519 void SctApi::sendAllABCDModules(BankType bank_type,
00520                                 ConfigType config_type,
00521                                 const bool enableDataMode /* enableDataMode should have default value true to ensure compatibility with old code*/) {
00522 
00523   std::cout << "AJB AJB sendAllABCDModules bank=" << bank_type << " config_type="
00524             << config_type << " enableDataMode=" << enableDataMode << std::endl;
00525   {
00526     boost::mutex::scoped_lock lock(log().mutex());
00527     log() << "sendABCDModule called for all modules. Bank: " << bank_type << endl;
00528   }
00529 
00530   /*
00531     This method is far too long...
00532 
00533     1) Change to ROD mode that allows configuration to be sent to the modules
00534     2) Check the BOC isn't interlocked
00535     3) Build and send a primitive list
00536      a) Disable trigger decoder
00537      b) Disable formatters
00538      c) Send configuration
00539      d) Reenable trigger decoder
00540     4) Change "back" to CALIBRATION_MODE
00541 
00542     option 2 (for early versions of the DSP code, probably not every stage necessary)
00543     1) Disable formatters
00544     2) Send configuration for each module in turn using sendABCDModule
00545     3) Setup module masks
00546     4) Reset some FIFOs...
00547 
00548 */
00549 
00550   cout << "Send config to all modules\n";
00551 
00552   PrimBuilder &builder = PrimBuilder::instance();
00553 
00554   // Set ROD mode to something appropriate (may be in TIM mode!)
00555   boost::shared_ptr<PrimListWrapper> rodModeList1(new PrimListWrapper(1));
00556   // Should CALIBRATION_SLINK_OVERRIDE_MODE be added to this (it works without!)
00557   builder.rodMode(rodModeList1, CALIBRATION_MODE, 0, 1, 1, 1, 1);
00558 
00559   synchSendPrimListAllCrates(rodModeList1);
00560 
00561 
00562   // If new primitive use it instead of doing a loop
00563 #if (R_SEND_CONFIG == 104) || (R_SEND_CONFIG == 105)
00564   {
00565     boost::mutex::scoped_lock lock(log().mutex());
00566     log() << "\tUsing one SEND_CONFIG primitive\n";
00567   }
00568 
00569   {
00570     for(list<RodLabel>::const_iterator rl = rodList.begin();
00571         rl!=rodList.end();
00572         rl++){
00573 
00574       if(!getCrate()->checkBOCLasersOn(rl->rod)) {
00575         cout << "Trying to send module configuration using BOC that has its lasers cut out\n";
00576         if(mrs) {
00577           *mrs << "BOC_INTERLOCKED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00578                << MRS_PARAM<int>("crate", rl->crate) 
00579                << MRS_PARAM<int>("rod", rl->rod)
00580                << MRS_TEXT("Can't send all module config (BOC interlocked)") << ENDM;
00581         }
00582 
00583         throw SctApiException("Send modules aborted due to interlock status");
00584       }
00585     }
00586   }
00587 
00588   boost::shared_ptr<PrimListWrapper> sendConfigList(new PrimListWrapper(1));
00589 
00590   // Write "Disable trigger decoder" to primList
00591 #ifdef RRIF_CMND_1
00592   builder.writeRegister(sendConfigList, RRIF_CMND_1, 18, 1, 0);
00593 #else
00594 #error "Unsupported no registers"
00595 #endif   // RRIF_CMND_1
00596 
00597   // Disable all formatters
00598 #ifdef FMT_LINK_EN
00599   for(int i=0; i<8; i++) {
00600     builder.writeRegister(sendConfigList, FMT_LINK_EN(i), 0, 32, 0);
00601   }
00602 #else
00603 #warning "Probably don't need to turn off formatters!?"
00604 #endif // FMT_LINK_EN
00605 
00606   int realBank = Utility::translateBank(bank_type);
00607   int realConfig = Utility::translateConfigType(config_type);
00608   //@todo SP_BOTH doesn't work with current DSP code
00609 #if USE_DUAL_PORTS
00610   // Send module configuration from both serial ports (ie two modules at a time)
00611   builder.sendConfig(sendConfigList, SP_BOTH, 0, ALL_MODULES, ALL_MODULES, ALL_CHIPS, 1, 1,
00612                      realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00613 #else
00614   builder.sendConfig(sendConfigList, SP0, 0, ALL_MODULES, ALL_MODULES, ALL_CHIPS, 1, 1,
00615                      realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00616 #endif
00617 
00618   // Write "Re-enable trigger decoder" to primList
00619 #ifdef RRIF_CMND_1
00620   builder.writeRegister(sendConfigList, RRIF_CMND_1, 18, 1, 1);
00621 #else
00622 #error "Unsupported no registers"
00623 #endif  // RRIF_CMND_1
00624 
00625   // setupModuleMask to reenable appropriate formatters??
00626 
00627   sendPrimListAll(sendConfigList);
00628   
00629   {
00630     int responseCode = awaitResponseAll(10);
00631     
00632     if(responseCode != 0) {
00633       cout << "Send modules unsuccessful\n";
00634     }
00635   }
00636 
00637   boost::shared_ptr<PrimListWrapper> rodModeList(new PrimListWrapper(1));
00638   // Should CALIBRATION_SLINK_OVERRIDE_MODE be added to this (it works without!)
00639   builder.rodMode(rodModeList, CALIBRATION_MODE, 0, 1, 1, 1, 1);
00640 
00641   sendPrimListAll(rodModeList);
00642 
00643   {
00644     int responseCode = awaitResponseAll(10);
00645     
00646     if(responseCode != 0) {
00647       cout << "Send modules rod mode unsuccessful\n";
00648     }
00649   }
00650 #else   // Use slow config (loop over modules)
00651   {
00652     boost::mutex::scoped_lock lock(log().mutex());
00653     log() << "\tUsing multiple SEND_CONFIG primitives\n";
00654   }
00655 
00656 #warning "Slow module sending"
00657 
00658   // Disable all formatters to avoid bus error!
00659 #ifdef FMT_LINK_EN
00660   boost::shared_ptr<PrimListWrapper> clearFormatList(new PrimListWrapper(1));
00661 
00662   for(int i=0; i<8; i++) {
00663     builder.writeRegister(clearFormatList, FMT_LINK_EN(i), 0, 32, 0);
00664   }
00665 
00666   sendPrimListAll(clearFormatList);
00667   
00668   {
00669     int responseCode = awaitResponseAll(10);
00670     
00671     if(responseCode != 0) {
00672       cout << "Clear formatters unsuccessful\n";
00673     }
00674   }
00675 #else
00676 #warning "Probably don't need to turn off formatters! (old version)"
00677 #endif   // FMT_LINK_EN
00678 
00679   for(map<UINT32, ABCDModule>::const_iterator iter = moduleMap.begin();
00680       iter != moduleMap.end();
00681       iter ++) {
00682     cout << "SendConfig " << iter->first << endl;
00683     sendABCDModule(iter->first, bank_type, config_type, enableDataMode);
00684   }
00685 #endif   // End of slow config sending
00686 
00687   // Restore link masks etc
00688   boost::shared_ptr<PrimListWrapper> setupMasks(new PrimListWrapper(1));
00689 
00690 #if USE_DUAL_PORTS
00691   // Masks also have to be both serial ports
00692   setupModuleMask(SP_BOTH, 0xf, setupMasks);
00693 #else
00694 #ifdef CMD_BUFFER_0
00695   setupModuleMask(CMD_BUFFER_0, 0xf, setupMasks);
00696 #else
00697   setupModuleMask(SP0, 0xf, setupMasks);
00698 #endif   // CMD_BUFFER_0
00699 #endif
00700 
00701   sendPrimListAll(setupMasks);
00702   
00703   {
00704     int responseCode = awaitResponseAll(10);
00705     
00706     if(responseCode != 0) {
00707       cout << "Setup masks unsuccessful\n";
00708     }
00709   }
00710   // Reset everything so its not confused by the clk/2
00711   boost::shared_ptr<PrimListWrapper> resetList(new PrimListWrapper(1));
00712 
00713   cout << "Resetting front end interface\n";
00714 #ifdef RRIF_CMND_0
00715   builder.writeRegister(resetList, RRIF_CMND_0, 0, 8, 0xff);  // Reset everything
00716   builder.writeRegister(resetList, RRIF_CMND_0, 0, 8, 0x78);  // Leave debug FIFO in reset
00717 #else
00718 #error "Unsupported no registers"
00719 #endif   // RRIF_CMND_0
00720 
00721   sendPrimListAll(resetList);
00722 
00723   int responseCode = awaitResponseAll(10);
00724 
00725   if(responseCode != 0) {
00726       cout << "ROD front end reset unsuccessful\n";
00727   }
00728 
00729   return;
00730 }
00731 
00732   void SctApi::sendABCDModule(UINT32 mid,
00733                   BankType bank_type, 
00734                   ConfigType config_type, 
00735                   const bool enableDataMode) {
00736     /* enableDataMode should have default value true to ensure compatibility with old code*/
00737   if(mid==0xffffffff){
00738     cout << "sendABCDModule with 0xffffffff\n";
00739     throw SctApiException("mid out of range");
00740   }
00741   
00742   int realConfig=Utility::translateConfigType(config_type);
00743 
00744   cout << "Send config to module " << mid << endl;
00745 
00746   {
00747     boost::mutex::scoped_lock lock(log().mutex());
00748     log() << "sendABCDModule: Mid: " << mid << " Bank: " << bank_type << " Type: " << config_type << endl;
00749   }
00750 
00751   unsigned int partition, crate, rod, channel;
00752   Utility::getpcrc(mid, partition, crate, rod, channel);
00753 
00754   if(!getCrate()) {
00755     cout << "Send module for non-existent crate " << partition << " " << crate << endl;
00756     return;
00757   }
00758 
00759   int realBank = Utility::translateBank(bank_type);
00760 
00761   if(realBank > SPARE_MODULE_CONFIG) {
00762     cout << "sendABCDModule with illegal bank (translated) " << realBank << endl;
00763     throw SctApiException("Illegal Bank");
00764   }
00765 
00766   if(!getCrate()->checkBOCLasersOn(rod)) {
00767     cout << "Trying to send module configuration using BOC that has its lasers cut out\n";
00768     if(mrs) {
00769       *mrs << "BOC_INTERLOCKED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00770            << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00771            << MRS_PARAM<int>("rod", rod)
00772            << MRS_TEXT("Can't send module config (BOC interlocked)") << ENDM;
00773     }
00774 
00775     return;
00776   }
00777 
00778   boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00779   PrimBuilder &builder = PrimBuilder::instance();
00780 
00781   // Write "Disable trigger decoder" to primList
00782 #ifdef RRIF_CMND_1
00783   builder.writeRegister(primList, RRIF_CMND_1, 18, 1, 0);
00784 #else
00785 #error "Unsupported no registers"
00786 #endif
00787 
00788   // Seeing as we're only sending one module, use only one serial port
00789   builder.sendConfig(primList, SP0, 0, channel, NO_MODULE, ALL_CHIPS, 1, 1,
00790                      realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00791 
00792   // Write "Re-enable trigger decoder" to primList
00793 #ifdef RRIF_CMND_1
00794   builder.writeRegister(primList, RRIF_CMND_1, 18, 1, 1);
00795 #else
00796 #error "Unsupported no registers"
00797 #endif
00798 
00799   sendPrimList(rod, primList);
00800 
00801   int responseCode = awaitResponse(rod, 10);
00802 
00803   if(responseCode != 0) {
00804     cout << "Send module unsuccessful\n";
00805   }
00806 }
00807 
00808 #warning "AJB fix to use primitive for multiple banks"
00809 void SctApi::modifyABCDVarROD(UINT32 mid, UINT32 chip, UINT32 type, FLOAT32 value, std::list<BankType> banks) {
00810   {
00811     boost::mutex::scoped_lock lock(log().mutex());
00812     log() << "modifyABCDVarROD (module " << mid << ": chip " << chip  << ") " << type << " " << value << " banks";
00813     printBanks(banks, log());
00814     log() << std::endl;
00815   }
00816 
00817   cout << "Change variable macro\n";
00818 
00819   unsigned int partition, crate, rod, channel;
00820   Utility::getpcrc(mid, partition, crate, rod, channel);
00821 
00822   if(!isRODPresent(rod)) {
00823     cout << "Trying to change module configuration on a non existant ROD\n";
00824     if(mrs) {
00825       *mrs << "ROD_UNCONFIGURED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00826            << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00827            << MRS_PARAM<int>("rod", rod)
00828            << MRS_TEXT("Can't modify module config (ROD non-existant)") << ENDM;
00829     }
00830 
00831     return;
00832   }
00833 
00834   for (std::list<BankType>::const_iterator bank_iterator=banks.begin(); bank_iterator!=banks.end(); ++bank_iterator){
00835     BankType bank_type=*bank_iterator;
00836 
00837     std::cout << "AJB AJB modifyABCDVarROD doing bank " << bank_type << std::endl;
00838     
00839     boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00840     int realBank = Utility::translateBank(bank_type);
00841     
00842     PrimBuilder::instance().writeModuleVariable(primList, realBank, MODULE_GROUP_ALL, channel, chip, type, value);
00843     
00844     sendPrimList(rod, primList);
00845     awaitResponse(rod, 5);
00846     
00847     // also update the cache!
00848     // update cache...
00849     boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00850     if (!the_banks.get()) {
00851       if(mrs) {
00852     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00853          << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00854          << MRS_PARAM<int>("rod", rod)
00855          << MRS_TEXT("Cant update cache for non-existant MID") << ENDM;
00856       }else{
00857     std::cout << "Cant update cache for non-existant MID "<< mid;
00858       }
00859       return;
00860     }
00861     boost::shared_ptr<ABCDModule> cached_config = the_banks->get(bank_type);
00862     if (!cached_config.get()){
00863       if(mrs) {
00864     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00865          << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00866          << MRS_PARAM<int>("rod", rod)
00867          << MRS_PARAM<int>("bank", bank_type)
00868          << MRS_TEXT("Cant update cache for non-existant BANK") << ENDM;
00869       }else{
00870     std::cout << "Cant update cache for non-existant BANK " << bank_type << std::endl;
00871       }
00872       return;
00873     }
00874     ConfigUtility::modifyVar(cached_config.get(), chip, type, value);
00875   }
00876 }
00877   
00878 #warning "AJB fix to use primitives for multiple banks"
00879 void SctApi::modifyABCDVarROD(UINT32 mid, UINT32 type, FLOAT32 value, std::list<BankType> banks) {
00880   cout << "Change variable macro\n";
00881   
00882   unsigned int partition, crate, rod, channel;
00883   Utility::getpcrc(mid, partition, crate, rod, channel);
00884   
00885   if(!isRODPresent(rod)) {
00886     cout << "Trying to change module configuration on a non existant ROD\n";
00887     if(mrs) {
00888       *mrs << "ROD_UNCONFIGURED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00889            << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00890            << MRS_PARAM<int>("rod", rod)
00891            << MRS_TEXT("Can't modify module config (ROD non-existant)") << ENDM;
00892     }
00893     
00894     return;
00895   }
00896   
00897   for (std::list<BankType>::const_iterator bank_iterator=banks.begin(); bank_iterator!=banks.end(); ++bank_iterator){
00898     BankType bank_type=*bank_iterator;  
00899     {
00900       boost::mutex::scoped_lock lock(log().mutex());
00901       log() << "modifyABCDVarROD (module " << mid << ") " << type << " " << value << " bank_type " << bank_type << "\n";
00902     }    
00903     
00904     boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00905     
00906     int realBank = Utility::translateBank(bank_type);
00907     
00908     PrimBuilder::instance().writeModuleVariable(primList, realBank, MODULE_GROUP_ALL, channel, ALL_CHIPS, type, value);
00909     
00910     sendPrimList(rod, primList);
00911     awaitResponse(rod, 5);
00912     
00913     // update cache...
00914     boost::shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00915     if (!the_banks.get()) {
00916       if(mrs) {
00917     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00918          << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00919          << MRS_PARAM<int>("rod", rod)
00920          << MRS_TEXT("Cant update cache for non-existant MID") << ENDM;
00921       }
00922     }
00923     boost::shared_ptr<ABCDModule> cached_config = the_banks->get(bank_type);
00924     if (!cached_config.get()){
00925       if(mrs) {
00926     *mrs << "ROD_BANK_CONFIG_CACHE" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00927          << MRS_PARAM<int>("module", mid) << MRS_PARAM<int>("crate", crate) 
00928          << MRS_PARAM<int>("rod", rod)
00929          << MRS_TEXT("Cant update cache for non-existant BANK") << ENDM;
00930       }
00931     }
00932     ConfigUtility::modifyVar(cached_config.get(), type, value);
00933   }
00934 }
00935 
00936 
00937 #warning "AJB fix to use primitives for multiple banks"
00938 void SctApi::modifyABCDVarROD(UINT32 type, FLOAT32 value, std::list<BankType> banks) {
00939   cout << "Change variable macro\n";
00940 
00941 
00942   for (std::list<BankType>::const_iterator bank_iterator=banks.begin(); bank_iterator!=banks.end(); ++bank_iterator){
00943     BankType bank_type=*bank_iterator;
00944     std::cout << "modifyABCDVarROD bank " << bank_type << std::endl;
00945     {
00946       boost::mutex::scoped_lock lock(log().mutex());
00947       log() << "modifyABCDVarROD (all modules, all chips) " << type << " " << value << " Bank: " << bank_type << "\n";
00948     }
00949 
00950     boost::shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00951     
00952     int realBank = Utility::translateBank(bank_type);
00953     
00954     PrimBuilder::instance().writeModuleVariable(primList, realBank, MODULE_GROUP_ALL, ALL_MODULES, ALL_CHIPS, type, value);
00955     
00956     for(list<RodLabel>::const_iterator rl = rodList.begin();
00957     rl!=rodList.end();
00958     rl++){
00959       
00960       unsigned int rod = rl->rod;
00961       
00962       if(!isRODPresent(rod)) {
00963     cout << "Trying to change module configuration on a non existant ROD\n";
00964     if(mrs) {
00965       *mrs << "ROD_UNCONFIGURED" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00966            << MRS_PARAM<int>("rod", rod)
00967            << MRS_TEXT("Can't modify module config (ROD non-existant)") << ENDM;
00968     }
00969     
00970     return;
00971       }
00972       sendPrimList(rod, primList);
00973       awaitResponse(rod, 2);
00974     }
00975   }
00976 }
00977 
00978 } // Close namespace

Generated on Fri Sep 16 18:01:58 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5