sis3820tests.cpp

Go to the documentation of this file.
00001 // Template for a test suite.
00002 #include <config.h>
00003 #include <cppunit/extensions/HelperMacros.h>
00004 #include <cppunit/Asserter.h>
00005 #include "Asserts.h"
00006 #include "CSIS3820.h"
00007 #include <Iostream.h>
00008 #include <unistd.h>
00009 #include <stdio.h>
00010 #ifdef HAVE_STD_NAMESPACE
00011 using namespace std;
00012 #endif
00013 
00014 #define SISBase 0x38000000
00015 const double FWlevel(1.1);
00016 
00017 class sis3820tests : public CppUnit::TestFixture {
00018   CPPUNIT_TEST_SUITE(sis3820tests);
00019   CPPUNIT_TEST(MapTestFail);
00020   CPPUNIT_TEST(MapTestOk);
00021   CPPUNIT_TEST(TestFirmware);
00022   CPPUNIT_TEST(TestCSRRead);
00023   CPPUNIT_TEST(TestReset);
00024   CPPUNIT_TEST(LatchMode);
00025   CPPUNIT_TEST(InvalidMode);
00026   CPPUNIT_TEST(TestInputModes);
00027   CPPUNIT_TEST(TestLNESource);
00028   CPPUNIT_TEST(Arm);
00029   CPPUNIT_TEST(Enable);
00030   CPPUNIT_TEST(ReferencePulser);
00031   CPPUNIT_TEST(CounterTestMode);
00032   CPPUNIT_TEST(Read1Channel);
00033   CPPUNIT_TEST(ReadAllChannels);
00034   CPPUNIT_TEST(AllChannelsCount);
00035   CPPUNIT_TEST(LatchTest);
00036   CPPUNIT_TEST(ClearChannels);
00037   CPPUNIT_TEST(ClearOnLatch);
00038   CPPUNIT_TEST_SUITE_END();
00039 
00040 
00041 private:
00042   CSIS3820* m_pModule;
00043 public:
00044   void setUp() {
00045     m_pModule = new CSIS3820(SISBase);
00046   }
00047   void tearDown() {
00048     delete m_pModule;
00049   }
00050 protected:
00051   void MapTestFail();
00052   void MapTestOk();
00053   void TestFirmware();
00054   void TestCSRRead();
00055   void TestReset();
00056   void LatchMode();
00057   void InvalidMode();
00058   void TestInputModes();
00059   void TestLNESource();
00060   void Arm();
00061   void Enable();
00062   void ReferencePulser();
00063   void CounterTestMode();
00064   void Read1Channel();
00065   void ReadAllChannels();
00066   void AllChannelsCount();
00067   void LatchTest();
00068   void ClearChannels();
00069   void ClearOnLatch();
00070 
00071   // Utilities:
00072 
00073   void ArmInLatchMode();
00074   void SetupReferencePulser();
00075   void Setup25MhzCounter();
00076   void Count2sec();
00077 };
00078 
00079 
00080 CPPUNIT_TEST_SUITE_REGISTRATION(sis3820tests);
00081 
00082 
00083 //
00084 // Test failing map of module.
00085 //  The constructor should throw a string exception:
00086 //  
00087 void
00088 sis3820tests::MapTestFail()
00089 {
00090   try {
00091     CSIS3820 module(SISBase+4); // Shift a bit to bad base address.
00092   }
00093   catch (string msg) {
00094     return;
00095   }
00096   catch (...) {
00097     cerr << "Weird exception type!!\n";
00098     return;
00099   }
00100   FAIL("Created a module where none is in the crate");
00101 }
00102 
00103 
00104 //  Test successful map.. should not throw!!
00105 void
00106 sis3820tests::MapTestOk()
00107 {
00108   try {
00109     CSIS3820 module(SISBase);
00110   }
00111   catch (string msg) {
00112     FAIL("Unable to create module at correct base address");
00113     return;
00114   }
00115 }
00116 //  Test the firmware rev fetch.
00117 // 
00118 void
00119 sis3820tests::TestFirmware()
00120 {
00121   double fw;
00122   fw   = m_pModule->getRevision();
00123   EQMSG("Firmware compare", FWlevel,fw);
00124 }
00125 
00126 //  Test Access to the CSR  this is a bit complex  we need
00127 //  to set a bit there (done by turning on the led
00128 //  we check then that the LED thinks it's on.
00129 //  then we turn it off and check that it's off
00130 //
00131 void
00132 sis3820tests::TestCSRRead()
00133 {
00134   m_pModule->LightOn();         // Turn on the LED.
00135   unsigned int csr;
00136   csr = m_pModule->getCsr();
00137   EQMSG("Led not on", static_cast<unsigned int>(1), (csr & 1));
00138 
00139   m_pModule->LightOff();        // Turn off the LED.
00140   csr = m_pModule->getCsr();
00141   EQMSG("Led not off", static_cast<unsigned int>(0), (csr & 1));
00142 }
00143 //
00144 //  Test the reset function of the module.
00146 //
00147 void
00148 sis3820tests::TestReset()
00149 {
00150 
00151   m_pModule->LightOn();         // give reset something to do.
00152 
00153   m_pModule->Reset();
00154  
00155   unsigned int csr = m_pModule->getCsr();
00156   EQMSG("Led not off", static_cast<unsigned int>(0), (csr & 1));
00157 }
00158 
00159 //  Test the ability to set the scaler mode to latching mode.
00160 //
00161 void
00162 sis3820tests::LatchMode()
00163 {
00164   m_pModule->setOperatingMode(CSIS3820::LatchingScaler);
00165 
00166   EQMSG("Incorrect operating mode", CSIS3820::LatchingScaler, 
00167         m_pModule->getOperatingMode());
00168 
00169 }
00170 //  Test that attempts to put the scaler into an invalid mode
00171 //  throw a string exception.
00172 void
00173 sis3820tests::InvalidMode()
00174 {
00175   try {
00176     m_pModule->setOperatingMode(CSIS3820::ReservedScaler1);
00177   } 
00178   catch(string text) {
00179     return;
00180 
00181   }
00182   catch(...) {
00183     FAIL("Invalid mode test - wrong exception thrown");
00184     return;
00185   }
00186   FAIL("Invalid mode test - no exception thrown");
00187 }
00188 //
00189 // Test the ability to set all supported input modes:
00190 //
00191 void
00192 sis3820tests::TestInputModes()
00193 {
00194   CSIS3820::InputMode Valid[] = {
00195     CSIS3820::NoInputs,
00196     CSIS3820::InputLatchInhibitLatch,
00197     CSIS3820::InputLatchInhibitAllAndLatch,
00198     CSIS3820::InputLatchInhibitAll,
00199     CSIS3820::InhibitGroups,
00200   };
00201   int validmodecount = sizeof(Valid)/sizeof(CSIS3820::InputMode);
00202 
00203   CSIS3820::InputMode Invalid[] = {
00204     CSIS3820::InputReserved7
00205   };
00206   int invalidmodecount = sizeof(Invalid)/sizeof(CSIS3820::InputMode);
00207 
00208   // For all valid modes:
00209   //  - The mode must set without an exception.
00210   //  - The mode set must be the same as the one we tried to set.
00211 
00212   for(int i = 0; i < validmodecount; i++) {
00213     CSIS3820::InputMode mode = Valid[i];
00214     try {
00215       m_pModule->setInputMode(mode);
00216     }
00217     catch (...) {
00218       FAIL("Set of valid mode threw exception");
00219     }
00220     mode = m_pModule->getInputMode();
00221     EQMSG("Mode set/get mismatch", Valid[i], mode);
00222 
00223   }
00224   // For all the invalid modes
00225   //  - The mode set must throw an exception.
00226   //  - The exception must be a string exception.
00227   //  - The mode must not be altered.
00228 
00229   bool failed;
00230   CSIS3820::InputMode initialMode = m_pModule->getInputMode();
00231   for(int i =0; i < invalidmodecount; i++) {
00232     CSIS3820::InputMode mode = Invalid[i];
00233     try {
00234       failed = true;
00235       m_pModule->setInputMode(mode);
00236     }
00237     catch (string msg) {
00238       failed = false;
00239     }
00240     catch (...) {
00241     }
00242     if(failed) {
00243       FAIL("Exception not thrown on invalid input mode set");
00244     }
00245     EQMSG("Invalid mode changed mode!!", initialMode,
00246           m_pModule->getInputMode());
00247   }
00248   
00249 }
00250 //  Test the ability to set the latch source.  We support:
00251 //
00252 void
00253 sis3820tests::TestLNESource()
00254 {
00255   CSIS3820::LNESource SupportedSources [] = {
00256     CSIS3820::LatchVMEOnly,
00257     CSIS3820::LatchFP,
00258     CSIS3820::Latch10Mhz 
00259   };
00260   int nSupported = sizeof(SupportedSources)/sizeof(CSIS3820::LNESource);
00261   
00262   CSIS3820::LNESource UnSupportedSources [] = {
00263     CSIS3820::LatchChannelN,
00264     CSIS3820::LatchPresetN,
00265     CSIS3820::LatchReserved5,
00266     CSIS3820::LatchReserved6,
00267     CSIS3820::LatchReserved7
00268   };
00269   int nUnsupported = sizeof(UnSupportedSources)/
00270                      sizeof(CSIS3820::LNESource);
00271                          
00272   // Each supported latch source:
00273   // - should set without an exception.
00274   // - should actually set the requested source.
00275 
00276   
00277   for(int i = 0; i < nSupported; i++ ) {
00278     CSIS3820::LNESource mode = SupportedSources[i];
00279     try {
00280       m_pModule->setLatchSource(mode);
00281     }
00282     catch (...) {
00283       FAIL("Supported latch source set failed");
00284     }
00285     EQMSG("Supported latch source did not read as set",
00286           mode, m_pModule->getLatchSource());
00287   }
00288   
00289   // Each unsupported latch source:
00290   // - should throw an exception if set.
00291   // - the exception should be a string exception.
00292   // - The latch source should not change.
00293 
00294   bool failed;
00295   CSIS3820::LNESource CurrentMode = m_pModule->getLatchSource();
00296   for(int i= 0; i < nUnsupported; i++) {
00297     CSIS3820::LNESource mode = UnSupportedSources[i];
00298     failed = true;
00299     try {
00300       m_pModule->setLatchSource(mode);
00301     }
00302     catch (string msg) {
00303       failed = false;           // This is the correct result.
00304     }
00305     catch (...) {
00306       // Wrong exception type.
00307 
00308       FAIL("Incorrect exception type for unsupported latch source");
00309     }
00310     if(failed) {
00311       FAIL("No exception thrown for unsupported latch source");
00312     }
00313 
00314     EQMSG("Mode changed on unsupported latch source ",
00315           CurrentMode, m_pModule->getLatchSource());
00316 
00317   }
00318 
00319 
00320     
00321 }
00322 //  Test the ability to arm the scaler module to count.
00323 //  To count, if I understand correctly, the module must be
00324 //  armed and enabled.
00325 void
00326 sis3820tests::Arm()
00327 {
00328   m_pModule->Arm();
00329 
00330   ASSERT(m_pModule->isArmed());
00331 
00332 
00333 }
00334 //   Test ability to enable/disable the module.
00335 //
00336 void
00337 sis3820tests::Enable()
00338 {
00339   m_pModule->Enable();
00340   ASSERT(m_pModule->isEnabled());
00341 
00342   m_pModule->Disable();
00343   ASSERT(!m_pModule->isEnabled());
00344 }
00345 //  Test ability to turn on/off the reference pulser.
00346 void
00347 sis3820tests::ReferencePulser()
00348 {
00349   m_pModule->EnableReferencePulser();
00350   ASSERT(m_pModule->isReferencePulserEnabled());
00351 
00352   m_pModule->DisableReferencePulser();
00353   ASSERT(!m_pModule->isReferencePulserEnabled());
00354 }
00355 //  Test the ability to turn on and off the counter
00356 //  Test mode (25mHz counter into all channels).
00357 void
00358 sis3820tests::CounterTestMode()
00359 {
00360   m_pModule->EnableTestCounter();
00361   ASSERT(m_pModule->isTestCounterOn());
00362  
00363   m_pModule->DisableTestCounter();
00364   ASSERT(!m_pModule->isTestCounterOn());
00365 }
00366 // Set module in latch mode and arm:
00367 void
00368 sis3820tests::ArmInLatchMode()
00369 {
00370   m_pModule->setOperatingMode(CSIS3820::LatchingScaler);
00371   m_pModule->Arm();
00372 }
00373 // 
00374 // Function to put the module in latching mode and setup the
00375 // reference pulser.  The scaler is left armed and ready
00376 //  This can only be used within a test as it assumes that
00377 // m_pModule is valid.
00378 void
00379 sis3820tests::SetupReferencePulser()
00380 {
00381   ArmInLatchMode();
00382   m_pModule->EnableReferencePulser();
00383 
00384 
00385 }
00386 
00387 // Enable the scaler count 2 secs, disable.
00388 
00389 void 
00390 sis3820tests::Count2sec()
00391 {
00392   m_pModule->Enable();          // Scaler is now counting.  
00393   sleep(2);                     // Let it count...
00394 
00395 
00396 }
00397 
00398 // Test ability to read a single channel of the scaler in
00399 // on the fly mode.
00400 //  We:
00401 //    enable the reference pulser, arm/enable the module
00402 //    read once, sleep, read again and ensure that the values
00403 //    differ.
00404 //    Note that an unclocked channel should not change!!.
00405 void
00406 sis3820tests::Read1Channel()
00407 {
00408   // test range checkingon ReadChannel:
00409 
00410   bool failed = true;
00411   try {
00412     m_pModule->ReadChannel(32); // boundary condition.
00413   }
00414   catch (string msg) {
00415     failed = false;             // should throw a string.
00416   }
00417   catch (...) {
00418     FAIL("Bad channel number threw wrong exception type");
00419   }
00420   if(failed) {
00421     FAIL("Bad channel number did not throw an exception!!");
00422   }
00423 
00424   // Test that the channels count.
00425 
00426   SetupReferencePulser();
00427   
00428 
00429   // The scaler is not yet counting... read it then start it..
00430   
00431   unsigned long initial = 
00432     m_pModule->ReadChannel(0); // Read first channel.
00433   unsigned long uninitial = 
00434     m_pModule->ReadChannel(1);  // This channel won't change.
00435 
00436   Count2sec();
00437 
00438   unsigned long final = 
00439     m_pModule->ReadChannel(0);
00440 
00441   if(initial == final) {
00442     FAIL("Read1Channel - initial value == final value");
00443   }
00444   EQMSG("Unclocked channel channged :-(",
00445         uninitial, m_pModule->ReadChannel(1));
00446 
00447 }
00448 //  Test that all channels read. THis test is essentially the same
00449 //  as the previous one, however all channels are read.. .the first
00450 //  channel should be a changing channel, the rest unchanging.
00451 //
00452 void
00453 sis3820tests::ReadAllChannels()
00454 {
00455   // Test that the channels count.
00456 
00457   SetupReferencePulser();
00458 
00459   // The scaler is not yet counting... read it then start it..
00460   
00461   unsigned long initial[32];
00462   m_pModule->ReadAllChannels(initial);
00463 
00464   Count2sec();
00465 
00466   unsigned long final[32];
00467   m_pModule->ReadAllChannels(final);
00468 
00469   for (int i =0; i < 32; i++) {
00470     if((i != 0)) {
00471       EQ(initial[i], final[i]);
00472     }
00473     
00474   }
00475 }
00476 
00477 void
00478 sis3820tests::Setup25MhzCounter()
00479 {
00480   ArmInLatchMode();
00481   m_pModule->EnableTestCounter();
00482 
00483 }
00484 // Test that all channels can be made to count by
00485 // turning on the TestCounter, counting for 2sec
00486 // and ensuring that all channel values have changed.
00487 //
00488 void sis3820tests::AllChannelsCount()
00489 {
00490   Setup25MhzCounter();
00491 
00492   unsigned long initial[32];
00493   m_pModule->ReadAllChannels(initial);
00494 
00495   Count2sec();
00496 
00497 
00498   unsigned long final[32];
00499   m_pModule->ReadAllChannels(final);
00500 
00501   for(int i =0; i < 32; i++) {
00502     char msg[100];
00503     sprintf(msg, "Channel %d is not counting", i);
00504     if(initial[i] == final[i]) {
00505       FAIL(msg);
00506     }
00507 
00508  }
00509 
00510 
00511 }
00512 //  Test the latch into the shadow registers.
00513 //  1. Latch - read the latched registers.
00514 //  2. start all channels counting on the 25mhz test counter
00515 //     for 2 sec.
00516 //  3. Read the latched registers - they should not have changed.
00517 //  4. Latch
00518 //     Read the latched registers - they should have changed now.
00519 void sis3820tests::LatchTest()
00520 {
00521 
00522   // Start the 25mhz test counter:
00523 
00524   Setup25MhzCounter();
00525 
00526   // Latch the counters before we count.
00527 
00528   unsigned long initial[32];
00529   unsigned long final[32];
00530 
00531   m_pModule->LatchAndRead(initial);
00532 
00533   Count2sec();
00534 
00535 
00536 
00537   // Simon didn't say latch so the latched registers should
00538   // be unchanged!!
00539 
00540   m_pModule->ReadAllLatchedChannels(final);
00541   for(int i =0; i < 32; i++) {
00542     char msg[100];
00543     sprintf(msg, "Latched channel %d changed without latch", i);
00544     EQMSG(msg, initial[i], final[i]);
00545   }
00546 
00547   m_pModule->LatchAndRead(final); // Now the latched registers change
00548   for(int i = 0; i < 32; i++) {
00549     char msg[100];
00550     if(initial[i] == final[i]) {
00551       sprintf(msg, "Initial = final channel %d values %d %d",
00552               i, initial[i], final[i]);
00553       FAIL(msg);
00554     }
00555   }
00556     
00557 }
00558 //   Test ability to clear all channels.  What we do is
00559 //   first run the LatchTest... that should leave us with
00560 //   channels having values and the 25Mhz test counter enabled.
00561 //   We then:
00562 //   - stop the 25mhz counter.
00563 //   - Disable counting for good measure.
00564 //   - Clear all channels.
00565 //   - Latch and verify that all shadow registers now contain 0.
00566 //
00567 void
00568 sis3820tests::ClearChannels()
00569 {
00570   LatchTest();                  // Get the channels 'dirty'.
00571   m_pModule->Disable();
00572   m_pModule->DisableTestCounter();
00573 
00574   // Clear the channels.
00575 
00576   m_pModule->ClearChannels();
00577 
00578   // Latch and read the channels:
00579 
00580   unsigned long buf[32];
00581   m_pModule->LatchAndRead(buf);
00582   for(int i = 0; i < 32; i++) {
00583     char msg[100];
00584     sprintf(msg, "Channel %d is non zero", i);
00585     EQMSG(msg, static_cast<unsigned long>(0), buf[i]);
00586   }
00587 
00588 }
00589 //  Test the functionality of the noclear on latch.
00590 //  By default the module clears the counters on a latch
00591 //  Therefore with the 25mhz input in, a read of 2 sec followed
00592 //  by a read of 1 sec should result in fewer counts the second
00593 //  read.
00594 //  If we then turn off this feature (DisableClearOnLatch)
00595 //  this will reverse
00596 //  If we turn it back on (EnbaleClearOnLatch) once more...
00597 //
00598 void
00599 sis3820tests::ClearOnLatch()
00600 {
00601   Setup25MhzCounter();          // Armed and ready...
00602   m_pModule->ClearChannels();   // All channels zeroed...
00603 
00604   unsigned long buf2sec[32];
00605   unsigned long buf1sec[32];
00606 
00607   Count2sec();
00608   m_pModule->LatchAndRead(buf2sec);
00609   sleep(1);
00610   m_pModule->LatchAndRead(buf1sec);
00611   
00612   for(int i=0; i < 32; i++) {
00613     if(buf1sec[i] >= buf2sec[i]) { // only if didn't clear!!
00614       char msg[100];
00615       sprintf(msg, "Channel %d looks like it didn't clear %d %d",
00616               i, buf1sec[i], buf2sec[i]);
00617       FAIL(msg);
00618     }
00619   }
00620 
00621   // Now:
00622   // - Turn off the clear
00623   // - Disable,
00624   // - Clear
00625   // - Enable 
00626   //  and count...
00627 
00628   m_pModule->DisableClearOnLatch();
00629   m_pModule->Disable();
00630   m_pModule->ClearChannels();           // start from zero...
00631   Count2sec();
00632   m_pModule->LatchAndRead(buf2sec);
00633   sleep(1);
00634   m_pModule->LatchAndRead(buf1sec);
00635 
00636   // the second interval should have started with the values
00637   // from the first interval.
00638 
00639   for(int i =0; i < 32; i++) {
00640     if(buf1sec[i] <= buf2sec[i]) {
00641       char msg[100];
00642       sprintf(msg, "Channel %d looks like it did clear %d %d",
00643               i, buf1sec[i], buf2sec[i]);
00644       FAIL(msg);
00645     }
00646   }
00647 
00648   // Go the other way:
00649   //
00650   m_pModule->EnableClearOnLatch();
00651   m_pModule->Disable();
00652   m_pModule->ClearChannels();
00653   Count2sec();
00654   m_pModule->LatchAndRead(buf2sec);
00655   sleep(1);
00656   m_pModule->LatchAndRead(buf1sec);
00657 
00658   for(int i=0; i < 32; i++) {
00659     if(buf1sec[i] >= buf2sec[i]) { // only if didn't clear!!
00660       char msg[100];
00661       sprintf(msg, "Channel %d looks like it didn't clear %d %d",
00662               i, buf1sec[i], buf2sec[i]);
00663       FAIL(msg);
00664     }
00665   }
00666 }

Generated on Wed Sep 17 08:38:09 2008 for NSCL Device support. by  doxygen 1.5.1