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

crate.cxx

00001 
00007 #include <unistd.h>
00008 #include <time.h>
00009 
00010 #include <iostream>
00011 #include <fstream>
00012 
00013 #include "Sct/SctNames.h"
00014 #include "Sct/Env.h"
00015 
00016 #include "RodCrate/RodModule.h"
00017 #include "RodCrate/BocCard.h"
00018 #include "RodCrate/TimModule.h"              // For TimMaskFrequency
00019 // #include "VmeInterface/VmeInterface.h"
00020 
00021 #include "sctConf/configXMLImpl.h"
00022 
00023 #include "../VmeInterface/DummyVmeInterface.h"
00024 #ifndef USE_DUMMY_VME
00025 #include "../VmeInterface/RCCVmeInterface.h"
00026 #endif
00027 
00028 #include "VmeDecode.h"
00029 
00030 #include "SctApiDebug.h"
00031 
00032 #include "SctApiConsts.h"
00033 #include "crateImpl.h"
00034 
00035 #include "extraScans.h"
00036 
00037 #ifdef USE_THREADS
00038 #include <boost/bind.hpp>
00039 #endif
00040 
00041 // For modify BOC params
00042 #include "ABCD/ABCDscans.h"
00043 
00044 using namespace SctPixelRod;
00045 using namespace SctConfiguration;
00046 // All std namespace are qualified explicitly
00047 
00048 namespace SctApi {
00049 /*
00050 The constructor. Tell this crate which partition it belongs to.
00051 This creates a VmeInterface.
00052 */
00053 CrateImpl::CrateImpl(unsigned int partition, unsigned int crate, 
00054                      boost::shared_ptr<Configuration> newConf) : 
00055   rodMap(), tim(0), config(newConf), vme(0), 
00056   partition(partition), crate(crate), mrs(0), 
00057   m_stopPolling(false), m_enablePolling(true)
00058 {
00059   // Create VME interface
00060   std::cout << "Initialising VME interface ... \n";
00061 
00062   MRSStream *tempMrs = 0;
00063 
00064   if(::Sct::SctNames::isMrsValid()) {
00065     tempMrs = &(::Sct::SctNames::Mrs());
00066     std::cerr << "Crate " << partition << ", " << crate << " found temporary mrs server\n";
00067   } else {
00068     std::cerr << "Crate " << partition << ", " << crate << " no mrs server, going to standalone mode\n";
00069   }
00070 
00071   if(config->isDummyCrate(partition, crate)) { 
00072     vme = new SctPixelRod::DummyVmeInterface();
00073 
00074     if(tempMrs) {
00075       *tempMrs << "CRATE_DUMMY"  << MRS_WARNING << MRS_QUALIF("SCTAPI") << MRS_TEXT("Using DUMMY interface") << ENDM;
00076     }
00077 #ifdef USE_DUMMY_VME
00078   } else {
00079     if(tempMrs) {
00080       *tempMrs << "CRATE_DUMMY"  << MRS_ERROR << MRS_QUALIF("SCTAPI") << MRS_TEXT("Non dummy crate requested, support not compiled!") << ENDM;
00081     }
00082 
00083     throw CrateException("RCC support not compiled");
00084   }
00085 #else
00086   } else {
00087     // Recent versions of VmeInterface check return code and throw exception
00088     try {
00089       vme = new SctPixelRod::RCCVmeInterface();
00090     } catch (VmeException &v) {
00091       Utility::decodeVme(v);
00092       std::cerr << "Interface not opened exception, check host and VME drivers. Crate initialisation failed!!\n";
00093 
00094       if(tempMrs) {
00095         *tempMrs << "CRATEINIT_FAILED" << MRS_ERROR << MRS_QUALIF("SCTAPI") << MRS_TEXT("Crate initialisation failed (VME interface)") << ENDM;
00096       }
00097 
00098       throw CrateException("Interface not found");
00099     }
00100 
00101     // Old versions don't, so we have to do it here
00102     if(vme->getLastErrcode() == 515) {
00103       // Failed to open interface (probably not running on an SBC!)
00104       std::cerr << "Interface not opened error, check host and VME drivers. Crate initialisation failed!!\n";
00105 
00106       if(tempMrs) {
00107         *tempMrs << "CRATEINIT_FAILED" << MRS_ERROR << MRS_QUALIF("SCTAPI") << MRS_TEXT("Crate initialisation failed (VME interface)") << ENDM;
00108       }
00109 
00110       throw CrateException("Interface not found");
00111     }
00112     //    std::cout << "Last error " << vme->getLastErrcode() << " (" << vme->getErrorMessage(vme->getLastErrcode()) << std::endl;
00113 
00114     if(tempMrs) {
00115       *tempMrs << "CRATEINIT_SUCCESS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") << MRS_TEXT("Successfully initialised VME interface") << ENDM;
00116     }
00117   }
00118 #endif
00119 
00120   std::cout << " ... Done\n";
00121 
00122   if(config.get() == 0) {
00123     std::cout << "Load configuration\n";
00124     config.reset(new ConfigurationXMLImpl());
00125   }
00126 
00127 #if USE_THREADS
00128   pollThread.reset(new boost::thread(boost::bind(&CrateImpl::pollingLoop, this)));
00129 #endif
00130 }
00131 
00132 /*
00133 The destructor. Delete all the RodModules and VmeInterface
00134 */
00135 CrateImpl::~CrateImpl() {
00136   // First make sure the polling is not using them
00137 #if USE_THREADS
00138   m_stopPolling = true;
00139   pollThread->join();
00140 #endif
00141 
00142   for(RodMap::const_iterator i=rodMap.begin();i!=rodMap.end();i++){
00143     std::cout << "RodModule on shutdown " << *(i->second.second) << std::endl;
00144     delete i->second.first;    //RodStatus
00145     delete i->second.second;   //RodModule
00146   }
00147   delete tim;
00148 
00149   delete vme;
00150 }
00151 
00152 void CrateImpl::rodInitialiseThread(int rod) {
00153   if(initialiseRod(rod) != 0) {
00154     std::cout << "Initialisation of rod  " << rod << " failed!\n";
00155     return;
00156   }
00157 
00158   rodCounter ++;
00159 
00160   if(initialiseBOC(rod) == 0) {
00161     if(Debug::getInstance()->checkDebugOption(DEBUG_DIAG)) {
00162       std::cout << "Should have initialised BOC now" << std::endl;
00163     }
00164   } // Else unsuccessful
00165 }
00166 
00167 int CrateImpl::initialiseCrate() {
00168   if(!initialiseTim()) {
00169     std::cout << "TIM initialise successful\n";
00170   }
00171 
00172   std::list<unsigned int> rods;
00173   try {
00174     rods = config->listRodsInCrate(partition, crate);
00175   } catch(ConfigurationException &c) {
00176     std::cout << "No RODs in this crate\n";
00177     std::cout << c.what() << std::endl;
00178 
00179     return 0;
00180   }
00181 
00182   std::cout << "Found configuration for " << rods.size() << " rods\n";
00183 
00184   std::list<boost::shared_ptr<boost::thread> > rodInitThreads;
00185 
00186   rodCounter = 0;
00187 
00188   for(std::list<unsigned int>::const_iterator r=rods.begin(); 
00189       r!=rods.end(); 
00190       r++) {
00191 
00192     rodInitThreads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CrateImpl::rodInitialiseThread, this, *r))));
00193   }
00194 
00195   for(std::list<boost::shared_ptr<boost::thread> >::const_iterator thread = rodInitThreads.begin();
00196       thread != rodInitThreads.end(); 
00197       thread ++) {
00198 
00199     if(*thread) {
00200       (*thread)->join();
00201     } else {
00202       std::cout << " Null pointer to thread!\n";
00203     }
00204   }
00205 
00206   int totalRods = rodCounter;
00207 
00208   return totalRods;
00209 }
00210 
00211 
00212 /*
00213   Create a TimModule object using information from the Configuration.
00214 */
00215 int CrateImpl::initialiseTim() {
00216   std::cout << "Load configuration for tim\n";
00217 
00218   TimConfig timConf;
00219   try {
00220     timConf = config->getTimConfig(partition, crate);
00221   } catch(ConfigurationException &c) {
00222     tim = 0;
00223     return -1;
00224   }
00225 
00226   try {
00227     // Create TimModule and initialize it
00228     std::cout << "Initialise TIM\n";
00229 
00230     tim = new SctPixelRod::TimModule(timConf.baseAddress, timMapSize, *vme);
00231 
00232     std::cout << "Constructed\n";
00233 
00234     tim->reset();
00235     tim->initialize();
00236 
00237     std::cout << "Initialised\n";
00238 
00239     std::cout << "Started TIM\n";
00240     tim->status();
00241 
00242     // Switch TIM trigger frequency to something not the default (600kHz!)
00243     timSetFrequency(timConf.trigFrequency, timConf.resetFrequency);
00244   } catch (SctPixelRod::TimException &r) {
00245     tim = 0;
00246 
00247     std::cerr << "While initialising TIM " << partition << " " << crate << ":\n";
00248     std::cerr << "Got TimException: " << std::endl;
00249     std::cerr << r.getDescriptor() << ", " << r.getData1() << ", " << r.getData2() << std::endl;
00250     std::cerr << "Continuing...\n";
00251   } catch (VmeException &v) {
00252     tim = 0;
00253 
00254     std::cout << "VmeException initialising TIM:\n";
00255     Utility::decodeVme(v);
00256 
00257     return -9;
00258   } catch (...) {
00259     tim = 0;
00260 
00261     std::cerr << "Unknown exception initialising TIM\n";
00262 
00263     return -6;
00264   }
00265 
00266   return 0;
00267 }
00268 
00269 /*
00270   Create a RodModule object using information from the Configuration.
00271 */
00272 int CrateImpl::initialiseRod(unsigned int rod) {
00273   int returnValue = 0;
00274 
00275   char *returnReason = "none  specified";
00276 
00277   int slave = 0;
00278 
00279   // 1 is not a valid address!
00280   unsigned long rodAddress=1;
00281 
00282   std::cout << "Load configuration for rod\n";
00283 
00284   if(config->isDummyCrate(partition, crate)) {
00285     // Don't create a RODModule!
00286     //  But return success so a ROD is counted
00287     return 0;
00288   }
00289 
00290 
00291   SctPixelRod::RodModule* rodObject;
00292 
00293   try {
00294     SctConfiguration::RodConfig rodConf;
00295 
00296     rodConf = config->getRodConfig(partition, crate, rod);
00297 
00298     rodAddress = rodConf.baseAddress;
00299 
00300     // Create RodModule and initialize it
00301     std::cout << "Initialise ROD " << rod << " at 0x" << std::hex << rodConf.baseAddress << std::dec << std::endl;
00302 
00303     rodObject = new SctPixelRod::RodModule(rodConf.baseAddress, 
00304                                            rodMapSize, 
00305                                            *vme, 
00306                                            numSlaves);
00307 
00308     std::cout << "Constructed\n";
00309 
00310     if(rodConf.resetLevel > 1) {
00311       std::cout << "*** ROD reset level " << rodConf.resetLevel << " (not reset) **** \n";
00312       std::cout << "*** Debug, ROD not reset **** \n";
00313       rodObject->initialize(false);  // Don't reset the ROD!
00314     } else {
00315       std::cout << "Doing full ROD reset...\n";
00316       // The true is a new feature to reset the ROD (what it always used to do!)
00317       rodObject->initialize(true);   // Use true to reset the ROD!
00318       std::cout << " ... done\n";
00319     }
00320 
00321     std::cout << "Initialised\n";
00322 
00323     std::cout << "Started ROD\n";
00324 
00325     rodObject->status();
00326 
00327     while(rodObject->textHandler() == TEXT_RQ_SET) {
00328       doTextBuffer(*rodObject);
00329       // textstate now TEXT_IDLE, check for multiple text buffers in while statement
00330     }
00331 
00332     RodStatus *currStatus = new RodStatus;
00333     currStatus->slaves = 0;
00334 #if USE_THREADS
00335     currStatus->currState = MYPRIM_STATE_IDLE;
00336     //     std::cout << "STATE: Initialising state to IDLE\n";
00337 #endif
00338 
00339 #if USE_ROD_MODULE_SLAVES
00340     int startedSlaves = 0;
00341 
00342     // Initialize slaves requested by config
00343     try {
00344       for(slave=0;  slave < rodConf.numSlaves; slave++) {
00345         if(rodConf.slaves[slave].ipramFile != "") {
00346           string ip(rodConf.slaves[slave].ipramFile);
00347           ip = Sct::Env::substituteVariables(ip);
00348 
00349           string id(rodConf.slaves[slave].idramFile);
00350           id = Sct::Env::substituteVariables(id);
00351 
00352           string ext(rodConf.slaves[slave].extFile);
00353           ext = Sct::Env::substituteVariables(ext);
00354 
00355           std::cerr << "Starting slave " << slave << std::endl;
00356           std::cerr << "((" << ip << ", " << id << ", " << ext << ")\n";
00357 
00358           rodObject->initSlaveDsp(ip, id, ext, slave, 'v');
00359 
00360           RodOutList *outList = rodObject->getOutList();
00361           if(outList) {
00362             unsigned long* outBody = outList->getBody();
00363 
00364             if(outBody) {
00365               if(outBody[3] != PRIM_LIST_REVISION) {
00366                 std::cout << "Prim list revision disagrees\n";
00367               }
00368 
00369               if(outBody[6] != START_SLAVE_EXECUTING) {
00370                 std::cout << "Prim ID not start slave!\n";
00371               }
00372 
00373               if(outBody[8] != slave) {
00374                 std::cout << "Start slave says slave 0x" << std::hex << outBody[8] << std::dec << " started not " << slave << std::endl;
00375               }
00376             } else {
00377               std::cout << "No body from start slave outlist!\n";
00378             }
00379           } else {
00380             std::cout << "No response from start slave!\n";
00381           }
00382           startedSlaves ++;
00383           currStatus->slaves |= 1<<slave;
00384         }
00385       }
00386     } catch (SctPixelRod::NoImageFile &f) {
00387       std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << " slave " << slave << ":\n";
00388       std::cerr << "No image file exception " << f.getFileName() << std::endl;
00389       std::cerr << "Continuing...\n";
00390 
00391       if(startedSlaves < 1) {
00392         *mrs << "ROD Slave Initialisation Failure" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00393              << MRS_PARAM<const char *>("Filename", f.getFileName().c_str())
00394              << ENDM;
00395       }
00396     } catch (SctPixelRod::RodException &r) {
00397       std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << " slave " << slave << ":\n";
00398       std::cerr << "Bad ROD exception: " << std::endl;
00399       std::cerr << r.getDescriptor() << ", " << r.getData1() << ", " << r.getData2() << std::endl;
00400       std::cerr << "Continuing...\n";
00401     }
00402 
00403     std::cout << "Started " << startedSlaves << " ROD slave DSPs\n";
00404 #endif
00405 
00406     rodMap.insert(std::make_pair(rod, std::make_pair(currStatus, rodObject)));
00407 
00408     std::cout << "ROD " << rod << " initialised\n";
00409 
00410     if(mrs) {
00411       *mrs << "ROD_INIT" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") 
00412            << MRS_PARAM<int>("number", rod)
00413            << MRS_PARAM<int>("slot", rodObject->getSlot())
00414            << MRS_TEXT("ROD Initialised")
00415            << ENDM;
00416     }
00417   } catch(ConfigurationException &c) {
00418     std::cout << "Configuration error for rod " << rod << "\n";
00419     std::cout << "\t" << c.what() << std::endl;
00420     returnValue = -1;
00421     returnReason = "Error in configuration database";
00422   } catch (SctPixelRod::PrimListException &p) {
00423     std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << ":\n";
00424     std::cerr << "Exception sending primlist:\n";
00425     std::cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << std::endl;
00426 
00427     returnReason = "PrimList exception";
00428     returnValue = -2;
00429   } catch (SctPixelRod::HpiException &h) {    
00430     std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << ":\n";
00431     std::cerr << "HpiException:\n";
00432     std::hex(std::cerr);
00433     std::cerr << h.getDescriptor() << '\n';
00434     std::cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " << 
00435       h.getReadAddr() << '\n';
00436     std::dec(std::cerr);
00437 
00438     returnReason = "HPI exception";
00439     returnValue = -3;
00440   } catch (SctPixelRod::RodException &r) {
00441     std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << ":\n";
00442     std::cerr << "Rod Exception\n";
00443     std::cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00444               << '\n';
00445 
00446     returnReason = "ROD exception";
00447     returnValue = -4;
00448   } catch (SctPixelRod::NoImageFile &f) { // This will be caught in the slave section!
00449     std::cerr << "While initialising ROD " << partition << " " << crate << " " << rod << " slave " << slave << ":\n";
00450     std::cerr << "No image file exception " << f.getFileName() << std::endl;
00451 
00452     returnReason = "NoImageFile exception";
00453     returnValue = -5;
00454   } catch (VmeException &v) {
00455     std::cout << "VmeException initialising ROD:\n";
00456     Utility::decodeVme(v);
00457 
00458     returnReason = "VmeException";
00459 
00460     returnValue = -9;
00461   } catch (...) {
00462     std::cerr << "Unknown exception initialising ROD\n";
00463     returnValue = -6;
00464   }
00465 
00466   if(returnValue < 0) {
00467     if(mrs) {
00468       *mrs << "RODINIT_FAIL" << MRS_ERROR << MRS_QUALIF("SCTAPI") 
00469            << MRS_TEXT("ROD init failure")
00470            << MRS_PARAM<const char *>("reason", returnReason)
00471            << MRS_PARAM<int>("number", rod);
00472       if(rodAddress != 1) 
00473         *mrs << MRS_PARAM<int>("address", rodAddress);
00474       *mrs << ENDM;
00475     }
00476   }
00477 
00478   return returnValue;
00479 }
00480 
00481 /*
00482   Initialise a BOC using information from the Configuration.
00483 */
00484 int CrateImpl::initialiseBOC(unsigned int rod) {
00485   BocCard* bocCard;
00486 
00487   try {
00488     //     SctConfiguration::RodConfig rodConf = config->getRodConfig(partition, crate, rod);
00489 
00490     //     if(!rodConf.bocPresent) {
00491     //       std::cout << "Skipping BOC (configuration says not present)\n";
00492     //       return -2;
00493     //     }
00494   } catch(ConfigurationException &c) {
00495     std::cout << "Request to initialise BOC with unconfigured rod\n";
00496     return -1;
00497   }
00498 
00499   if(RODPresent(rod)) {
00500     try {
00501       std::cout << "Initialise BOC " << rod << std::endl;
00502 
00503       bocCard = getRod(rod)->getBocCard();
00504 
00505       if(bocCard == 0) {
00506         // Jumper on ROD set for no BOC 
00507         return -2;
00508       }
00509 
00510       bocCard->initialize();
00511       bocCard->status(); // temporary
00512 
00513     } catch (VmeException &v) {
00514       std::cout << "VmeException initialising BOC:\n";
00515       Utility::decodeVme(v);
00516       return -9;
00517     } catch (BocException &b) {
00518       std::cout << "BocException initialising BOC:\n";
00519       std::cout << b << std::endl;
00520       return -9;
00521     } catch (...) {
00522       std::cerr << "Unknown exception initialising BOC\n";
00523       return -6;
00524     }
00525 
00526     configureBOC(rod);
00527   } else {
00528     std::cout << "Request for non-existent BOC " << partition << " " << crate << " " << rod << std::endl;
00529     return -1;
00530   }
00531 
00532   return 0;
00533 }
00534 
00535 /*
00536   Set up a BOC parameters according to information from the Configuration.
00537 */
00538 int CrateImpl::configureBOC(unsigned int rod) {
00539   if(!RODPresent(rod) || getRod(rod)->getBocCard() == 0) {
00540     std::cout << " configureBOC called on missing ROD/BOC " << rod << std::endl;
00541     throw CrateException("Trying to configure missing BOC");
00542   }
00543 
00544   BocCard *bocCard = getRod(rod)->getBocCard();
00545 
00546 
00547   std::cout << " *************  Turning lasers on ROD " << rod << " ON  ***************\n";
00548 
00549   BOCGlobalConfig globalConf = config->getBOCGlobalConfig(partition, crate, rod);
00550   for(int r=0; r<9; r++) {
00551     if(globalConf.validMask & 1<<r) {
00552       switch(r) {
00553       case 0:
00554         bocCard->setClockControl(globalConf.clockControl);
00555         break;
00556       case 1:
00557         bocCard->setRxDataMode(globalConf.rxDataMode);
00558         break;
00559       case 2:
00560         if(globalConf.rxDacClear)
00561           bocCard->clearRxDac();
00562         break;
00563       case 3:
00564         if(globalConf.txDacClear)
00565           bocCard->clearTxDac();
00566         break;
00567       case 4:
00568         bocCard->setVernierFinePhase(globalConf.vernierFinePhase);
00569         break;
00570       case 5:
00571         bocCard->setVernierClockPhase0(globalConf.vernierClockPhase0);
00572         break;
00573       case 6:
00574         bocCard->setVernierClockPhase1(globalConf.vernierClockPhase1);
00575         break;
00576       case 7:
00577         bocCard->setBpmClockPhase(globalConf.bpmClockPhase);
00578         break;
00579       case 8:
00580         bocCard->setBregClockPhase(globalConf.bregClockPhase);
00581         break;
00582       }
00583     }
00584   }
00585 
00586   unsigned char *mappings = config->getFibreMappings(partition, crate, rod);
00587 
00588   for(int channel=0;channel<48;channel++){
00589     // How far we got
00590     int step = 0;
00591 
00592     try {
00593       BOCChannelConfig channelConfig = config->getBOCConfig(partition, crate, rod, channel);
00594       std::cout << " Data for channel " << channel << std::endl;
00595 
00596       // NB - fibre mapping hopefully now not hard wired
00597       int txChannel = mappings[channel * 3 + 0];
00598       int rx0Channel = mappings[channel * 3 + 1];
00599       int rx1Channel = mappings[channel * 3 + 2];
00600 
00601       // Neither fibre is DATA_LINK_OFF
00602       if(rx0Channel <= 95 && rx1Channel <= 95 
00603      // Check for stated condition
00604      && (((rx0Channel / 2) != (rx1Channel / 2)) || (rx0Channel == rx1Channel))) {
00605         std::cout << "Illegal rx fibre mappings for channel " << channel << std::endl;
00606         std::cout << "  rx fibres must be mapped in consecutive pairs and low fibre must be even\n";
00607         if(mrs) {
00608           *mrs << "CRATE_FIBRES"  << MRS_WARNING << MRS_QUALIF("SCTAPI")
00609                << MRS_TEXT("RX fibres must be mapped in consecutive pairs and low fibre must be even") 
00610                << MRS_PARAM<int>("channel", channel)
00611                << MRS_PARAM<int>("fibre0", rx0Channel)
00612                << MRS_PARAM<int>("fibre1", rx1Channel)
00613                << MRS_PARAM<int>("partition", partition)
00614                << MRS_PARAM<int>("crate", crate)
00615                << MRS_PARAM<int>("rod", rod)
00616                << ENDM;
00617         }
00618       }
00619 
00620       //        std::cout << txChannel << " " << rx0Channel << " " << rx1Channel << std::endl;
00621 
00622       // Configure clock/command output
00623       bocCard->setLaserCurrent(txChannel,   channelConfig.current);
00624       step ++;
00625       bocCard->setBpmFineDelay(txChannel,   (channelConfig.delay&0xff) );
00626       step ++;
00627       bocCard->setBpmCoarseDelay(txChannel, ((channelConfig.delay>>8)&0xff));
00628       step ++;
00629       bocCard->setBpmMarkSpace(txChannel,   channelConfig.markSpace);
00630       step ++;
00631 
00632       // Configure data reception
00633       if((unsigned char)rx0Channel != (unsigned char)DATA_LINK_OFF) {
00634     bocCard->setRxThreshold(rx0Channel, channelConfig.threshold0);
00635         step ++;
00636     bocCard->setRxDataDelay(rx0Channel, channelConfig.delay0);
00637         step ++;
00638       }
00639       if((unsigned char)rx1Channel != (unsigned char)DATA_LINK_OFF) {
00640     bocCard->setRxThreshold(rx1Channel, channelConfig.threshold1);
00641         step ++;
00642     bocCard->setRxDataDelay(rx1Channel, channelConfig.delay1);
00643         step ++;
00644       }
00645     } catch(ConfigurationException &c) {
00646       // This would be worth saying if a module was attached
00647       //         std::cout << "No channel data for BOC " << rod << " channel " << channel << std::endl;
00648     } catch(BaseException &b) {
00649       std::cout << "Exception setting channel data for BOC step " << step << " ROD (" << rod << " channel " << channel << "): " << b << std::endl;
00650     }
00651   }
00652 
00653   delete [] mappings;
00654 
00655   return 0;
00656 }
00657 
00663 int CrateImpl::sendPrimList(unsigned int rod, boost::shared_ptr<PrimListWrapper> prim) {
00664   if(RODPresent(rod)) {   // If there's a rod presumably there's a data structure with it...
00665 #if USE_THREADS
00666     if(m_stopPolling) {
00667       std::cerr << "PRIM LIST: Send prim list called when polling stopped\n";
00668       throw(CrateException("Called sendPrimList with polling stopped"));
00669     }
00670 
00671     {
00672       RodStatus &stat = getRodData(rod);
00673       boost::mutex::scoped_lock lock(stat.mutex);
00674 
00675       getRod(rod)->deleteOutList();
00676 
00677       {
00678         boost::mutex::scoped_lock lock(primQueue_mutex);
00679         stat.listQueue.push_back(prim);
00680         primQueue_notEmpty.notify_one();
00681       }
00682 
00683       //       std::cout << "STATE: Changing state to LOADED\n";
00684       if(stat.currState == MYPRIM_STATE_IDLE) {
00685         stat.currState = MYPRIM_STATE_LOADED;
00686       } else {
00687 #warning "Throw exception?"
00688         std::cerr << "PRIM LIST: Sending prim list when not idle! (" << stat.currState << ")!\n";
00689         stat.currState = MYPRIM_STATE_LOADED;
00690         return -10;
00691       }
00692     }  // Release lock
00693 #else
00694     try {
00695       // So the result can't be confused with any previous
00696       getRod(rod)->deleteOutList();
00697       getRod(rod)->sendPrimList(prim->list.get());
00698     } catch (SctPixelRod::PrimListException &p) {
00699       std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00700       std::cerr << "Exception sending primlist:\n";
00701       std::cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << std::endl;
00702       return -6;
00703     } catch (SctPixelRod::HpiException &h) {    
00704       std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00705       std::cerr << "HpiException:\n";
00706       std::hex(std::cerr);
00707       std::cerr << h.getDescriptor() << '\n';
00708       std::cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " << 
00709         h.getReadAddr() << '\n';
00710       std::dec(std::cerr);
00711       return -2;
00712     } catch (SctPixelRod::RodException &r) {
00713       std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00714       std::cerr << "Rod Exception\n";
00715       std::cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00716                 << '\n';
00717       return -3;
00718     } catch (SctPixelRod::NoImageFile &f) {
00719       std::cerr << "While sending primlist " << partition << " " << crate << " " << rod << ":\n";
00720       std::cerr << "No image file exception " << f.getFileName() << std::endl;
00721       return -4;
00722     } catch (...) {
00723       std::cerr << "Unknown exception sending primlist to ROD\n";
00724       return -5;
00725     }
00726     //    std::cout << "Status after sendPrimList is: " << *(getRod(rod));
00727 
00728 #endif
00729   } else {
00730     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
00731     return -1;
00732   }
00733 
00734   return 0;
00735 }
00736 
00740 int CrateImpl::sendPrimListAll(boost::shared_ptr<PrimListWrapper> prim) {
00741 #if USE_THREADS
00742   {
00743     boost::mutex::scoped_lock lock(primQueue_mutex);
00744     listQueueAll.push_back(prim);
00745     primQueue_notEmpty.notify_one();
00746   }
00747 
00748   return 0;
00749 #else
00750   int result = 0;
00751   for(RodMap::const_iterator item = rodMap.begin();
00752       item != rodMap.end();
00753       item++) {
00754     int rod = item->first;
00755 
00756     int newResult = sendPrimList(rod, prim);
00757     if(result == 0) result = newResult;
00758   }
00759 
00760   return result;
00761 #endif
00762 }
00763 
00764 void CrateImpl::primListControl(unsigned int index, PLControl function) {
00765   if(RODPresent(index)) {
00766     SctPixelRod::RodModule &rod = *(getRod(index));
00767 
00768     switch(function) {
00769     case C_PL_STOP:
00770       rod.setVmeCommandRegBit(CR_ABORT);
00771       break;
00772     case C_PL_PAUSE:
00773       rod.setVmeCommandRegBit(CR_PAUSE);
00774       break;
00775     case C_PL_RESUME:
00776       rod.setVmeCommandRegBit(CR_RESUME);
00777       break;
00778     case C_PL_CANCEL:
00779       rod.clearVmeCommandRegBit(CR_IN_LIST_RDY);
00780       break;
00781     }
00782   }
00783 }
00784 
00785 /*
00786   Await response from a ROD within this crate
00787 */
00788 int CrateImpl::awaitResponse(unsigned int rod, int timeout) {
00789   // Preliminary implementation from EchoTest
00790   // Wait for ROD to begin executing and then wait for it to finish executing
00791   // Check for error messages in text buffer and read them out if they exist.
00792 
00793   using namespace SctPixelRod;
00794 
00795   bool timedout = false;
00796 
00797   time_t start_time = time(0);
00798 
00799   if(RODPresent(rod)) {
00800 #if USE_THREADS
00801     //     RodPrimState returnPState;
00802     /* Using threads we let the polling thread handle the text buffers
00803        and all the communication with the ROD 
00804     */
00805 
00806     RodStatus &status = getRodData(rod);
00807 
00808     // Shouldn't be called in the idle state...
00809     //  but for sendPrimListAll can get here before changing state.
00810 
00811     try {
00812       // Assign value to prevent warnings
00813       RodPrimState localState = MYPRIM_STATE_EXECUTING;
00814       do {
00815         if((time(0) - start_time) > timeout) {
00816           timedout = true;
00817           std::cout << "Timeout from wait complete\n";
00818 
00819           SctPixelRod::RodModule &myRod = *getRod(rod);
00820           std::cout << "  Current state is ";
00821           switch(myRod.getPrimState()) {
00822           case PRIM_IDLE: std::cout << "IDLE"; break;
00823           case PRIM_LOADED: std::cout << "LOADED"; break;
00824           case PRIM_EXECUTING: std::cout << "EXECUTING"; break;
00825           case PRIM_WAITING: std::cout << "WAITING"; break;
00826           case PRIM_PAUSED: std::cout << "PAUSED"; break;
00827           }
00828           std::cout << std::endl;
00829           std::cout << "  Local state is ";
00830           switch(localState) {
00831           case MYPRIM_STATE_LOADED: std::cout << "LOADED"; break;
00832           case MYPRIM_STATE_EXECUTING: std::cout << "EXECUTING"; break;
00833           case MYPRIM_STATE_COMPLETE: std::cout << "COMPLETE"; break;
00834           case MYPRIM_STATE_IDLE: std::cout << "IDLE"; break;
00835           }
00836           std::cout << std::endl;
00837         }
00838 
00839         // Yield when haven't got the lock...
00840         sched_yield();
00841 
00842         {
00843           boost::mutex::scoped_lock statLock(status.mutex);
00844           localState = status.currState;
00845         }
00846       } while ((localState != MYPRIM_STATE_COMPLETE)
00847                &&(!timedout));
00848       //      std::cout << "AwaitResponse: done wait or idle " << status.currState << "\n";
00849 
00850       {
00851         boost::mutex::scoped_lock statLock(status.mutex);
00852         status.currState = MYPRIM_STATE_IDLE;
00853         //         std::cout << "STATE: Changing state to IDLE\n";
00854 
00855         //         std::cout << "Current length of queue " << status.listQueue.size() << std::endl;
00856         //         std::cout << "Current RodModule state  " << getRod(rod)->getPrimState() << std::endl;
00857       }
00858 
00859       if(timedout) {
00860         std::cout << "Timed out at " << timeout << " seconds\n";
00861         return -200;
00862 #warning "If timeout then should try to abort primitive..."
00863       }
00864     } catch (BaseException &b) {
00865       std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00866       std::cerr << "Exception: " << b << std::endl;
00867       return -6;
00868     } catch (...) {
00869       std::cerr << "Unknown exception in await response\n";
00870       return -2;
00871     }
00872 #else  // No threads
00873     // Create a buffer for test messages
00874     PrimState returnPState;
00875     TextBuffState returnTState;
00876 
00877     SctPixelRod::RodModule* rod0 = getRod(rod);
00878 
00879     try {
00880       int exceptCount = 0;
00881       do {
00882         // If there's an exception here its probably OK to try again a bit later
00883         try {
00884           returnPState = rod0->primHandler();
00885           returnTState = rod0->textHandler();
00886           exceptCount = 0;
00887 
00888           while (returnTState == TEXT_RQ_SET) {
00889             doTextBuffer(*rod0);
00890             // textState is cleared to TEXT_IDLE
00891             // Check there isn't another text buffer
00892             returnTState = rod0->textHandler();
00893           }
00894 
00895           if((time(0) - start_time) > timeout) {
00896             timedout = true;
00897             std::cout << "Timeout from wait execute\n";
00898           }
00899         } catch(VmeException &e) {
00900           exceptCount ++;
00901           if(exceptCount < 2) {
00902             std::cout << "Caught an exception, trying ignoring\n";
00903             rod0->sleep(100);
00904           } else {
00905             std::cout << " Repeat of exception, throwing anyway\n";
00906             throw;
00907           }
00908         }
00909       } while ((returnPState != PRIM_EXECUTING) && (!timedout));
00910       do {
00911         returnPState = rod0->primHandler();
00912 
00913         if((time(0) - start_time) > timeout) {
00914           timedout = true;
00915           std::cout << "Timeout from wait finish\n";
00916         }
00917       } while ((returnPState != PRIM_WAITING)&&(returnPState != PRIM_IDLE) &&(!timedout));
00918 
00919       if(timedout) {
00920         std::cout << "Timed out at " << timeout << " seconds\n";
00921         return -200;
00922 #warning "If timeout then should try to abort primitive..."
00923       }
00924     } catch (PrimListException &p) {
00925       std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00926       std::cerr << "Exception sending primlist:\n";
00927       std::cerr << p.getDescriptor() << " " << p.getData1() << ", " << p.getData2() << std::endl;
00928       return -6;
00929     } catch (HpiException &h) {    
00930       std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00931       std::cerr << "HpiException:\n";
00932       std::hex(std::cerr);
00933       std::cerr << h.getDescriptor() << '\n';
00934       std::cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " << 
00935         h.getReadAddr() << '\n';
00936       std::dec(std::cerr);
00937       return -5;
00938     } catch (VmeException &v) {
00939       std::cout << "VmeException in await response:\n";
00940       Utility::decodeVme(v);
00941 
00942       return -9;
00943     } catch (RodException &r) {
00944       std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00945       std::cerr << "Rod Exception\n";
00946       std::cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00947                 << '\n';
00948       return -4;
00949     } catch (NoImageFile &f) {
00950       std::cerr << "In await response " << partition << " " << crate << " " << rod << ":\n";
00951       std::cerr << "No image file exception " << f.getFileName() << std::endl;
00952       return -3;
00953     } catch (...) {
00954       std::cerr << "Unknown exception in await response\n";
00955       return -2;
00956     }
00957     //    std::cout << "Status at end of awaitResponse: " << *rod0;
00958 #endif
00959   } else {
00960     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
00961 
00962     return -1;
00963   }
00964 
00965   return 0;
00966 }
00967 
00968 /*
00969   Await response from all RODs within this crate
00970 */
00971 int CrateImpl::awaitResponseAll(int timeout) {
00972   int result = 0;
00973   for(RodMap::const_iterator item = rodMap.begin();
00974       item != rodMap.end();
00975       item++) {
00976     int rod = item->first;
00977 
00978     int newResult = awaitResponse(rod, timeout);
00979     if(result == 0) result = newResult;
00980   }
00981 
00982   return 0;
00983 }
00984 
00985 /*
00986   Get the last response from a ROD within this crate
00987 */
00988 boost::shared_ptr<RodOutList> CrateImpl::getResponse(unsigned int rod) {
00989   RodOutList *result = 0;
00990 
00991   if(RODPresent(rod)) {
00992     // This doesn't actually talk to the ROD just copies memory...
00993     RodOutList *response = getRod(rod)->getOutList();
00994 
00995     if(response) {
00996       result = new RodOutList(response->getLength());
00997 
00998       unsigned long *oldBody = response->getBody();
00999       unsigned long *newBody = result->getBody();
01000 
01001       for(int i=0; i<result->getLength(); i++) {
01002         newBody[i] = oldBody[i];
01003       }
01004 
01005       getRod(rod)->deleteOutList();
01006     } else {
01007       std::cout << "**** No response found when expected\n";
01008       result = 0;
01009     }
01010   } else {
01011     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01012     result = 0;
01013   }
01014 
01015   return boost::shared_ptr<RodOutList>(result);
01016 }
01017 
01018 void CrateImpl::setMrsStream(MRSStream *stream) 
01019 {
01020   std::cerr << "Crate " << partition << ", " << crate << " using mrs server\n";
01021   mrs = stream;
01022 }
01023 
01024 /*
01025   Read the message buffer if there is anything there
01026 */
01027 bool CrateImpl::getRodMessage(unsigned int rod, char *buffer, unsigned long &length) {
01028   bool complete = true;
01029 
01030   char myBuffer[TEXT_BUFF_SIZE];
01031   long myLength;
01032 
01033   TEXT_BUFFER_TYPE dummy;
01034   if(RODPresent(rod)) {
01035     if(getRod(rod)->textHandler() == TEXT_READOUT) {
01036       getRod(rod)->getTextBuffer(myBuffer, myLength, dummy);
01037       getRod(rod)->clearTextBuffer();
01038 
01039       // Copy across what's allowed
01040       for(unsigned int i=0; i<length || i<(unsigned long)myLength; i++) {
01041         buffer[i] = myBuffer[i];
01042       }
01043 
01044       if(length < (unsigned long)myLength) {
01045         complete = false;
01046       } else {
01047         length = myLength;
01048       }
01049     } else {
01050       buffer[0] = '\0';
01051       length = 0;
01052       complete = false;
01053     }
01054   }
01055 
01056   return complete;
01057 }
01058 
01059 /*
01060   Write a block of master dsp memory 
01061 */
01062 int CrateImpl::mdspBlockWrite(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords) {
01063   if(RODPresent(rod)) {
01064     try {
01065       getRod(rod)->mdspBlockWrite(dspStart, buffer, numWords);
01066     } catch(BaseException &b) {
01067       std::cout << "Exception writing mdsp\n";
01068       std::cout << b;
01069       return -3;
01070     } catch(...) {
01071       std::cout << "Exception writing mdsp\n";
01072       return -2;
01073     }
01074   } else {
01075     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01076     return -1;
01077   }
01078 
01079   return 0;
01080 }
01081 
01082 /*
01083   Read a block of master dsp memory 
01084 */
01085 int CrateImpl::mdspBlockRead(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords) {
01086   if(RODPresent(rod)) {
01087     try {
01088 //       std::cout << "Calling RodModule::mdspBlockRead(0x" << std::hex << dspStart << ", " << buffer << ", " << std::dec << numWords << ");\n";
01089       getRod(rod)->mdspBlockRead(dspStart, buffer, numWords);
01090     } catch(BaseException &b) {
01091       std::cout << "Exception reading mdsp\n";
01092       std::cout << b;
01093       std::cout << "0x" << std::hex << dspStart << ", " << std::dec << numWords << std::endl;
01094       return -3;
01095     } catch(...) {
01096       std::cout << "Unknown exception reading mdsp\n";
01097       std::cout << "0x" << std::hex << dspStart << ", " << std::dec << numWords << std::endl;
01098       return -2;
01099     }
01100   } else {
01101     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01102     return -1;
01103   }
01104 
01105   return 0;
01106 }
01107 
01108 /*
01109   Read a block of slave dsp memory 
01110 */
01111 int CrateImpl::slvBlockWrite(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords, long dspNumber) {
01112   if(RODPresent(rod)) {
01113     try {
01114       getRod(rod)->slvBlockWrite(dspStart, buffer, numWords, dspNumber);
01115     } catch(BaseException &b) {
01116       std::cout << "Exception writing to slave\n";
01117       std::cout << b;
01118       return -3;
01119     } catch(...) {
01120       std::cout << "Exception writing to slave\n";
01121       return -2;
01122     }
01123   } else {
01124     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01125     return -1;
01126   }
01127   return -0;
01128 }
01129 
01130 /*
01131   Read a block of slave dsp memory 
01132 */
01133 int CrateImpl::slvBlockRead(unsigned int rod, long dspStart, unsigned long* buffer, unsigned long numWords, long dspNumber) {
01134   if(RODPresent(rod)) {
01135     try {
01136       RodModule &r = *getRod(rod);
01137 #warning "Get lock so nobody else comes in and does something"
01138       unsigned long val = r.readRodStatusReg(2);
01139       // Turn off mdsp polling of that slave
01140       r.mdspSingleWrite(STATUS_REG[2], val & (~(1<<dspNumber)));
01141       r.slvBlockRead(dspStart, buffer, numWords, dspNumber);
01142       r.mdspSingleWrite(STATUS_REG[2], val);
01143     } catch(BaseException &b) {
01144       std::cout << "Exception reading slave\n";
01145       std::cout << b;
01146       return -3;
01147     } catch(...) {
01148       std::cout << "Exception reading slave\n";
01149       return -2;
01150     }
01151   } else {
01152     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01153     return -1;
01154   }
01155   return 0;
01156 }
01157 
01158 unsigned long CrateImpl::readRodStatusReg(unsigned int rod, long regNumber) {
01159   unsigned long result = 0;
01160 
01161   if(RODPresent(rod)) {
01162     try {
01163       result = getRod(rod)->readRodStatusReg(regNumber);
01164     } catch(BaseException &b) {
01165       std::cout << "Exception reading rod status\n";
01166       std::cout << b;
01167     } catch(...) {
01168       std::cout << "Exception reading rod status\n";
01169     }
01170   } else {
01171     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01172   }
01173   return result;
01174 }
01175 
01176 unsigned long CrateImpl::readRodCommandReg(unsigned int rod, long regNumber) {
01177   unsigned long result = 0;
01178 
01179   if(RODPresent(rod)) {
01180     try {
01181       result = getRod(rod)->readRodCommandReg(regNumber);
01182     } catch(BaseException &b) {
01183       std::cout << "Exception reading rod command\n";
01184       std::cout << b;
01185     } catch(...) {
01186       std::cout << "Exception reading rod command\n";
01187     }
01188   } else {
01189     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01190   }
01191   return result;
01192 }
01193 
01194 unsigned long CrateImpl::dspSingleRead(unsigned int rod, const unsigned long dspAddr, long dspNumber) {
01195   unsigned long result = 0;
01196 
01197   if(RODPresent(rod)) {
01198     try {
01199       if(dspNumber == -1) {
01200         result = getRod(rod)->mdspSingleRead(dspAddr);
01201       } else {
01202         result = getRod(rod)->slvSingleRead(dspAddr, dspNumber);
01203       } 
01204     } catch(BaseException &b) {
01205       std::cout << "Exception dsp single read\n";
01206       std::cout << b;
01207     } catch(...) {
01208       std::cout << "Exception dsp single read\n";
01209     }
01210   } else {
01211     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01212   }
01213   return result;
01214 }
01215 
01216 int CrateImpl::dspSingleWrite(unsigned int rod, unsigned long dspAddr, unsigned long buffer, long dspNumber) {
01217   if(RODPresent(rod)) {
01218     try {
01219       if(dspNumber == -1) {
01220         getRod(rod)->mdspSingleWrite(dspAddr, buffer);
01221       } else {
01222         getRod(rod)->slvSingleWrite(dspAddr, buffer, dspNumber);
01223       }
01224     } catch(BaseException &b) {
01225       std::cout << "Exception dsp single write\n";
01226       std::cout << b;
01227     } catch(...) {
01228       std::cout << "Exception dsp single write\n";
01229       return -2;
01230     }
01231   } else {
01232     std::cout << "Request for non-existent ROD " << partition << " " << crate << " " << rod << std::endl;
01233     return -1;
01234   }
01235 
01236   return 0;
01237 }
01238 
01239 void CrateImpl::status() {
01240   std::cout << "TIM status\n";
01241   if(tim) 
01242     tim->status();
01243   std::cout << std::endl;
01244 
01245   if(rodMap.size() == 0) {
01246     if(mrs) {
01247       *mrs << "CRATE_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") 
01248            << MRS_PARAM<int>("partition", partition) << MRS_PARAM<int>("crate", crate) 
01249            << MRS_TEXT("No RODs loaded") << ENDM;
01250     }
01251   }
01252 
01253   for(RodMap::const_iterator item = rodMap.begin();
01254       item != rodMap.end();
01255       item++) {
01256     RodModule &rod = *(item->second.second);
01257 
01258     try {
01259       //       SctConfiguration::RodConfig rodConf = config->getRodConfig(partition, crate, item->first);
01260       //       if(rodConf.bocPresent) {
01261       std::cout << "BOC status\n";
01262       if(rod.getBocCard() != 0) {
01263         rod.getBocCard()->status();
01264 
01265         if(mrs) {
01266           *mrs << "BOC_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") 
01267                << MRS_PARAM<int>("partition", partition) << MRS_PARAM<int>("crate", crate) 
01268                << MRS_PARAM<int>("slot", rod.getSlot()) 
01269                << MRS_TEXT("BOC loaded") << ENDM;
01270         }
01271       } else {
01272         std::cout << "*********** No BOC status (BOC not present!!!!)\n";
01273       }
01274     } catch(ConfigurationException &c) {
01275       std::cout << "Request for status on unconfigured ROD! (impossible)\n";
01276       return;
01277     }
01278 
01279     if(mrs) {
01280       *mrs << "ROD_STATUS" << MRS_INFORMATION << MRS_QUALIF("SCTAPI") 
01281            << MRS_PARAM<int>("partition", partition) << MRS_PARAM<int>("crate", crate) 
01282            << MRS_PARAM<int>("slot", rod.getSlot()) 
01283            << MRS_TEXT("ROD loaded") << ENDM;
01284     }
01285 
01286     std::cout << "ROD status\n";
01287     rod.status();
01288 
01289     if(rod.readRodStatusBit(0, SR_RUNNING)) {
01290       std::cout << "Running ";
01291     }
01292     if(rod.readRodStatusBit(0, SR_BUSY)) {
01293       std::cout << "Busy ";
01294     }
01295     if(rod.readRodStatusBit(0, SR_PAUSED)) {
01296       std::cout << "Paused ";
01297     }
01298     if(rod.readRodStatusBit(0, SR_OUT_LIST_RDY)) {
01299       std::cout << "Out list ready ";
01300     }
01301     if(rod.readRodStatusBit(0, SR_EXECUTING)) {
01302       std::cout << "Executing \n";
01303       unsigned long sr2 = rod.readRodStatusReg(1);
01304 
01305       std::cout << "Current Primitive index = " << ((sr2 & 0xfffff0) >> 4) << std::endl;
01306       std::cout << "Current List index = " << (sr2 & 0xf);
01307     }
01308 
01309     std::cout << std::endl;
01310   }
01311 }
01312 
01313 /* 
01314    Lookup the RodModule object to send instructions to.
01315    Return 0 if not found.
01316 */
01317 SctPixelRod::RodModule *CrateImpl::getRod(unsigned int rod) const {
01318   RodMap::const_iterator found;
01319 
01320   found = rodMap.find(rod);
01321   if(found == rodMap.end()) return 0;
01322   else return found->second.second;
01323 }
01324 
01325 const RodStatus &CrateImpl::getRodData(unsigned int rod) const {
01326   RodMap::const_iterator found;
01327 
01328   found = rodMap.find(rod);
01329   if(found == rodMap.end()) {
01330 //     std::cerr << "AJB ERROR Hello world" 
01331 //               <<  __FILE__ << ":" <<__LINE__ << std::endl;
01332     std::cerr << " getRodData called on missing ROD " << rod << std::endl;
01333     throw CrateException("Asked for data on non-existant ROD (const)");
01334   }
01335   else return *(found->second.first);
01336 }
01337 
01338 RodStatus &CrateImpl::getRodData(unsigned int rod) {
01339   RodMap::const_iterator found;
01340 
01341   found = rodMap.find(rod);
01342   if(found == rodMap.end()) {
01343 //     std::cerr << "AJB ERROR Hello world" 
01344 //               <<  __FILE__ << ":" <<__LINE__ << std::endl;
01345     std::cerr << " getRodData (const) called on missing ROD " << rod << std::endl;
01346     throw CrateException("Asked for data on non-existant ROD");
01347   }
01348   else return *(found->second.first);
01349 }
01350 
01351 void CrateImpl::doTextBuffer(SctPixelRod::RodModule &rod) {
01352   TEXT_BUFFER_TYPE myTextType;
01353   TextBuffState returnTState;
01354 
01355   std::cout << "Got some text: crate: " << crate << " rod slot: " << rod.getSlot() << "\n";
01356   do {
01357     returnTState = rod.textHandler();
01358   } while (returnTState != TEXT_READOUT);
01359 
01360   const bool textToMrs=((bool)mrs && false);
01361   if(textToMrs) {
01362     *mrs << "TEXTBUFF_ARRIVE" << MRS_DIAGNOSTIC << MRS_QUALIF("SCTAPI")
01363          << MRS_PARAM<int>("partition", partition)
01364          << MRS_PARAM<int>("crate", crate)
01365          << MRS_PARAM<int>("rodSlot", rod.getSlot());
01366   }
01367 
01368   char * myTextBuffer = new char[TEXT_BUFF_SIZE];
01369   long myTextLength;
01370 
01371   rod.getTextBuffer(myTextBuffer, myTextLength, myTextType);
01372   rod.clearTextBuffer();
01373 
01374   std::string type;
01375   switch(myTextType) {
01376   case TEXT_ERR: type = "ERROR"; break;
01377   case TEXT_INFO: type = "INFO"; break;
01378   case TEXT_DIAG: type = "DIAG"; break;
01379   case TEXT_XFER: type = "TRANSFER"; break;
01380   case TEXT_UNDEF: type = "**Undefined**"; break;
01381   }
01382 
01383   std::cout << "Text " << type << " : " << myTextLength << std::endl;
01384   if(textToMrs) {
01385     *mrs << MRS_PARAM<const char *>("Type", type.c_str());
01386   }
01387 
01388   if(myTextLength != 32768) {
01389     std::ostringstream message;    
01390     std::ostringstream short_message;
01391     for (int i=0; i<myTextLength; i++) {
01392       message << myTextBuffer[i];
01393       if (myTextBuffer[i]!='\n' && i<100) short_message << myTextBuffer[i];
01394     }
01395     std::cout << message.str();
01396     myTextBuffer[myTextLength] = 0;
01397     if(textToMrs) {
01398       *mrs << MRS_TEXT(short_message.str().c_str())
01399            << MRS_PARAM<const char *>("Text", myTextBuffer);
01400     }
01401   } else {
01402     std::cout << "Buffersize suspiciously precisely 32768...\n";
01403     if(textToMrs) {
01404       *mrs << MRS_TEXT("Buffersize suspiciously precisely 32768...");
01405     }
01406 
01407     if (false) {
01408       std::string fileName = Sct::SctNames::getLogDir() + "/SctApi32k" + type + "BufferDump.txt";
01409       std::ofstream outFile(fileName.c_str(), std::ios::binary | std::ios::app);
01410       time_t currTime = time(0);
01411       outFile << "Rod: " << rod.getSerialNumber() << " Time: " << ctime(&currTime) << std::endl;
01412       outFile.write(myTextBuffer, myTextLength);
01413       outFile << "\nEnd of dump\n";
01414     }
01415   }
01416 
01417   std::cout << std::endl;
01418 
01419 #warning "This should use debug level instead, but that's in SctApi not Crate!"
01420 #ifdef DEBUG
01421   std::ofstream outFile((type + "BufferDump.txt").c_str(), std::ios::binary | std::ios::app);
01422   outFile << "\nBuffer block length " << myTextLength << " rod " << rod.getSerialNumber() << std::endl;
01423   time_t currTime = time(0);
01424   outFile << "Time " << ctime(&currTime);
01425   outFile.write(myTextBuffer, myTextLength);
01426 #endif
01427 
01428   if(textToMrs) {
01429     *mrs << ENDM;
01430   }
01431 
01432   delete [] myTextBuffer;
01433 }
01434 
01435 void CrateImpl::printBOCSetup(unsigned int rod) {
01436   if(RODPresent(rod)) {
01437     if(getRod(rod)->getBocCard() == 0) {
01438       std::cerr << " printBOCSetup called on missing BOC " << rod << std::endl;
01439       throw CrateException("No BOC for print setup");
01440     }
01441 
01442     BocCard &bocCard = *(getRod(rod)->getBocCard());
01443 
01444     std::cout.fill('0');
01445     for(int c=0; c<48; c++) {
01446       std::cout << "Channel ";
01447       std::cout.width(2);
01448       std::cout << c << ":  I 0x";
01449       std::cout << std::hex;
01450       std::cout.width(2);
01451       std::cout << bocCard.getLaserCurrent(c) << " Delay 0x";
01452       std::cout.width(2);
01453       std::cout << bocCard.getBpmFineDelay(c) << "/0x";
01454       std::cout.width(2);
01455       std::cout << bocCard.getBpmCoarseDelay(c)
01456                 << " M/S 0x";
01457       std::cout.width(2);
01458       std::cout << bocCard.getBpmMarkSpace(c);
01459       std::cout << "  Input 0: Th 0x";
01460       std::cout.width(2);
01461       std::cout << bocCard.getRxThreshold(c*2) << " Delay 0x";
01462       std::cout.width(2);
01463       std::cout << bocCard.getRxDataDelay(c*2)
01464                 << "  Input 1: Th 0x";
01465       std::cout.width(2);
01466       std::cout << bocCard.getRxThreshold(c*2+1) << " Delay 0x";
01467       std::cout.width(2);
01468       std::cout << bocCard.getRxDataDelay(c*2+1)
01469                 << std::endl;
01470     }
01471     std::cout.fill(' ');
01472     std::cout << std::dec;
01473   }
01474 }
01475 
01476 std::vector<SctConfiguration::BOCChannelConfig> CrateImpl::currentBOCSetup(unsigned int rod) {
01477   std::vector<SctConfiguration::BOCChannelConfig> result;
01478 
01479   if(RODPresent(rod)) {
01480     if(getRod(rod)->getBocCard() == 0) {
01481       std::cerr << " currentBOCSetup called on missing BOC " << rod << std::endl;
01482       throw CrateException("No BOC to get setup from");
01483     }
01484 
01485     BocCard &bocCard = *(getRod(rod)->getBocCard());
01486 
01487     for(int c=0; c<48; c++) {
01488       SctConfiguration::BOCChannelConfig chan;
01489 
01490       chan.current = bocCard.getLaserCurrent(c);
01491       chan.delay =  (bocCard.getBpmCoarseDelay(c) << 8) + bocCard.getBpmFineDelay(c);
01492       chan.markSpace = bocCard.getBpmMarkSpace(c);
01493       chan.threshold0 = bocCard.getRxThreshold(c*2);
01494       chan.delay0 = bocCard.getRxDataDelay(c*2);
01495       chan.threshold1 = bocCard.getRxThreshold(c*2+1);
01496       chan.delay1 = bocCard.getRxDataDelay(c*2+1);
01497 
01498       result.push_back(chan);
01499     }
01500   }
01501 
01502   return result;
01503 }
01504 
01505 void CrateImpl::printBOCRegisters(unsigned int rod) {
01506   if(RODPresent(rod)) {
01507     if(getRod(rod)->getBocCard() == 0) {
01508       std::cerr << " printBOCRegisters called on missing BOC " << rod << std::endl;
01509       throw CrateException("No BOC for print registers");
01510     }
01511 
01512     BocCard &bocCard = *(getRod(rod)->getBocCard());
01513 
01514     std::cout << std::hex;
01515 
01516     std::cout << "BOC register dump\n";
01517 
01518     std::cout << "Clock control  0x" << bocCard.getClockControl() << std::endl;
01519     std::cout << "RX data mode   0x" << bocCard.getRxDataMode() << std::endl;
01520     std::cout << "RX DAC clear   0x" << bocCard.getRxDacClear() << std::endl;
01521     std::cout << "TX DAC clear   0x" << bocCard.getTxDacClear() << std::endl;
01522     std::cout << "Vernier fine   0x" << bocCard.getVernierFinePhase() << std::endl;
01523     std::cout << "Vernier clk 0  0x" << bocCard.getVernierClockPhase0() << std::endl;
01524     std::cout << "Vernier clk 1  0x" << bocCard.getVernierClockPhase1() << std::endl;
01525     std::cout << "BPM clk phase  0x" << bocCard.getBpmClockPhase() << std::endl;
01526     std::cout << "BReg clk phase 0x" << bocCard.getBregClockPhase() << std::endl;
01527     std::cout << "BOC reset      0x" << bocCard.getBocReset() << std::endl;
01528     std::cout << "BPM reset      0x" << bocCard.getBpmReset() << std::endl;
01529     std::cout << "BOC status     0x" << bocCard.getBocStatusRegister() << std::endl;
01530 
01531     std::cout << std::dec;
01532   } else {
01533     std::cout << "No ROD found\n";
01534   }
01535 }
01536 
01537 SctConfiguration::BOCGlobalConfig CrateImpl::currentBOCRegisters(unsigned int rod) {
01538   BOCGlobalConfig result;
01539 
01540   if(RODPresent(rod)) {
01541     if(getRod(rod)->getBocCard() == 0) {
01542       std::cerr << " currentBOCRegisters called on missing BOC " << rod << std::endl;
01543       throw CrateException("No BOC for current registers");
01544     }
01545 
01546     BocCard &bocCard = *(getRod(rod)->getBocCard());
01547 
01548     result.validMask = 0x1ff;
01549     result.clockControl = bocCard.getClockControl();
01550     result.rxDataMode = bocCard.getRxDataMode();
01551     result.rxDacClear = bocCard.getRxDacClear();
01552     result.txDacClear = bocCard.getTxDacClear();
01553     result.vernierFinePhase = bocCard.getVernierFinePhase();
01554     result.vernierClockPhase0 = bocCard.getVernierClockPhase0();
01555     result.vernierClockPhase1 = bocCard.getVernierClockPhase1();
01556     result.bpmClockPhase = bocCard.getBpmClockPhase();
01557     result.bregClockPhase = bocCard.getBregClockPhase();
01558 
01559     // Also getBocReset, getBpmReset and getBocStatusRegister
01560   }
01561 
01562   return result;
01563 }
01564 
01565 void CrateImpl::saveBOCSetup(unsigned int rod, BankType bank) {
01566   getRodData(rod).savedBocSetup[bank] = currentBOCSetup(rod);
01567 }
01568 
01569 void CrateImpl::saveBOCRegisters(unsigned int rod, BankType bank) {
01570   getRodData(rod).savedBocRegisters[bank].reset(new BOCGlobalConfig(currentBOCRegisters(rod)));
01571 }
01572 
01573 void CrateImpl::restoreBOCSetup(unsigned int rod, BankType bank) {
01574   BocCard *bocCard = getRod(rod)->getBocCard();
01575 
01576   std::vector<SctConfiguration::BOCChannelConfig> &setup = getRodData(rod).savedBocSetup[bank];
01577 
01578 //   char *mappings = config->getFibreMappings(partition, crate, rod);
01579 
01580   for(int channel=0;channel<48;channel++){
01581     try {
01582       BOCChannelConfig channelConfig = setup[channel];
01583 
01584       std::cout << " Restoring channel " << channel << std::endl;
01585 
01586       int txChannel = channel;
01587       int rx0Channel = channel * 2;
01588       int rx1Channel = channel * 2 + 1;
01589 
01590       // Configure clock/command output
01591       bocCard->setLaserCurrent(txChannel,   channelConfig.current);
01592       bocCard->setBpmFineDelay(txChannel,   (channelConfig.delay&0xff) );
01593       bocCard->setBpmCoarseDelay(txChannel, ((channelConfig.delay>>8)&0xff));
01594       bocCard->setBpmMarkSpace(txChannel,   channelConfig.markSpace);
01595 
01596       // Configure data reception
01597       // Don't need to check for DATA_LINK_OFF as rx?Channel is generated locally
01598       bocCard->setRxThreshold(rx0Channel, channelConfig.threshold0);
01599       bocCard->setRxDataDelay(rx0Channel, channelConfig.delay0);
01600 
01601       bocCard->setRxThreshold(rx1Channel, channelConfig.threshold1);
01602       bocCard->setRxDataDelay(rx1Channel, channelConfig.delay1);
01603     } catch(BaseException &b) {
01604       std::cout << "Exception setting channel data for BOC " << " ROD (" << rod << " channel " << channel << "): " << b << std::endl;
01605     }
01606   }
01607 }
01608 
01609 void CrateImpl::restoreBOCRegisters(unsigned int rod, BankType bank) {
01610   BocCard *bocCard = getRod(rod)->getBocCard();
01611 
01612   BOCGlobalConfig &globalConf = *getRodData(rod).savedBocRegisters[bank];
01613   for(int r=0; r<9; r++) {
01614     if(globalConf.validMask & 1<<r) {
01615       switch(r) {
01616       case 0:
01617         bocCard->setClockControl(globalConf.clockControl);
01618         break;
01619       case 1:
01620         bocCard->setRxDataMode(globalConf.rxDataMode);
01621         break;
01622       case 2:
01623         if(globalConf.rxDacClear)
01624           bocCard->clearRxDac();
01625         break;
01626       case 3:
01627         if(globalConf.txDacClear)
01628           bocCard->clearTxDac();
01629         break;
01630       case 4:
01631         bocCard->setVernierFinePhase(globalConf.vernierFinePhase);
01632         break;
01633       case 5:
01634         bocCard->setVernierClockPhase0(globalConf.vernierClockPhase0);
01635         break;
01636       case 6:
01637         bocCard->setVernierClockPhase1(globalConf.vernierClockPhase1);
01638         break;
01639       case 7:
01640         bocCard->setBpmClockPhase(globalConf.bpmClockPhase);
01641         break;
01642       case 8:
01643         bocCard->setBregClockPhase(globalConf.bregClockPhase);
01644         break;
01645       }
01646     }
01647   }
01648 }
01649 
01650 // Check that the BOC lasers are on
01651 /*
01652   status = 0xe2
01653   status = 0x82 when crate interlock not off
01654   status = 0xa0 when on board interlock not off
01655 */
01656 bool CrateImpl::checkBOCLasersOn(unsigned int rod) { 
01657   //   unsigned long status = getRod(rod)->getBocCard()->getBocStatusRegister();
01658 
01659   //   return status == 0xe2;
01660 
01661   if(RODPresent(rod)) {
01662     if(getRod(rod)->getBocCard() == 0) {
01663       return false; // Ie it won't work ... (but because the BOC's not there!...)
01664     }
01665     return getRod(rod)->getBocCard()->getInterlockStatus();
01666   } else {
01667     return false; // Ie it won't work ... (but because the ROD's not configured...)
01668   }
01669 }
01670 
01671 void CrateImpl::enterBOCClockBy2Mode(unsigned int rod) {
01672   if(RODPresent(rod)) {
01673     if(getRod(rod)->getBocCard() == 0) {
01674       std::cerr << " enterBOCClockBy2Mode called on missing BOC " << rod << std::endl;
01675       throw CrateException("No BOC for enter clock/2");
01676     }
01677 
01678     BocCard &bocCard = *(getRod(rod)->getBocCard());
01679 
01680     bocCard.setRxDataMode(1);
01681     bocCard.setClockControl(2);
01682   }
01683 }
01684 
01685 void CrateImpl::leaveBOCClockBy2Mode(unsigned int rod) {
01686   if(RODPresent(rod)) {
01687     if(getRod(rod)->getBocCard() == 0) {
01688       std::cerr << " leaveBOCClockBy2Mode called on missing BOC " << rod << std::endl;
01689       throw CrateException("No BOC for leave clock/2");
01690     }
01691 
01692     BocCard &bocCard = *(getRod(rod)->getBocCard());
01693 
01694     bocCard.setRxDataMode(0);
01695     bocCard.setClockControl(0);
01696   }
01697 }
01698 
01699 std::vector<double> CrateImpl::getBOCMonitorArray(unsigned int rod) {
01700   if(!RODPresent(rod)) {
01701     std::cerr << " getBOCMonitorArray called on missing BOC " << rod << std::endl;
01702     throw CrateException("No BOC for getBOCMonitorArray");
01703   }
01704 
01705   if(getRod(rod)->getBocCard() == 0) {
01706     std::cerr << " getBOCMonitorArray called on missing BOC " << rod << std::endl;
01707     throw CrateException("No BOC for getBOCMonitorArray");
01708   }
01709 
01710   BocCard &bocCard = *(getRod(rod)->getBocCard());
01711 
01712   std::vector<double> result;
01713 
01714   for(int i=0; i<12; i++) {
01715     result.push_back(bocCard.getMonitorAdc(i));
01716   }
01717 
01718   return result;
01719 }
01720 
01721 void CrateImpl::modifyBOCParam(unsigned int type, unsigned int val, bool raw) {
01722   for(RodMap::const_iterator ri = rodMap.begin();
01723       ri!=rodMap.end();
01724       ri++) {
01725     int rod = ri->first;
01726     BocCard &bocCard = *(getRod(rod)->getBocCard());
01727     switch(type) {
01728       // Global BOC registers
01729     case SCT_SCAN_BOC_BPM_PHASE:
01730       bocCard.setBpmClockPhase(val);
01731       break;
01732     case SCT_SCAN_BOC_BREG_PHASE:
01733       bocCard.setBregClockPhase(val);
01734       break;
01735     case SCT_SCAN_BOC_V0_PHASE:
01736       bocCard.setVernierClockPhase0(val);
01737       break;
01738     case SCT_SCAN_BOC_V1_PHASE:
01739       bocCard.setVernierClockPhase1(val);
01740       break;
01741     case SCT_SCAN_BOC_V_PHASES:
01742       bocCard.setVernierClockPhases(val);
01743       break;
01744     case SCT_SCAN_BOC_VRN_FINE:
01745       bocCard.setVernierFinePhase(val);
01746       break;
01747       // Useful scans for finding modules...
01748     case SCT_SCAN_TX_CHANNELS:
01749       setupScanTx(rod, val);
01750       break;
01751     case SCT_SCAN_RAW_TX_CHANNELS:
01752       setupScanRawTx(rod, val);
01753       break;
01754     default:
01755       // All the others are done per channel
01756       for(int channel=0; channel<48; channel++) {
01757         modifyBOCParam(rod, channel, type, val, raw);
01758       }
01759     }
01760   }
01761 }
01762 
01763 void CrateImpl::modifyBOCParam(unsigned int rod, unsigned int channel, unsigned int type, unsigned int val, bool raw) {
01764   if(RODPresent(rod)) {
01765     if(!getRod(rod)->getBocCard()) {
01766       std::cerr << " modifyBOCParam called on missing BOC " << rod << std::endl;
01767       throw CrateException("No BOC for modify BOC param");
01768     }
01769 
01770     BocCard &bocCard = *(getRod(rod)->getBocCard());
01771 
01772     // Raw channels don't need look up
01773     int txFibre = channel;
01774     int rxFibre1 = channel * 2 + 0;
01775     int rxFibre2 = channel * 2 + 1;
01776 
01777     if(!raw) {
01778       unsigned char *mappings;
01779 
01780       try { 
01781         mappings = config->getFibreMappings(partition, crate, rod);
01782       }  catch(ConfigurationException &c) {
01783         std::cout << "No fibre mappings for appropriate module: \n";
01784         std::cout << c.what() << std::endl;
01785 
01786         //     log << "  (Not found)\n";
01787 
01788         return;
01789       }
01790 
01791       txFibre = mappings[channel * 3];
01792       rxFibre1 = mappings[channel * 3 + 1];
01793       rxFibre2 = mappings[channel * 3 + 2];
01794     }
01795 
01796     try {
01797       switch(type) {
01798       case ST_RX_DELAY0:
01799         if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre1, val);
01800         break;
01801       case ST_RX_DELAY1:
01802         if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre2, val);
01803         break;
01804       case ST_RX_DELAY:
01805         if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre1, val);
01806         if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxDataDelay(rxFibre2, val);
01807         break;
01808 
01809       case ST_RX_THRESHOLD0:
01810         if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre1, val);
01811         break;
01812       case ST_RX_THRESHOLD1:
01813         if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre2, val);
01814         break;
01815       case ST_RX_THRESHOLD:
01816         if(rxFibre1 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre1, val);
01817         if(rxFibre2 != DATA_LINK_OFF) bocCard.setRxThreshold(rxFibre2, val);
01818         break;
01819 
01820       case ST_TX_CURRENT:
01821         if(txFibre != DATA_LINK_OFF) bocCard.setLaserCurrent(txFibre, val);
01822         break;
01823       case ST_TX_MARKSPACE:
01824         if(txFibre != DATA_LINK_OFF) bocCard.setBpmMarkSpace(txFibre, val);
01825         break;
01826       case ST_TX_DELAY:
01827         if(txFibre != DATA_LINK_OFF) bocCard.setBpmCoarseDelay(txFibre, (val&0xff00) >> 8);
01828         if(txFibre != DATA_LINK_OFF) bocCard.setBpmFineDelay(txFibre, (val&0xff));
01829         break;
01830       case ST_TX_COARSE:
01831         if(txFibre != DATA_LINK_OFF) bocCard.setBpmCoarseDelay(txFibre, val);
01832         break;
01833       case ST_TX_FINE:
01834         if(txFibre != DATA_LINK_OFF) bocCard.setBpmFineDelay(txFibre, val);
01835         break;
01836 
01837         // Extra scans
01838       case SCT_SCAN_BOC_BPM_PHASE:
01839         bocCard.setBpmClockPhase(val);
01840         break;
01841       case SCT_SCAN_BOC_BREG_PHASE:
01842         bocCard.setBregClockPhase(val);
01843         break;
01844       case SCT_SCAN_BOC_V0_PHASE:
01845         bocCard.setVernierClockPhase0(val);
01846         break;
01847       case SCT_SCAN_BOC_V1_PHASE:
01848         bocCard.setVernierClockPhase1(val);
01849         break;
01850       case SCT_SCAN_BOC_V_PHASES:
01851         bocCard.setVernierClockPhases(val);
01852         break;
01853       case SCT_SCAN_BOC_VRN_FINE:
01854         bocCard.setVernierFinePhase(val);
01855         break;
01856 
01857         // Useful scans for finding modules...
01858       case SCT_SCAN_TX_CHANNELS:
01859         setupScanTx(rod, val);
01860         break;
01861 
01862       case SCT_SCAN_RAW_TX_CHANNELS:
01863         setupScanRawTx(rod, val);
01864         break;
01865 
01866       default:
01867         break;
01868       }
01869     } catch(BocException &b) {
01870       std::cout << "BocException in modifyBOCParam: " << b << std::endl;
01871       throw CrateException("BOCException in modify");
01872     }
01873   }
01874 }
01875 
01876 void CrateImpl::lasersOff() {
01877   for(RodMap::const_iterator ri = rodMap.begin();
01878       ri!=rodMap.end();
01879       ri++) {
01880     if(ri->second.second->getBocCard() == 0) {
01881       std::cerr << " Missing BOC in lasersOff\n";
01882       continue;
01883 //       throw CrateException("No BOC for lasers off");
01884     }
01885 
01886     BocCard &bocCard = *(ri->second.second->getBocCard());
01887 
01888     for(int i=0; i<48; i++) {
01889       bocCard.setLaserCurrent(i, 0);
01890     }
01891   }
01892 }
01893 
01894 void CrateImpl::timSetFrequency(double trigFreq, double rstFreq) {
01895   if(tim) {
01896     std::cout << "Setting TIM frequencies: " << trigFreq << "kHz " << rstFreq << "Hz\n";
01897     int highBits;
01898 
01899     // std:: needed because of ROOT (I think)
01900     int power = (int)std::ceil(std::log10(trigFreq/8.0));
01901     std::cout << "trigPower " << power << std::endl;
01902     double trigBase;
01903     switch(power) {
01904     case 2: highBits = 0; trigBase = trigFreq / 10; break;
01905     case 1: highBits = 1; trigBase = trigFreq / 1; break;
01906     case 0: highBits = 2; trigBase = trigFreq / 0.1; break;
01907     case -1: highBits = 3; trigBase = trigFreq / 0.01; break;
01908     default:
01909       if(power<-1) { highBits = 3; trigBase = trigFreq / 0.01; }
01910       else { highBits = 0; trigBase = trigFreq / 10; }
01911     }
01912 
01913     std::cout << "trigBase " << trigBase << std::endl;
01914     int lowBits =  60.0 / trigBase;
01915 
01916     if(lowBits == 1) lowBits = 0;
01917     if(lowBits == 10) lowBits = 1;
01918     if(lowBits > 6) lowBits = 7;
01919 
01920     int trigNibble = (lowBits & 0x7) + ((highBits & 0xf) << 3);
01921     std::cout << "trigNibble " << trigNibble << " (" << lowBits << ", " << highBits << ")\n";
01922 
01923     // Decode reset frequency
01924 
01925 
01926     // std:: needed because of ROOT (I think)
01927     power = (int)std::ceil(std::log10(rstFreq/8.0));
01928     std::cout << "rstPower " << power << std::endl;
01929     double rstBase;
01930     switch(power) {
01931     case 2: highBits = 0; rstBase = rstFreq / 100; break;
01932     case 1: highBits = 1; rstBase = rstFreq / 10; break;
01933     case 0: highBits = 2; rstBase = rstFreq / 1; break;
01934     case -1: highBits = 3; rstBase = rstFreq / 0.1; break;
01935     default:
01936       if(power<-1) { highBits = 3; rstBase = rstFreq / 0.1; }
01937       else { highBits = 0; rstBase = rstFreq / 100; }
01938     }
01939 
01940     std::cout << "rstBase " << rstBase << std::endl;
01941 
01942     lowBits =  (int)(6.0 / rstBase);
01943 
01944     if(lowBits == 1) lowBits = 0;
01945     if(lowBits == 10) lowBits = 1;
01946     if(lowBits > 6) lowBits = 7;
01947 
01948     int rstNibble = (lowBits & 0x7) + ((highBits & 0xf) << 3);
01949     std::cout << "rstNibble " << rstNibble << " (" << lowBits << ", " << highBits << ")\n";
01950 
01951     tim->regLoad(TIM_REG_FREQUENCY, trigNibble + (rstNibble << 8));
01952   }
01953 }
01954 
01955 void CrateImpl::freeTriggers() {
01956   if(tim) {
01957     // Enable L1As
01958     tim->loadBitSet(TIM_REG_ENABLES, SctPixelRod::TIM_BIT_EN_INT_TRIG);
01959   }
01960 }
01961 
01962 void CrateImpl::stopTriggers() {
01963   if(tim)
01964     tim->intTrigStop();
01965 }
01966 
01967 void CrateImpl::timL1A() {
01968   if(tim) {
01969     tim->issueCommand(SctPixelRod::TIM_VTRG);
01970     usleep(1);
01971     tim->loadBitClear(TIM_REG_COMMAND, SctPixelRod::TIM_VTRG);
01972   }
01973 }
01974 
01975 void CrateImpl::timCalL1A(int delay) {
01976   if(tim)
01977     tim->issueVCAL(delay);
01978 }
01979 
01980 
01981 void CrateImpl::timECR() {
01982   if(tim) {
01983     tim->issueCommand(SctPixelRod::TIM_VECR);
01984     // Manually send TIM ECR
01985     //     tapi.timRegLoad(0, 0, 2, 0x04); 
01986     timRegLoad(2, 0x0);
01987   }
01988 }
01989 
01990 void CrateImpl::timBCR() {
01991   if(tim) {
01992     tim->issueCommand(SctPixelRod::TIM_VBCR);
01993     // Manually send TIM BCR
01994     //    tapi.timRegLoad(0, 0, 2, 0x08); 
01995     timRegLoad(2, 0x0);
01996   }
01997 }
01998 
01999 void CrateImpl::timFER() {
02000   if(tim) {
02001     tim->issueCommand(SctPixelRod::TIM_VFER);
02002     // Manually send TIM FER
02003     // tapi.timRegLoad(0, 0, 2, 0x20); 
02004     timRegLoad(2, 0x0);
02005   }
02006 }
02007 
02008 void CrateImpl::sendTimBurst(int count) {
02009   if(tim) {
02010     // Load count
02011     tim->regLoad(TIM_REG_BURST_COUNT, count);
02012     // Enable burst mode
02013     tim->loadBitSet(TIM_REG_COMMAND, 0x200);
02014 
02015     // Use single L1A
02016     tim->loadBitSet(TIM_REG_ENABLES, SctPixelRod::TIM_BIT_EN_INT_TRIG);
02017 
02018     // Start burst
02019     tim->loadBitSet(TIM_REG_COMMAND, 0x400);
02020 
02021 //     std::cout << "Status is " << std::hex << tim->regFetch(TIM_REG_STATUS) << std::dec << std::endl;
02022 
02023     // Wait for burst to finish
02024     while(tim->regFetch(TIM_REG_STATUS) & 0x10)
02025       ;
02026 
02027 //     std::cout << "Status now " << std::hex << tim->regFetch(TIM_REG_STATUS) << std::dec << std::endl;
02028 
02029     // Stop burst
02030     tim->loadBitClear(TIM_REG_COMMAND, 0x400);
02031 
02032     // Stop triggers before leaving burst mode
02033     tim->loadBitClear(TIM_REG_ENABLES, SctPixelRod::TIM_BIT_EN_INT_TRIG);
02034 
02035     // Disable burst mode
02036     tim->loadBitClear(TIM_REG_COMMAND, 0x200);
02037   }
02038 }
02039 
02040 void CrateImpl::timVerbose() {
02041   for(int r = 0; r<0x34; r+=2) {
02042     std::cout.width(2);
02043     std::cout << std::hex << r << std::dec 
02044               << ": 0x" << std::hex << tim->regFetch((SctPixelRod::TimRegister)r) << std::dec << std::endl;
02045   }
02046 }
02047 
02048 void CrateImpl::timRegLoad(int reg, UINT16 val) {
02049   if(tim) {
02050     tim->regLoad(SctPixelRod::TimRegister(reg), val);
02051   }
02052 }
02053 
02054 UINT16 CrateImpl::timRegRead(int reg) {
02055   if(tim) {
02056     return tim->regFetch(SctPixelRod::TimRegister(reg));
02057   } else {
02058     return 0;
02059   }
02060 }
02061 
02062 bool CrateImpl::slavePresent(int rod, int index) const {
02063   bool present;
02064 
02065   if(!RODPresent(rod)) 
02066     present = false;   // The ROD's not present so the slave definitely isn't!
02067   else {
02068     present = (getRodData(rod).slaves & (1<<index))?true:false;
02069   }
02070 
02071   return present;
02072 }
02073 
02074 void CrateImpl::slaveStarted(int rod, int slave){
02075   getRodData(rod).slaves |= 1<<slave;
02076 }
02077 
02078 bool CrateImpl::RODPresent(int rod) const {
02079   return getRod(rod);
02080 }
02081 
02082 long CrateImpl::getRodSlot(int rod) const {
02083   return getRod(rod)->getSlot();
02084 }
02085 
02086 int CrateImpl::getRodRevision(int rod) const {
02087   return getRod(rod)->getRevision();
02088 }
02089 
02090 void CrateImpl::stopPolling() {
02091   m_enablePolling = false;
02092 }
02093 
02094 void CrateImpl::resumePolling() {
02095   m_enablePolling = true;
02096 }
02097 
02098 void CrateImpl::setupScanTx(unsigned int rod, unsigned int channel) {
02099   BocCard &bocCard = *(getRod(rod)->getBocCard());
02100 
02101   UINT32 iBuffer[48];
02102 
02103   unsigned char *mappings;
02104   try {
02105     mappings = config->getFibreMappings(partition, crate, rod);
02106   } catch(ConfigurationException &c) {
02107     std::cout << "No mapping data for channel this rod\n";
02108     return;
02109   }
02110 
02111   // Turn all channels off
02112   for(unsigned int ch=0;ch<48;ch++){
02113     if(ch == channel) continue;
02114     int txChannel = mappings[ch * 3 + 0];
02115     iBuffer[txChannel] = 0;
02116   }
02117 
02118   try {
02119     BOCChannelConfig channelConfig = config->getBOCConfig(partition, crate, rod, channel);
02120 
02121     int txChannel = mappings[channel * 3 + 0];
02122     iBuffer[txChannel] = channelConfig.current;
02123   } catch(ConfigurationException &c) {
02124     std::cout << "No current configuration for channel " << channel << " leaving at 0\n";
02125   }
02126 
02127   // Configure clock/command outputs in one go
02128   bocCard.setLaserCurrent(0, iBuffer, 48);
02129 }
02130 
02131 void CrateImpl::setupScanRawTx(unsigned int rod, unsigned int channel) {
02132   BocCard &bocCard = *(getRod(rod)->getBocCard());
02133 
02134   UINT32 iBuffer[48];
02135 
02136   // Turn all channels off
02137   for(unsigned int ch=0;ch<48;ch++){
02138     // Except the current channel...
02139     if(ch == channel) {
02140 #warning "This shouldn't be a constant current! (where should it come from though? Configuration may not be right...)"
02141       iBuffer[ch] = 0x90;
02142     } else {
02143       iBuffer[ch] = 0; 
02144     }
02145   }
02146 
02147   // Configure clock/command output
02148   bocCard.setLaserCurrent(0, iBuffer, 48);
02149 }
02150 
02151 } // End of namespace SctApi

Generated on Mon Feb 21 11:43:41 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5