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

TimModule.cxx

Go to the documentation of this file.
00001 //File: TimModule.cxx
00002 
00038 #include <ctime>     // for clock only
00039 #include <iostream>  // for debug only
00040 
00041 using namespace std;
00042 
00043 #include "TimModule.h"
00044 
00045 #ifdef    RCDAQ
00046 #include "TIMModule/TIMException.h"
00047 #endif // RCDAQ
00048 
00049 // Namespace for the common routines for SCT and PIXEL ROD software.
00050 
00051 namespace SctPixelRod {
00052 
00053 // ************************* Class TimException ******************************
00054 
00056 
00057 TimException::TimException( std::string descriptor, int data1, int data2 ) :
00058              BaseException( descriptor ) {
00059 
00060   m_data1 = data1;
00061   m_data2 = data2;
00062   setType( TIM );
00063 
00064 #ifdef    RCDAQ
00065   throw   TIMException (TIMException::TIMBusError);
00066 #endif // RCDAQ
00067 }
00068 
00069 void TimException::what( std::ostream& os ) {
00070 
00071   os << "TimException: " << getDescriptor() << endl;
00072   os << "Data1: " << getData1() << endl;
00073   os << "Data2: " << getData2() << endl;
00074 }
00075 
00076 // ************************* Class TimModule *********************************
00077 
00078 // Constructors, destructor, and assignment
00079 
00080 // ------------------------- Constructor -------------------------------------
00081 
00083 
00087 TimModule::TimModule( UINT32 baseAddr, UINT32 mapSize, VmeInterface & vme ) :
00088        VmeModule( baseAddr, mapSize, vme ) {
00089 
00090   m_serialNumber = 0xFFFFFFFF;  // Set in initialize
00091 
00092   if (&vme == 0) throw TimException( "TimModule has no VmeInterface", 0, 0 );
00093 
00094   try {
00095     m_vmePort = new VmePort( baseAddr, mapSize, VmeInterface::A32, vme );
00096 
00097     m_vmePort->setExceptionTrapping( true );
00098   }
00099   catch (bad_alloc) {
00100     throw TimException( "TimModule caught bad_alloc", 0, 0 );
00101   }
00102   catch (VmeException x) {
00103     throw TimException( "TimModule caught VmeException",
00104                         x.getErrorClass(), x.getErrorCode() );
00105   }
00106 }
00107 
00108 // ------------------------- Destructor --------------------------------------
00109 
00113 TimModule::~TimModule() {
00114 
00115   delete m_vmePort;
00116   m_vmePort = 0;
00117 }
00118 
00119 // ---------------------------------------------------------------------------
00120 
00121 // Member methods
00122 
00123 // ------------------------- initialize --------------------------------------
00124 
00128 void TimModule::initialize() {
00129 
00130 
00131   regLoad( TIM_REG_TRIGGER_BCID, TIM_BCID_OFFSET << 12 );  // set BCID offset
00132   regLoad( TIM_REG_ROD_MASK, 0xFFFF );                    // enable all slots
00133   fetchTimID();                                          // read serial number
00134 
00135 // Disable fixed frequency veto on TIM 3C (JCH)
00136   if(m_serialNumber>=0x26) { 
00137     loadBitSet(TIM_REG_DEBUG_CTL,TIM_BIT_DEBUGCTL_FVDISABLE);
00138   }
00139 
00140   loadFrequencyTrig( 10. ); // kHz
00141   loadFrequencyFECR( 0.1 ); //  Hz
00142 
00143   setupVME();
00144 }
00145 
00146 // ------------------------- reset -------------------------------------------
00147 
00153 void TimModule::reset() throw (TimException &) {
00154 
00155   regLoad( TIM_REG_COMMAND, TIM_BIT_VRESET );
00156   int timeLeft = regTimeout( TIM_REG_COMMAND, TIM_BIT_VRESET, 0, 100 );
00157   if (timeLeft < 1) throw TimException( "TimModule reset bit timeout", 0, 0 );
00158 
00159 //For TIM 3C, should check that the PLL is stable also. Before doing so,
00160 //sxet the CSBDISABLE bit.
00161 
00162   fetchTimID();
00163   if(m_serialNumber>=0x26) {    //Select TIM 3C
00164     loadBitSet(TIM_REG_DEBUG_CTL,TIM_BIT_DEBUGCTL_CSBDISABLE);
00165 //
00166     int timeLeft = regTimeout(TIM_REG_STATUS3,TIM_BIT_STATUS3_PLLSTABLE,TIM_BIT_STATUS3_PLLSTABLE,1000);
00167     if (timeLeft < 1) throw TimException( "TimModule PLL stable bit timeout", 0, 0 );
00168   }
00169 
00170 }
00171 
00172 // ------------------------- status ------------------------------------------
00173 
00178 void TimModule::status() {
00179 
00180   statusPrint( cout );
00181 }
00182 
00183 // ------------------------- fetchL1ID ---------------------------------------
00187 UINT32 TimModule::fetchL1ID() {
00188 
00189   const UINT32 lo = regFetch( TIM_REG_TRIGGER_IDLO );
00190   const UINT32 hi = regFetch( TIM_REG_TRIGGER_IDHI );
00191   UINT32 l1id;
00192 
00193   if (m_firmware < 9) l1id = (lo & 0x0FFF) + ((hi & 0x0FFF) << 12);
00194   else                l1id = (lo & 0xFFFF) + ((hi & 0x00FF) << 16);
00195   return l1id;
00196 }
00197 
00198 // ------------------------- fetchTimID --------------------------------------
00199 
00203 UINT16 TimModule::fetchTimID() {
00204 
00205   const UINT16 timID = regFetch( TIM_REG_TIM_ID );
00206 
00207   m_serialNumber = timID & 0xFF;
00208   m_firmware     = timID >> 8;
00209 
00210   if (m_serialNumber == 0    || m_firmware == 0 ||
00211       m_serialNumber == 0xFF || m_firmware == 0xFF)
00212       throw TimException( "TimModule finds illegal TIM ID register",
00213                           m_serialNumber, m_firmware );
00214 
00215   if (m_serialNumber >= 0x20) m_firmware += 0xF00; // FPGA
00216 
00217   return timID;
00218 }
00219 
00220 // ------------------------- intTrigStart ------------------------------------
00221 
00225 void TimModule::intTrigStart( const double frequency ) {
00226 
00227   loadFrequencyTrig( frequency );
00228   loadBitSet( TIM_REG_ENABLES, TIM_BIT_EN_INT_TRIG );
00229 }
00230 
00231 // ------------------------- intTrigStart ------------------------------------
00232 
00236 void TimModule::intTrigStart( const TimMaskFrequency frequency ) {
00237 
00238   loadByteLo( TIM_REG_FREQUENCY, frequency );
00239   loadBitSet( TIM_REG_ENABLES, TIM_BIT_EN_INT_TRIG );
00240 }
00241 
00242 // ------------------------- intTrigStop -------------------------------------
00243 
00247 void TimModule::intTrigStop(void) { //*** void
00248 
00249   loadBitClear( TIM_REG_ENABLES, TIM_BIT_EN_INT_TRIG );
00250 }
00251 
00252 // ------------------------- issueCommand ------------------------------------
00253 
00257 void TimModule::issueCommand( const TimBitCommand mask ) {
00258 
00259   if (mask <= TIM_VSPA) loadBitClear( TIM_REG_COMMAND, mask );
00260   loadBitSet( TIM_REG_COMMAND, mask );
00261   if (mask <= TIM_VSPA) loadBitClear( TIM_REG_COMMAND, mask );
00262 }
00263 
00264 // ------------------------- issueVCAL ---------------------------------------
00265 
00270 void TimModule::issueVCAL( const UINT8 pipelineDelay ) {
00271 
00272   loadByteLo(   TIM_REG_DELAY, pipelineDelay );
00273   issueCommand( TIM_VCAL );
00274 }
00275 
00276 // ------------------------- loadBitSet --------------------------------------
00277 
00282 void TimModule::loadBitSet( const TimRegister addr, const UINT16 mask ) {
00283 
00284   UINT16 value = vmeFetch( addr );
00285   vmeLoad( addr, value | mask );
00286 }
00287 
00288 // ------------------------- loadBitClear ------------------------------------
00289 
00294 void TimModule::loadBitClear( const TimRegister addr, const UINT16 mask ) {
00295 
00296   UINT16 value = vmeFetch( addr );
00297   vmeLoad( addr, value & ~mask );
00298 }
00299 
00300 // ------------------------- loadByteHi --------------------------------------
00301 
00306 void TimModule::loadByteHi( const TimRegister addr, const UINT8 byte ) {
00307 
00308   UINT16 value = vmeFetch( addr );
00309   vmeLoad( addr, (value & 0x00FF) | (byte << 8) );
00310 }
00311 
00312 // ------------------------- loadByteLo --------------------------------------
00313 
00318 void TimModule::loadByteLo( const TimRegister addr, const UINT8 byte ) {
00319 
00320   UINT16 value = vmeFetch( addr );
00321   vmeLoad( addr, (value & 0xFF00) | byte );
00322 }
00323 
00324 // ------------------------- loadFrequencyFECR -------------------------------
00325 
00329 void TimModule::loadFrequencyFECR( const double frequency ) {
00330 
00331   const int freq = int (frequency * 1000.); // mHz
00332 
00333   int pattern = TIM_MASK_FECR_0_100HZ; // default
00334   int chooser = 0;
00335 
00336   for (int i = 0; i < TIM_FREQ_SIZE; i++) {
00337     if (TIM_FECR_FREQUENCY[i][1] <= freq &&
00338         TIM_FECR_FREQUENCY[i][1] > chooser) {
00339       chooser = TIM_FECR_FREQUENCY[i][1];
00340       pattern = TIM_FECR_FREQUENCY[i][0];
00341     }
00342   }
00343 
00344   loadByteHi( TIM_REG_FREQUENCY, pattern );
00345 }
00346 
00347 // ------------------------- loadFrequencyTrig -------------------------------
00348 
00352 void TimModule::loadFrequencyTrig( const double frequency ) {
00353 
00354   const int freq = int (frequency * 1000.); // Hz
00355 
00356   int pattern = TIM_MASK_TRIG_10_0KHZ; // default
00357   int chooser = 0;
00358 
00359   for (int i = 0; i < TIM_FREQ_SIZE; i++) {
00360     if (TIM_TRIG_FREQUENCY[i][1] <= freq &&
00361         TIM_TRIG_FREQUENCY[i][1] > chooser) {
00362       chooser = TIM_TRIG_FREQUENCY[i][1];
00363       pattern = TIM_TRIG_FREQUENCY[i][0];
00364     }
00365   }
00366 
00367   loadByteLo( TIM_REG_FREQUENCY, pattern );
00368 }
00369 
00370 // ------------------------- msleep ------------------------------------------
00371 
00375 void TimModule::msleep( const double milliSecs ) {
00376 
00377   clock_t delay = clock_t( milliSecs * CLOCKS_PER_SEC / 1000. );
00378   clock_t start = clock();
00379 
00380   while (clock() - start < delay)
00381       ;
00382 }
00383 
00384 // ------------------------- regFetch ----------------------------------------
00385 
00389 UINT16 TimModule::regFetch( const TimRegister addr ) {
00390 
00391   UINT16 data = vmeFetch( addr );
00392   return data;
00393 }
00394 
00395 // ------------------------- regLoad -----------------------------------------
00396 
00400 void TimModule::regLoad( const TimRegister addr, const UINT16 data ) {
00401 
00402   vmeLoad( addr, data );
00403 }
00404 
00405 // ------------------------- regTimeout --------------------------------------
00406 
00410 int TimModule::regTimeout( const TimRegister addr, const int mask1,
00411                            const int mask2, const int timeout ) {
00412 
00413   int timeLeft = timeout;
00414 
00415   while (timeLeft > 0 && (regFetch( addr ) & mask1) != mask2) {
00416     timeLeft --;
00417     msleep( 1.);
00418   }
00419   return timeLeft;
00420 }
00421 
00422 // ------------------------- seqRun ------------------------------------------
00423 
00427 void TimModule::seqRun( const UINT16 size ) {
00428 
00429   regLoad( TIM_REG_SEQ_END,     size - 1 );
00430   regLoad( TIM_REG_SEQ_CONTROL, TIM_BIT_SEQ_RESET );
00431   regLoad( TIM_REG_SEQ_CONTROL, 0 );
00432   regLoad( TIM_REG_SEQ_CONTROL, TIM_BIT_SEQ_GO | TIM_BIT_SEQ_EN_ALL );
00433   // all outputs enabled
00434 }
00435 
00436 // ------------------------- seqFetch ----------------------------------------
00437 
00441 void TimModule::seqFetch( const UINT16 size, UINT16 buffer[] ) {
00442 
00443   for (int i = 0; i < size; i++) {
00444     buffer[i] = vmeFetch( TIM_SEQ_ADDR + i*2 );
00445   }
00446 }
00447 
00448 // ------------------------- seqLoad -----------------------------------------
00449 
00453 void TimModule::seqLoad( const UINT16 size, const UINT16 buffer[] ) {
00454 
00455   UINT16 data;
00456   for (int i = 0; i < size; i++) {
00457     data = buffer[i];
00458     vmeLoad( TIM_SEQ_ADDR + i*2, data );
00459   }
00460 }
00461 
00462 // ------------------------- setupTTC ----------------------------------------
00463 
00467 void TimModule::setupTTC() {
00468 
00469   // enable serial output streams and TTC signals
00470   regLoad( TIM_REG_RUN_ENABLES, TIM_BIT_EN_ID | TIM_BIT_EN_TYPE | 0xFF );
00471   regLoad( TIM_REG_COMMAND, TIM_BIT_EN_TTC );       // set Run mode
00472   regLoad( TIM_REG_ENABLES, 0 );                    // ensure no signals
00473 
00474   int timeLeft = regTimeout( TIM_REG_TTC_STATUS, TIM_BIT_TTC_READY,
00475                                                  TIM_BIT_TTC_READY, 1000 );
00476   if (timeLeft < 1) throw TimException( "TimModule TTC Ready timeout", 0, 0 );
00477 }
00478 
00479 // ------------------------- setupVME ----------------------------------------
00480 
00484 void TimModule::setupVME() {
00485 
00486   // enable serial output streams
00487   regLoad( TIM_REG_RUN_ENABLES, TIM_BIT_EN_ID | TIM_BIT_EN_TYPE );
00488   regLoad( TIM_REG_COMMAND, 0 );                    // ensure stand-alone mode
00489   regLoad( TIM_REG_ENABLES, 0 );                    // ensure no signals
00490 }
00491 
00492 // ------------------------- statusPrint -------------------------------------
00493 
00497 void TimModule::statusPrint( ostream& os ) {
00498 
00499   os << "TIM status" << endl;
00500 
00501   os << " Serial Number: " << m_serialNumber;
00502   os << " Version: "       << m_firmware;
00503   os << endl;
00504   hex(os);
00505   os << " L1ID: "   << fetchL1ID();
00506   os << " BCID: "   << regFetch( TIM_REG_TRIGGER_BCID );
00507   os << " status: " << regFetch( TIM_REG_STATUS );
00508   os << endl;
00509   dec(os);
00510 }
00511 
00512 // ------------------------- vmeFetch ----------------------------------------
00513 
00517 UINT16 TimModule::vmeFetch( const UINT32 addr )
00518           throw (VmeException &) {
00519 
00520   UINT16 data = 0;
00521   bool trying = true;
00522   bool error = false;
00523 
00524   while (trying) {
00525     try {
00526       data = m_vmePort->read16( addr );
00527       trying = false;
00528     }
00529     catch (VmeException & vmeFailed) {
00530       if (error) throw vmeFailed;
00531       error = true;
00532     }
00533   }
00534   if (error) cerr << "TimModule::vmeFetch recovers from VmeException" << endl;
00535   return data;
00536 }
00537 
00538 // ------------------------- vmeLoad -----------------------------------------
00539 
00543 void TimModule::vmeLoad( const UINT32 addr, const UINT16 data )
00544         throw (VmeException & ) {
00545 
00546   bool trying = true;
00547   bool error = false;
00548 
00549   while (trying) {
00550     try {
00551       m_vmePort->write16( addr, data );
00552 //debug  throw VmeException(VmeException::BUS_ERROR, 1, m_vmePort);
00553       trying = false;
00554     }
00555     catch (VmeException & vmeFailed) {
00556       if (error) throw vmeFailed;
00557       error = true;
00558     }
00559   }
00560   if (error) cerr << "TimModule::vmeLoad recovers from VmeException" << endl;
00561 }
00562 
00563 } // End namespace SctPixelRod
00564 
00565 // ------------------------- Overload operator<< -----------------------------
00566 
00571 using namespace SctPixelRod;
00572 
00573 namespace std {
00574 
00575 ostream& operator<<( ostream& os, TimModule& tim ) {
00576 
00577   tim.statusPrint( os );
00578 
00579   return os;
00580 }
00581 
00582 } // End namespace std

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