sis3300.cpp

Go to the documentation of this file.
00001 /*
00002     This software is Copyright by the Board of Trustees of Michigan
00003     State University (c) Copyright 2005.
00004 
00005     You may use this software under the terms of the GNU public license
00006     (GPL).  The terms of this license are described at:
00007 
00008      http://www.gnu.org/licenses/gpl.txt
00009 
00010      Author:
00011              Ron Fox
00012              NSCL
00013              Michigan State University
00014              East Lansing, MI 48824-1321
00015 */
00016 
00017 
00018 //   Implementation of the SIS3300 readout class.
00019 //   This software reads out the SIS 3300 flash adc .
00020 //   See the doxygen html, or comments in the header for restrictions and
00021 //   usage information.
00022 //
00023 //   Ron Fox
00024 //   NSCL
00025 //   Michigan State University
00026 //   East Lansing, MI 48824-1321
00027 //   mailto: fox@nscl.msu.edu
00028 //
00029 // Copyright (c) 2001 NSCL all rights reserved.
00030 //
00031 #include <config.h>
00032 #ifdef HAVE_STD_NAMESPACE
00033 using namespace std;            // Needed here for spectrodaq
00034 #endif
00035 
00036 #include <spectrodaq.h>
00037 #include <sis3300.h>
00038 #include <string>
00039 #include <CVMEInterface.h>
00040 
00041 #include <sys/types.h>
00042 #include <sys/stat.h>
00043 #include <fcntl.h>
00044 #include <unistd.h>
00045 #include <sys/mman.h>
00046 #include <stdio.h>
00047 
00048 
00049 #include <Iostream.h>
00050 #include <Iomanip.h>
00051 
00052 
00053 
00054 const char* sDevice="/dev/vme32d32";
00055 const unsigned long nDeviceSize = 0x383000;
00056 const unsigned long K = 1024L;
00057 
00058 // Bits in the control register: Each control has a set/unset bit (J/K flip
00059 // flop control).
00060 
00061 const unsigned long CRLedOn                    =        1;
00062 const unsigned long CRUserOutputOn             =        2;
00063 const unsigned long CREnableTriggerOutput      =        4;
00064 const unsigned long CRInvertTriggerOutput      = 0x000010;
00065 const unsigned long CRTriggerOnArmedAndStarted = 0x000020;
00066 const unsigned long CRLedOff                   = 0x010000;
00067 const unsigned long CRUserOutputOff            = 0x020000;
00068 const unsigned long CREnableUserOutput         = 0x040000;
00069 const unsigned long CRNormalTriggerOutput      = 0x100000;
00070 const unsigned long CRTriggerOnArmed           = 0x200000;
00071 
00072 // Bits in the status register:
00073 
00074 const unsigned long SRLedStatus            =        1;
00075 const unsigned long SRUserOutputState      =        2;
00076 const unsigned long SRTriggerOutputState   =        4; 
00077 const unsigned long SRTriggerIsInverted    = 0x000010;
00078 const unsigned long SRTriggerCondition     = 0x000020; //1: armed and started
00079 const unsigned long SRUserInputCondition   = 0x010000;
00080 const unsigned long SRP2_TEST_IN           = 0x020000;
00081 const unsigned long SRP2_RESET_IN          = 0x040000;
00082 const unsigned long SRP2_SAMPLE_IN         = 0X080000;
00083 
00084 
00085 // Bits in the data acquisition control register:
00086 //
00087 const unsigned long DAQSampleBank1On       = 0x00000001;
00088 const unsigned long DAQSampleBank2On       = 0x00000002;
00089 const unsigned long DAQEnableHiRARCM       = 0x00000008;
00090 const unsigned long DAQAutostartOn         = 0x00000010;
00091 const unsigned long DAQMultiEventOn        = 0x00000020;
00092 const unsigned long DAQStopDelayOn         = 0x00000080;
00093 const unsigned long DAQStartDelayOn        = 0x00000040;
00094 const unsigned long DAQEnableLemoStartStop = 0x00000100;
00095 const unsigned long DAQEnableP2StartStop   = 0x00000200;
00096 const unsigned long DAQEnableGateMode      = 0x00000400;
00097 const unsigned long DAQEnableRandomClock   = 0x00000800;
00098 const unsigned long DAQClockSetMask        = 0x00007000;
00099 const unsigned long DAQDisableHiRARCM      = 0x00080000;
00100 const unsigned long DAQClockSetShiftCount  = 12;
00101 const unsigned long DAQSampleBank1Off      = 0x00010000;
00102 const unsigned long DAQBusyStatus          = 0x00010000;
00103 const unsigned long DAQSampleBank2Off      = 0x00020000;
00104 const unsigned long DAQAutostartOff        = 0x00100000;
00105 const unsigned long DAQMultiEventOff       = 0x00200000;
00106 const unsigned long DAQStopDelayOff        = 0x00800000;
00107 const unsigned long DAQStartDelayOff       = 0x00400000;
00108 const unsigned long DAQDisableLemoStartStop= 0x01000000;
00109 const unsigned long DAQDisableP2StartStop  = 0x02000000;
00110 const unsigned long DAQDisableGateMode     = 0x04000000;
00111 const unsigned long DAQDisableRandomClock  = 0x08000000;
00112 const unsigned long DAQClockClearMask      = 0x70000000;
00113 const unsigned long DAQCLockClearShiftCount= 28;
00114 
00115 
00116 // Bits and fields in the event configuration register.
00117 //
00118 
00119 const unsigned long ECFGPageSizeMask      = 7;
00120 const unsigned long ECFGPageSizeShiftCount= 0;
00121 const unsigned long ECFGWrapMask          = 8;
00122 const unsigned long ECFGWrapShiftCount    = 3;
00123 const unsigned long ECFGRandomClock       = (1 << 11);
00124 
00125 // Bits and fields in the threshold register.
00126 const unsigned long THRLt                 =0x8000;
00127 const unsigned long THRChannelShift    = 16;
00128 
00129 // Bits and fields in the event directory longs:
00130 //
00131 
00132 const unsigned long EDIREndEventMask(0x1ffff);
00133 const unsigned long EDIRWrapFlag(0x80000);
00134 
00135 // HiRA firmware is a pre-requisite to using the HiRA
00136 // indpendent random clock mode.
00137 
00138 const unsigned long HIRAFWMAJOR = 0x13;
00139 const unsigned long HIRAFWMINOR = 0x05;
00140 
00141 
00154 CSIS3300::CSIS3300(unsigned long nBaseAddress,
00155                    unsigned int           nCrate) :
00156   m_nBase(nBaseAddress),
00157   m_nFd(0),
00158   m_pCsrs(0),
00159   m_pEi1(0),
00160   m_pEi2(0),
00161   m_pEi3(0),
00162   m_pEi4(0),
00163   m_pModuleId(0),
00164   m_pCsr(0),
00165   m_pAcqReg(0),
00166   m_pResetKey(0),
00167   m_pStart(0),
00168   m_pEventConfig(0),
00169   m_pStartDelay(0),
00170   m_pStopDelay(0),
00171   m_pAddressReg1(0),
00172   m_pAddressReg2(0),
00173   m_pAddressReg3(0),
00174   m_pAddressReg4(0),
00175   m_pEventDirectory1(0),
00176   m_pEventDirectory2(0),
00177   m_pEventDirectory3(0),  
00178   m_pEventDirectory4(0),
00179   m_fStartDelayEnabled(false),
00180   m_nStartDelayClocks(0),
00181   m_fStopDelayEnabled(false),
00182   m_nStopDelayClocks(0),
00183   m_fGateMode(false),
00184   m_fRandomClock(false),
00185   m_fLemoStartStop(false),
00186   m_fP2StartStop(false),
00187   m_fHiRA_RCM(false),
00188   m_fStopTrigger(false),
00189   m_fPageWrap(false)
00190 {
00191   m_eClock = Internal100Mhz;
00192   m_pBank1Buffers[0] = 0;  
00193   m_pBank1Buffers[1] = 0;  
00194   m_pBank1Buffers[2] = 0;  
00195   m_pBank1Buffers[3] = 0;
00196 
00197   m_pThresholds[0]   = 0;
00198   m_pThresholds[1]   = 0;
00199   m_pThresholds[2]   = 0;
00200   m_pThresholds[3]   = 0;
00201 
00202   for(int i = 0; i < 8; i++) {  // This threshold is never made.
00203     m_fThresholdLt[i] = true;
00204     m_nThresholds[i]  = 0;
00205   }
00206 
00207 
00208   //  Event config register:
00209 
00210 
00211 
00212 
00213 
00214 
00215   // Map to the base address in A32/D32 space.
00216 
00217 
00218   void *p = CVMEInterface::Open(CVMEInterface::A32, nCrate);
00219   m_nFd = p;
00220   m_pCsrs  = (volatile unsigned long*)CVMEInterface::Map(p, m_nBase, 
00221                                                           0x3000);
00222 
00223   
00224 
00225   // Calculate and store the pointers to the useful module registers.
00226 
00227   // CSR Block:
00228 
00229   m_pModuleId    = m_pCsrs + (4/sizeof(long));
00230 
00231   // If the module is not an SIS 3300 or 3301 according to the
00232   // module Id register throw a hissy fit:
00233 
00234   unsigned long id    = *m_pModuleId;
00235   unsigned long model = (id >> 16) & 0xffff;
00236   if ((model != 0x3300) && (model != 0x3301)) {
00237     CVMEInterface::Unmap(m_nFd, (void*)m_pCsrs, 0x3000);
00238     CVMEInterface::Close(m_nFd);
00239     char error[1024];
00240     sprintf(error, "CSIS3300: Module at %08x is not a 3300 nor a 3301\n",
00241             m_nBase);
00242     throw string(error);
00243   }
00244   
00245 
00246   m_pCsr         = m_pCsrs;
00247   m_pAcqReg      = m_pCsrs + (0x10/sizeof(long));
00248   m_pResetKey    = m_pCsrs + (0x20/sizeof(long));
00249   m_pStart       = m_pCsrs + (0x30/sizeof(long));
00250   m_pStop        = m_pCsrs + (0x34/sizeof(long));
00251   m_pStartDelay  = m_pCsrs + (0x14/sizeof(long));
00252   m_pStopDelay   = m_pCsrs + (0x18/sizeof(long));
00253 
00254 
00255   m_pEventConfig = (volatile unsigned long*)CVMEInterface::Map(m_nFd,
00256                                                     m_nBase + 0x100000, 0x10);
00257 
00258 
00259   //
00260 
00261   m_pEi1  = (volatile unsigned long*)CVMEInterface::Map(m_nFd, 
00262                                                         m_nBase + 0x200000, 
00263                                                         0x3000);
00264 
00265   m_pThresholds[0] = m_pEi1 + (4/sizeof(long));
00266   m_pAddressReg1    = m_pEi1 + (8/sizeof(long));
00267   m_pEventDirectory1= m_pEi1 + (0x1000/sizeof(long));
00268 
00269   m_pEi2 = (volatile unsigned long*)CVMEInterface::Map(m_nFd, 
00270                                                        m_nBase + 0x280000, 
00271                                                        0x3000);
00272   m_pThresholds[1] = m_pEi2 + (4/sizeof(long));
00273   m_pAddressReg2    = m_pEi2 + (8/sizeof(long));
00274   m_pEventDirectory2= m_pEi2 + (0x1000/sizeof(long));
00275 
00276   m_pEi3 = (volatile unsigned long*)CVMEInterface::Map(m_nFd, 
00277                                                        m_nBase + 0x300000, 
00278                                                        0x3000);
00279   m_pThresholds[2] = m_pEi3 + (4/sizeof(long));
00280   m_pAddressReg3    = m_pEi3 + (8/sizeof(long));
00281   m_pEventDirectory3= m_pEi3 + (0x1000/sizeof(long));
00282  
00283   m_pEi4 = (volatile unsigned long*)CVMEInterface::Map(m_nFd, 
00284                                                        m_nBase + 0x380000, 
00285                                                        0x3000);
00286   m_pThresholds[3] = m_pEi4 + (4/sizeof(long));
00287   m_pAddressReg4    = m_pEi4 + (8/sizeof(long));
00288   m_pEventDirectory4= m_pEi4 + (0x1000/sizeof(long));
00289 
00290 
00291   
00292 
00293 
00294   // Set module modes which should be done via internal functions to
00295   // ensure internal self consistency.
00296 
00297   SetSampleSize(Sample128K);
00298 
00299   
00300 }
00301 
00307 CSIS3300::~CSIS3300()
00308 {
00309   CVMEInterface::Unmap(m_nFd, (void*)m_pCsrs, 0x3000);
00310   CVMEInterface::Unmap(m_nFd, (void*)m_pEventConfig, 0x10);
00311   CVMEInterface::Unmap(m_nFd, (void*)m_pEi1, 0x3000);
00312   CVMEInterface::Unmap(m_nFd, (void*)m_pEi2, 0x3000);
00313   CVMEInterface::Unmap(m_nFd, (void*)m_pEi3, 0x3000);
00314   CVMEInterface::Unmap(m_nFd, (void*)m_pEi4, 0x3000);
00315                       
00316   CVMEInterface::Close(m_nFd);
00317 }
00326 void
00327 CSIS3300::SetClock(ClockSource eClock)
00328 {
00329   m_eClock = eClock;
00330 }
00341 void
00342 CSIS3300::SetStartDelay(bool Enable, unsigned int nClocks)
00343 {
00344   m_fStartDelayEnabled = Enable;
00345   m_nStartDelayClocks  = nClocks;
00346 }
00362 void
00363 CSIS3300::SetStopDelay(bool Enable, unsigned int nClocks)
00364 {
00365   m_fStopDelayEnabled = Enable;
00366   m_nStopDelayClocks  = nClocks;
00367 }
00375 void
00376 CSIS3300::GateMode(bool Enable)
00377 {
00378   m_fGateMode = Enable;
00379 }
00389 void
00390 CSIS3300::RandomClock(bool Enable)
00391 {
00392   m_fRandomClock = Enable;
00393 }
00398 void
00399 CSIS3300::LemoStartStop(bool Enable)
00400 {
00401    m_fLemoStartStop = Enable;
00402 }
00406 void
00407 CSIS3300::P2StartStop(bool Enable)
00408 {
00409    m_fP2StartStop = Enable;
00410 }
00422 void
00423 CSIS3300::HiRA_RCM(bool Enable)
00424 {
00425   if((!haveHiRAFirmware()) && Enable) {    
00426     throw string("Attempting to use HiRA Random clock with non HiRA firmware");
00427   }
00428   else {
00429     m_fHiRA_RCM = Enable;
00430   }
00431 }
00438 void
00439 CSIS3300::TriggerOnStop(bool Enable)
00440 {
00441   m_fStopTrigger = Enable;
00442 }
00449 void
00450 CSIS3300::SetSampleSize(SampleSize ePagesize)
00451 {
00452   m_ePagesize = ePagesize;
00453   switch (m_ePagesize) {
00454   case Sample128K:
00455     m_nPagesize = 128*K;
00456     break;
00457   case Sample16K:
00458     m_nPagesize = 16*K;
00459     break;
00460   case Sample4K:
00461     m_nPagesize = 4*K;
00462     break;
00463   case Sample2K:
00464     m_nPagesize = 2*K;
00465     break;
00466   case Sample1K:
00467     m_nPagesize = K;
00468     break;
00469   case Sample512:
00470     m_nPagesize = 512;
00471     break;
00472   case Sample256:
00473     m_nPagesize = 256;
00474     break;
00475   case Sample128:
00476     m_nPagesize = 128;
00477     break;
00478   }
00479 }
00480 
00487 /********
00488 void
00489 CSIS3300::SetSampleSize(unsigned int ePagesize)
00490 {
00491   m_ePagesize = ePagesize;
00492   if(m_ePagesize>128000) m_ePagesize = 128000;
00493   m_nPagesize = m_ePagesize;
00494 }
00495 */
00496 
00506 void
00507 CSIS3300::EnableWrap(bool Enable)
00508 {
00509   m_fPageWrap = Enable;
00510 }
00511 
00516 CSIS3300::ClockSource
00517 CSIS3300::getCurrentClockSource()
00518 {
00519   return m_eClock;
00520 }
00526 bool
00527 CSIS3300::isStartDelayEnabled()
00528 {
00529   return m_fStartDelayEnabled;
00530 }
00536 bool
00537 CSIS3300::isStopDelayEnabled()
00538 {
00539   return m_fStopDelayEnabled;
00540 }
00547 unsigned int
00548 CSIS3300::getStartDelayClocks()
00549 {
00550   return m_nStartDelayClocks;
00551 }
00559 unsigned int
00560 CSIS3300::getStopDelayClocks()
00561 {
00562   return m_nStopDelayClocks;
00563 }
00579 void
00580 CSIS3300::SetThresholds(bool* pLessthan, unsigned int* pValues)
00581 {
00582   for(int i = 0; i < 8; i++) {
00583     m_fThresholdLt[i] = *pLessthan++;
00584     m_nThresholds[i]  = (*pValues++) & 0x3fff;
00585   }
00586 }
00587 
00593 void
00594 CSIS3300::InitDaq()
00595 {
00596 
00597   *m_pResetKey = 0;             // Reset the module.
00598 
00599   // Set up the Status register pointed to by m_pCsr:
00600   //   LED off, Output is trigger. Trigger output is univerted.
00601   //   Trigger on armed if trigger is start, or armed and started if trigger
00602   //   is stop.
00603   unsigned csrmask = CRLedOff | CRUserOutputOff | CREnableTriggerOutput |
00604                      CRNormalTriggerOutput;
00605   if(m_fStopTrigger) {
00606     csrmask |= CRTriggerOnArmedAndStarted;
00607   }
00608   else {
00609     csrmask |= CRTriggerOnArmed;
00610   }
00611   *m_pCsr = csrmask;
00612   
00613   // Set up the Acquisition control register *m_pAcqReg according to:
00614   // Enable sample clock for bank 1, Enable multievent mode,
00615   // m_fStartDelayEnabled, m_fStopDelayEnabled, Front panel start/stop enabled.
00616   // P2 disabled, m_fGateMode, m_eClock  
00617   //  Note that the rest has turned all the bits off:
00618   // Note: Multievent mode is required for page size confinement e.g.
00619   // for post trigger modes and should be harmless for the start modes.
00620   
00621   *m_pAcqReg = 0xffff0000;
00622         //  csrmask = DAQEnableLemoStartStop |     DAQMultiEventOn;
00623   csrmask = 0;
00624 
00625   if(m_fStartDelayEnabled) {
00626     csrmask |= DAQStartDelayOn;
00627     *m_pStartDelay = m_nStartDelayClocks;
00628   }
00629   if(m_fStopDelayEnabled) {
00630     csrmask |= DAQStopDelayOn;
00631     *m_pStopDelay = m_nStopDelayClocks;
00632     
00633   }
00634   if(m_fGateMode) {
00635     csrmask |= DAQEnableGateMode;
00636   }
00637   if(m_fRandomClock) {
00638     csrmask |= DAQEnableRandomClock;
00639   }
00640   if(m_fLemoStartStop) {
00641     csrmask |= DAQEnableLemoStartStop;
00642   }
00643   if(m_fP2StartStop) {
00644     csrmask |= DAQEnableP2StartStop;
00645   }
00646 
00647   /* Added by M. Famiano  to Enable the HiRA RCM */
00648 
00649 
00650   csrmask |= (m_eClock << DAQClockSetShiftCount) ;
00651 
00652 
00653 
00654   if(m_fHiRA_RCM) {
00655     csrmask |= DAQEnableHiRARCM;
00656   }
00657   /************************************************/
00658 
00659   *m_pAcqReg = csrmask;
00660 
00661 
00662   // Configure the global event configuration register.
00663   // We set the event size in this register from m_ePagesize and
00664   // we set the wrap bit from m_fPageWrap
00665   //
00666   csrmask = m_ePagesize << ECFGPageSizeShiftCount;
00667   if(m_fPageWrap) csrmask |= ECFGWrapMask;
00668   if(m_fRandomClock) csrmask |= ECFGRandomClock;
00669 
00670     
00671   *m_pEventConfig = csrmask;
00672 
00673   // Configure the channel thresholds.
00674   
00675   int tchan = 0;
00676   for(int i =0; i < 4; i++) {
00677     unsigned long eventhresh = m_nThresholds[tchan];
00678     if(m_fThresholdLt[tchan]) eventhresh |= THRLt;
00679     tchan++;
00680     unsigned long oddthresh = m_nThresholds[tchan];
00681     if(m_fThresholdLt[tchan]) oddthresh |= THRLt;
00682     tchan++;
00683 
00684     *(m_pThresholds[i]) = (oddthresh << THRChannelShift) | eventhresh;
00685   }
00686   
00687   // Enable sampling into bank1.
00688   
00689   *m_pAcqReg = DAQSampleBank1On;        // Arm sampling into bank1.
00690 }
00691 
00692 /*The following functions added by Mike Famiano */
00693 
00697 void
00698 CSIS3300::LightOn()
00699 {
00700   *m_pCsrs = 0x1;
00701 }
00705 void
00706 CSIS3300::LightOff()
00707 {
00708   *m_pCsrs = 0x10000;
00709 }
00710 
00714 void
00715 CSIS3300::EnableUserOut()
00716 {
00717   *m_pCsrs = 0x2;
00718 }
00719 
00723 void
00724 CSIS3300::DisableUserOut()
00725 {
00726   *m_pCsrs = 0x4;
00727 }
00728 
00734 void
00735 CSIS3300::StrobeUserOut(int time)
00736 {
00737  *m_pCsrs = 0x2;
00738  usleep(time);
00739  *m_pCsrs = 0;
00740 }
00741 
00747 unsigned int
00748 CSIS3300::GetUserInput()
00749 {
00750   return (*m_pCsrs&SRUserInputCondition)>>16;
00751 }
00752 
00758 void
00759 CSIS3300::StartSampling()
00760 {
00761   *m_pStart = 0;
00762 }
00763 
00769 void
00770 CSIS3300::StopSampling()
00771 {
00772   *m_pStop = 0;
00773 }
00774 
00775 
00776 /*The Previous functions added by Mike Famiano */
00777 
00785 bool
00786 CSIS3300::WaitUntilDone(int timeout)
00787 {
00788   int i;
00789   for(i = 0; i < timeout; i ++) {
00790     if(((*m_pAcqReg) & DAQBusyStatus) == 0) break;
00791   }
00792 
00793   if(i >= timeout) return false;
00794 
00795   unsigned long  last = *m_pAddressReg1;
00796   while(last != *m_pAddressReg1) 
00797     last = *m_pAddressReg1;             // Wait for address reg. to stabilize.
00798 
00799   *m_pAcqReg = DAQSampleBank1Off | DAQSampleBank2Off ; // Disable sampling
00800 
00801   return true;
00802 
00803 }
00808 unsigned long
00809 CSIS3300::EventNumber(int bank)
00810 {
00811   unsigned long last;
00812   if(bank==1)last = *m_pAddressReg1;
00813   else if(bank==2)last = *m_pAddressReg2;
00814   else if(bank==3)last = *m_pAddressReg3;
00815   else last = *m_pAddressReg4;
00816 
00817   return last;
00818 }
00819 
00824 void 
00825 CSIS3300::ClearDaq()
00826 {
00827 
00828   *m_pAcqReg = DAQSampleBank1On; // Enable bank1.
00829 }
00837 void 
00838 CSIS3300::DisArm1()
00839 {
00840 
00841   *m_pAcqReg = DAQSampleBank1Off; // Enable bank2.
00842 }
00848 void 
00849 CSIS3300::DisArm2()
00850 {
00851 
00852   *m_pAcqReg = DAQSampleBank2Off; // Enable bank1.
00853 }
00858 void 
00859 CSIS3300::Arm1()
00860 {
00861 
00862   *m_pAcqReg = DAQSampleBank1On; // Enable bank1.
00863 }
00868 void 
00869 CSIS3300::Arm2()
00870 {
00871 
00872   *m_pAcqReg = DAQSampleBank2On; // Enable bank1.
00873 }
00903 unsigned int 
00904 CSIS3300::ReadAGroup(void* pbuffer,
00905                           volatile unsigned long* pAddressReg,
00906                           unsigned long           nBase)
00907 {
00908 
00909   unsigned long nPagesize(m_nPagesize); // Max conversion count.
00910 
00911   // Decode the event directory entry:
00912 
00913   unsigned long    AddressRegister = *pAddressReg;
00914   bool           fWrapped      = (*pAddressReg & EDIRWrapFlag ) != 0;
00915   unsigned long  nEventEnd     = (*pAddressReg & EDIREndEventMask);
00916   nEventEnd                   &= (nPagesize-1); // Wrap the pointer to pagesize
00917   unsigned long  nLongs(0);
00918   unsigned long* Samples((unsigned long*)pbuffer);
00919 
00920   // The three cases above break into two cases: fWrapped true or not.
00921 
00922   if(fWrapped) {
00923     //  Full set of samples... 
00924 
00925     nLongs = nPagesize;
00926     
00927     // Breaks down into two reads:
00928 
00929     // The first read is from nEventEnd -> nPagesize.
00930 
00931     int nReadSize = (nPagesize - nEventEnd);
00932     if(nReadSize > 0) {
00933       CVMEInterface::Read((void*)m_nFd,
00934                           nBase + nEventEnd*sizeof(long),
00935                           Samples,
00936                           nReadSize*sizeof(long));
00937     }
00938 
00939     // The second read, if necessary, is from 0 ->nEventEnd-1.
00940     
00941     unsigned long nOffset =  nReadSize; // Offset into Samples where data goes.
00942     nReadSize = nPagesize - nReadSize;  // Size of remaining read.
00943     if(nReadSize > 0) {
00944       CVMEInterface::Read((void*)m_nFd,
00945                           nBase,
00946                           &(Samples[nOffset]),
00947                           nReadSize*sizeof(long));
00948     }
00949     nLongs = nPagesize;
00950   }
00951   else {                        
00952     // Only 0 - nEventEnd to read...
00953     if(nEventEnd > 0) {
00954       CVMEInterface::Read((void*)m_nFd,
00955                           nBase, Samples, 
00956                           (nEventEnd*sizeof(long)));
00957       nLongs = nEventEnd;
00958     } 
00959     else {                      // nothing to read...
00960       nLongs = 0;
00961     }
00962   }
00963 
00964   return nLongs*sizeof(unsigned long)/sizeof(unsigned short);
00965 
00966 }
00967 
00997 unsigned int
00998 CSIS3300:: ReadAGroup(DAQWordBufferPtr& pBuffer,
00999                           volatile unsigned long* pAddressReg,
01000                           unsigned long  nBase)
01001 {
01002 
01003   unsigned long nPagesize(m_nPagesize); // Max conversion count.
01004   unsigned long Samples[nPagesize];
01005 
01006   unsigned int nWords = ReadAGroup(Samples,
01007                                    pAddressReg,
01008                                    nBase);
01009 
01010   // The data are now read into the first nLongs of Sample.
01011   // Now copy them into the data buffer:
01012 
01013   if(nWords > 0) {
01014 #ifdef CLIENT_HAS_POINTER_COPYIN
01015     pBuffer.CopyIn((unsigned short*)Samples, 0,  nWords);
01016     pBuffer += nWords;
01017 #else
01018     unsigned short* pSrc = (unsigned short*)Samples;
01019     for(int i =0; i < nWords; i++) {
01020       *pBuffer = *pSrc++;
01021       ++pBuffer;
01022     }
01023 #endif
01024   }
01025   return nWords;
01026 
01027 }
01028 
01042 unsigned int
01043 CSIS3300::ReadAllGroups(DAQWordBufferPtr& pBuffer)
01044 {
01045   int nRead(0);
01046 
01047   nRead += ReadGroup1(pBuffer);
01048   nRead += ReadGroup2(pBuffer);
01049   nRead += ReadGroup3(pBuffer);
01050   nRead += ReadGroup4(pBuffer);
01051 
01052   return nRead;
01053 }
01054 // With ordinary buffers:
01055 
01056 unsigned int
01057 CSIS3300::ReadAllGroups(void* pBuff)
01058 {
01059   int nRead(0);
01060   int nSegSize;
01061 
01062   unsigned short *pBuffer;
01063 
01064   nSegSize = ReadGroup1(pBuffer);
01065   pBuffer += nSegSize;
01066   nRead   += nSegSize;
01067   nSegSize = ReadGroup2(pBuffer);
01068   pBuffer += nSegSize;
01069   nRead   += nSegSize;
01070   nSegSize = ReadGroup3(pBuffer);
01071   pBuffer += nSegSize;
01072   nRead   += nSegSize;
01073   nSegSize = ReadGroup4(pBuffer);
01074   pBuffer += nSegSize;
01075   nRead   += nSegSize;
01076 
01077   return nRead;
01078 }
01079 
01088 unsigned int
01089 CSIS3300::ReadGroup1(DAQWordBufferPtr& pBuffer)
01090 {
01091 
01092   unsigned long endaddress = *m_pAddressReg1; // For debugging.
01093   return ReadAGroup(pBuffer, m_pEventDirectory1, m_nBase + 0x400000);
01094 }
01095 // Now with ordinary buffers:
01096 
01097 unsigned int
01098 CSIS3300::ReadGroup1(void* pBuffer)
01099 {
01100   unsigned long endaddress = *m_pAddressReg1;
01101   return ReadAGroup(pBuffer, m_pEventDirectory1, m_nBase + 0x400000);
01102 }
01111 unsigned int
01112 CSIS3300::ReadGroup2(DAQWordBufferPtr& pBuffer)
01113 {
01114   unsigned long endaddress = *m_pAddressReg1; // For debugging.
01115   return ReadAGroup(pBuffer, m_pEventDirectory2, m_nBase + 0x480000);
01116 }
01117 // Now with ordinary buffers:
01118 
01119 unsigned int
01120 CSIS3300::ReadGroup2(void* pBuffer)
01121 {
01122   unsigned long endaddress = *m_pAddressReg1;
01123   return ReadAGroup(pBuffer, m_pEventDirectory2, m_nBase+0x480000);
01124 
01125 }
01134 unsigned int
01135 CSIS3300::ReadGroup3(DAQWordBufferPtr& pBuffer)
01136 {
01137   unsigned long endaddress = *m_pAddressReg1; // For debugging.
01138   return ReadAGroup(pBuffer, m_pEventDirectory3, m_nBase + 0x500000);
01139 }
01140 // Now with ordinary buffers:
01141 
01142 unsigned int 
01143 CSIS3300::ReadGroup3(void* pBuffer)
01144 {
01145   unsigned long endaddress = *m_pAddressReg1; // For debugging.
01146   return ReadAGroup(pBuffer, m_pEventDirectory3, m_nBase + 0x500000);
01147 }
01148 
01157 unsigned int
01158 CSIS3300::ReadGroup4(DAQWordBufferPtr& pBuffer)
01159 {
01160   unsigned long endaddress = *m_pAddressReg1; // For debugging.
01161   return ReadAGroup(pBuffer, m_pEventDirectory4, m_nBase + 0x580000 );
01162 }
01163 // With ordinary buffers:
01164 
01165 unsigned int
01166 CSIS3300::ReadGroup4(void* pBuffer)
01167 {
01168   unsigned long endaddress = *m_pAddressReg1; // For debugging.
01169   return ReadAGroup(pBuffer, m_pEventDirectory4, m_nBase + 0x580000 );
01170 }
01171 
01172 
01178 void 
01179 CSIS3300::Reset()
01180 {
01181   *m_pResetKey = 0;
01182 }
01186 bool
01187 CSIS3300::haveHiRAFirmware() const
01188 {
01189 
01190   // Read the module firmware..
01191 
01192 
01193   unsigned int major = getFirmwareMajor();
01194   unsigned int minor = getFirmwareMinor();
01195 
01196   return ((HIRAFWMAJOR == major));
01197 
01198 }

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