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

TimModule.cxx

Go to the documentation of this file.
00001 //File: TimModule.cxx
00002 
00053 #include <ctime>     // for clock only
00054 #include <iostream>  // for debug only
00055 
00056 using namespace std;
00057 
00058 #include "TimModule.h"
00059 
00060 #ifdef    RCDAQ
00061 #include "TIMModule/TIMException.h"
00062 #endif // RCDAQ
00063 
00064 // Namespace for the common routines for SCT and PIXEL ROD software.
00065 
00066 namespace SctPixelRod {
00067 
00068 // ************************* Class TimException ******************************
00069 
00071 
00072 TimException::TimException( std::string descriptor, int data1, int data2 ) :
00073              BaseException( descriptor ) {
00074 
00075   m_data1 = data1;
00076   m_data2 = data2;
00077   setType( TIM );
00078 
00079 #ifdef    RCDAQ
00080   throw   TIMException (TIMException::TIMBusError);
00081 #endif // RCDAQ
00082 }
00083 
00084 void TimException::what( std::ostream& os ) {
00085 
00086   os << "TimException: " << getDescriptor() << endl;
00087   os << "Data1: " << getData1() << endl;
00088   os << "Data2: " << getData2() << endl;
00089 }
00090 
00091 // ************************* Class TimModule *********************************
00092 
00093 // Constructors, destructor, and assignment
00094 
00095 // ------------------------- Constructor -------------------------------------
00096 
00098 
00102 TimModule::TimModule( UINT32 baseAddr, UINT32 mapSize, VmeInterface & vme ) :
00103        VmeModule( baseAddr, mapSize, vme ) {
00104 
00105   m_serialNumber = 0xFFFFFFFF;  // Set in initialize
00106 
00107   if (&vme == 0) throw TimException( "TimModule has no VmeInterface", 0, 0 );
00108 
00109   try {
00110     m_vmePort = new VmePort( baseAddr, mapSize, VmeInterface::A32, vme );
00111 
00112     m_vmePort->setExceptionTrapping( true );
00113   }
00114   catch (bad_alloc) {
00115     throw TimException( "TimModule caught bad_alloc", 0, 0 );
00116   }
00117   catch (VmeException x) {
00118     throw TimException( "TimModule caught VmeException",
00119                         x.getErrorClass(), x.getErrorCode() );
00120   }
00121 }
00122 
00123 // ------------------------- Destructor --------------------------------------
00124 
00128 TimModule::~TimModule() {
00129 
00130   delete m_vmePort;
00131   m_vmePort = 0;
00132 }
00133 
00134 // ---------------------------------------------------------------------------
00135 
00136 // Member methods
00137 
00138 // ------------------------- initialize --------------------------------------
00139 
00143 void TimModule::initialize() {
00144 
00145 
00146   regLoad( TIM_REG_BCID, TIM_BCID_OFFSET << 12 );  // set BCID offset
00147   regLoad( TIM_REG_RB_MASK, 0xFFFF );                    // enable all slots
00148   fetchTimID();                                          // read serial number
00149 
00150 // Don't disable fixed frequency veto on TIM 3C - remove code which
00151 // was here (JCH)
00152 
00153   loadFrequencyTrig( 10. ); // kHz
00154   loadFrequencyFECR( 0.1 ); //  Hz
00155 
00156   setupVME();
00157 }
00158 
00159 // ------------------------- reset -------------------------------------------
00160 
00166 void TimModule::reset() throw (TimException &) {
00167 
00168   regLoad( TIM_REG_COMMAND, TIM_BIT_VRESET );
00169   int timeLeft = regTimeout( TIM_REG_COMMAND, TIM_BIT_VRESET, 0, 100 );
00170   if (timeLeft < 1) throw TimException( "TimModule reset bit timeout", 0, 0 );
00171 
00172 //For TIM 3C, should check that the PLL is stable also. Before doing so,
00173 //set the CSBDISABLE bit.
00174 
00175   fetchTimID();
00176   if(m_serialNumber>=0x26) {    //Select TIM 3C
00177     loadBitSet(TIM_REG_DEBUG_CTL,TIM_BIT_DEBUGCTL_CSBDISABLE);
00178 //
00179     int timeLeft = regTimeout(TIM_REG_STATUS3,TIM_BIT_STATUS3_PLLSTABLE,TIM_BIT_STATUS3_PLLSTABLE,1000);
00180     if (timeLeft < 1) throw TimException( "TimModule PLL stable bit timeout", 0, 0 );
00181   }
00182 
00183 }
00184 
00185 // ------------------------- status ------------------------------------------
00186 
00191 void TimModule::status() {
00192 
00193   statusPrint( cout );
00194 }
00195 
00196 // ------------------------- fetchL1ID ---------------------------------------
00200 UINT32 TimModule::fetchL1ID() {
00201 
00202   const UINT32 lo = regFetch( TIM_REG_L1IDL );
00203   const UINT32 hi = regFetch( TIM_REG_L1IDH );
00204   UINT32 l1id;
00205 
00206   if (m_firmware < 9) l1id = (lo & 0x0FFF) + ((hi & 0x0FFF) << 12);
00207   else                l1id = (lo & 0xFFFF) + ((hi & 0x00FF) << 16);
00208   return l1id;
00209 }
00210 
00211 // ------------------------- fetchTimID --------------------------------------
00212 
00216 UINT16 TimModule::fetchTimID() {
00217 
00218   const UINT16 timID = regFetch( TIM_REG_TIM_ID );
00219 
00220   m_serialNumber = timID & 0xFF;
00221   m_firmware     = timID >> 8;
00222 
00223   if (m_serialNumber == 0    || m_firmware == 0 ||
00224       m_serialNumber == 0xFF || m_firmware == 0xFF)
00225       throw TimException( "TimModule finds illegal TIM ID register",
00226                           m_serialNumber, m_firmware );
00227 
00228   if (m_serialNumber >= 0x20) m_firmware += 0xF00; // FPGA
00229 
00230   return timID;
00231 }
00232 
00233 // ------------------------- intTrigStart ------------------------------------
00234 
00238 void TimModule::intTrigStart( const double frequency ) {
00239 
00240   loadFrequencyTrig( frequency );
00241   loadBitSet( TIM_REG_ENABLES, TIM_BIT_EN_INT_TRIG );
00242 }
00243 
00244 // ------------------------- intTrigStart ------------------------------------
00245 
00249 void TimModule::intTrigStart( const TimMaskFrequency frequency ) {
00250 
00251   loadByteLo( TIM_REG_FREQUENCY, frequency );
00252   loadBitSet( TIM_REG_ENABLES, TIM_BIT_EN_INT_TRIG );
00253 }
00254 
00255 // ------------------------- intTrigStop -------------------------------------
00256 
00260 void TimModule::intTrigStop(void) { //*** void
00261 
00262   loadBitClear( TIM_REG_ENABLES, TIM_BIT_EN_INT_TRIG );
00263 }
00264 
00265 // ------------------------- issueCommand ------------------------------------
00266 
00270 void TimModule::issueCommand( const TimBitCommand mask ) {
00271 
00272   if (mask <= TIM_VSPA) loadBitClear( TIM_REG_COMMAND, mask );
00273   loadBitSet( TIM_REG_COMMAND, mask );
00274   if (mask <= TIM_VSPA) loadBitClear( TIM_REG_COMMAND, mask );
00275 }
00276 
00277 // ------------------------- issueVCAL ---------------------------------------
00278 
00283 void TimModule::issueVCAL( const UINT8 pipelineDelay ) {
00284 
00285   loadByteLo(   TIM_REG_DELAYS, pipelineDelay );
00286   issueCommand( TIM_VCAL );
00287 }
00288 
00289 // ------------------------- loadBitSet --------------------------------------
00290 
00295 void TimModule::loadBitSet( const TimRegister addr, const UINT16 mask ) {
00296 
00297   UINT16 value = vmeFetch( addr );
00298   vmeLoad( addr, value | mask );
00299 }
00300 
00301 // ------------------------- loadBitClear ------------------------------------
00302 
00307 void TimModule::loadBitClear( const TimRegister addr, const UINT16 mask ) {
00308 
00309   UINT16 value = vmeFetch( addr );
00310   vmeLoad( addr, value & ~mask );
00311 }
00312 
00313 // ------------------------- loadByteHi --------------------------------------
00314 
00319 void TimModule::loadByteHi( const TimRegister addr, const UINT8 byte ) {
00320 
00321   UINT16 value = vmeFetch( addr );
00322   vmeLoad( addr, (value & 0x00FF) | (byte << 8) );
00323 }
00324 
00325 // ------------------------- loadByteLo --------------------------------------
00326 
00331 void TimModule::loadByteLo( const TimRegister addr, const UINT8 byte ) {
00332 
00333   UINT16 value = vmeFetch( addr );
00334   vmeLoad( addr, (value & 0xFF00) | byte );
00335 }
00336 
00337 // ------------------------- loadFrequencyFECR -------------------------------
00338 
00342 void TimModule::loadFrequencyFECR( const double frequency ) {
00343 
00344   const int freq = int (frequency * 1000.); // mHz
00345 
00346   int pattern = TIM_MASK_FECR_0_100HZ; // default
00347   int chooser = 0;
00348 
00349   for (int i = 0; i < TIM_FREQ_SIZE; i++) {
00350     if (TIM_FECR_FREQUENCY[i][1] <= freq &&
00351         TIM_FECR_FREQUENCY[i][1] > chooser) {
00352       chooser = TIM_FECR_FREQUENCY[i][1];
00353       pattern = TIM_FECR_FREQUENCY[i][0];
00354     }
00355   }
00356 
00357   loadByteHi( TIM_REG_FREQUENCY, pattern >> 8 );
00358 }
00359 
00360 // ------------------------- loadFrequencyTrig -------------------------------
00361 
00365 void TimModule::loadFrequencyTrig( const double frequency ) {
00366 
00367   const int freq = int (frequency * 1000.); // Hz
00368 
00369   int pattern = TIM_MASK_TRIG_10_0KHZ; // default
00370   int chooser = 0;
00371 
00372   for (int i = 0; i < TIM_FREQ_SIZE; i++) {
00373     if (TIM_TRIG_FREQUENCY[i][1] <= freq &&
00374         TIM_TRIG_FREQUENCY[i][1] > chooser) {
00375       chooser = TIM_TRIG_FREQUENCY[i][1];
00376       pattern = TIM_TRIG_FREQUENCY[i][0];
00377     }
00378   }
00379 
00380   loadByteLo( TIM_REG_FREQUENCY, pattern );
00381 }
00382 
00383 // ------------------------- msleep ------------------------------------------
00384 
00388 void TimModule::msleep( const double milliSecs ) {
00389 
00390   clock_t delay = clock_t( milliSecs * CLOCKS_PER_SEC / 1000. );
00391   clock_t start = clock();
00392 
00393   while (clock() - start < delay)
00394       ;
00395 }
00396 
00397 // ------------------------- regFetch ----------------------------------------
00398 
00402 UINT16 TimModule::regFetch( const TimRegister addr ) {
00403 
00404   UINT16 data = vmeFetch( addr );
00405   return data;
00406 }
00407 
00408 // ------------------------- regLoad -----------------------------------------
00409 
00413 void TimModule::regLoad( const TimRegister addr, const UINT16 data ) {
00414 
00415   vmeLoad( addr, data );
00416 }
00417 
00418 // ------------------------- regTimeout --------------------------------------
00419 
00423 int TimModule::regTimeout( const TimRegister addr, const int mask1,
00424                            const int mask2, const int timeout ) {
00425 
00426   int timeLeft = timeout;
00427 
00428   while (timeLeft > 0 && (regFetch( addr ) & mask1) != mask2) {
00429     timeLeft --;
00430     msleep( 1.);
00431   }
00432   return timeLeft;
00433 }
00434 
00435 // ------------------------- seqRun ------------------------------------------
00436 
00440 void TimModule::seqRun( const UINT16 size ) {
00441 
00442   regLoad( TIM_REG_SEQ_END,     size - 1 );
00443   regLoad( TIM_REG_SEQ_CTL, TIM_BIT_SEQ_RESET );
00444   regLoad( TIM_REG_SEQ_CTL, 0 );
00445   regLoad( TIM_REG_SEQ_CTL, TIM_BIT_SEQ_GO | TIM_BIT_SEQ_EN_ALL );
00446   // all outputs enabled
00447 }
00448 
00449 // ------------------------- seqFetch ----------------------------------------
00450 
00454 void TimModule::seqFetch( const UINT16 size, UINT16 buffer[] ) {
00455 
00456   for (int i = 0; i < size; i++) {
00457     buffer[i] = vmeFetch( TIM_SEQ_ADDR + i*2 );
00458   }
00459 }
00460 
00461 // ------------------------- seqLoad -----------------------------------------
00462 
00466 void TimModule::seqLoad( const UINT16 size, const UINT16 buffer[] ) {
00467 
00468   UINT16 data;
00469   for (int i = 0; i < size; i++) {
00470     data = buffer[i];
00471     vmeLoad( TIM_SEQ_ADDR + i*2, data );
00472   }
00473 }
00474 
00475 // ------------------------- setupTTC ----------------------------------------
00476 
00480 void TimModule::setupTTC() {
00481 
00482   // enable serial output streams and TTC signals
00483   regLoad( TIM_REG_RUN_ENABLE, TIM_BIT_EN_ID | TIM_BIT_EN_TYPE | 0xFF );
00484   regLoad( TIM_REG_COMMAND, TIM_BIT_EN_TTC );       // set Run mode
00485   regLoad( TIM_REG_ENABLES, 0 );                    // ensure no signals
00486 
00487   int timeLeft = regTimeout( TIM_REG_TTC_STATUS, TIM_BIT_TTC_READY,
00488                                                  TIM_BIT_TTC_READY, 1000 );
00489   if (timeLeft < 1) throw TimException( "TimModule TTC Ready timeout", 0, 0 );
00490 }
00491 
00492 // ------------------------- setupVME ----------------------------------------
00493 
00497 void TimModule::setupVME() {
00498 
00499   // enable serial output streams
00500   regLoad( TIM_REG_RUN_ENABLE, TIM_BIT_EN_ID | TIM_BIT_EN_TYPE );
00501   regLoad( TIM_REG_COMMAND, 0 );                    // ensure stand-alone mode
00502   regLoad( TIM_REG_ENABLES, 0 );                    // ensure no signals
00503 }
00504 
00505 // ------------------------- statusPrint -------------------------------------
00506 
00510 void TimModule::statusPrint( ostream& os ) {
00511 
00512   os << "TIM status" << endl;
00513 
00514   os << " Serial Number: " << m_serialNumber;
00515   os << " Version: "       << m_firmware;
00516   os << endl;
00517   hex(os);
00518   os << " L1ID: "   << fetchL1ID();
00519   os << " BCID: "   << regFetch( TIM_REG_BCID );
00520   os << " status: " << regFetch( TIM_REG_STATUS );
00521   os << endl;
00522   dec(os);
00523 }
00524 
00525 // ------------------------- vmeFetch ----------------------------------------
00526 
00530 UINT16 TimModule::vmeFetch( const UINT32 addr )
00531           throw (VmeException &) {
00532 
00533   UINT16 data = 0;
00534   bool trying = true;
00535   bool error = false;
00536 
00537   while (trying) {
00538     try {
00539       data = m_vmePort->read16( addr );
00540       trying = false;
00541     }
00542     catch (VmeException & vmeFailed) {
00543       if (error) throw vmeFailed;
00544       error = true;
00545     }
00546   }
00547   if (error) cerr << "TimModule::vmeFetch recovers from VmeException" << endl;
00548   return data;
00549 }
00550 
00551 // ------------------------- vmeLoad -----------------------------------------
00552 
00556 void TimModule::vmeLoad( const UINT32 addr, const UINT16 data )
00557         throw (VmeException & ) {
00558 
00559   bool trying = true;
00560   bool error = false;
00561 
00562   while (trying) {
00563     try {
00564       m_vmePort->write16( addr, data );
00565 //debug  throw VmeException(VmeException::BUS_ERROR, 1, m_vmePort);
00566       trying = false;
00567     }
00568     catch (VmeException & vmeFailed) {
00569       if (error) throw vmeFailed;
00570       error = true;
00571     }
00572   }
00573   if (error) cerr << "TimModule::vmeLoad recovers from VmeException" << endl;
00574 }
00575 
00576 } // End namespace SctPixelRod
00577 
00578 // ------------------------- Overload operator<< -----------------------------
00579 
00584 using namespace SctPixelRod;
00585 
00586 namespace std {
00587 
00588 ostream& operator<<( ostream& os, TimModule& tim ) {
00589 
00590   tim.statusPrint( os );
00591 
00592   return os;
00593 }
00594 
00595 } // End namespace std

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