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

Generated on Thu Dec 15 21:14:23 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5