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
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
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
00134
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
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
00218
00219
00220 shared_ptr<SctApiConfigCache::ModuleBanks> the_banks=module_cache.getFromMid(mid);
00221
00222
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
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
00245
00246
00247
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
00276 unsigned int partition, crate, rod, channel;
00277 Utility::getpcrc(mid, partition, crate, rod, channel);
00278
00279
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
00297
00298 unsigned long outNumPrims = outBody[2];
00299
00300
00301 if(outNumPrims == 1) {
00302 unsigned long primLength = outBody[4];
00303
00304 unsigned long primID = outBody[6];
00305
00306
00307 if(primID == RW_MODULE_DATA) {
00308 if(primLength != (sizeof(ABCDModule)/sizeof(UINT32) + 4)) {
00309 cout << "Output primitive was " << primLength << " not " << sizeof(ABCDModule)/sizeof(UINT32) << endl;
00310 }
00311
00312
00313 ABCDModule result;
00314
00315
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
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) {
00377 cout << "Output primitive was " << primLength << " not " << expectedSize << endl;
00378 }
00379
00380 result.reset(new ABCDModule);
00381
00382
00383
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
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
00423 return;
00424 }
00425
00426
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
00475 const unsigned int zeroTo95Pos = Sct::FibreNumberConverters::from124FormatTo96Format(zeroTo123Pos);
00476 if (zeroTo123Pos==DATA_LINK_OFF) {
00477
00478
00479 } else if(zeroTo123Pos <= 123 && zeroTo95Pos < 96) {
00480
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
00498 setupModuleMask(SP_BOTH, 0xf, primList);
00499 #else
00500
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 ) {
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
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 cout << "Send config to all modules\n";
00551
00552 PrimBuilder &builder = PrimBuilder::instance();
00553
00554
00555 boost::shared_ptr<PrimListWrapper> rodModeList1(new PrimListWrapper(1));
00556
00557 builder.rodMode(rodModeList1, CALIBRATION_MODE, 0, 1, 1, 1, 1);
00558
00559 synchSendPrimListAllCrates(rodModeList1);
00560
00561
00562
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
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
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
00609 #if USE_DUAL_PORTS
00610
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
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
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
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
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
00688 boost::shared_ptr<PrimListWrapper> setupMasks(new PrimListWrapper(1));
00689
00690 #if USE_DUAL_PORTS
00691
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
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);
00716 builder.writeRegister(resetList, RRIF_CMND_0, 0, 8, 0x78);
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
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
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
00789 builder.sendConfig(primList, SP0, 0, channel, NO_MODULE, ALL_CHIPS, 1, 1,
00790 realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00791
00792
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
00848
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
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 }