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
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
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
00266 if (!the_banks.get()) {
00267
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
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
00289
00290
00291
00292
00293 unsigned differences=ConfigUtility::diff(*current_cache, *lookup);
00294
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
00333 unsigned int partition, crate, rod, channel;
00334 Utility::getpcrc(mid, partition, crate, rod, channel);
00335
00336
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
00354
00355 unsigned long outNumPrims = outBody[2];
00356
00357
00358 if(outNumPrims == 1) {
00359 unsigned long primLength = outBody[4];
00360
00361 unsigned long primID = outBody[6];
00362
00363
00364 if(primID == RW_MODULE_DATA) {
00365 if(primLength != (sizeof(ABCDModule)/sizeof(UINT32) + 4)) {
00366 cout << "Output primitive was " << primLength << " not " << sizeof(ABCDModule)/sizeof(UINT32) << endl;
00367 }
00368
00369
00370 ABCDModule result;
00371
00372
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
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) {
00434 cout << "Output primitive was " << primLength << " not " << expectedSize << endl;
00435 }
00436
00437 result.reset(new ABCDModule);
00438
00439
00440
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
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
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 std::cout << "set all modules in " << set_modules_timer.elapsed() << " seconds" << std::endl;
00495 return;
00496 }
00497
00498
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
00543 setupModuleMask(SP_BOTH, 0xf, primList);
00544 #else
00545
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
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
00581 if (synchSendPrimListAll(zeroMasksList, 5)!=0) errorText+="Error zeroing module error masks\n";
00582 }
00583
00584
00585
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
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 ) {
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
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 cout << "Send config to all modules\n";
00654
00655 PrimBuilder &builder = PrimBuilder::instance();
00656
00657
00658 boost::shared_ptr<PrimListWrapper> rodModeList1(new PrimListWrapper(1));
00659
00660 builder.rodMode(rodModeList1, CALIBRATION_MODE, 0, 1, 1, 1, 1);
00661
00662 synchSendPrimListAll(rodModeList1);
00663
00664
00665
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
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
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
00712
00713
00714
00715 #if USE_DUAL_PORTS
00716
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
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
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
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
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
00793 boost::shared_ptr<PrimListWrapper> setupMasks(new PrimListWrapper(1));
00794
00795 #if USE_DUAL_PORTS
00796
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
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);
00821 builder.writeRegister(resetList, RRIF_CMND_0, 0, 8, 0x78);
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
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
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
00914 builder.sendConfig(primList, SP0, 0, channel, NO_MODULE, ALL_CHIPS, 1, 1,
00915 realBank, MODULE_GROUP_ALL, realConfig, 0, enableDataMode);
00916
00917
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
00972
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
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 }
01098