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

BocCard.cxx

00001 // File: BocCard.cxx
00002 
00003 
00004 #include "BocCard.h"
00005 
00007 namespace SctPixelRod {
00008 
00009 
00010 
00011 //**************************class BocException***********************
00012 //
00013 // Description:
00014 //  This class provides the exception handling for the BocCard routines.
00015 //
00016 // Author(s):
00017 //  John Hill (hill@hep.phy.cam.ac.uk) - originator
00018 //
00019 //-------------------------------Constructor-------------------------
00020 
00021 /*
00022 Define two constructors - one for no data, one for two data items.
00023 Default destructor is used.
00024 */
00025 
00026 
00027 BocException::BocException(std::string descriptor) :
00028                            BaseException(descriptor) {
00029   m_numValue = 0;
00030   m_value1 = 0;
00031   m_value2 = 0;
00032   setType(BOC);
00033 }
00034 
00035 BocException::BocException(std::string descriptor,INT32 value1,INT32 value2) :
00036                            BaseException(descriptor) {
00037   m_numValue = 2;
00038   m_value1 = value1;
00039   m_value2 = value2;
00040   setType(BOC);
00041 }
00042 
00043 void BocException::what(std::ostream& os) {
00044   unsigned long numData;
00045   numData = getNumData();
00046   os << "BocException: " << getDescriptor() << std::endl;
00047   if (numData == 0) return;
00048   os << "Data1:" << getData1() << std::endl;
00049   os << "Data2:" << getData2() << std::endl;
00050 }
00051 
00052 
00053 //****************************class BocCard**************************
00054 //
00055 // Description:
00056 //  This class provides the software interface to the BOC module.
00057 //
00058 // Author(s):
00059 //  John Hill (hill@hep.phy.cam.ac.uk) - originator
00060 //
00061 //-------------------------------Constructor-------------------------
00062 
00063 /*
00064 This is the only constructor to use.
00065 */
00066 
00067 
00068 BocCard::BocCard(RodModule & rod) {
00069   m_myrod = &rod;
00070   m_serialNumber = 0xFFFFFFFF;  //initialize overwrites this
00071 }
00072 
00073 
00074 //-------------------------------Destructor--------------------------
00075 
00076 /*
00077 Just remove reference to ROD. The RodModule class is not deleted, as
00078 BocCard did not create it.
00079 */
00080 
00081 
00082 BocCard::~BocCard() {
00083   m_myrod = 0;
00084 }
00085 
00086 
00087 //  Member methods
00088 
00089 
00090 //------------------------initialize--------------------------------
00091 
00098 void BocCard::initialize() {
00099 
00100 
00101 // Reset the BOC
00102 
00103   resetBoc();
00104 
00105 // Get all the readonly identification information into the private
00106 // variables
00107 
00108   m_serialNumber = singleRead(BOC_SERIAL_NUMBER);
00109   m_manufacturer = singleRead(BOC_MANUFACTURER);
00110   m_moduleType = singleRead(BOC_MODULE_TYPE);
00111   m_hardwareRevision = singleRead(BOC_HW_REV);
00112 
00113 // The type of BOC is now (from 3 March 2004) determined from the
00114 // top 3 bits of the Hardware Revision register. The bottom 5 bits
00115 // indicate the hardware revision for that BOC type.
00116 
00117   m_bocType = ((m_hardwareRevision)>>5) & 0x7;
00118   m_hardwareRevision &= 0x1F;
00119 //
00120   m_firmwareRevision = singleRead(BOC_FW_REV);
00121 
00122 // Set the setup bus mask.
00123   m_bocMask = (1<<BOC_REGISTER_WIDTH) - 1;
00124 
00125 // Initialise the two I2C streams (Rx data delays), by writing to the first
00126 // channel in each stream (data written is not relevant)
00127 
00128   setRxDataDelay(0,0);      //I2C0
00129   setRxDataDelay(0x40,0);   //I2C1
00130 
00131 // Initialise the Monitor ADC
00132 
00133   resetMonitorAdc();
00134 
00135 //Set the clocks
00136 
00137   setClockControl(0);       //Clock Control register
00138   setVernierClockPhase0(0);
00139   setVernierClockPhase1(0); //Two vernier clocks...
00140   setVernierFinePhase(0);   //...and the vernier fine phase
00141   setBpmClockPhase(0);      //BPM Clock Phase
00142   setBregClockPhase(0xC);   //Breg Clock Phase (note non-zero).
00143 
00144 //Clear the RX and TX DACs
00145 
00146   clearRxDac();
00147   clearTxDac();
00148 
00149 //Reset the Vpins
00150   resetVpin();
00151 
00152 //Reset the BOC_OK bit
00153   resetBocOk();
00154 
00155 // Set all the receiver thresholds to 0xFF (ie. off!) and the data delays
00156 // to zero.
00157 
00158   for(unsigned int i=0;i<BOC_RECEIVE_CHANNELS;i++) {
00159     setRxThreshold(i,0xFF);
00160     setRxDataDelay(i,0);
00161 
00162   }
00163 
00164 // Set all the laser currents to 0
00165 
00166   for(unsigned int i=0;i<BOC_TRANSMIT_CHANNELS;i++) {
00167     setLaserCurrent(i,0);
00168   }
00169 
00170 // Set all the strobe delays to 0. These are no longer used in normal
00171 // operation, but the spare channels ARE connected, so for completeness...
00172 
00173   for(unsigned int i=0;i<BOC_STROBE_CHANNELS;i++) {
00174     setStrobeDelay(i,0);
00175   }
00176   
00177 // Make sure the BPMs are reset before trying to set them.
00178  
00179   resetBpm();
00180 
00181 // Now set the BPMs for all channels. The first 12 channels
00182 // of a BPM are used by the "real" control fibres. Channels
00183 // 12 and 13 of a BPM are used for test structures, and these
00184 // also have to be set correctly.
00185 
00186   for(unsigned int i=0;i<BOC_TRANSMIT_CHANNELS;i++) {
00187     setBpmStreamInhibit(i,0);   //Enable all channels
00188     setBpmMarkSpace(i,0x13);        //Approved starting value
00189     setBpmCoarseDelay(i,0);
00190     setBpmFineDelay(i,0);
00191   }
00192 
00193 //Use the private bpmWrite method for writing to BPM channels 12 and 13
00194 //The code assumes that BPMs are fully utilised, with the Tx channels
00195 //in groups of 12 in as many BPMs as are needed. This may not be true
00196 //for Pixels?
00197 
00198   for(unsigned int i=0;i<(BOC_TRANSMIT_CHANNELS+11/12);i++) {
00199     bpmWrite(i,12,0,0x20);      //0x20 into channel 12
00200     bpmWrite(i,13,0,0x40);      //0x40 into channel 13
00201   }
00202 
00203 //Now set the Rx Data Mode, and we should be done.
00204 
00205   setRxDataMode(0);
00206 
00207 }
00208 
00209   
00210 //------------------------reset-------------------------------------
00211 
00218 void BocCard::reset() {
00219 
00220   resetBoc();
00221   resetBpm();
00222   clearRxDac();
00223   clearTxDac();
00224   resetVpin();
00225   resetBocOk();
00226 
00227 }
00228 
00229 
00230 //------------------------status------------------------------------
00231 
00237 void BocCard::status() {
00238 
00239   if(m_bocType == PRE_PRODUCTION_BOC) {
00240     std::cout << "Pre-production BOC: ";
00241   }
00242   else if(m_bocType == PRODUCTION_REVA_BOC) {
00243     std::cout << "Production BOC - Revision A: ";
00244   }
00245   else if(m_bocType == PRODUCTION_REVB_BOC) {
00246     std::cout << "Production BOC - Revision B: ";
00247   }
00248   else if(m_bocType == PRODUCTION_REVC_BOC) {
00249     std::cout << "Production BOC - Revision C: ";
00250   }
00251   else {
00252     std::cout << "Unknown BOC type: ";
00253   }
00254   std::cout << "status" << std::endl;
00255 //
00256   std::cout << std::dec << " Module Type: " << m_moduleType;
00257   std::cout << " Serial Number: " << m_serialNumber;
00258   std::cout << std::endl;
00259   std::cout << " Hardware Version: " << m_hardwareRevision;
00260   std::cout << " Firmware Version: " << m_firmwareRevision;
00261   std::cout << std::endl;
00262   std::cout << std::hex << " Manufacturer: "   << m_manufacturer;
00263 //
00264 // If a series BOC, least significant 2 bits are undefined.
00265 //
00266   std::cout << " Status Register: " << getBocStatusRegister();
00267   
00268   std::cout << std::dec << std::endl;
00269 }
00270 
00271 
00272 //------------------------getLaserCurrent---------------------------
00273 
00278 void BocCard::getLaserCurrent(const UINT32 channel, UINT32 buffer[],
00279         const UINT32 numChannels) throw (BocException&) {
00280 //
00281   UINT32 address;
00282 //
00283 // Check for invalid values in arguments
00284 //
00285   if(channel<0) {
00286     throw BocException("BOC Transmit, start channel <",0,channel);
00287   }
00288 
00289   if(numChannels<0) {
00290     throw BocException("BOC Transmit, number of channels <",0,numChannels);
00291   }
00292 
00293   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
00294     throw BocException("BOC Transmit, maximum channel >=",
00295         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
00296   }
00297 
00298 //
00299 // Get the start address (relative to start of BOC window)
00300 //
00301   address = BOC_LASER_DAC + (channel<<2);
00302 
00303   if(numChannels <= 1) {
00304 // Use the single read method
00305     buffer[0] = singleRead(address);
00306   }
00307   else {
00308 // Use the block read method
00309     blockRead(address, buffer, numChannels);
00310   }
00311 // Now mask off bits that are not well-defined.
00312 //
00313   for(unsigned int i=0;i<numChannels;i++) {
00314     buffer[i] &= m_bocMask;
00315   }
00316 
00317 }
00318 
00319 
00320 UINT32 BocCard::getLaserCurrent(const UINT32 channel) throw (BocException&) {
00321 //
00322   UINT32 address;
00323 
00324 //
00325 // Check for invalid values in arguments
00326 //
00327   if(channel<0) {
00328     throw BocException("BOC Transmit, start channel <",0,channel);
00329   }
00330 
00331   if(channel>=BOC_TRANSMIT_CHANNELS) {
00332     throw BocException("BOC Transmit, maximum channel >=",
00333         BOC_TRANSMIT_CHANNELS,channel);
00334   }
00335 
00336 //
00337 // Get the start address (relative to start of BOC window)
00338 //
00339   address = BOC_LASER_DAC + (channel<<2);
00340 
00341 // Use the single read method
00342   return (singleRead(address) & m_bocMask);
00343 
00344 }
00345 
00346 
00347 //------------------------setLaserCurrent---------------------------
00348 
00353 void BocCard::setLaserCurrent(const UINT32 channel, const UINT32 buffer[],
00354         const UINT32 numChannels) throw (BocException&) {
00355 //
00356   UINT32 address;
00357 //
00358 // Check for invalid values in arguments
00359 //
00360   if(channel<0) {
00361     throw BocException("BOC Transmit, start channel <",0,channel);
00362   }
00363 
00364   if(numChannels<0) {
00365     throw BocException("BOC Transmit, number of channels <",0,numChannels);
00366   }
00367 
00368   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
00369     throw BocException("BOC Transmit, maximum channel >=",
00370         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
00371   }
00372 
00373   for(unsigned int i=0;i<numChannels;i++) {
00374     if(buffer[i]>m_bocMask) {
00375       throw BocException("BOC Transmit, maximum value >",
00376     m_bocMask,buffer[i]);
00377     }
00378   }
00379 
00380 //
00381 // Get the start address (relative to start of BOC window)
00382 //
00383   address = BOC_LASER_DAC + (channel<<2);
00384 
00385   if(numChannels <= 1) {
00386 // Use the single write method
00387     singleWrite(address,buffer[0]);
00388   }
00389   else {
00390 // Use the block write method
00391     blockWrite(address, buffer, numChannels);
00392   }
00393 
00394 }
00395 
00396 
00397 void BocCard::setLaserCurrent(const UINT32 channel, const UINT32 value) 
00398         throw (BocException&) {
00399 //
00400   UINT32 address;
00401 
00402 //
00403 // Check for invalid values in arguments
00404 //
00405   if(channel<0) {
00406     throw BocException("BOC Transmit, start channel <",0,channel);
00407   }
00408 
00409   if(channel>=BOC_TRANSMIT_CHANNELS) {
00410     throw BocException("BOC Transmit, maximum channel >=",
00411         BOC_TRANSMIT_CHANNELS,channel);
00412   }
00413 
00414   if(value>m_bocMask) {
00415     throw BocException("BOC Transmit, maximum value >",
00416       m_bocMask,value);
00417   }
00418 
00419 //
00420 // Get the start address (relative to start of BOC window)
00421 //
00422   address = BOC_LASER_DAC + (channel<<2);
00423 
00424 // Use the single write method
00425   singleWrite(address,value);
00426 
00427 }
00428 
00429 
00430 //------------------------getRxThreshold---------------------------
00431 
00436 void BocCard::getRxThreshold(const UINT32 channel, UINT32 buffer[],
00437         const UINT32 numChannels) throw (BocException&) {
00438 //
00439   UINT32 address;
00440 //
00441 // Check for invalid values in arguments
00442 //
00443   if(channel<0) {
00444     throw BocException("BOC Receive, start channel <",0,channel);
00445   }
00446 
00447   if(numChannels<0) {
00448     throw BocException("BOC Receive, number of channels <",0,numChannels);
00449   }
00450 
00451   if((channel+numChannels)>BOC_RECEIVE_CHANNELS) {
00452     throw BocException("BOC Receive, maximum channel >=",
00453         BOC_RECEIVE_CHANNELS,channel+numChannels-1);
00454   }
00455 
00456 //
00457 // Get the start address (relative to start of BOC window)
00458 //
00459   address = BOC_THRESHOLD_DAC + (channel<<2);
00460 
00461   if(numChannels <= 1) {
00462 // Use the single read method
00463     buffer[0] = singleRead(address);
00464   }
00465   else {
00466 // Use the block read method
00467     blockRead(address, buffer, numChannels);
00468   }
00469 
00470 // Now mask off bits that are not well-defined.
00471 //
00472   for(unsigned int i=0;i<numChannels;i++) {
00473     buffer[i] &= m_bocMask;
00474   }
00475 
00476 }
00477 
00478 
00479 UINT32 BocCard::getRxThreshold(const UINT32 channel) throw (BocException&) {
00480 //
00481   UINT32 address;
00482 
00483 //
00484 // Check for invalid values in arguments
00485 //
00486   if(channel<0) {
00487     throw BocException("BOC Receive, start channel <",0,channel);
00488   }
00489 
00490   if(channel>=BOC_RECEIVE_CHANNELS) {
00491     throw BocException("BOC Receive, maximum channel >=",
00492         BOC_RECEIVE_CHANNELS,channel);
00493   }
00494 
00495 //
00496 // Get the start address (relative to start of BOC window)
00497 //
00498   address = BOC_THRESHOLD_DAC + (channel<<2);
00499 
00500 // Use the single read method
00501 
00502   return (singleRead(address) & m_bocMask);
00503 
00504 }
00505 
00506 
00507 //------------------------setRxThreshold---------------------------
00508 
00513 void BocCard::setRxThreshold(const UINT32 channel, const UINT32 buffer[],
00514         const UINT32 numChannels) throw (BocException&) {
00515 //
00516   UINT32 address;
00517 //
00518 // Check for invalid values in arguments
00519 //
00520   if(channel<0) {
00521     throw BocException("BOC Receive, start channel <",0,channel);
00522   }
00523 
00524   if(numChannels<0) {
00525     throw BocException("BOC Receive, number of channels <",0,numChannels);
00526   }
00527 
00528   if((channel+numChannels)>BOC_RECEIVE_CHANNELS) {
00529     throw BocException("BOC Receive, maximum channel >=",
00530         BOC_RECEIVE_CHANNELS,channel+numChannels-1);
00531   }
00532 
00533   for(unsigned int i=0;i<numChannels;i++) {
00534     if(buffer[i]>m_bocMask) {
00535       throw BocException("BOC Transmit, maximum value >",
00536         m_bocMask,buffer[i]);
00537     }
00538   }
00539 
00540 //
00541 // Get the start address (relative to start of BOC window)
00542 //
00543   address = BOC_THRESHOLD_DAC + (channel<<2);
00544 
00545   if(numChannels <= 1) {
00546 // Use the single write method
00547     singleWrite(address,buffer[0]);
00548   }
00549   else {
00550 // Use the block write method
00551     blockWrite(address, buffer, numChannels);
00552   }
00553 
00554 }
00555 
00556 
00557 void BocCard::setRxThreshold(const UINT32 channel, const UINT32 value) 
00558         throw (BocException&) {
00559 //
00560   UINT32 address;
00561 //
00562 // Check for invalid values in arguments
00563 //
00564   if(channel<0) {
00565     throw BocException("BOC Receive, start channel <",0,channel);
00566   }
00567 
00568   if(channel>=BOC_RECEIVE_CHANNELS) {
00569     throw BocException("BOC Receive, maximum channel >=",
00570         BOC_RECEIVE_CHANNELS,channel);
00571   }
00572 
00573   if(value>m_bocMask) {
00574     throw BocException("BOC Transmit, maximum value >",
00575       m_bocMask,value);
00576   }
00577 
00578 //
00579 // Get the start address (relative to start of BOC window)
00580 //
00581   address = BOC_THRESHOLD_DAC + (channel<<2);
00582 
00583 // Use the single write method
00584   singleWrite(address,value);
00585 
00586 }
00587 
00588 
00589 //------------------------getRxDataDelay---------------------------
00590 
00595 void BocCard::getRxDataDelay(const UINT32 channel, UINT32 buffer[],
00596         const UINT32 numChannels) throw (BocException&){
00597 //
00598   UINT32 address;
00599   UINT32 mask;
00600 //
00601 // Check for invalid values in arguments
00602 //
00603   if(channel<0) {
00604     throw BocException("BOC Data Delay, start channel <",0,channel);
00605   }
00606 
00607   if(numChannels<0) {
00608     throw BocException("BOC Data Delay, number of channels <",0,numChannels);
00609   }
00610 
00611   if((channel+numChannels)>BOC_RECEIVE_CHANNELS) {
00612     throw BocException("BOC Data Delay, maximum channel >=",
00613         BOC_RECEIVE_CHANNELS,channel+numChannels-1);
00614   }
00615 
00616 //
00617 // Get the start address (relative to start of BOC window)
00618 //
00619   address = BOC_DATA_DELAY + (channel<<2);
00620 
00621   if(numChannels <= 1) {
00622 // Use the single read method
00623     buffer[0] = singleRead(address);
00624   }
00625   else {
00626 // Use the block read method
00627     blockRead(address, buffer, numChannels);
00628   }
00629 
00630 // Now mask off bits that are not well-defined.
00631 //
00632   mask = (1<<BOC_DATA_DELAY_WIDTH)-1;
00633   for(unsigned int i=0;i<numChannels;i++) {
00634     buffer[i] &= mask;
00635   }
00636 
00637 }
00638 
00639 
00640 UINT32 BocCard::getRxDataDelay(const UINT32 channel) throw (BocException&){
00641 //
00642   UINT32 address;
00643   UINT32 mask;
00644 //
00645 // Check for invalid values in arguments
00646 //
00647   if(channel<0) {
00648     throw BocException("BOC Data Delay, start channel <",0,channel);
00649   }
00650 
00651   if(channel>=BOC_RECEIVE_CHANNELS) {
00652     throw BocException("BOC Data Delay, maximum channel >=",
00653         BOC_RECEIVE_CHANNELS,channel);
00654   }
00655 
00656 //
00657 // Get the start address (relative to start of BOC window)
00658 //
00659   address = BOC_DATA_DELAY + (channel<<2);
00660   mask = (1<<BOC_DATA_DELAY_WIDTH)-1;
00661 
00662 // Use the singleRead method
00663   return (singleRead(address) & mask);
00664 
00665 }
00666 
00667 
00668 //------------------------setRxDataDelay---------------------------
00669 
00674 void BocCard::setRxDataDelay(const UINT32 channel, const UINT32 buffer[],
00675         const UINT32 numChannels) throw (BocException&) {
00676 //
00677   UINT32 address;
00678 //
00679 // Check for invalid values in arguments
00680 //
00681   if(channel<0) {
00682     throw BocException("BOC Data Delay, start channel <",0,channel);
00683   }
00684 
00685   if(numChannels<0) {
00686     throw BocException("BOC Data Delay, number of channels <",0,numChannels);
00687   }
00688 
00689   if((channel+numChannels)>BOC_RECEIVE_CHANNELS) {
00690     throw BocException("BOC Data Delay, maximum channel >=",
00691         BOC_RECEIVE_CHANNELS,channel+numChannels-1);
00692   }
00693 
00694   for(unsigned int i=0;i<numChannels;i++) {
00695     if(buffer[i]>=(1<<BOC_DATA_DELAY_WIDTH)) {
00696       throw BocException("BOC Transmit, maximum value >=",
00697         (1<<BOC_DATA_DELAY_WIDTH),buffer[i]);
00698     }
00699   }
00700 
00701 //
00702 // Get the start address (relative to start of BOC window)
00703 //
00704   address = BOC_DATA_DELAY + (channel<<2);
00705 
00706   if(numChannels <= 1) {
00707 // Use the single write method
00708     singleWrite(address,buffer[0]);
00709   }
00710   else {
00711 // Use the block write method
00712     blockWrite(address, buffer, numChannels);
00713   }
00714 
00715 }
00716 
00717 
00718 void BocCard::setRxDataDelay(const UINT32 channel, const UINT32 value) 
00719         throw (BocException&) {
00720 //
00721   UINT32 address;
00722 //
00723 // Check for invalid values in arguments
00724 //
00725   if(channel<0) {
00726     throw BocException("BOC Data Delay, start channel <",0,channel);
00727   }
00728 
00729   if(channel>=BOC_RECEIVE_CHANNELS) {
00730     throw BocException("BOC Data Delay, maximum channel >=",
00731         BOC_RECEIVE_CHANNELS,channel);
00732   }
00733 
00734   if(value>=(1<<BOC_DATA_DELAY_WIDTH)) {
00735     throw BocException("BOC Transmit, maximum value >=",
00736       (1<<BOC_DATA_DELAY_WIDTH),value);
00737   }
00738 
00739 //
00740 // Get the start address (relative to start of BOC window)
00741 //
00742   address = BOC_DATA_DELAY + (channel<<2);
00743 
00744 // Use the single write method
00745   singleWrite(address,value);
00746 
00747 }
00748 
00749 
00750 //------------------------getStrobeDelay---------------------------
00751 
00758 void BocCard::getStrobeDelay(const UINT32 channel, UINT32 buffer[],
00759         const UINT32 numChannels) throw (BocException&) {
00760 //
00761   UINT32 address;
00762   UINT32 mask;
00763 //
00764 // Check for invalid values in arguments
00765 //
00766   if(channel<0) {
00767     throw BocException("BOC Strobe Delay, start channel <",0,channel);
00768   }
00769 
00770   if(numChannels<0) {
00771     throw BocException("BOC Strobe Delay, number of channels <",0,numChannels);
00772   }
00773 
00774   if((channel+numChannels)>BOC_STROBE_CHANNELS) {
00775     throw BocException("BOC Strobe Delay, maximum channel >=",
00776         BOC_STROBE_CHANNELS,channel+numChannels-1);
00777   }
00778 
00779 //
00780 // Get the start address (relative to start of BOC window)
00781 // Note that step is in units of 0x10.
00782 //
00783   address = BOC_STROBE_DELAY + (channel<<4);
00784 
00785   if(numChannels <= 1) {
00786 // Use the single read method
00787     buffer[0] = singleRead(address);
00788   }
00789   else {
00790 // Use the block read method
00791     blockRead(address, buffer, numChannels);
00792   }
00793 
00794 // Now mask off bits that are not well-defined.
00795 //
00796   mask = (1<<BOC_STROBE_DELAY_WIDTH)-1;
00797   for(unsigned int i=0;i<numChannels;i++) {
00798     buffer[i] &= mask;
00799   }
00800 
00801 }
00802 
00803 
00804 UINT32 BocCard::getStrobeDelay(const UINT32 channel) throw (BocException&) {
00805 //
00806   UINT32 address;
00807   UINT32 mask;
00808 //
00809 // Check for invalid values in arguments
00810 //
00811   if(channel<0) {
00812     throw BocException("BOC Strobe Delay, start channel <",0,channel);
00813   }
00814 
00815   if(channel>=BOC_STROBE_CHANNELS) {
00816     throw BocException("BOC Strobe Delay, maximum channel >=",
00817         BOC_STROBE_CHANNELS,channel);
00818   }
00819 
00820 //
00821 // Get the start address (relative to start of BOC window)
00822 //
00823   address = BOC_STROBE_DELAY + (channel<<4);
00824   mask = (1<<BOC_STROBE_DELAY_WIDTH)-1;
00825 
00826 // Use the single read method
00827   return (singleRead(address) & mask);
00828 
00829 }
00830 
00831 
00832 //------------------------setStrobeDelay---------------------------
00833 
00840 void BocCard::setStrobeDelay(const UINT32 channel, const UINT32 buffer[],
00841         const UINT32 numChannels) throw (BocException&) {
00842 //
00843   UINT32 address;
00844 //
00845 // Check for invalid values in arguments
00846 //
00847   if(channel<0) {
00848     throw BocException("BOC Strobe Delay, start channel <",0,channel);
00849   }
00850 
00851   if(numChannels<0) {
00852     throw BocException("BOC Strobe Delay, number of channels <",0,numChannels);
00853   }
00854 
00855   if((channel+numChannels)>BOC_STROBE_CHANNELS) {
00856     throw BocException("BOC Strobe Delay, maximum channel >=",
00857         BOC_STROBE_CHANNELS,channel+numChannels-1);
00858   }
00859 
00860   for(unsigned int i=0;i<numChannels;i++) {
00861     if(buffer[i]>=(1<<BOC_STROBE_DELAY_WIDTH)) {
00862       throw BocException("BOC Transmit, maximum value >=",
00863         (1<<BOC_STROBE_DELAY_WIDTH),buffer[i]);
00864     }
00865   }
00866 
00867 //
00868 // Get the start address (relative to start of BOC window)
00869 // Note that the step is 0x10.
00870 //
00871   address = BOC_STROBE_DELAY + (channel<<4);
00872 
00873   if(numChannels <= 1) {
00874 // Use the single write method
00875     singleWrite(address,buffer[0]);
00876   }
00877   else {
00878 // Use the block write method
00879     blockWrite(address, buffer, numChannels);
00880   }
00881 
00882 }
00883 
00884 
00885 void BocCard::setStrobeDelay(const UINT32 channel, const UINT32 value) 
00886         throw (BocException&) {
00887 //
00888   UINT32 address;
00889 //
00890 // Check for invalid values in arguments
00891 //
00892   if(channel<0) {
00893     throw BocException("BOC Strobe Delay, start channel <",0,channel);
00894   }
00895 
00896   if(channel>=BOC_STROBE_CHANNELS) {
00897     throw BocException("BOC Strobe Delay, maximum channel >=",
00898         BOC_STROBE_CHANNELS,channel);
00899   }
00900 
00901   if(value>=(1<<BOC_STROBE_DELAY_WIDTH)) {
00902     throw BocException("BOC Transmit, maximum value >=",
00903       (1<<BOC_STROBE_DELAY_WIDTH),value);
00904   }
00905 //
00906 // Get the start address (relative to start of BOC window)
00907 // Note that the step is 0x10.
00908 //
00909   address = BOC_STROBE_DELAY + (channel<<4);
00910 
00911 // Use the single write method
00912     singleWrite(address,value);
00913 
00914 }
00915 
00916 
00917 //BPM public methods. Private methods are provided to access channel n on
00918 //BPM m. The following methods hide the details of BPM channel number -
00919 //the BPM functionality is accessed via Tx stream number. 
00920 
00921 
00922 //------------------------getBpmStreamInhibit----------------------
00923 
00928 void BocCard::getBpmStreamInhibit(const UINT32 channel, UINT32 buffer[],
00929         const UINT32 numChannels) throw (BocException&) {
00930 //
00931   UINT32 mask;
00932 //
00933 // Check for invalid values in arguments
00934 //
00935   if(channel<0) {
00936     throw BocException("BOC BPM Stream Inhibit, start channel <",0,channel);
00937   }
00938 
00939   if(numChannels<0) {
00940     throw BocException("BOC BPM Stream Inhibit, number of channels <",0,numChannels);
00941   }
00942 
00943   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
00944     throw BocException("BOC BPM Stream Inhibit, maximum channel >=",
00945         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
00946   }
00947 
00948 //
00949 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
00950 // for "real" channels.
00951 //
00952 
00953   mask = (1<<BOC_BPM_INHIBIT_WIDTH) - 1;
00954 
00955   for(unsigned int i=0;i<numChannels;i++) {
00956     buffer[i] = (bpmRead((channel+i)/12,(channel+i)%12,BOC_BPM_INHIBIT) & mask);
00957   }
00958 
00959 }
00960 
00961 
00962 UINT32 BocCard::getBpmStreamInhibit(const UINT32 channel) throw (BocException&) {
00963 //
00964   UINT32 mask;
00965 //
00966 // Check for invalid values in arguments
00967 //
00968   if(channel<0) {
00969     throw BocException("BOC BPM Stream Inhibit, start channel <",0,channel);
00970   }
00971 
00972   if(channel>=BOC_TRANSMIT_CHANNELS) {
00973     throw BocException("BOC BPM Stream Inhibit, maximum channel >=",
00974         BOC_TRANSMIT_CHANNELS,channel);
00975   }
00976 
00977 //
00978 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
00979 // for "real" channels.
00980 //
00981   mask = (1<<BOC_BPM_INHIBIT_WIDTH) - 1;
00982 
00983   return (bpmRead(channel/12,channel%12,BOC_BPM_INHIBIT) & mask);
00984 
00985 }
00986 
00987 
00988 //------------------------setBpmStreamInhibit----------------------
00989 
00994 void BocCard::setBpmStreamInhibit(const UINT32 channel, const UINT32 buffer[],
00995         const UINT32 numChannels) throw (BocException&) {
00996 //
00997 // Check for invalid values in arguments
00998 //
00999   if(channel<0) {
01000     throw BocException("BOC BPM Stream Inhibit, start channel <",0,channel);
01001   }
01002 
01003   if(numChannels<0) {
01004     throw BocException("BOC BPM Stream Inhibit, number of channels <",0,numChannels);
01005   }
01006 
01007   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01008     throw BocException("BOC BPM Stream Inhibit, maximum channel >=",
01009         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01010   }
01011 
01012   for(unsigned int i=0;i<numChannels;i++) {
01013     if(buffer[i]>=(1<<BOC_BPM_INHIBIT_WIDTH)) {
01014       throw BocException("BOC BPM Stream Inhibit, maximum value >=",
01015         (1<<BOC_BPM_INHIBIT_WIDTH),buffer[i]);
01016     }
01017   }
01018 
01019 //
01020 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01021 // for "real" channels.
01022 //
01023   for(unsigned int i=0;i<numChannels;i++) {
01024     bpmWrite((channel+i)/12,(channel+i)%12,BOC_BPM_INHIBIT,buffer[i]);
01025   }
01026 
01027 }
01028 
01029 
01030 void BocCard::setBpmStreamInhibit(const UINT32 channel, const UINT32 value) 
01031         throw (BocException&) {
01032 //
01033 // Check for invalid values in arguments
01034 //
01035   if(channel<0) {
01036     throw BocException("BOC BPM Stream Inhibit, start channel <",0,channel);
01037   }
01038 
01039   if(channel>=BOC_TRANSMIT_CHANNELS) {
01040     throw BocException("BOC BPM Stream Inhibit, maximum channel >=",
01041         BOC_TRANSMIT_CHANNELS,channel);
01042   }
01043 
01044   if(value>=(1<<BOC_BPM_INHIBIT_WIDTH)) {
01045     throw BocException("BOC BPM Stream Inhibit, maximum value >=",
01046       (1<<BOC_BPM_INHIBIT_WIDTH),value);
01047   }
01048 
01049 //
01050 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01051 // for "real" channels.
01052 //
01053   bpmWrite(channel/12,channel%12,BOC_BPM_INHIBIT,value);
01054 
01055 }
01056 
01057 
01058 //------------------------getBpmMarkSpace--------------------------
01059 
01064 void BocCard::getBpmMarkSpace(const UINT32 channel, UINT32 buffer[],
01065         const UINT32 numChannels) throw (BocException&) {
01066 //
01067   UINT32 mask;
01068 //
01069 // Check for invalid values in arguments
01070 //
01071   if(channel<0) {
01072     throw BocException("BOC BPM Mark/Space, start channel <",0,channel);
01073   }
01074 
01075   if(numChannels<0) {
01076     throw BocException("BOC BPM Mark/Space, number of channels <",0,numChannels);
01077   }
01078 
01079   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01080     throw BocException("BOC BPM Mark/Space, maximum channel >=",
01081         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01082   }
01083 
01084 //
01085 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
01086 // for "real" channels.
01087 //
01088   mask = (1<<BOC_BPM_MARK_SPACE_WIDTH) - 1;
01089 
01090   for(unsigned int i=0;i<numChannels;i++) {
01091     buffer[i] = (bpmRead((channel+i)/12,(channel+i)%12,BOC_BPM_MARK_SPACE) & mask);
01092   }
01093 
01094 }
01095 
01096 
01097 UINT32 BocCard::getBpmMarkSpace(const UINT32 channel) throw (BocException&) {
01098 //
01099   UINT32 mask;
01100 //
01101 // Check for invalid values in arguments
01102 //
01103   if(channel<0) {
01104     throw BocException("BOC BPM Mark/Space, start channel <",0,channel);
01105   }
01106 
01107   if(channel>=BOC_TRANSMIT_CHANNELS) {
01108     throw BocException("BOC BPM Mark/Space, maximum channel >=",
01109         BOC_TRANSMIT_CHANNELS,channel);
01110   }
01111 
01112 //
01113 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
01114 // for "real" channels.
01115 //
01116   mask = (1<<BOC_BPM_MARK_SPACE_WIDTH) - 1;
01117 
01118   return (bpmRead(channel/12,channel%12,BOC_BPM_MARK_SPACE) & mask);
01119 
01120 }
01121 
01122 
01123 //------------------------setBpmMarkSpace--------------------------
01124 
01129 void BocCard::setBpmMarkSpace(const UINT32 channel, const UINT32 buffer[],
01130         const UINT32 numChannels) throw (BocException&) {
01131 
01132 //
01133 // Check for invalid values in arguments
01134 //
01135   if(channel<0) {
01136     throw BocException("BOC BPM Mark/Space, start channel <",0,channel);
01137   }
01138 
01139   if(numChannels<0) {
01140     throw BocException("BOC BPM Mark/Space, number of channels <",0,numChannels);
01141   }
01142 
01143   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01144     throw BocException("BOC BPM Mark/Space, maximum channel >=",
01145         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01146   }
01147 
01148   for(unsigned int i=0;i<numChannels;i++) {
01149     if(buffer[i]>=(1<<BOC_BPM_MARK_SPACE_WIDTH)) {
01150       throw BocException("BOC BPM Mark/Space, maximum value >=",
01151         (1<<BOC_BPM_MARK_SPACE_WIDTH),buffer[i]);
01152     }
01153   }
01154 
01155 //
01156 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01157 // for "real" channels.
01158 //
01159   for(unsigned int i=0;i<numChannels;i++) {
01160     bpmWrite((channel+i)/12,(channel+i)%12,BOC_BPM_MARK_SPACE,buffer[i]);
01161   }
01162 
01163 }
01164 
01165 
01166 void BocCard::setBpmMarkSpace(const UINT32 channel, const UINT32 value) 
01167         throw (BocException&) {
01168 //
01169 // Check for invalid values in arguments
01170 //
01171   if(channel<0) {
01172     throw BocException("BOC BPM Mark/Space, start channel <",0,channel);
01173   }
01174 
01175   if(channel>=BOC_TRANSMIT_CHANNELS) {
01176     throw BocException("BOC BPM Mark/Space, maximum channel >=",
01177         BOC_TRANSMIT_CHANNELS,channel);
01178   }
01179 
01180   if(value>=(1<<BOC_BPM_MARK_SPACE_WIDTH)) {
01181     throw BocException("BOC BPM Mark/Space, maximum value >=",
01182       (1<<BOC_BPM_MARK_SPACE_WIDTH),value);
01183   }
01184 
01185 //
01186 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01187 // for "real" channels.
01188 //
01189   bpmWrite(channel/12,channel%12,BOC_BPM_MARK_SPACE,value);
01190 
01191 }
01192 
01193 
01194 //------------------------getBpmCoarseDelay------------------------
01195 
01200 void BocCard::getBpmCoarseDelay(const UINT32 channel, UINT32 buffer[],
01201         const UINT32 numChannels) throw (BocException&) {
01202 //
01203   UINT32 mask;
01204 
01205 // Check for invalid values in arguments
01206 //
01207   if(channel<0) {
01208     throw BocException("BOC BPM Coarse Delay, start channel <",0,channel);
01209   }
01210 
01211   if(numChannels<0) {
01212     throw BocException("BOC BPM Coarse Delay, number of channels <",0,numChannels);
01213   }
01214 
01215   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01216     throw BocException("BOC BPM Coarse Delay, maximum channel >=",
01217         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01218   }
01219 
01220 //
01221 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
01222 // for "real" channels.
01223 //
01224   mask = (1<<BOC_BPM_COARSE_WIDTH) - 1;
01225 
01226   for(unsigned int i=0;i<numChannels;i++) {
01227     buffer[i] = (bpmRead((channel+i)/12,(channel+i)%12,BOC_BPM_COARSE) & mask);
01228   }
01229 
01230 }
01231 
01232 
01233 UINT32 BocCard::getBpmCoarseDelay(const UINT32 channel) throw (BocException&) {
01234 //
01235   UINT32 mask;
01236 //
01237 // Check for invalid values in arguments
01238 //
01239   if(channel<0) {
01240     throw BocException("BOC BPM Coarse Delay, start channel <",0,channel);
01241   }
01242 
01243   if(channel>=BOC_TRANSMIT_CHANNELS) {
01244     throw BocException("BOC BPM Coarse Delay, maximum channel >=",
01245         BOC_TRANSMIT_CHANNELS,channel);
01246   }
01247 
01248 //
01249 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
01250 // for "real" channels.
01251 //
01252   mask = (1<<BOC_BPM_COARSE_WIDTH) - 1;
01253 
01254   return (bpmRead(channel/12,channel%12,BOC_BPM_COARSE) & mask);
01255 
01256 }
01257 
01258 
01259 //------------------------setBpmCoarseDelay----------------------
01260 
01265 void BocCard::setBpmCoarseDelay(const UINT32 channel, const UINT32 buffer[],
01266         const UINT32 numChannels) throw (BocException&) {
01267 //
01268 // Check for invalid values in arguments
01269 //
01270   if(channel<0) {
01271     throw BocException("BOC BPM Coarse Delay, start channel <",0,channel);
01272   }
01273 
01274   if(numChannels<0) {
01275     throw BocException("BOC BPM Coarse Delay, number of channels <",0,numChannels);
01276   }
01277 
01278   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01279     throw BocException("BOC BPM Coarse Delay, maximum channel >=",
01280         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01281   }
01282 
01283   for(unsigned int i=0;i<numChannels;i++) {
01284     if(buffer[i]>=(1<<BOC_BPM_COARSE_WIDTH)) {
01285       throw BocException("BOC BPM Coarse Delay, maximum value >=",
01286         (1<<BOC_BPM_COARSE_WIDTH),buffer[i]);
01287     }
01288   }
01289 
01290 //
01291 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01292 // for "real" channels.
01293 //
01294   for(unsigned int i=0;i<numChannels;i++) {
01295     bpmWrite((channel+i)/12,(channel+i)%12,BOC_BPM_COARSE,buffer[i]);
01296   }
01297 
01298 }
01299 
01300 
01301 void BocCard::setBpmCoarseDelay(const UINT32 channel, const UINT32 value) 
01302         throw (BocException&) {
01303 //
01304 // Check for invalid values in arguments
01305 //
01306   if(channel<0) {
01307     throw BocException("BOC BPM Coarse Delay, start channel <",0,channel);
01308   }
01309 
01310   if(channel>=BOC_TRANSMIT_CHANNELS) {
01311     throw BocException("BOC BPM Coarse Delay, maximum channel >=",
01312         BOC_TRANSMIT_CHANNELS,channel);
01313   }
01314 
01315   if(value>=(1<<BOC_BPM_COARSE_WIDTH)) {
01316     throw BocException("BOC BPM Coarse Delay, maximum value >=",
01317       (1<<BOC_BPM_COARSE_WIDTH),value);
01318   }
01319 
01320 //
01321 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01322 // for "real" channels.
01323 //
01324   bpmWrite(channel/12,channel%12,BOC_BPM_COARSE,value);
01325 
01326 }
01327 
01328 
01329 //------------------------getBpmFineDelay--------------------------
01330 
01335 void BocCard::getBpmFineDelay(const UINT32 channel, UINT32 buffer[],
01336         const UINT32 numChannels) throw (BocException&) {
01337 //
01338   UINT32 mask;
01339 //
01340 // Check for invalid values in arguments
01341 //
01342   if(channel<0) {
01343     throw BocException("BOC BPM Fine Delay, start channel <",0,channel);
01344   }
01345 
01346   if(numChannels<0) {
01347     throw BocException("BOC BPM Fine Delay, number of channels <",0,numChannels);
01348   }
01349 
01350   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01351     throw BocException("BOC BPM Fine Delay, maximum channel >=",
01352         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01353   }
01354 
01355 //
01356 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
01357 // for "real" channels.
01358 //
01359   mask = (1<<BOC_BPM_FINE_WIDTH) - 1;
01360  
01361   for(unsigned int i=0;i<numChannels;i++) {
01362     buffer[i] = (bpmRead((channel+i)/12,(channel+i)%12,BOC_BPM_FINE) & mask);
01363   }
01364 
01365 }
01366 
01367 
01368 UINT32 BocCard::getBpmFineDelay(const UINT32 channel) throw (BocException&) {
01369 //
01370   UINT32 mask;
01371 //
01372 // Check for invalid values in arguments
01373 //
01374   if(channel<0) {
01375     throw BocException("BOC BPM Fine Delay, start channel <",0,channel);
01376   }
01377 
01378   if(channel>=BOC_TRANSMIT_CHANNELS) {
01379     throw BocException("BOC BPM Fine Delay, maximum channel >=",
01380         BOC_TRANSMIT_CHANNELS,channel);
01381   }
01382 
01383 //
01384 // Use bpmRead to access the registers. Streams 0-11 on the BPM are used
01385 // for "real" channels.
01386 //
01387   mask = (1<<BOC_BPM_FINE_WIDTH) - 1;
01388 
01389   return (bpmRead(channel/12,channel%12,BOC_BPM_FINE) & mask);
01390 
01391 }
01392 
01393 
01394 //------------------------setBpmFineDelay--------------------------
01395 
01400 void BocCard::setBpmFineDelay(const UINT32 channel, const UINT32 buffer[],
01401         const UINT32 numChannels) throw (BocException&) {
01402 //
01403 // Check for invalid values in arguments
01404 //
01405   if(channel<0) {
01406     throw BocException("BOC BPM Fine Delay, start channel <",0,channel);
01407   }
01408 
01409   if(numChannels<0) {
01410     throw BocException("BOC BPM Fine Delay, number of channels <",0,numChannels);
01411   }
01412 
01413   if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) {
01414     throw BocException("BOC BPM Fine Delay, maximum channel >=",
01415         BOC_TRANSMIT_CHANNELS,channel+numChannels-1);
01416   }
01417 
01418   for(unsigned int i=0;i<numChannels;i++) {
01419     if(buffer[i]>=(1<<BOC_BPM_FINE_WIDTH)) {
01420       throw BocException("BOC BPM Fine Delay, maximum value >=",
01421         (1<<BOC_BPM_FINE_WIDTH),buffer[i]);
01422     }
01423   }
01424 
01425 //
01426 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01427 // for "real" channels.
01428 //
01429   for(unsigned int i=0;i<numChannels;i++) {
01430     bpmWrite((channel+i)/12,(channel+i)%12,BOC_BPM_FINE,buffer[i]);
01431   }
01432 
01433 }
01434 
01435 
01436 void BocCard::setBpmFineDelay(const UINT32 channel, const UINT32 value) 
01437         throw (BocException&) {
01438 //
01439 // Check for invalid values in arguments
01440 //
01441   if(channel<0) {
01442     throw BocException("BOC BPM Fine Delay, start channel <",0,channel);
01443   }
01444 
01445   if(channel>=BOC_TRANSMIT_CHANNELS) {
01446     throw BocException("BOC BPM Fine Delay, maximum channel >=",
01447         BOC_TRANSMIT_CHANNELS,channel);
01448   }
01449 
01450   if(value>=(1<<BOC_BPM_FINE_WIDTH)) {
01451     throw BocException("BOC BPM Fine Delay, maximum value >=",
01452       (1<<BOC_BPM_FINE_WIDTH),value);
01453   }
01454 
01455 //
01456 // Use bpmWrite to access the registers. Streams 0-11 on the BPM are used
01457 // for "real" channels.
01458 //
01459   bpmWrite(channel/12,channel%12,BOC_BPM_FINE,value);
01460 
01461 }
01462 
01463 
01464 // Methods to access individual registers. Whether it is the best solution
01465 // to have a series of trivial methods is open to debate...
01466 
01467 
01468 //------------------------getClockControl------------------------
01469 
01474 UINT32 BocCard::getClockControl() {
01475 //
01476   UINT32 mask;
01477   UINT32 width;
01478 
01479 // Mask off undefined bits. The width of this register is different for
01480 // pre-production, Rev A/Rev B series BOCs and Rev C series BOCs.
01481 //
01482   if(m_bocType == PRE_PRODUCTION_BOC) {
01483         width = BOC_CLK_CONTROL_WIDTH - 2;
01484   }
01485   else if((m_bocType == PRODUCTION_REVA_BOC)||
01486        (m_bocType == PRODUCTION_REVB_BOC)) {
01487         width = BOC_CLK_CONTROL_WIDTH - 1;
01488   }
01489   else if(m_bocType == PRODUCTION_REVC_BOC) {
01490         width = BOC_CLK_CONTROL_WIDTH;
01491   }
01492 // Unknown BOC, set the mask to return maximum number of bits.
01493   else {
01494         width = BOC_REGISTER_WIDTH;
01495   }
01496   mask = (1<<width) - 1;
01497   
01498   return (singleRead(BOC_CLK_CONTROL) & mask);
01499 
01500 }
01501 
01502 
01503 //------------------------setClockControl------------------------
01504 
01509 void BocCard::setClockControl(const UINT32 value) throw (BocException&) {
01510 //
01511 UINT32 limit;
01512 UINT32 width;
01513 //
01514 // Check for invalid values in the argument - the PHOS4_FIX bit is only
01515 // available for series BOCs, so the maximum allowed value of the argument
01516 // varies with BOC type. In addition the HALF_INHIBIT bit is only on RevC
01517 // BOCs.
01518 //
01519   if(m_bocType == PRE_PRODUCTION_BOC) { 
01520         width = BOC_CLK_CONTROL_WIDTH - 2;
01521   }
01522   else if((m_bocType == PRODUCTION_REVA_BOC)||
01523        (m_bocType == PRODUCTION_REVB_BOC)) {
01524         width = BOC_CLK_CONTROL_WIDTH - 1;
01525   }
01526   else if(m_bocType == PRODUCTION_REVC_BOC) { 
01527         width = BOC_CLK_CONTROL_WIDTH;
01528   }
01529 // Unknown BOC, set the limit to the maximum.
01530   else {
01531     width = BOC_REGISTER_WIDTH;
01532   }
01533   limit = 1<<width;
01534 
01535 //
01536   if(value>=limit) {
01537         throw BocException("BOC Clock Control >=",limit,value);
01538   }
01539 //
01540   singleWrite(BOC_CLK_CONTROL,value);
01541 
01542 }
01543 
01544 
01545 //------------------------getRxDataMode--------------------------
01546 
01551 UINT32 BocCard::getRxDataMode() {
01552 //
01553   UINT32 mask;
01554 // Mask off undefined bits
01555   mask = (1<<BOC_RX_DATA_MODE_WIDTH) - 1;
01556 
01557   return (singleRead(BOC_RX_DATA_MODE) & mask);
01558 
01559 }
01560 
01561 
01562 //------------------------setRxDataMode--------------------------
01563 
01568 void BocCard::setRxDataMode(const UINT32 value) throw (BocException&) {
01569 //
01570 //
01571 //
01572 // Check for invalid values in the argument - Rx Data Mode can have values
01573 // up to BOC_RX_DATA_MODE_WIDTH bits wide.
01574 //
01575   if(value>=(1<<BOC_RX_DATA_MODE_WIDTH)) {
01576         throw BocException("BOC Rx Data Mode >=",
01577           1<<BOC_RX_DATA_MODE_WIDTH,value);
01578   }
01579 //
01580   singleWrite(BOC_RX_DATA_MODE,value);
01581 
01582 }
01583 
01584 
01585 //------------------------getRxDacClear--------------------------
01586 
01592 UINT32 BocCard::getRxDacClear() {
01593 //
01594 
01595 // Pre-production BOC
01596   if(m_bocType == PRE_PRODUCTION_BOC) {
01597     return (singleRead(BOC_RXDAC_CLEAR) & 0x1);
01598   }
01599 // Series BOCs
01600   else if((m_bocType == PRODUCTION_REVA_BOC)||
01601        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
01602     return ((singleRead(BOC_RESET)>>BOC_RXDAC_CLEAR_BIT)&0x1);
01603   }
01604   else {
01605     return 0;
01606   }
01607 
01608 }
01609 
01610 
01611 //------------------------clearRxDac-----------------------------
01612 
01622 void BocCard::clearRxDac() {
01623 //
01624 
01625 // Pre-production BOC
01626   if(m_bocType == PRE_PRODUCTION_BOC) {
01627     singleWrite(BOC_RXDAC_CLEAR,1);
01628     singleWrite(BOC_RXDAC_CLEAR,0);
01629   }
01630 // Series BOCs
01631   else if((m_bocType == PRODUCTION_REVA_BOC)||
01632        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
01633     singleWrite(BOC_RESET,1<<BOC_RXDAC_CLEAR_BIT);
01634     singleWrite(BOC_RESET,0);
01635   }
01636 // Any other value - don't do anything.
01637 }
01638 
01639 
01640 //------------------------getTxDacClear--------------------------
01641 
01647 UINT32 BocCard::getTxDacClear() {
01648 //
01649 
01650 // Pre-production BOC
01651   if(m_bocType == PRE_PRODUCTION_BOC) {
01652     return (singleRead(BOC_TXDAC_CLEAR) & 0x1);
01653   }
01654 // Series BOCs
01655   else if((m_bocType == PRODUCTION_REVA_BOC)||
01656        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
01657     return ((singleRead(BOC_RESET)>>BOC_TXDAC_CLEAR_BIT)&0x1);
01658   }
01659   else {
01660     return 0;
01661   }
01662 
01663 }
01664 
01665 
01666 //------------------------clearTxDac-----------------------------
01667 
01677 void BocCard::clearTxDac() {
01678 //
01679 
01680 // Pre-production BOC
01681   if(m_bocType == PRE_PRODUCTION_BOC) {
01682     singleWrite(BOC_TXDAC_CLEAR,1);
01683     singleWrite(BOC_TXDAC_CLEAR,0);
01684   }
01685 // Series BOCs
01686   else if((m_bocType == PRODUCTION_REVA_BOC)||
01687        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
01688     singleWrite(BOC_RESET,1<<BOC_TXDAC_CLEAR_BIT);
01689     singleWrite(BOC_RESET,0);
01690   }
01691 // Any other value - don't do anything.
01692 }
01693 
01694 
01695 //------------------------getVernierFinePhase--------------------
01696 
01701 UINT32 BocCard::getVernierFinePhase() {
01702 //
01703 
01704   return (singleRead(BOC_VERNIER_FINE_PHASE) & m_bocMask);
01705 
01706 }
01707 
01708 
01709 //------------------------setVernierFinePhase--------------------
01710 
01715 void BocCard::setVernierFinePhase(const UINT32 value) throw (BocException&){
01716 //
01717 // Check that the argument is not too large.
01718 //
01719   if(value>m_bocMask) {
01720     throw BocException("BOC Vernier Fine Phase >",
01721           m_bocMask,value);
01722   }
01723 
01724   singleWrite(BOC_VERNIER_FINE_PHASE,value);
01725 
01726 }
01727 
01728 
01729 //------------------------getVernierClockPhase0-------------------
01730 
01737 UINT32 BocCard::getVernierClockPhase0() {
01738 //
01739   UINT32 mask;
01740 //
01741   mask = (1<<BOC_VERNIER_CLK0_WIDTH) - 1;
01742 
01743   return (singleRead(BOC_VERNIER_CLK0_PHASE) & mask);
01744 
01745 }
01746 
01747 
01748 //------------------------setVernierClockPhase0-------------------
01749 
01756 void BocCard::setVernierClockPhase0(const UINT32 value) throw (BocException&){
01757 //
01758 // Check that the argument is not too large.
01759 //
01760   if(value>=(1<<BOC_VERNIER_CLK0_WIDTH)) {
01761     throw BocException("BOC Vernier Clock Phase0 >=",
01762           (1<<BOC_VERNIER_CLK0_WIDTH),value);
01763   }
01764 
01765   singleWrite(BOC_VERNIER_CLK0_PHASE,value);
01766 
01767 }
01768 
01769 
01770 //------------------------getVernierClockPhase1-------------------
01771 
01778 UINT32 BocCard::getVernierClockPhase1() {
01779 //
01780   UINT32 mask;
01781 //
01782   mask = (1<<BOC_VERNIER_CLK1_WIDTH) - 1;
01783 
01784   return (singleRead(BOC_VERNIER_CLK1_PHASE) & mask);
01785 
01786 }
01787 
01788 
01789 //------------------------setVernierClockPhase1-------------------
01790 
01797 void BocCard::setVernierClockPhase1(const UINT32 value) throw (BocException&) {
01798 //
01799 // Check that the argument is not too large.
01800 //
01801   if(value>=(1<<BOC_VERNIER_CLK1_WIDTH)) {
01802     throw BocException("BOC Vernier Clock Phase1 >=",
01803           (1<<BOC_VERNIER_CLK1_WIDTH),value);
01804   }
01805 
01806   singleWrite(BOC_VERNIER_CLK1_PHASE,value);
01807 
01808 }
01809 
01810 
01811 //------------------------getVernierClockPhases-------------------
01812 
01819 UINT32 BocCard::getVernierClockPhases(UINT32 *value0, UINT32 *value1) {
01820 //
01821   UINT32 mask;
01822 //
01823   mask = (1<<BOC_VERNIER_CLK1_WIDTH) - 1;
01824 
01825   *value0 = getVernierClockPhase0();
01826   *value1 = getVernierClockPhase1();
01827 
01828   return (*value0 + *value1);
01829 
01830 }
01831 
01832 
01833 //------------------------setVernierClockPhases-------------------
01834 
01843 void BocCard::setVernierClockPhases(const UINT32 value) throw (BocException&) {
01844 //
01845   UINT32 clock0;
01846   UINT32 clock1;
01847 //
01848 // Check that the argument is not too large.
01849 //
01850   if(value>BOC_VERNIER_CLK_MAXIMUM) {
01851     throw BocException("BOC Vernier Clock Phases >",
01852           BOC_VERNIER_CLK_MAXIMUM,value);
01853   }
01854 
01855   clock0 = value/2;
01856   clock1 = value - clock0;  //To allow for odd values
01857 
01858   setVernierClockPhase0(clock0); 
01859   setVernierClockPhase1(clock1);
01860 
01861 }
01862 
01863 
01864 //------------------------getBpmClockPhase-------------------
01865 
01870 UINT32 BocCard::getBpmClockPhase() {
01871 //
01872 
01873   return (singleRead(BOC_BPM_CLK_PHASE) & m_bocMask);
01874 
01875 }
01876 
01877 
01878 //------------------------setBpmClockPhase-------------------
01879 
01884 void BocCard::setBpmClockPhase(const UINT32 value) throw (BocException&) {
01885 //
01886 // Check that the argument is not too large.
01887 //
01888   if(value>m_bocMask) {
01889     throw BocException("BOC BPM Clock Phase >",
01890           m_bocMask,value);
01891   }
01892 
01893   singleWrite(BOC_BPM_CLK_PHASE,value);
01894 
01895 }
01896 
01897 
01898 //------------------------getBregClockPhase-------------------
01899 
01904 UINT32 BocCard::getBregClockPhase() {
01905 //
01906 
01907   return (singleRead(BOC_BREG_CLK_PHASE) & m_bocMask);
01908 
01909 }
01910 
01911 
01912 //------------------------setBregClockPhase-------------------
01913 
01918 void BocCard::setBregClockPhase(const UINT32 value) throw (BocException&) {
01919 //
01920 // Check that the argument is not too large.
01921 //
01922   if(value>m_bocMask) {
01923     throw BocException("BOC BPM Clock Phase >",
01924           m_bocMask,value);
01925   }
01926 
01927   singleWrite(BOC_BREG_CLK_PHASE,value);
01928 
01929 }
01930 
01931 
01932 //------------------------getBocReset-------------------------
01933 
01940 UINT32 BocCard::getBocReset() {
01941 //
01942 // Determine the type of BOC.
01943 //
01944   if(m_bocType == PRE_PRODUCTION_BOC) {
01945 // Pre-production BOCs
01946     return (singleRead(BOC_RESET) & 0x1);
01947   }
01948   else if((m_bocType == PRODUCTION_REVA_BOC)||
01949        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
01950 //Series BOCs - resets are top 4 bits.
01951     return (singleRead(BOC_RESET) & 0xF0);
01952   }
01953   else {
01954     return 0;
01955   }
01956 
01957 }
01958 
01959 
01960 //------------------------resetBoc-----------------------------
01961 
01970 void BocCard::resetBoc() {
01971 //
01972 
01973   singleWrite(BOC_RESET,0xFF);
01974   singleWrite(BOC_RESET,0);
01975 
01976 }
01977 
01978 
01979 //------------------------getBpmReset-------------------------
01980 
01986 UINT32 BocCard::getBpmReset() {
01987 //
01988 
01989   if(m_bocType == PRE_PRODUCTION_BOC) {
01990 // Pre-production BOCs
01991     return (singleRead(BOC_BPM_RESET) & 0x1);
01992   }
01993   else if((m_bocType == PRODUCTION_REVA_BOC)||
01994        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
01995 //Series BOCs
01996     return ((singleRead(BOC_RESET)>>BOC_BPM_RESET_BIT)&0x1);
01997   }
01998   else {
01999     return 0;
02000   }
02001 
02002 }
02003 
02004 
02005 //------------------------resetBpm-----------------------------
02006 
02015 void BocCard::resetBpm() {
02016 //
02017 
02018   if(m_bocType == PRE_PRODUCTION_BOC) {
02019 // Pre-production BOCs
02020     singleWrite(BOC_BPM_RESET,1);
02021     singleWrite(BOC_BPM_RESET,0);
02022   }
02023   else if((m_bocType == PRODUCTION_REVA_BOC)||
02024        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02025 //Series BOCs
02026     singleWrite(BOC_RESET,1<<BOC_BPM_RESET_BIT);
02027     singleWrite(BOC_RESET,0);
02028   }
02029 // For other types, do nothing.
02030 }
02031 
02032 
02033 //------------------------getVpinReset-------------------------
02034 
02041 UINT32 BocCard::getVpinReset() {
02042 //
02043 
02044   if((m_bocType == PRODUCTION_REVA_BOC)||
02045     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02046 //Series BOCs
02047     return ((singleRead(BOC_RESET)>>BOC_VPIN_RESET_BIT)&0x1);
02048   }
02049   else {
02050     return 0;
02051   }
02052 
02053 }
02054 
02055 
02056 //------------------------resetVpin----------------------------
02057 
02065 void BocCard::resetVpin() {
02066 //
02067 
02068   if((m_bocType == PRODUCTION_REVA_BOC)||
02069     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02070 //Series BOCs
02071     singleWrite(BOC_RESET,1<<BOC_VPIN_RESET_BIT);
02072 // Sleep long enough for the reset to occur. Use the RodModule sleep
02073 // as it is convenient.
02074     m_myrod->sleep(1);
02075 //
02076     singleWrite(BOC_RESET,0);
02077   }
02078 // For other types, do nothing.
02079 }
02080 
02081 
02082 //------------------------getBocOkReset-------------------------
02083 
02090 UINT32 BocCard::getBocOkReset() {
02091 //
02092 
02093   if((m_bocType == PRODUCTION_REVA_BOC)||
02094     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02095 //Series BOCs
02096     return ((singleRead(BOC_RESET)>>BOC_OK_RESET_BIT)&0x1);
02097   }
02098   else {
02099     return 0;
02100   }
02101 
02102 }
02103 
02104 
02105 //------------------------resetBocOk----------------------------
02106 
02113 void BocCard::resetBocOk() {
02114 //
02115 
02116   if((m_bocType == PRODUCTION_REVA_BOC)||
02117     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02118 //Series BOCs
02119     singleWrite(BOC_RESET,1<<BOC_OK_RESET_BIT);
02120 //
02121     singleWrite(BOC_RESET,0);
02122   }
02123 // For other types, do nothing.
02124 }
02125 
02126 
02127 //------------------------getBocStatusRegister----------------
02128 
02133 UINT32 BocCard::getBocStatusRegister() {
02134 //
02135   UINT32 mask;
02136 //
02137 // If this is a series BOC, the first bit is ill-defined
02138 // and hence is masked off.
02139 //
02140   if((m_bocType == PRODUCTION_REVA_BOC)||
02141     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02142     mask = m_bocMask & ~0x1;
02143   }
02144   else {
02145     mask = m_bocMask;
02146   }
02147   return (singleRead(BOC_STATUS) & mask);
02148 }
02149 
02150 
02151 //------------------------getMonitorAdc-------------------------
02152 
02159 double BocCard::getMonitorAdc(const UINT32 channel, std::string &units,
02160                               std::string &type) throw (BocException&) {
02161 //
02162 //
02163 // Check if channel number valid.
02164 //
02165   if (channel > BOC_MONITOR_CHANNELS) {
02166      throw BocException("BOC Monitor Adc, channel >",
02167                         BOC_MONITOR_CHANNELS, channel);
02168   }
02169   units = getMonitorAdcUnits(channel);
02170   type = getMonitorAdcType(channel);
02171 //
02172 // Use the alternative method to do the work.
02173 //
02174   return getMonitorAdc(channel);
02175 }
02176 
02177 double BocCard::getMonitorAdc(const UINT32 channel) throw (BocException&) {
02178 //
02179   UINT32 lsbMask;
02180   UINT32 msbMask;
02181   double adcValue;
02182   double logRTherm;
02183 //
02184 // Check if channel number valid.
02185 //
02186   if (channel > BOC_MONITOR_CHANNELS) {
02187      throw BocException("BOC Monitor Adc, channel >",
02188                         BOC_MONITOR_CHANNELS, channel);
02189   }
02190 //
02191 //Only do this with production BOC.
02192 //
02193   if((m_bocType == PRODUCTION_REVA_BOC)||
02194     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02195 
02196     singleWrite(BOC_ADC_CONFIG, channel);   //set channel to convert
02197     singleWrite(BOC_ADC_CONVERT, 0);        //convert - data irrelevant
02198 //
02199 //10-bit or 12-bit ADC is in two registers
02200 //
02201     lsbMask = m_bocMask;
02202     msbMask = (1<<BOC_ADC_MSB_WIDTH[m_hardwareRevision]) - 1;
02203 
02204     adcValue = (double) ((singleRead(BOC_ADC_LSB)&lsbMask) 
02205                + ((singleRead(BOC_ADC_MSB)&msbMask)<<BOC_REGISTER_WIDTH));
02206 //Rescale for 12-bit ADC.
02207     if(m_hardwareRevision == 1) adcValue /= 4.0;
02208 //
02209 // Channel types are defined in the array MONITOR_CHANNEL_TYPE[].
02210 //
02211 //Rev A, Rev B and Rev C have different parameters.
02212 //
02213 // Currents in mA
02214 //
02215     if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_CURRENT) {
02216       if(m_bocType == PRODUCTION_REVA_BOC) {
02217         return(iArevA*adcValue+iBrevA);
02218       }
02219       else if(m_bocType == PRODUCTION_REVB_BOC) {
02220     return(iArevB*adcValue+iBrevB);
02221       }
02222       else if(m_bocType == PRODUCTION_REVC_BOC) {
02223         return(iArevC*adcValue+iBrevC);
02224       }
02225       else {
02226         return -1.0;
02227       }
02228     }
02229 //Voltages in Volts
02230 //
02231     else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_VOLTAGE) {
02232       if(m_bocType == PRODUCTION_REVA_BOC) {
02233         return(vArevA*adcValue+vBrevA);
02234       }
02235       else if(m_bocType == PRODUCTION_REVB_BOC) {
02236         return(vArevB*adcValue+vBrevB);
02237       }
02238       else if(m_bocType == PRODUCTION_REVC_BOC) {
02239         return(vArevC*adcValue+vBrevC);
02240       }
02241       else {
02242         return -1.0;
02243       }
02244     }
02245 //Temperatures in degrees C
02246 //
02247     else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_TEMP) {
02248 //
02249 // Temperature calculation is more complicated.
02250 //
02251 // Get the log(resistance) first, then plug into the formula.
02252 //
02253       if(m_bocType == PRODUCTION_REVA_BOC) {
02254     logRTherm = log((tArevA*(tBrevA-adcValue))/adcValue);
02255         return((1.0/(tC0revA+tC1revA*logRTherm + tC2revA*pow(logRTherm,3)))-273.15);
02256       }
02257       else if(m_bocType == PRODUCTION_REVB_BOC) {
02258         logRTherm = log((tArevB*(tBrevB-adcValue))/adcValue);
02259         return((1.0/(tC0revB+tC1revB*logRTherm + tC2revB*pow(logRTherm,3)))-273.15);
02260       }
02261       else if(m_bocType == PRODUCTION_REVC_BOC) {
02262         logRTherm = log((tArevC*(tBrevC-adcValue))/adcValue);
02263         return((1.0/(tC0revC+tC1revC*logRTherm + tC2revC*pow(logRTherm,3)))-273.15);
02264       }
02265       else {
02266         return -1.0;
02267       }
02268     }
02269     else {
02270       return -1.0;
02271     }
02272   }
02273   return -1.0;
02274 }
02275 
02276 
02277 //------------------------getMonitorAdcType-------------------
02278 
02282 std::string BocCard::getMonitorAdcType(const UINT32 channel) throw (BocException&) {
02283 //
02284 // Check if channel number valid.
02285 //
02286   if (channel > BOC_MONITOR_CHANNELS) {
02287      throw BocException("BOC Monitor Adc Type, channel >",
02288                         BOC_MONITOR_CHANNELS, channel);
02289   }
02290 //
02291 // Return the type in a string
02292 //
02293   if (MONITOR_CHANNEL_TYPE[channel] == MONITOR_CURRENT) {
02294      return "PIN Current";
02295   }
02296   else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_VOLTAGE) {
02297      return "PIN Voltage";
02298   }
02299   else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_TEMP) {
02300      return "Temperature";
02301   }
02302   else {
02303      return "";
02304   }
02305 //
02306 }
02307 
02308 
02309 //------------------------getMonitorAdcUnits------------------
02310 
02314 std::string BocCard::getMonitorAdcUnits(const UINT32 channel) throw (BocException&) {
02315 //
02316 // Check if channel number valid.
02317 //
02318   if (channel > BOC_MONITOR_CHANNELS) {
02319      throw BocException("BOC Monitor Adc Units, channel >",
02320                         BOC_MONITOR_CHANNELS, channel);
02321   }
02322 //
02323 // Return the units in a string
02324 //
02325   if (MONITOR_CHANNEL_TYPE[channel] == MONITOR_CURRENT) {
02326      return "mA";
02327   }
02328   else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_VOLTAGE) {
02329      return "Volts";
02330   }
02331   else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_TEMP) {
02332      return "Celcius";
02333   }
02334   else {
02335      return "";
02336   }
02337 }
02338 
02339 
02340 //------------------------getMonitorAdcCurrents------------------
02341 
02347 UINT32 BocCard::getMonitorAdcCurrents(double currents[], UINT32 count, 
02348               std::string &units) throw (BocException&) {
02349 
02350 UINT32 numCurrents = 0;
02351 
02352 //
02353 // Check if array size is large enough.
02354 //
02355   if (getMonitorAdcCurrentsCount() > count) {
02356      throw BocException("BOC Monitor Adc Currents, array size <",
02357                         count, getMonitorAdcCurrentsCount());
02358   }
02359 
02360 //
02361 // Now loop through the channels and extract the currents.
02362 //
02363   for (unsigned int i=0; i<BOC_MONITOR_CHANNELS; i++) {
02364     if (MONITOR_CHANNEL_TYPE[i] == MONITOR_CURRENT) {
02365       currents[numCurrents] = getMonitorAdc(i);
02366       if(numCurrents == 0) units = getMonitorAdcUnits(i);
02367       numCurrents++;
02368     }
02369   }
02370 
02371   return numCurrents;
02372 }
02373 
02374 
02375 //------------------------getMonitorAdcCurrentsCount------------------
02376 
02381 UINT32 BocCard::getMonitorAdcCurrentsCount() {
02382 //
02383 UINT32 numCurrents = 0;
02384 
02385 //
02386 // Loop through the channels and count the currents.
02387 //
02388   for (unsigned int i=0; i<BOC_MONITOR_CHANNELS; i++) {
02389     if (MONITOR_CHANNEL_TYPE[i] == MONITOR_CURRENT) {
02390       numCurrents++;
02391     }
02392   }
02393 
02394   return numCurrents;
02395 }
02396 
02397 
02398 //------------------------getMonitorAdcVoltages------------------
02399 
02405 UINT32 BocCard::getMonitorAdcVoltages(double voltages[], UINT32 count,
02406              std::string &units) throw (BocException&) {
02407 
02408 UINT32 numVoltages = 0;
02409 
02410 //
02411 // Check if array size is large enough.
02412 //
02413   if (getMonitorAdcVoltagesCount() > count) {
02414      throw BocException("BOC Monitor Adc Voltages, array size <",
02415                         count, getMonitorAdcVoltagesCount());
02416   }
02417 
02418 //
02419 // Now loop through the channels and extract the voltages.
02420 //
02421   for (unsigned int i=0; i<BOC_MONITOR_CHANNELS; i++) {
02422     if (MONITOR_CHANNEL_TYPE[i] == MONITOR_VOLTAGE) {
02423       voltages[numVoltages] = getMonitorAdc(i);
02424       if(numVoltages == 0) units = getMonitorAdcUnits(i);
02425       numVoltages++;
02426     }
02427   }
02428 
02429   return numVoltages;
02430 }
02431 
02432 
02433 //------------------------getMonitorAdcVoltagesCount------------------
02434 
02439 UINT32 BocCard::getMonitorAdcVoltagesCount() {
02440 //
02441 UINT32 numVoltages = 0;
02442 
02443 //
02444 // Loop through the channels and count the voltages.
02445 //
02446   for (unsigned int i=0; i<BOC_MONITOR_CHANNELS; i++) {
02447     if (MONITOR_CHANNEL_TYPE[i] == MONITOR_VOLTAGE) {
02448       numVoltages++;
02449     }
02450   }
02451 
02452   return numVoltages;
02453 }
02454 
02455 
02456 //------------------------getMonitorAdcTemps------------------
02457 
02463 UINT32 BocCard::getMonitorAdcTemps(double temps[], UINT32 count,
02464              std::string &units) throw (BocException&) {
02465 
02466 UINT32 numTemps = 0;
02467 
02468 //
02469 // Check if array size is large enough.
02470 //
02471   if (getMonitorAdcTempsCount() > count) {
02472      throw BocException("BOC Monitor Adc Temps, array size <",
02473                         count, getMonitorAdcTempsCount());
02474   }
02475 
02476 //
02477 // Now loop through the channels and extract the temperatures.
02478 //
02479   for (unsigned int i=0; i<BOC_MONITOR_CHANNELS; i++) {
02480     if (MONITOR_CHANNEL_TYPE[i] == MONITOR_TEMP) {
02481       temps[numTemps] = getMonitorAdc(i);
02482       if(numTemps == 0) units = getMonitorAdcUnits(i);
02483       numTemps++;
02484     }
02485   }
02486 
02487   return numTemps;
02488 }
02489 
02490 
02491 //------------------------getMonitorAdcTempsCount------------------
02492 
02497 UINT32 BocCard::getMonitorAdcTempsCount() {
02498 //
02499 UINT32 numTemps = 0;
02500 
02501 //
02502 // Loop through the channels and count the temperatures
02503 //
02504   for (unsigned int i=0; i<BOC_MONITOR_CHANNELS; i++) {
02505     if (MONITOR_CHANNEL_TYPE[i] == MONITOR_TEMP) {
02506       numTemps++;
02507     }
02508   }
02509 
02510   return numTemps;
02511 }
02512 
02513 
02514 //------------------------resetMonitorAdc---------------------
02515 
02520 void BocCard::resetMonitorAdc() {
02521 //
02522 // Only do this if production BOC
02523 //
02524   if((m_bocType==PRODUCTION_REVA_BOC)||
02525     (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02526     singleWrite(BOC_ADC_SETUP,0);       //data is irrelevant
02527   }
02528 }
02529 
02530 
02531 //------------------------getInterlockStatus----------------
02532 
02545 UINT32 BocCard::getInterlockStatus(UINT32 *localEnable, UINT32 *remoteEnable) {
02546 //
02547 //
02548 // For pre-production BOC, check bits 2, 6 and 7
02549 //
02550   if(m_bocType==PRE_PRODUCTION_BOC) {
02551     *localEnable = (getBocStatusRegister()&(1<<BOC_PRE_PRODUCTION_LOCLASEN))!=0;
02552     *remoteEnable = (getBocStatusRegister()&(1<<BOC_PRE_PRODUCTION_REMLASEN))!=0;
02553 
02554     return(((getBocStatusRegister()&(1<<BOC_PRE_PRODUCTION_SW4))!=0)&&
02555           (*localEnable)&&(*remoteEnable));
02556   }
02557 //
02558 // If this is a series BOC, the interlock status bits are 6 and 7.
02559 //
02560   else if((m_bocType == PRODUCTION_REVA_BOC)||
02561        (m_bocType==PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02562     *localEnable = (getBocStatusRegister()&(1<<BOC_PRODUCTION_LOCLASEN))!=0;
02563     *remoteEnable = (getBocStatusRegister()&(1<<BOC_PRODUCTION_REMLASEN))!=0;
02564 
02565     return ((*localEnable)&&(*remoteEnable));
02566   }
02567 //
02568 // Unknown BOC, return 0
02569 //
02570   else {
02571     *localEnable = 0;
02572     *remoteEnable = 0;
02573     return 0;
02574   }
02575 }
02576 
02577 UINT32 BocCard::getInterlockStatus() {
02578 //
02579   UINT32 localEnable;
02580   UINT32 remoteEnable;
02581 //
02582 // For pre-production BOC, check bits 2, 6 and 7
02583 //
02584   if(m_bocType == PRE_PRODUCTION_BOC) {
02585     localEnable = getBocStatusRegister()&(1<<BOC_PRE_PRODUCTION_LOCLASEN);
02586     remoteEnable = getBocStatusRegister()&(1<<BOC_PRE_PRODUCTION_REMLASEN);
02587 
02588     return(((getBocStatusRegister()&(1<<BOC_PRE_PRODUCTION_SW4))!=0)&&
02589           (localEnable!=0)&&(remoteEnable!=0));
02590   }
02591 //
02592 // If this is a series BOC, the interlock status bits are 6 and 7.
02593 //
02594   else if((m_bocType == PRODUCTION_REVA_BOC)||
02595        (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) {
02596     localEnable = getBocStatusRegister()&(1<<BOC_PRODUCTION_LOCLASEN);
02597     remoteEnable = getBocStatusRegister()&(1<<BOC_PRODUCTION_REMLASEN);
02598 
02599     return ((localEnable!=0)&&(remoteEnable!=0));
02600   }
02601 //
02602 // Unknown BOC, return 0
02603 //
02604   else {
02605     return 0;
02606   }
02607 }
02608 
02609 
02610 
02611 //Private methods follow
02612 
02613 //Read/write access methods. Block read and write methods are provided,
02614 // though in fact they use the single read and write methods. I have made
02615 // these methods private, as the user shouldn't need to see them.
02616 //
02617 
02618 
02619 //------------------------singleRead-----------------------------
02620 
02626 UINT32 BocCard::singleRead(const UINT32 address) throw (BocException&) {
02627 //
02628   UINT32 bocAddress;
02629   UINT32 value;
02630   clock_t start;
02631 //
02632   bocAddress = address + BOC_ADDRESS_BASE;
02633   value = m_myrod->mdspSingleRead(bocAddress);
02634 //
02635 //Check if the BOC is busy and wait until it isn't (with a 1 second
02636 //timeout).
02637 //
02638   start = clock();
02639   
02640   while(m_myrod->mdspSingleRead(RRIF_STATUS_1_ADDRESS)&BOC_BUSY_0) {
02641     if(clock() - start > (clock_t)CLOCKS_PER_SEC) {
02642       throw BocException("single read - BOC_BUSY_0 not cleared after 1 second");
02643     }
02644   }
02645 
02646 //
02647   return value;
02648 }
02649 
02650 
02651 //------------------------singleWrite-----------------------------
02652 
02658 void BocCard::singleWrite(const UINT32 address, const UINT32 value) throw (BocException&) {
02659 //
02660   UINT32 bocAddress;
02661   clock_t start;
02662 //
02663   bocAddress = address + BOC_ADDRESS_BASE;
02664   m_myrod->mdspSingleWrite(bocAddress, value);
02665 //
02666 //Check if the BOC is busy and wait until it isn't - there is a timeout of
02667 //1 second for this happening.
02668 //
02669   start = clock();
02670   while(m_myrod->mdspSingleRead(RRIF_STATUS_1_ADDRESS)&BOC_BUSY_0) {
02671     if((clock() - start) > (clock_t)CLOCKS_PER_SEC) {
02672       throw BocException("single write, BOC_BUSY_0 not cleared after 1 second");
02673     }
02674   }
02675 
02676 //
02677 
02678 }
02679 
02680 
02681 //------------------------blockRead-----------------------------
02682 
02690 void BocCard::blockRead(const UINT32 address, UINT32 buffer[],
02691          const INT32 wordCount) {
02692 //
02693 //
02694   for(int i=0;i<wordCount;i++) {
02695     buffer[i] = singleRead(address+4*i);
02696   }
02697 //
02698 
02699 }
02700 
02701 
02702 //------------------------blockWrite-----------------------------
02703 
02710 void BocCard::blockWrite(const UINT32 address, const UINT32 buffer[],
02711          const INT32 wordCount) {
02712 //
02713 //
02714   for(int i=0;i<wordCount;i++) {
02715     singleWrite(address+4*i,buffer[i]);
02716   }
02717 //
02718 
02719 }
02720 
02721 
02722 //Read and write routines for BPM. These methods access a BPM via its
02723 //internal channel numbers, and shouldn't be needed by users. They are
02724 //useful mainly for access to the channels not used for "normal" BPM
02725 //operations (channels 12-15 have special uses and are not mapped to
02726 //by the Tx streams).
02727 
02728 
02729 //------------------------bpmRead---------------------------------
02730 
02736 UINT32 BocCard::bpmRead(const UINT32 bpm, const UINT32 stream, 
02737         const UINT32 offset) {
02738 //
02739   UINT32 address;
02740   UINT32 value;
02741 //
02742 // Get the address (relative to start of BOC window)
02743 //
02744   address = BOC_BPM_BASE + (bpm<<8) + (stream<<4) + offset;
02745 
02746   value = singleRead(address);
02747 
02748   return value;
02749 
02750 }
02751 
02752 
02753 //------------------------bpmWrite--------------------------------
02754 
02760 void BocCard::bpmWrite(const UINT32 bpm, const UINT32 stream,
02761         const UINT32 offset, const UINT32 value) {
02762 //
02763   UINT32 address;
02764 //
02765 // Get the address (relative to start of BOC window)
02766 //
02767   address = BOC_BPM_BASE + (bpm<<8) + (stream<<4) + offset;
02768 
02769   singleWrite(address, value);
02770 
02771 }
02772 
02773 
02774 } // End namespace SctPixelRod

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