// File: BocCard.cxx #include "BocCard.h" //! Namespace for the common routines for SCT and PIXEL ROD software. namespace SctPixelRod { //**************************class BocException*********************** // // Description: // This class provides the exception handling for the BocCard routines. // // Author(s): // John Hill (hill@hep.phy.cam.ac.uk) - originator // //-------------------------------Constructor------------------------- /* Define two constructors - one for no data, one for two data items. Default destructor is used. */ BocException::BocException(std::string descriptor) : BaseException(descriptor) { m_numValue = 0; m_value1 = 0; m_value2 = 0; setType(BOC); } BocException::BocException(std::string descriptor,INT32 value1,INT32 value2) : BaseException(descriptor) { m_numValue = 2; m_value1 = value1; m_value2 = value2; setType(BOC); } void BocException::what(std::ostream& os) { unsigned long numData; numData = getNumData(); os << "BocException: " << getDescriptor() << std::endl; if (numData == 0) return; os << "Data1:" << getData1() << std::endl; os << "Data2:" << getData2() << std::endl; } //****************************class BocCard************************** // // Description: // This class provides the software interface to the BOC module. // // Author(s): // John Hill (hill@hep.phy.cam.ac.uk) - originator // //-------------------------------Constructor------------------------- /* This is the only constructor to use. */ BocCard::BocCard(RodModule & rod) { m_myrod = &rod; m_serialNumber = 0xFFFFFFFF; //initialize overwrites this } //-------------------------------Destructor-------------------------- /* Just remove reference to ROD. The RodModule class is not deleted, as BocCard did not create it. */ BocCard::~BocCard() { m_myrod = 0; } // Member methods //------------------------initialize-------------------------------- /*! Initialize (sic!) the BOC - set to a well-defined state. A lot * of the settings in this method will be power-on defaults, but it * is helpful to do this explicitly. */ void BocCard::initialize() { // Reset the BOC resetBoc(); // Get all the readonly identification information into the private // variables m_serialNumber = singleRead(BOC_SERIAL_NUMBER); m_manufacturer = singleRead(BOC_MANUFACTURER); m_moduleType = singleRead(BOC_MODULE_TYPE); m_hardwareRevision = singleRead(BOC_HW_REV); // The type of BOC is now (from 3 March 2004) determined from the // top 3 bits of the Hardware Revision register. The bottom 5 bits // indicate the hardware revision for that BOC type. m_bocType = ((m_hardwareRevision)>>5) & 0x7; m_hardwareRevision &= 0x1F; // m_firmwareRevision = singleRead(BOC_FW_REV); // Set the setup bus mask. m_bocMask = (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC Transmit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } // // Get the start address (relative to start of BOC window) // address = BOC_LASER_DAC + (channel<<2); if(numChannels <= 1) { // Use the single read method buffer[0] = singleRead(address); } else { // Use the block read method blockRead(address, buffer, numChannels); } // Now mask off bits that are not well-defined. // for(unsigned int i=0;i=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC Transmit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } // // Get the start address (relative to start of BOC window) // address = BOC_LASER_DAC + (channel<<2); // Use the single read method return (singleRead(address) & m_bocMask); } //------------------------setLaserCurrent--------------------------- /*! Write one or more TX laser current settings to the BOC */ void BocCard::setLaserCurrent(const UINT32 channel, const UINT32 buffer[], const UINT32 numChannels) throw (BocException&) { // UINT32 address; // // Check for invalid values in arguments // if(channel<0) { throw BocException("BOC Transmit, start channel <",0,channel); } if(numChannels<0) { throw BocException("BOC Transmit, number of channels <",0,numChannels); } if((channel+numChannels)>BOC_TRANSMIT_CHANNELS) { throw BocException("BOC Transmit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;im_bocMask) { throw BocException("BOC Transmit, maximum value >", m_bocMask,buffer[i]); } } // // Get the start address (relative to start of BOC window) // address = BOC_LASER_DAC + (channel<<2); if(numChannels <= 1) { // Use the single write method singleWrite(address,buffer[0]); } else { // Use the block write method blockWrite(address, buffer, numChannels); } } void BocCard::setLaserCurrent(const UINT32 channel, const UINT32 value) throw (BocException&) { // UINT32 address; // // Check for invalid values in arguments // if(channel<0) { throw BocException("BOC Transmit, start channel <",0,channel); } if(channel>=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC Transmit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } if(value>m_bocMask) { throw BocException("BOC Transmit, maximum value >", m_bocMask,value); } // // Get the start address (relative to start of BOC window) // address = BOC_LASER_DAC + (channel<<2); // Use the single write method singleWrite(address,value); } //------------------------getRxThreshold--------------------------- /*! Read one or more RX threshold settings from the BOC */ void BocCard::getRxThreshold(const UINT32 channel, UINT32 buffer[], const UINT32 numChannels) throw (BocException&) { // UINT32 address; // // Check for invalid values in arguments // if(channel<0) { throw BocException("BOC Receive, start channel <",0,channel); } if(numChannels<0) { throw BocException("BOC Receive, number of channels <",0,numChannels); } if((channel+numChannels)>BOC_RECEIVE_CHANNELS) { throw BocException("BOC Receive, maximum channel >=", BOC_RECEIVE_CHANNELS,channel+numChannels-1); } // // Get the start address (relative to start of BOC window) // address = BOC_THRESHOLD_DAC + (channel<<2); if(numChannels <= 1) { // Use the single read method buffer[0] = singleRead(address); } else { // Use the block read method blockRead(address, buffer, numChannels); } // Now mask off bits that are not well-defined. // for(unsigned int i=0;i=BOC_RECEIVE_CHANNELS) { throw BocException("BOC Receive, maximum channel >=", BOC_RECEIVE_CHANNELS,channel); } // // Get the start address (relative to start of BOC window) // address = BOC_THRESHOLD_DAC + (channel<<2); // Use the single read method return (singleRead(address) & m_bocMask); } //------------------------setRxThreshold--------------------------- /*! Write one or more RX threshold settings to the BOC */ void BocCard::setRxThreshold(const UINT32 channel, const UINT32 buffer[], const UINT32 numChannels) throw (BocException&) { // UINT32 address; // // Check for invalid values in arguments // if(channel<0) { throw BocException("BOC Receive, start channel <",0,channel); } if(numChannels<0) { throw BocException("BOC Receive, number of channels <",0,numChannels); } if((channel+numChannels)>BOC_RECEIVE_CHANNELS) { throw BocException("BOC Receive, maximum channel >=", BOC_RECEIVE_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;im_bocMask) { throw BocException("BOC Transmit, maximum value >", m_bocMask,buffer[i]); } } // // Get the start address (relative to start of BOC window) // address = BOC_THRESHOLD_DAC + (channel<<2); if(numChannels <= 1) { // Use the single write method singleWrite(address,buffer[0]); } else { // Use the block write method blockWrite(address, buffer, numChannels); } } void BocCard::setRxThreshold(const UINT32 channel, const UINT32 value) throw (BocException&) { // UINT32 address; // // Check for invalid values in arguments // if(channel<0) { throw BocException("BOC Receive, start channel <",0,channel); } if(channel>=BOC_RECEIVE_CHANNELS) { throw BocException("BOC Receive, maximum channel >=", BOC_RECEIVE_CHANNELS,channel); } if(value>m_bocMask) { throw BocException("BOC Transmit, maximum value >", m_bocMask,value); } // // Get the start address (relative to start of BOC window) // address = BOC_THRESHOLD_DAC + (channel<<2); // Use the single write method singleWrite(address,value); } //------------------------getRxDataDelay--------------------------- /*! Read one or more RX data delay settings from the BOC */ void BocCard::getRxDataDelay(const UINT32 channel, UINT32 buffer[], const UINT32 numChannels) throw (BocException&){ // UINT32 address; UINT32 mask; // // Check for invalid values in arguments // if(channel<0) { throw BocException("BOC Data Delay, start channel <",0,channel); } if(numChannels<0) { throw BocException("BOC Data Delay, number of channels <",0,numChannels); } if((channel+numChannels)>BOC_RECEIVE_CHANNELS) { throw BocException("BOC Data Delay, maximum channel >=", BOC_RECEIVE_CHANNELS,channel+numChannels-1); } // // Get the start address (relative to start of BOC window) // address = BOC_DATA_DELAY + (channel<<2); if(numChannels <= 1) { // Use the single read method buffer[0] = singleRead(address); } else { // Use the block read method blockRead(address, buffer, numChannels); } // Now mask off bits that are not well-defined. // mask = (1<=BOC_RECEIVE_CHANNELS) { throw BocException("BOC Data Delay, maximum channel >=", BOC_RECEIVE_CHANNELS,channel); } // // Get the start address (relative to start of BOC window) // address = BOC_DATA_DELAY + (channel<<2); mask = (1<BOC_RECEIVE_CHANNELS) { throw BocException("BOC Data Delay, maximum channel >=", BOC_RECEIVE_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;i=(1<=", (1<=BOC_RECEIVE_CHANNELS) { throw BocException("BOC Data Delay, maximum channel >=", BOC_RECEIVE_CHANNELS,channel); } if(value>=(1<=", (1<BOC_STROBE_CHANNELS) { throw BocException("BOC Strobe Delay, maximum channel >=", BOC_STROBE_CHANNELS,channel+numChannels-1); } // // Get the start address (relative to start of BOC window) // Note that step is in units of 0x10. // address = BOC_STROBE_DELAY + (channel<<4); if(numChannels <= 1) { // Use the single read method buffer[0] = singleRead(address); } else { // Use the block read method blockRead(address, buffer, numChannels); } // Now mask off bits that are not well-defined. // mask = (1<=BOC_STROBE_CHANNELS) { throw BocException("BOC Strobe Delay, maximum channel >=", BOC_STROBE_CHANNELS,channel); } // // Get the start address (relative to start of BOC window) // address = BOC_STROBE_DELAY + (channel<<4); mask = (1<BOC_STROBE_CHANNELS) { throw BocException("BOC Strobe Delay, maximum channel >=", BOC_STROBE_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;i=(1<=", (1<=BOC_STROBE_CHANNELS) { throw BocException("BOC Strobe Delay, maximum channel >=", BOC_STROBE_CHANNELS,channel); } if(value>=(1<=", (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Stream Inhibit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Stream Inhibit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Stream Inhibit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;i=(1<=", (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Stream Inhibit, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } if(value>=(1<=", (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Mark/Space, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Mark/Space, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Mark/Space, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;i=(1<=", (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Mark/Space, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } if(value>=(1<=", (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Coarse Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Coarse Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Coarse Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;i=(1<=", (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Coarse Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } if(value>=(1<=", (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Fine Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Fine Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } // // Use bpmRead to access the registers. Streams 0-11 on the BPM are used // for "real" channels. // mask = (1<BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Fine Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel+numChannels-1); } for(unsigned int i=0;i=(1<=", (1<=BOC_TRANSMIT_CHANNELS) { throw BocException("BOC BPM Fine Delay, maximum channel >=", BOC_TRANSMIT_CHANNELS,channel); } if(value>=(1<=", (1<=limit) { throw BocException("BOC Clock Control >=",limit,value); } // singleWrite(BOC_CLK_CONTROL,value); } //------------------------getRxDataMode-------------------------- /*! Read the Rx Data Mode register */ UINT32 BocCard::getRxDataMode() { // UINT32 mask; // Mask off undefined bits mask = (1<=(1<=", 1<>BOC_RXDAC_CLEAR_BIT)&0x1); } else { return 0; } } //------------------------clearRxDac----------------------------- /*! Clear the Rx DAC. This involves writing 1 followed by 0 to * the RXDAC register. A method to do a single write does not seem * to be necessary, and so is not provided. * For pre-production BOCs, bit 0 of the BOC_RXDAC_CLEAR register * is used. * For series BOCs, bit BOC_RXDAC_CLEAR_BIT of BOC_RESET is used. */ void BocCard::clearRxDac() { // // Pre-production BOC if(m_bocType == PRE_PRODUCTION_BOC) { singleWrite(BOC_RXDAC_CLEAR,1); singleWrite(BOC_RXDAC_CLEAR,0); } // Series BOCs else if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { singleWrite(BOC_RESET,1<>BOC_TXDAC_CLEAR_BIT)&0x1); } else { return 0; } } //------------------------clearTxDac----------------------------- /*! Clear the Tx DAC. This involves writing 1 followed by 0 to * the TXDAC register. A method to do a single write does not seem * to be necessary, and so is not provided. * For pre-production BOCs, bit 0 of the BOC_TXDAC_CLEAR register * is used. * For series BOCs, bit BOC_TXDAC_CLEAR_BIT of BOC_RESET is used. */ void BocCard::clearTxDac() { // // Pre-production BOC if(m_bocType == PRE_PRODUCTION_BOC) { singleWrite(BOC_TXDAC_CLEAR,1); singleWrite(BOC_TXDAC_CLEAR,0); } // Series BOCs else if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { singleWrite(BOC_RESET,1<m_bocMask) { throw BocException("BOC Vernier Fine Phase >", m_bocMask,value); } singleWrite(BOC_VERNIER_FINE_PHASE,value); } //------------------------getVernierClockPhase0------------------- /*! Read the Vernier Clock Phase register 0. There are two registers * (0 and 1) which act in series to give a clock range of 50nsec in * 1 nsec steps. */ UINT32 BocCard::getVernierClockPhase0() { // UINT32 mask; // mask = (1<=(1<=", (1<=(1<=", (1<m_bocMask) { throw BocException("BOC BPM Clock Phase >", m_bocMask,value); } singleWrite(BOC_BPM_CLK_PHASE,value); } //------------------------getBregClockPhase------------------- /*! Read the Breg Clock Phase register. */ UINT32 BocCard::getBregClockPhase() { // return (singleRead(BOC_BREG_CLK_PHASE) & m_bocMask); } //------------------------setBregClockPhase------------------- /*! Write to the Breg Clock Phase register. */ void BocCard::setBregClockPhase(const UINT32 value) throw (BocException&) { // // Check that the argument is not too large. // if(value>m_bocMask) { throw BocException("BOC BPM Clock Phase >", m_bocMask,value); } singleWrite(BOC_BREG_CLK_PHASE,value); } //------------------------getBocReset------------------------- /*! Read the BOC Reset register. For series BOCs, this register * merges the various registers that were separate on pre-production * BOCs. */ UINT32 BocCard::getBocReset() { // // Determine the type of BOC. // if(m_bocType == PRE_PRODUCTION_BOC) { // Pre-production BOCs return (singleRead(BOC_RESET) & 0x1); } else if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { //Series BOCs - resets are top 4 bits. return (singleRead(BOC_RESET) & 0xF0); } else { return 0; } } //------------------------resetBoc----------------------------- /*! Reset the BOC by writing 0xFF followed by 0 to the BOC Reset * register. A method to write a specific value to this register * is not provided, as it doesn't seem to be necessary. However, * for series BOCs, the resetting of BPM, Rx, Tx are bits on this * register, and so there are methods to reset these individually. */ void BocCard::resetBoc() { // singleWrite(BOC_RESET,0xFF); singleWrite(BOC_RESET,0); } //------------------------getBpmReset------------------------- /*! Read the BPM Reset register. For series BOCs, this is the * BOC_BPM_RESET_BIT on the BOC_RESET register. */ UINT32 BocCard::getBpmReset() { // if(m_bocType == PRE_PRODUCTION_BOC) { // Pre-production BOCs return (singleRead(BOC_BPM_RESET) & 0x1); } else if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { //Series BOCs return ((singleRead(BOC_RESET)>>BOC_BPM_RESET_BIT)&0x1); } else { return 0; } } //------------------------resetBpm----------------------------- /*! Reset the BPMs by writing 1 followed by 0 to the BPM Reset * register. A method to write a specific value to this register * is not provided, as it doesn't seem to be necessary. * For pre-production BOCs, this is a separate register. For * series BOCs, this is bit BOC_BPM_RESET_BIT on BOC_RESET. */ void BocCard::resetBpm() { // if(m_bocType == PRE_PRODUCTION_BOC) { // Pre-production BOCs singleWrite(BOC_BPM_RESET,1); singleWrite(BOC_BPM_RESET,0); } else if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { //Series BOCs singleWrite(BOC_RESET,1<>BOC_VPIN_RESET_BIT)&0x1); } else { return 0; } } //------------------------resetVpin---------------------------- /*! Reset the Vpin overcurrent trip by writing 1 followed by 0 to the Vpin * reset bit on BOC_RESET register. This function is only available * on series BOCs. It is necessary to have the "1" asserted for a length * of time, so sleep between the writes. */ void BocCard::resetVpin() { // if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { //Series BOCs singleWrite(BOC_RESET,1<sleep(1); // singleWrite(BOC_RESET,0); } // For other types, do nothing. } //------------------------getBocOkReset------------------------- /*! Read the BOC_OK Reset register. For series BOCs, this is * the BOC_OK_RESET_BIT on the BOC_RESET register. For pre-production * BOCs, it doesn't exist! */ UINT32 BocCard::getBocOkReset() { // if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { //Series BOCs return ((singleRead(BOC_RESET)>>BOC_OK_RESET_BIT)&0x1); } else { return 0; } } //------------------------resetBocOk---------------------------- /*! Reset the BOC_OK bit by writing 1 followed by 0 to the BOC_OK * reset bit on BOC_RESET register. This function is only available * on series BOCs. */ void BocCard::resetBocOk() { // if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { //Series BOCs singleWrite(BOC_RESET,1< BOC_MONITOR_CHANNELS) { throw BocException("BOC Monitor Adc, channel >", BOC_MONITOR_CHANNELS, channel); } units = getMonitorAdcUnits(channel); type = getMonitorAdcType(channel); // // Use the alternative method to do the work. // return getMonitorAdc(channel); } double BocCard::getMonitorAdc(const UINT32 channel) throw (BocException&) { // UINT32 lsbMask; UINT32 msbMask; double adcValue; double logRTherm; // // Check if channel number valid. // if (channel > BOC_MONITOR_CHANNELS) { throw BocException("BOC Monitor Adc, channel >", BOC_MONITOR_CHANNELS, channel); } // //Only do this with production BOC. // if((m_bocType == PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { singleWrite(BOC_ADC_CONFIG, channel); //set channel to convert singleWrite(BOC_ADC_CONVERT, 0); //convert - data irrelevant // //10-bit or 12-bit ADC is in two registers // lsbMask = m_bocMask; msbMask = (1< BOC_MONITOR_CHANNELS) { throw BocException("BOC Monitor Adc Type, channel >", BOC_MONITOR_CHANNELS, channel); } // // Return the type in a string // if (MONITOR_CHANNEL_TYPE[channel] == MONITOR_CURRENT) { return "PIN Current"; } else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_VOLTAGE) { return "PIN Voltage"; } else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_TEMP) { return "Temperature"; } else { return ""; } // } //------------------------getMonitorAdcUnits------------------ /*! Get the units for the channel we are monitoring */ std::string BocCard::getMonitorAdcUnits(const UINT32 channel) throw (BocException&) { // // Check if channel number valid. // if (channel > BOC_MONITOR_CHANNELS) { throw BocException("BOC Monitor Adc Units, channel >", BOC_MONITOR_CHANNELS, channel); } // // Return the units in a string // if (MONITOR_CHANNEL_TYPE[channel] == MONITOR_CURRENT) { return "mA"; } else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_VOLTAGE) { return "Volts"; } else if(MONITOR_CHANNEL_TYPE[channel] == MONITOR_TEMP) { return "Celcius"; } else { return ""; } } //------------------------resetMonitorAdc--------------------- /*! Reset the monitoring ADC chip. */ void BocCard::resetMonitorAdc() { // // Only do this if production BOC // if((m_bocType==PRODUCTION_REVA_BOC)|| (m_bocType == PRODUCTION_REVB_BOC)||(m_bocType == PRODUCTION_REVC_BOC)) { singleWrite(BOC_ADC_SETUP,0); //data is irrelevant } } //------------------------getInterlockStatus---------------- /*! Read the BOC Status Register and extract the status of the laser * interlocks. Return value = 1 for all interlocks OK, 0 if there * is an interlock of some sort. The two arguments return the local * and remote interlock enable statuses. * Note that for pre-production boards, SW4 is the physical switch, * which may be removed and replaced by a short for sites that don't * need its protection. The switch is checked, as it is part of * the interlock mechanism on these boards, but its status is not * returned by this method for reasons of forward compatibility. */ UINT32 BocCard::getInterlockStatus(UINT32 *localEnable, UINT32 *remoteEnable) { // // // For pre-production BOC, check bits 2, 6 and 7 // if(m_bocType==PRE_PRODUCTION_BOC) { *localEnable = (getBocStatusRegister()&(1<getMdspMap(); ce0Base = myMdspMap->rodRegisterBase(); bocAddressBase = ce0Base + 0x8000; bocAddress = address + bocAddressBase; value = m_myrod->mdspSingleRead(bocAddress); // //Check if the BOC is busy and wait until it isn't (with a 1 second //timeout). // start = clock(); rrifStatus1Address = ce0Base + + 0x4420; while(m_myrod->mdspSingleRead(rrifStatus1Address)&BOC_BUSY_0) { if(clock() - start > (clock_t)CLOCKS_PER_SEC) { throw BocException("single read - BOC_BUSY_0 not cleared after 1 second"); } } // return value; } //------------------------singleWrite----------------------------- /*! This method writes a single 32-bit word to a BOC address. An exception * will be thrown if the BOC_BUSY_0 bit does not clear within 1 second. */ void BocCard::singleWrite(const UINT32 address, const UINT32 value) throw (BocException&) { // UINT32 bocAddress, bocAddressBase, ce0Base, rrifStatus1Address; clock_t start; MdspMemoryMap* myMdspMap; // myMdspMap = m_myrod->getMdspMap(); ce0Base = myMdspMap->rodRegisterBase(); bocAddressBase = ce0Base + 0x8000; bocAddress = address + bocAddressBase; m_myrod->mdspSingleWrite(bocAddress, value); // //Check if the BOC is busy and wait until it isn't - there is a timeout of //1 second for this happening. // start = clock(); rrifStatus1Address = ce0Base + 0x4420; while(m_myrod->mdspSingleRead(rrifStatus1Address)&BOC_BUSY_0) { if((clock() - start) > (clock_t)CLOCKS_PER_SEC) { throw BocException("single write, BOC_BUSY_0 not cleared after 1 second"); } } // } //------------------------blockRead----------------------------- /*! This method reads a block of 32-bit words from a BOC. Because * the setup bus is slow, we have to wait after each read until * the BOC_BUSY_0 bit is cleared. Hence we use the singleRead * method in a loop. */ void BocCard::blockRead(const UINT32 address, UINT32 buffer[], const INT32 wordCount) { // // for(int i=0;i