00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 static const char* Copyright= "(C) Copyright Michigan State University 2002, All rights reserved";
00377
00378 #include <config.h>
00379
00380
00381 #include "CAENcard.h"
00382 #include <string>
00383 #include <unistd.h>
00384
00385 #include <assert.h>
00386 #ifdef HAVE_STD_NAMESPACE
00387 using namespace std;
00388 #endif
00389
00390
00391
00392 #define swaplong(n) (((n >> 16) & 0xffff) | ((n & 0xffff) << 16))
00393
00394
00395 #define VME_CRATE_SIZE 24 // Slots in a VME crate.
00396
00397 #define CAEN_REGISTERSIZE 0x2000 // Size of CAEN Register set.
00398 #define CAEN_ROMSIZE 0x1000 // Size of CAEN ROM page.
00399 #define CAEN_ROMOFFSET 0x8000 // Offset from base of ROM page.
00400
00401
00402
00403
00404
00405
00406 #define KILLBIT 0x100 // Kill bit in threshold registers.
00407
00408
00409
00410 #define RESET 0x080
00411 #define SELADDR 0x010
00412
00413
00414
00415
00416 #define DREADY 0x001
00417 #define GDREADY 0x002
00418 #define BUSY 0x004
00419 #define GBUSY 0x008
00420
00421
00422
00423
00424 #define OFFLINE 0x002
00425 #define CLEARDATA 0x004
00426 #define KEEPOVER 0x008
00427 #define KEEPTHRESH 0x010
00428 #define KEEPINVALID 0x020
00429 #define COMMONSTOP 0x400
00430 #define STEPTHR 0x100
00431 #define AUTOIN 0x800
00432 #define EMPTY 0x1000
00433 #define SLIDESUB 0x2000
00434 #define ALLTRG 0x4000
00435
00436
00437
00438
00439 #define CTL1BLKEND 0x04
00440 #define CTL1PROGRST 0x10
00441 #define CTL1BERRENA 0x20
00442 #define CTL1ALIGN64 0x40
00443
00444
00445
00446
00447 #define MCSTFIRST 2
00448 #define MCSTLAST 1
00449
00450
00451
00452
00453 #define SR2EMPTY 2 // MEB empty
00454 #define SR2FULL 4 // MEB full.
00455
00456
00457
00458
00459
00460 struct Registers {
00461 unsigned long Buffer[0x1000/sizeof(long)];
00462 unsigned short FirmwareRev;
00463 unsigned short GeoAddress;
00464 unsigned short MCSTAddress;
00465 unsigned short BitSet1;
00466 unsigned short BitClear1;
00467 unsigned short InterruptLevel;
00468 unsigned short InterruptVector;
00469 unsigned short Status1;
00470 unsigned short Control1;
00471 unsigned short HighAddress;
00472 unsigned short LowAddress;
00473 unsigned short Reset;
00474 unsigned short pad1;
00475 unsigned short MCSTControl;
00476 unsigned short pad2;
00477 unsigned short pad3;
00478 unsigned short EventTrigger;
00479 unsigned short Status2;
00480 unsigned short EventCounterLow;
00481 unsigned short EventCounterHigh;
00482 unsigned short IncrementEvent;
00483 unsigned short IncrementOffset;
00484 unsigned short LoadTestRegister;
00485 unsigned short FCLRWindow;
00486 unsigned short pad4;
00487 unsigned short BitSet2;
00488 unsigned short BitClear2;
00489 unsigned short WMemoryTestAddress;
00490 unsigned short MemoryTestHigh;
00491 unsigned short MemoryTestLow;
00492 unsigned short CrateSelect;
00493 unsigned short TestEventWrite;
00494 unsigned short EventCounterReset;
00495 unsigned short pad5[15];
00496 unsigned short TDCRange;
00497 unsigned short pad7;
00498 unsigned short RMemoryTestAddress;
00499 unsigned short pad8;
00500 unsigned short SWComm;
00501 unsigned short SlideConstant;
00502 unsigned short pad10;
00503 unsigned short pad11;
00504 unsigned short AAD;
00505 unsigned short BAD;
00506 unsigned short pad9[6];
00507 unsigned short Thresholds[32];
00508
00509 };
00510 #define QDCIPedestal TDCRange // same register offsets.
00511
00512
00513
00514
00515
00516 struct ROM {
00517 unsigned short pad1[0x26/sizeof(short)];
00518 unsigned short OUIMSB;
00519 unsigned short pad2;
00520 unsigned short OUI;
00521 unsigned short pad3;
00522 unsigned short OUILSB;
00523 unsigned short pad4;
00524 unsigned short Version;
00525 unsigned short pad5;
00526 unsigned short BoardIdMSB;
00527 unsigned short pad6;
00528 unsigned short BoardId;
00529 unsigned short pad7;
00530 unsigned short BoardIdLSB;
00531 unsigned short pad8[7];
00532 unsigned short Revision;
00533 unsigned short pad9[0xb0/sizeof(short)];
00534 unsigned short pad10[0xe00/sizeof(short)];
00535 unsigned short pad11;
00536 unsigned short SerialMSB;
00537 unsigned short pad12;
00538 unsigned short SerialLSB;
00539 };
00540
00541
00542
00543
00544
00545 #define Offset(structname, field) \
00546 ((unsigned int)&(((structname*)0x0)->field))
00547
00549
00550 #define ShortOffset(structname, field) Offset(structname, field)/sizeof(short)
00551 #define LongOffset(structname, field) Offset(structname, field)/sizeof(long)
00552
00555 #ifdef HAVE_VME_MAPPING
00556 #define ReadBuffer (((volatile Registers*)m_pModule)->Buffer[0])
00557 #else
00558 #define ReadBuffer (m_pModule->peekl(LongOffset(Registers, Buffer)));
00559 #endif
00560
00561
00567 void
00568 CAENcard::ReadBufferBlock(int* pDest, Int_t nLongs)
00569 {
00570 #ifdef HAVE_VME_MAPPING
00571 for(int i = 0; i < nLongs; i++) {
00572 int Datum = ReadBuffer;
00573 *pDest++ = swaplong(Datum);
00574 }
00575 #else
00576 int* pd = pDest;
00577 m_pModule->readl(pd, LongOffset(Registers, Buffer), nLongs);
00578 for(int i =0; i < nLongs; i++) {
00579 *pDest++ = swaplong(*pDest);
00580 }
00581 #endif
00582 }
00583
00584
00613 CAENcard::CAENcard(int slotNum, int crateNum ,
00614 bool Geo, long nBase) :
00615 m_nSlot(slotNum),
00616 m_nCrate(crateNum),
00617 m_fGeo(Geo),
00618 m_nBase(nBase),
00619 m_pModule(0),
00620 m_nFirmware(0)
00621 {
00622 assert(sizeof(Registers) == 0x10c0);
00623 assert(sizeof(ROM) == 0xf08);
00624 slotInit();
00625 }
00636 CAENcard::CAENcard(const CAENcard& card) :
00637 m_nSlot(card.m_nSlot),
00638 m_nCrate(card.m_nCrate),
00639 m_fGeo(card.m_fGeo),
00640 m_nBase(card.m_nBase),
00641 m_pModule(0),
00642 m_fSmallThresholds(false)
00643 {
00644 MapCard();
00645 }
00646
00658 CAENcard& CAENcard::operator=(const CAENcard& card)
00659 {
00660 if(this != &card) {
00661 if(this->m_pModule) DestroyCard();
00662 m_nSlot = card.m_nSlot;
00663 m_nCrate = card.m_nCrate;
00664 m_fGeo = m_fGeo;
00665 m_nBase = card.m_nBase;
00666 MapCard();
00667 }
00668 return *this;
00669 }
00670
00671
00672
00687 void
00688 CAENcard::slotInit()
00689 {
00690
00691 MapCard();
00692
00693 reset();
00694 channelOn(-1);
00695 setCrate(m_nCrate);
00696
00697 if(cardType() == 775) {
00698
00699
00700
00701 commonStart();
00702 setRange(0xFF);
00703 setThreshold(-1, 0x19);
00704
00705 }
00706 else if((cardType() == 785) ||
00707 (cardType() == 1785)) {
00708
00709
00710 setThreshold(-1, 0x01);
00711
00712 }
00713 else if((cardType() == 792) || (cardType() == 862)) {
00714
00715 setThreshold(-1, 0);
00716 }
00717
00718
00719 }
00720
00726 CAENcard::~CAENcard()
00727 {
00728 DestroyCard();
00729 }
00730
00736 int
00737 CAENcard::cardType()
00738 {
00739 return m_nCardType;
00740 }
00741
00753 void
00754 CAENcard::setCrate(int crateNum)
00755 {
00756 #ifdef HAVE_VME_MAPPING
00757 volatile Registers* pModule = (volatile Registers*)m_pModule;
00758 pModule->CrateSelect = crateNum & 0x0ff;
00759 #else
00760 m_pModule->pokew((0x0ff & m_pModule->peekw(ShortOffset(Registers,CrateSelect))),
00761 ShortOffset(Registers,CrateSelect));
00762 #endif
00763 }
00764
00772 int
00773 CAENcard::getCrate()
00774 {
00775 #ifdef HAVE_VME_MAPPING
00776 volatile Registers* pModule = (volatile Registers*)m_pModule;
00777 return (pModule->CrateSelect & 0xff);
00778 #else
00779 return (m_pModule->peekw(ShortOffset(Registers, CrateSelect)) & 0xff);
00780 #endif
00781
00782 }
00783
00809 void
00810 CAENcard::setThreshold(int ch, int threshold)
00811 {
00812 volatile Registers* pModule = (volatile Registers*)m_pModule;
00813 threshold = threshold & 0x00FF;
00814
00815 if( ch < 0 ) {
00816 for(int i = 0; i < 32; i++) {
00817 setThreshold(i,threshold);
00818 }
00819 }
00820 else {
00821 #ifdef HAVE_VME_MAPPING
00822 Registers* pModule = (Registers*)m_pModule;
00823 pModule->Thresholds[ch] = threshold |
00824 (pModule->Thresholds[ch] & KILLBIT);
00825 #else
00826 int noffset = ShortOffset(Registers, Thresholds[ch]);
00827 int now = m_pModule->peekw(noffset);
00828 now = threshold | (now & KILLBIT);
00829 m_pModule->pokew(now, noffset);
00830 #endif
00831 }
00832 }
00833
00846 void
00847 CAENcard::setThresholdVoltage(int ch, double voltage)
00848 {
00849 if(m_fSmallThresholds) {
00850 setThreshold(ch,(int)(voltage*64.0));
00851 }
00852 else {
00853 setThreshold(ch, (int)(voltage*8.0));
00854 }
00855 }
00856
00864 void CAENcard::keepUnderThresholdData()
00865 {
00866 Bitset2(KEEPTHRESH);
00867 }
00868
00873 void CAENcard::discardUnderThresholdData()
00874 {
00875 Bitclear2(KEEPTHRESH);
00876
00877 }
00884 void CAENcard::keepOverflowData()
00885 {
00886 Bitset2(KEEPOVER);
00887 }
00888
00894 void CAENcard::discardOverflowData()
00895 {
00896 Bitclear2(KEEPOVER);
00897
00898 }
00899
00907 void
00908 CAENcard::keepInvalidData()
00909 {
00910
00911 if(cardType() == 775) {
00912 Bitset2(KEEPINVALID);
00913 }
00914 else {
00915 throw string("keepInvalidData - Module is not a V775 TDC");
00916 }
00917 }
00924 void
00925 CAENcard::discardInvalidData()
00926 {
00927 if(cardType() == 775)
00928 {
00929 Bitclear2(KEEPINVALID);
00930 }
00931 else
00932 {
00933 throw string("discardInvalidData - Module is not a V775 TDC");
00934 }
00935 }
00941 void
00942 CAENcard::emptyEnable()
00943 {
00944 Bitset2(EMPTY);
00945 }
00952 void
00953 CAENcard::emptyDisable()
00954 {
00955 Bitclear2(EMPTY);
00956 }
00957
00969 void CAENcard::commonStart()
00970 {
00971
00972 if(cardType() == 775)
00973 {
00974 Bitclear2(COMMONSTOP);
00975 }
00976 else
00977 {
00978 throw string("commonStart() - Module is not a V775 TDC");
00979 }
00980 }
00981
00989 void
00990 CAENcard::commonStop()
00991 {
00992
00993 if(cardType() == 775)
00994 {
00995 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
00996 Bitset2(COMMONSTOP);
00997
00998 }
00999 else
01000 {
01001 throw string("commonStop() - Module is not a V775 TDC");
01002 }
01003 }
01004
01022 void
01023 CAENcard::setRange(int range)
01024 {
01025
01026
01027 if(cardType() == 775)
01028 {
01029 if(range > 0x001D && range < 0x0100)
01030 {
01031 #ifdef HAVE_VME_MAPPING
01032 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01033 pRegisters->TDCRange = (short int)range;
01034 #else
01035 m_pModule->pokew(range, ShortOffset(Registers, TDCRange));
01036 #endif
01037
01038 }
01039 else
01040 {
01041 throw
01042 string("setRange - TDC Range value must be in [0x1e,0xff");
01043 }
01044 }
01045 else
01046 {
01047 throw string("setRange - Module is not a V775 TDC");
01048 }
01049 }
01050
01066 void
01067 CAENcard::setPedestalCurrent(int ped)
01068 {
01069
01070 int type = cardType();
01071 if((type == 792) || (type == 862))
01072 {
01073 ped = ped & 0xff;
01074 #ifdef HAVE_VME_MAPPING
01075 volatile Registers* pRegisters = (volatile Registers*) m_pModule;
01076 pRegisters->QDCIPedestal = (ped);
01077 #else
01078 m_pModule->pokew(ped, ShortOffset(Registers,QDCIPedestal));
01079 #endif
01080 }
01081 else
01082 {
01083 throw string("setPedestalCurrent - module is not a V792 or V862 QDC");
01084 }
01085 }
01093 void
01094 CAENcard::cardOff()
01095 {
01096 Bitset2(OFFLINE);
01097 }
01098
01102 void
01103 CAENcard::cardOn()
01104 {
01105 Bitclear2(OFFLINE);
01106 }
01107
01127 void CAENcard::channelOff(int ch)
01128 {
01129
01130 if( ch < 0 ) {
01131 for( int i = 0; i < 32; ++i )
01132 channelOff(i);
01133 }
01134 else {
01135 if(ch < 32) {
01136 #ifdef HAVE_VME_MAPPING
01137 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01138 pRegisters->Thresholds[ch] |= KILLBIT;
01139 #else
01140 short thresh = m_pModule->peekw(ShortOffset(Registers,Thresholds[ch])) | KILLBIT;
01141 m_pModule->pokew(thresh, ShortOffset(Registers,Thresholds[ch]));
01142 #endif
01143 } else {
01144 throw string("channelOff - channel number must be in [0,31]");
01145 }
01146 }
01147 }
01148
01164 void
01165 CAENcard::channelOn(int ch)
01166 {
01167
01168 if( ch < 0 ) {
01169 for( int i = 0; i < 32; ++i )
01170 channelOn(i);
01171 }
01172 else {
01173 if(ch < 32) {
01174 #ifdef HAVE_VME_MAPPING
01175 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01176 pRegisters->Thresholds[ch] &= ~(KILLBIT);
01177 #else
01178 int thresh = m_pModule->peekw(ShortOffset(Registers,Thresholds[ch])) & ~(KILLBIT);
01179 m_pModule->pokew(thresh, ShortOffset(Registers, Thresholds[ch]));
01180 #endif
01181 }
01182 else {
01183 throw string("channelOn - channel number must be in [0,31]");
01184 }
01185 }
01186
01187 }
01188
01193 void
01194 CAENcard::resetEventCounter()
01195 {
01196
01197
01198 #ifdef HAVE_VME_MAPPING
01199 ((volatile Registers*)m_pModule)->EventCounterReset = 1;
01200 #else
01201 m_pModule->pokew(1, ShortOffset(Registers, EventCounterReset));
01202 #endif
01203
01204
01205 ((volatile Registers*)m_pModule)->EventCounterReset = 1;
01206
01207 }
01208
01213 void CAENcard::clearData()
01214 {
01215 Bitset2(CLEARDATA);
01216 Bitclear2(CLEARDATA);
01217 };
01218
01233 void
01234 CAENcard::reset()
01235 {
01236 Bitset1(RESET);
01237 Bitclear1(RESET);
01238 };
01239
01247 bool
01248 CAENcard::dataPresent()
01249 {
01250 #ifdef HAVE_VME_MAPPING
01251 volatile Registers* pReg = (volatile Registers*)m_pModule;
01252 return ((pReg->Status1 & DREADY) != 0);
01253 #else
01254 return ((m_pModule->peekw(ShortOffset(Registers, Status1)) & DREADY) != 0);
01255 #endif
01256 };
01257
01270 int
01271 CAENcard::readEvent(void* buf)
01272 {
01273
01274 int* pBuf((int*)buf);
01275 if(dataPresent())
01276 {
01277 int n = 1;
01278 int Header = ReadBuffer;
01279 int* pHeader = pBuf;
01280 int nRawChancnt= (Header >> 8) & 0x3f;
01281 *pBuf++ = swaplong(Header);
01282 if(0 && (getFirmware() >= 0x808) ) {
01283
01284 ReadBufferBlock(pBuf, nRawChancnt+1);
01285 return (nRawChancnt+2)*sizeof(long);
01286
01287 } else {
01288 int datum;
01289 do {
01290 datum = ReadBuffer;
01291 *pBuf++ = swaplong(datum);
01292 n++;
01293 datum = (datum >> 24) & 7;
01294 } while ( (datum == 0) && (n <= 34));
01295 if(datum != 4) {
01296 cerr << " Data type in terminating long wrong: " << hex
01297 <<datum << dec << endl;
01298 m_nInvalidTrailers++;
01299 }
01300 if ((n-2) < nRawChancnt) m_nChancountHigh++;
01301 if ((n-2) > nRawChancnt) m_nChancountLow++;
01302 Header &= 0xffffC0ff;
01303 Header |= ((n-2) << 8);
01304 *pHeader = swaplong(Header);
01305 m_nEvents++;
01306 return n * sizeof(long);
01307 }
01308 }else {
01309
01310 return 0;
01311 }
01312 }
01313
01330 int
01331 CAENcard::readEvent(DAQWordBuffer& wbuf, int offset)
01332 {
01333 int localBuffer[32+2];
01334 short* pBuf((short*)localBuffer);
01335
01336
01337 int n = readEvent(localBuffer);
01338 int nWords = n/sizeof(int);
01339 for(int i = 0; i < nWords; i++) {
01340 wbuf[offset] = *pBuf++;
01341 offset++;
01342 }
01343 return nWords;
01344
01345
01346 }
01347
01362 int CAENcard::readEvent(DAQWordBufferPtr& wp)
01363 {
01364
01365
01366 int localBuffer[32+200];
01367 short *pBuf((short*)localBuffer);
01368 int nbytes = readEvent(localBuffer);
01369 int nWords = nbytes / sizeof(short);
01370 #ifdef CLIENT_HAS_POINTER_COPYIN
01371 wp.CopyIn(localBuffer, 0, nWords);
01372 wp += nWords;
01373 #else
01374 for(int i =0; i < nWords; i++) {
01375 *wp = *pBuf++;
01376 ++wp;
01377 }
01378 #endif
01379 return nWords;
01380
01381 };
01382
01396 int
01397 CAENcard::readEvent(DAQDWordBuffer& dwbuf, int offset)
01398 {
01399 int localBuffer[32+2];
01400 int nbytes = readEvent(localBuffer);
01401 int nlongs = nbytes/sizeof(long);
01402 int* pLocal(localBuffer);
01403 for(int i =0; i < nlongs; i++) {
01404 dwbuf[offset] = *pLocal++;
01405 offset++;
01406 }
01407 return nlongs;
01408
01409
01410 }
01411
01422 int CAENcard::readEvent(DAQDWordBufferPtr& dwp)
01423 {
01424 int localBuffer[32+2];
01425 int nbytes = readEvent(localBuffer);
01426 int nlongs = nbytes/sizeof(long);
01427 int* pLocal(localBuffer);
01428 for(int i =0; i < nlongs; i++) {
01429 *dwp = *pLocal++;
01430 ++dwp;
01431 }
01432 return nlongs;
01433
01434
01435 }
01436
01437
01438
01445 void CAENcard::setIped(int value)
01446 {
01447 setPedestalCurrent(value);
01448 }
01453 int CAENcard::getIped()
01454 {
01455 if((cardType() == 792) || (cardType() == 862)) {
01456 #ifdef HAVE_VME_MAPPING
01457 return ((volatile Registers*)m_pModule)->QDCIPedestal;
01458 #else
01459 return m_pModule->peekw(ShortOffset(Registers, QDCIPedestal));
01460 #endif
01461 } else {
01462 throw string("getIped - Module is not a V792 or V862 QDC");
01463 }
01464
01465 }
01483 void CAENcard::MapCard()
01484 {
01485
01486
01487 m_nCrate = m_nCrate & 0xff;
01488
01489 if(m_nSlot > VME_CRATE_SIZE)
01490 {
01491 throw string("Invalid slot number specified to MapCard(). ");
01492 }
01493
01494
01495
01496
01497 void* fd;
01498 #ifndef HAVE_VME_MAPPING
01499 CVmeModule* pRom;
01500 #else
01501 ROM *pRom;
01502 #endif
01503 if( m_fGeo) {
01504 #ifndef HAVE_VME_MAPPING
01505 m_pModule = new CVmeModule(CVmeModule::geo, m_nSlot << 19,
01506 CAEN_REGISTERSIZE, m_nCrate);
01507 pRom = new CVmeModule(CVmeModule::geo,
01508 ((long)m_nSlot << 19) + CAEN_ROMOFFSET,
01509 CAEN_ROMSIZE);
01510 #else
01511 fd = CVMEInterface::Open(CVMEInterface::GEO, m_nCrate);
01512 m_pModule= (volatile unsigned short*)
01513 CVMEInterface::Map(fd,
01514 (unsigned long)m_nSlot << 19,
01515 CAEN_REGISTERSIZE);
01516 pRom = (ROM*)
01517 CVMEInterface::Map(fd,
01518 ((long)m_nSlot <<19) +
01519 CAEN_ROMOFFSET,
01520 CAEN_ROMSIZE);
01521 #endif
01522 }
01523 else {
01524 #ifndef HAVE_VME_MAPPING
01525 m_pModule = new CVmeModule(CVmeModule::a32d32, m_nBase,
01526 CAEN_REGISTERSIZE, m_nCrate);
01527 pRom = new CVmeModule(CVmeModule::a32d32, m_nBase+CAEN_ROMOFFSET,
01528 CAEN_ROMSIZE);
01529
01530
01531
01532 m_pModule->pokew(m_nSlot, ShortOffset(Registers, GeoAddress));
01533 #else
01534 fd = CVMEInterface::Open(CVMEInterface::A32, m_nCrate);
01535 m_pModule = (volatile unsigned short*) CVMEInterface::Map(fd,
01536 m_nBase,
01537 CAEN_REGISTERSIZE);
01538 pRom = (ROM*)CVMEInterface::Map(fd,
01539 m_nBase + CAEN_ROMOFFSET,
01540 CAEN_ROMSIZE);
01541
01542
01543
01544 ((volatile Registers*)m_pModule)->GeoAddress = m_nSlot;
01545 #endif
01546 }
01547
01548
01549
01550
01551 #ifndef HAVE_VME_MAPPING
01552 m_nCardType = (pRom->peekw(ShortOffset(ROM, BoardIdMSB)) & 0xff) << 16 |
01553 (pRom->peekw(ShortOffset(ROM, BoardId)) & 0xff) << 8 |
01554 (pRom->peekw(ShortOffset(ROM, BoardIdLSB)) & 0xff);
01555 m_nSerialno = (pRom->peekw(ShortOffset(ROM, SerialMSB)) & 0xff) << 8 |
01556 (pRom->peekw(ShortOffset(ROM, SerialLSB)) & 0xff);
01557 m_nHardwareRev = pRom->peekw(ShortOffset(ROM, Revision));
01558 delete pRom;
01559 #else
01560 m_nCardType = (pRom->BoardIdMSB & 0xff) << 16 |
01561 (pRom->BoardId & 0xff) << 8 |
01562 (pRom->BoardIdLSB & 0xff);
01563 m_nSerialno = pRom->SerialMSB << 8 |
01564 pRom->SerialLSB;
01565 m_nHardwareRev = pRom->Revision;
01566
01567
01568
01569 CVMEInterface::Unmap(fd, (void*)pRom, CAEN_ROMSIZE);
01570 #endif
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581 #ifndef HAVE_VME_MAPPING
01582 int nSlot = m_pModule->peekw(ShortOffset(Registers, GeoAddress)) & 0x1f;
01583 #else
01584 int nSlot = ((volatile Registers*)m_pModule)->GeoAddress & 0x1f;
01585 #endif
01586
01587 if(!(
01588 ( m_nSlot == nSlot ) &&
01589 ( (m_nCardType == 775) ||
01590 (m_nCardType == 785) ||
01591 (m_nCardType == 792) ||
01592 (m_nCardType == 862) ||
01593 (m_nCardType == 1785))
01594 )) {
01595 #ifndef HAVE_VME_MAPPING
01596 delete m_pModule;
01597 #else
01598 CVMEInterface::Unmap(fd,
01599 (void*)m_pModule, CAEN_REGISTERSIZE);
01600
01601 CVMEInterface::Close(fd);
01602 #endif
01603 char buffer[128];
01604 sprintf(buffer, "Card in crate %d, slot %d is incompatible or missing %d\n",
01605 m_nCrate, m_nSlot, m_nCardType);
01606 throw string(buffer);
01607
01608 string("Card is incompatable type or not inserted");
01609 }
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620 if(m_fGeo) {
01621
01622
01623 #ifndef HAVE_VME_MAPPING
01624 m_pModule->pokew(m_nSlot, ShortOffset(Registers, HighAddress));
01625 m_pModule->pokew(0, ShortOffset(Registers, LowAddress));
01626 #else
01627 ((volatile Registers*)m_pModule)->HighAddress = m_nSlot;
01628 ((volatile Registers*)m_pModule)->LowAddress = 0;
01629 #endif
01630
01631
01632
01633 Bitset1(SELADDR);
01634
01635
01636
01637
01638 #ifndef HAVE_VME_MAPPING
01639 delete m_pModule;
01640 m_pModule = new CVmeModule(CVmeModule::a32d32, (long)m_nSlot << 24,
01641 CAEN_REGISTERSIZE);
01642
01643 #else
01644
01645 CVMEInterface::Unmap(fd, (void*)m_pModule, CAEN_REGISTERSIZE);
01646 CVMEInterface::Close(fd);
01647
01648 fd = CVMEInterface::Open(CVMEInterface::A32, m_nCrate);
01649
01650
01651
01652 m_pModule = (volatile unsigned short *)
01653 CVMEInterface::Map(fd,
01654 (long)m_nSlot << 24,
01655 CAEN_REGISTERSIZE);
01656 #endif
01657 }
01658 m_nFd = fd;
01659
01660 }
01661
01662
01669 void CAENcard::DestroyCard()
01670 {
01671 #ifndef HAVE_VME_MAPPING
01672 delete m_pModule;
01673 #else
01674 CVMEInterface::Unmap(m_nFd,
01675 (void*)m_pModule,
01676 CAEN_REGISTERSIZE);
01677 CVMEInterface::Close(m_nFd);
01678 #endif
01679 }
01680
01684 int CAENcard::getFirmware()
01685 {
01686 if (!m_nFirmware) {
01687 #ifndef HAVE_VME_MAPPING
01688 m_nFirmware = m_pModule->peekw(ShortOffset(Registers, FirmwareRev));
01689 #else
01690 m_nFirmware = ((Registers*)m_pModule)->FirmwareRev;
01691 #endif
01692 }
01693 return m_nFirmware;
01694 }
01700 void
01701 CAENcard::setFastClearWindow(int n)
01702 {
01703 #ifdef HAVE_VME_MAPPING
01704 Registers* pRegs = (Registers*)m_pModule;
01705 pRegs->FCLRWindow = n;
01706 #else
01707 m_pModule->pokew(n, ShortOffset(Registers, FCLRWindow));
01708 #endif
01709 }
01721 void
01722 CAENcard::enableSmallThresholds()
01723 {
01724 Bitset2(STEPTHR);
01725 m_fSmallThresholds = true;
01726
01727 }
01738 void
01739 CAENcard::disableSmallThresholds()
01740 {
01741 Bitclear2(STEPTHR);
01742 m_fSmallThresholds = false;
01743 }
01744
01745
01759 void
01760 CAENcard::SetCBLTChainMembership(int cbltaddr,
01761 CAENcard::ChainMember where)
01762 {
01763
01764
01765 int mask;
01766 switch (where) {
01767 case NotInChain:
01768 mask = 0;
01769 break;
01770 case FirstInChain:
01771 mask = MCSTFIRST;
01772 break;
01773 case LastInChain:
01774 mask = MCSTLAST;
01775 break;
01776 case IntermediateInChain:
01777 mask = MCSTFIRST | MCSTLAST;
01778 break;
01779 default:
01780 throw string("CAENcard::SetCBLTChainMembership: Invalid chain membership selector");
01781 }
01782 #ifdef HAVE_VME_MAPPING
01783 ((Registers*)m_pModule)->MCSTControl = mask;
01784 ((Registers*)m_pModule)->MCSTAddress = cbltaddr;
01785 ((Registers*)m_pModule)->Control1 = CTL1BERRENA;
01786 #else
01787 m_pModule->pokew(mask, ShortOffset(Registers, MCSTControl));
01788 m_pModule->pokew(cbltaddr, ShortOffset(Registers, MCSTAddress));
01789 m_pModule->pokew(CTL1BERRENA, ShortOffset(Registers, Control1));
01790 #endif
01791 }
01795 bool
01796 CAENcard::gdataPresent()
01797 {
01798 #ifdef HAVE_VME_MAPPING
01799 volatile Registers* pReg = (volatile Registers*)m_pModule;
01800 return ((pReg->Status1 & GDREADY) != 0);
01801 #else
01802 short mask = m_pModule->peekw(ShortOffset(Registers, Status1));
01803 return ((mask & GDREADY) != 0);
01804 #endif
01805
01806 }
01810 bool
01811 CAENcard::Busy()
01812 {
01813 #ifdef HAVE_VME_MAPPING
01814 volatile Registers* pReg = (volatile Registers*)m_pModule;
01815 return ((pReg->Status1 & BUSY) != 0);
01816 #else
01817 short mask = m_pModule->peekw(ShortOffset(Registers, Status1));
01818 return ((mask & BUSY) != 0);
01819 #endif
01820 }
01825 bool
01826 CAENcard::gBusy()
01827 {
01828 #ifdef HAVE_VME_MAPPING
01829 volatile Registers* pReg = (volatile Registers*)m_pModule;
01830 return ((pReg->Status1 & GBUSY) != 0);
01831 #else
01832 short mask = m_pModule->peekw(ShortOffset(Registers, Status1));
01833 return ((mask & GBUSY) != 0);
01834 #endif
01835 }
01839 bool
01840 CAENcard::MEBFull()
01841 {
01842 #ifdef HAVE_VME_MAPPING
01843 volatile Registers* pReg = (volatile Registers*)m_pModule;
01844 return ((pReg->Status2 & SR2FULL) != 0);
01845 #else
01846 short mask = m_pModule->peekw(ShortOffset(Registers, Status2));
01847 return ((mask & SR2FULL) != 0);
01848 #endif
01849 }
01853 bool
01854 CAENcard::MEBEmpty()
01855 {
01856 #ifdef HAVE_VME_MAPPING
01857 volatile Registers* pReg = (volatile Registers*)m_pModule;
01858 return ((pReg->Status2 & SR2EMPTY) != 0);
01859 #else
01860 short mask = m_pModule->peekw(ShortOffset(Registers, Status2));
01861 return ((mask & SR2EMPTY) != 0);
01862 #endif
01863 }
01867 void
01868 CAENcard::ClearStatistics()
01869 {
01870 m_nInvalidTrailers = 0;
01871 m_nChancountHigh = 0;
01872 m_nChancountLow = 0;
01873 m_nEvents = 0;
01874 }
01881 int
01882 CAENcard::InvalidTrailerCount()
01883 {
01884 return m_nInvalidTrailers;
01885 }
01893 int
01894 CAENcard::ChannelsTooBigCount()
01895 {
01896 return m_nChancountHigh;
01897 }
01904 int
01905 CAENcard::ChannelsTooSmallCount()
01906 {
01907 return m_nChancountLow;
01908 }
01913 int
01914 CAENcard::EventCount()
01915 {
01916 return m_nEvents;
01917 }
01923 void
01924 CAENcard::Bitset1(short mask)
01925 {
01926 #ifndef HAVE_VME_MAPPING
01927 m_pModule->pokew(mask, ShortOffset(Registers, BitSet1));
01928 #else
01929 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01930 pRegisters->BitSet1 = mask;
01931 #endif
01932 }
01938 void
01939 CAENcard::Bitclear1(short mask)
01940 {
01941 #ifndef HAVE_VME_MAPPING
01942 m_pModule->pokew(mask, ShortOffset(Registers, BitClear1));
01943 #else
01944 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01945 pRegisters->BitClear1 = mask;
01946 #endif
01947 }
01951 void
01952 CAENcard::Bitset2(short mask)
01953 {
01954 #ifndef HAVE_VME_MAPPING
01955 m_pModule->pokew(mask, ShortOffset(Registers, BitSet2));
01956 #else
01957 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01958 pRegisters->BitSet2 = mask;
01959 #endif
01960 }
01966 void
01967 CAENcard::Bitclear2(short mask)
01968 {
01969 #ifndef HAVE_VME_MAPPING
01970 m_pModule->pokew(mask, ShortOffset(Registers, BitClear2));
01971 #else
01972 volatile Registers* pRegisters = (volatile Registers*)m_pModule;
01973 pRegisters->BitClear2 = mask;
01974 #endif
01975 }