00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <config.h>
00010
00011 #include "CCAENV1x90.h"
00012 #include "CCAENV1x90Registers.h"
00013 #include "CCAENV1x90Data.h"
00014 #include "CCAENV1x90Opcodes.h"
00015
00016 #include <stdio.h>
00017 #include <string.h>
00018 #include <unistd.h>
00019
00020 #include <string>
00021 #include <vector>
00022
00023
00024
00025
00026
00027 #ifdef HAVE_STD_NAMESPACE
00028 using namespace std;
00029 #endif
00030 using namespace DesignByContract;
00031 using namespace CCAENV1x90Registers;
00032 using namespace CCAENV1x90Data;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 const unsigned short CCAENV1x90::ERR_VERNIER (0x0001);
00043 const unsigned short CCAENV1x90::ERR_COARSE (0x0002);
00044 const unsigned short CCAENV1x90::ERR_SELECT (0x0004);
00045 const unsigned short CCAENV1x90::ERR_L1PARITY (0x0008);
00046 const unsigned short CCAENV1x90::ERR_TFIFOPARITY(0x0010);
00047 const unsigned short CCAENV1x90::ERR_MATCHERROR (0x0020);
00048 const unsigned short CCAENV1x90::ERR_RFIFOPARITY(0x0040);
00049 const unsigned short CCAENV1x90::ERR_RDOSTATE (0x0080);
00050 const unsigned short CCAENV1x90::ERR_SUPPARITY (0x0100);
00051 const unsigned short CCAENV1x90::ERR_CTLPARITY (0x0200);
00052 const unsigned short CCAENV1x90::ERR_JTAGPARITY (0x0400);
00053
00054
00055
00056
00057
00058 const unsigned short CCAENV1x90::TAP_CONTACT1(4);
00059 const unsigned short CCAENV1x90::TAP_CONTACT2(2);
00060 const unsigned short CCAENV1x90::TAP_CONTACT3(1);
00061
00062
00063
00064
00065 static const unsigned int MINMATCHWIDTH(1);
00066 static const unsigned int MAXMATCHWIDTH(0xfff);
00067 static const unsigned int MATCHMASK(0xfff);
00068
00069 static const int MINWINDOWOFFSET(-2048);
00070 static const int MAXWINDOWOFFSET(40);
00071 static const int WINDOWOFFSETMASK(0xfff);
00072
00073 static const unsigned int MINEXTRAMARGIN(0);
00074 static const unsigned int MAXEXTRAMARGIN(2047);
00075 static const unsigned int EXTRAMARGINMASK(0xfff);
00076
00077 static const unsigned int MINREJECTMARGIN(0);
00078 static const unsigned int MAXREJECTMARGIN(2047);
00079 static const unsigned int REJECTMARGINMASK(0xfff);
00080
00081 static const unsigned int EDGEDETECTIONMASK(3);
00082
00083 static const unsigned int EDGERESOLUTIONMASK(3);
00084 static const unsigned int LERESOLUTIONMASK(7);
00085
00086 static const unsigned int PWRESOLUTIONRSHIFT(8);
00087 static const unsigned int PWRESOLUTIONMASK(0xff00);
00088
00089 static const unsigned int TRUEBIT(1);
00090
00091 static const unsigned int COARSEMAX(0x7ff);
00092 static const unsigned int COARSEMASK(0x7ff);
00093
00094 static const unsigned int VERNIERMAX(0x1f);
00095 static const unsigned int VERNIERMASK(0x1f);
00096
00097 static const unsigned int CHANOFFSETMAX(0xff);
00098 static const unsigned int CHANOFFSETMASK(0xff);
00099
00100 static const unsigned int TAPCONTACTMASK(0x7);
00101 static const unsigned int TAPCONTACTRSHIFT(3);
00102
00103 static const unsigned int MAXTESTVALUE(0x7fffff);
00104
00105 static const unsigned int MAXGEO(0x1f);
00106 static const unsigned int GEOMASK(0x1f);
00107
00108 static const unsigned long RESET_DELAY(1000);
00109
00110
00111
00113
00114 static inline unsigned long OffsetW(unsigned long nByteOffset)
00115 {
00116 return nByteOffset/sizeof(short);
00117 }
00119
00120 static inline unsigned long OffsetL(unsigned long nByteOffset)
00121 {
00122 return nByteOffset/sizeof(long);
00123 }
00124
00126
00127
00128 template <class T>
00129 static inline string FormatValue(const char* pFormatString, T value)
00130 {
00131 int nformatsize = strlen(pFormatString);
00132 char* message = new char[nformatsize+100];
00133 sprintf(message, pFormatString, value);
00134 string m(message);
00135 delete []message;
00136 return m;
00137
00138 }
00139
00141
00142 static unsigned short
00143 inline HI(unsigned int nValue)
00144 {
00145 return static_cast<unsigned short>((nValue >> 16) & 0xffff);
00146 }
00147
00149
00150 static unsigned short
00151 inline LO(unsigned int nValue)
00152 {
00153 return static_cast<unsigned short>(nValue & 0xffff);
00154 }
00155
00156
00158
00197 CCAENV1x90::CCAENV1x90(unsigned int nSlot,
00198 unsigned int nCrate,
00199 unsigned long nBase) :
00200 m_nBase(nBase),
00201 m_nCrate(nCrate),
00202 m_nSlot(nSlot),
00203 m_pRegisters(CVmeModule::a32d32, nBase, RegisterSize, nCrate)
00204 {
00205
00206
00207 REQUIRE(((nSlot >= 1) && (nSlot <=20)), "Slot out of range");
00208 REQUIRE(((nCrate >= 0) && (nCrate <= 7)), "Crate out of range");
00209
00210
00211
00212
00213
00214
00215 CVmeModule pRom(CVmeModule::a32d32,
00216 m_nBase+ConfigRom,
00217 ConfigRomSize,
00218 m_nCrate);
00219
00220
00221
00222 ENSURE(ValidBoard(pRom),
00223 "Board is not a valid CAEN V1x90 module");
00224
00225
00226
00227
00228
00229 BoardProperties(pRom);
00230
00231
00232
00233
00234 ENSURE(((m_nModel == 1190) || (m_nModel == 1290)),
00235 "Model number is incorrect on postcondition check");
00236 ENSURE(((m_cVersion == 'A') || (m_cVersion == 'B') ||
00237 (m_cVersion == 'N')),
00238 "Version is not A,B, or N in postcondition check");
00239
00240
00241
00242
00243 Reset();
00244
00245 }
00246
00255 CCAENV1x90::~CCAENV1x90()
00256 {}
00257
00258
00270 bool
00271 CCAENV1x90::isSetCR(unsigned short bit)
00272 {
00273 return ((ReadCR() & (1 << bit)) != 0);
00274 }
00281 void
00282 CCAENV1x90::Terminate()
00283 {
00284 BitSetCR(ControlRegister::NTERM_SW);
00285 BitSetCR(ControlRegister::NTERM);
00286 }
00294 void
00295 CCAENV1x90::Unterminate()
00296 {
00297 BitSetCR(ControlRegister::NTERM_SW);
00298 BitClearCR(ControlRegister::NTERM);
00299 }
00310 void
00311 CCAENV1x90::TerminateWithSwitch()
00312 {
00313 BitClearCR(ControlRegister::NTERM_SW);
00314 }
00322 void
00323 CCAENV1x90::EnableTriggerTagTime()
00324 {
00325 BitSetCR(ControlRegister::NTRIGGER_TAG_ENABLE);
00326 }
00332 void
00333 CCAENV1x90::DisableTriggerTagTime()
00334 {
00335 BitClearCR(ControlRegister::NTRIGGER_TAG_ENABLE);
00336 }
00347 bool
00348 CCAENV1x90::DataReady()
00349 {
00350 return isSetSR(StatusRegister::NDATA_READY);
00351 }
00364 bool
00365 CCAENV1x90::AlmostFull()
00366 {
00367 return isSetSR(StatusRegister::NALM_FULL);
00368 }
00369
00383 bool
00384 CCAENV1x90::isFull()
00385 {
00386 return isSetSR(StatusRegister::NFULL);
00387 }
00388
00410 bool
00411 CCAENV1x90::isTriggerMatching()
00412 {
00413 return isSetSR(StatusRegister::NTRG_MATCH);
00414 }
00427 bool
00428 CCAENV1x90::isHeaderEnabled()
00429 {
00430 return isSetSR(StatusRegister::NHEADER_EN);
00431 }
00432
00445 bool
00446 CCAENV1x90::isTerminated()
00447 {
00448 return isSetSR(StatusRegister::NTERM_ON);
00449 }
00471 bool
00472 CCAENV1x90::HadError(unsigned int nChip)
00473 {
00474
00475
00476 REQUIRE(nChip < m_nChipCount, "Illegal chip number for device");
00477
00478
00479
00480
00481
00482 ENSURE(((1 << StatusRegister::NCHIP0_ERROR) |
00483 (1 << (StatusRegister::NCHIP0_ERROR+1)) |
00484 (1 << (StatusRegister::NCHIP0_ERROR+2)) |
00485 (1 << (StatusRegister::NCHIP0_ERROR+3))) ==
00486 ((StatusRegister::CHIP0_ERROR) |
00487 (StatusRegister::CHIP1_ERROR) |
00488 (StatusRegister::CHIP2_ERROR) |
00489 (StatusRegister::CHIP3_ERROR)),
00490 "Chip error bits are not continguous in the register");
00491 unsigned int nChipBit = 1 << (StatusRegister::NCHIP0_ERROR + nChip);
00492
00493
00494
00495 return isSetSR(nChipBit);
00496
00497 }
00510 int
00511 CCAENV1x90::ReadResolution()
00512 {
00513 int Resmask = SR() & StatusRegister::RESOLUTIONMASK;
00514
00515 if(Resmask == StatusRegister::RES_800ps) {
00516 return 800;
00517 }
00518 else if (Resmask == StatusRegister::RES_200ps) {
00519 return 200;
00520 }
00521 else if (Resmask == StatusRegister::RES_100ps) {
00522 return 100;
00523 }
00524 else if(Resmask == StatusRegister::RES_25ps) {
00525 m_fIsHiResMode = true;
00526 return 25;
00527 }
00528 else {
00529 CHECK(0, "Unrecognized resolution code");
00530 }
00531 }
00532
00543 bool
00544 CCAENV1x90::isPairMode()
00545 {
00546
00547
00548
00549
00550 if((m_nModel == 1290) && (ReadResolution() == 25)) {
00551 return false;
00552 }
00553 return isSetSR(StatusRegister::NPAIR);
00554 }
00565 bool
00566 CCAENV1x90::WereTriggersLost()
00567 {
00568 return isSetSR(StatusRegister::NTRIGGERLOST);
00569 }
00593 void
00594 CCAENV1x90::SetGeographicalID(unsigned short nSlot)
00595 {
00596
00597
00598
00599 REQUIRE(nSlot <= MAXGEO, "Slot number too big.");
00600
00601
00602
00603 m_pRegisters.pokew(nSlot, OffsetW(WVirtualSlot));
00604
00605
00606
00607 if (GetGeographicalID() != nSlot) {
00608 throw
00609 string ("Attempt to set geo register of geo-recognizing module");
00610 }
00611
00612 }
00613
00622 unsigned short
00623 CCAENV1x90::GetGeographicalID()
00624 {
00625 unsigned short g = m_pRegisters.peekw(OffsetW(WVirtualSlot));
00626 g &= GEOMASK;
00627 return g;
00628
00629 }
00633 void
00634 CCAENV1x90::Reset()
00635 {
00636 m_pRegisters.pokew(0, OffsetW(WReset));
00637 m_fTriggerMatching = isTriggerMatching();
00638 WaitMicroWrite();
00639
00640
00641
00642
00643 SetGeographicalID(m_nSlot);
00644 BitSetCR(ControlRegister::NEVENT_FIFO_ENABLE);
00645
00646
00647 }
00657 void
00658 CCAENV1x90::Clear()
00659 {
00660 m_pRegisters.pokew(0, OffsetW(WClear));
00661 m_fTriggerMatching = isTriggerMatching();
00662 }
00663
00669 void
00670 CCAENV1x90::EventReset()
00671 {
00672 m_pRegisters.pokew(0, OffsetW(WEventReset));
00673 m_fTriggerMatching = isTriggerMatching();
00674 }
00675
00682 void
00683 CCAENV1x90::Trigger()
00684 {
00685 m_pRegisters.pokew(0, OffsetW(WSWTrigger));
00686 }
00687
00697 unsigned long
00698 CCAENV1x90::TriggerCount()
00699 {
00700 return m_pRegisters.peekl(OffsetL(LEventCounter));
00701 }
00702
00710 unsigned short
00711 CCAENV1x90::EventCount()
00712 {
00713 return m_pRegisters.peekw(OffsetW(WEventStored));
00714 }
00715
00730 void
00731 CCAENV1x90::SetAlmostFullLevel(unsigned int nWords)
00732 {
00733
00734
00735 REQUIRE(nWords > 0, "Number of words is too small");
00736 REQUIRE(nWords <= 32735, "Number of words too big");
00737
00738
00739
00740 m_pRegisters.pokew(static_cast<unsigned short>(nWords),
00741 OffsetW(WAlmostFullLevel));
00742
00743 }
00744
00755 unsigned short
00756 CCAENV1x90::GetAlmostFullLevel()
00757 {
00758 return m_pRegisters.peekw(OffsetW(WAlmostFullLevel));
00759 }
00760
00783 void
00784 CCAENV1x90::DefineECLOutput(CCAENV1x90::ECLOutputSelect Signal)
00785 {
00786
00787
00788 REQUIRE(((Signal == DATA_READY) ||
00789 (Signal == FULL) ||
00790 (Signal == ALMOST_FULL) ||
00791 (Signal == ERROR)),
00792 "Signal parameter is invalid.");
00793
00794
00795
00796
00797 unsigned short value;
00798
00799 switch (Signal) {
00800 case DATA_READY:
00801 value = OutputControl::DATA_READY;
00802 break;
00803 case FULL:
00804 value = OutputControl::FULL;
00805 break;
00806 case ALMOST_FULL:
00807 value = OutputControl::ALM_FULL;
00808 break;
00809 case ERROR:
00810 value = OutputControl::ERROR;
00811 break;
00812
00813
00814 }
00815
00816 m_pRegisters.pokew(value, OffsetW(WOutputControl));
00817
00818 }
00837 CCAENV1x90::ECLOutputSelect
00838 CCAENV1x90::GetECLOutputDefinition()
00839 {
00840 unsigned short
00841 value = m_pRegisters.peekw(OffsetW(WOutputControl)) &
00842 OutputControl::MASK;
00843
00844
00845
00846
00847 if(value == OutputControl::DATA_READY) {
00848 return DATA_READY;
00849 }
00850 else if (value == OutputControl::FULL) {
00851 return FULL;
00852 }
00853 else if (value == OutputControl::ALM_FULL) {
00854 return ALMOST_FULL;
00855 }
00856 else if (value == OutputControl::ERROR) {
00857 return ERROR;
00858 }
00859 else {
00860 ENSURE(0, "Illegal value from output control register");
00861 }
00862
00863 }
00875 unsigned short
00876 CCAENV1x90::EventFIFOCount()
00877 {
00878 return m_pRegisters.peekw(OffsetW(WEventFIFOStored)) &
00879 EventFIFO::FIFOCOUNT_MASK;
00880 }
00894 unsigned short
00895 CCAENV1x90::FIFOEventNumber(unsigned long fifoentry)
00896 {
00897 return (fifoentry & EventFIFO::EVENTCOUNT_MASK) >>
00898 EventFIFO::EVENTCOUNT_RSHIFT;
00899 }
00900
00915 unsigned short
00916 CCAENV1x90::FIFOWordCount(unsigned long fifoentry)
00917 {
00918 return (fifoentry & EventFIFO::WORDCOUNT_MASK) >>
00919 EventFIFO::WORDCOUNT_RSHIFT;
00920 }
00921
00942 unsigned long
00943 CCAENV1x90::ReadEventFIFO()
00944 {
00945
00946
00947 REQUIRE(isEventFIFOReady(), "Attempting to read empty FIFO");
00948
00949 return m_pRegisters.peekl(OffsetL(LEventFIFO));
00950 }
00951
00960 bool
00961 CCAENV1x90::isEventFIFOReady()
00962 {
00963
00964 return ((m_pRegisters.peekw(OffsetW(WEventFIFOStatus)) &
00965 FIFOStatus::EVFIFODATA_READY) != 0);
00966 }
00967
00977 bool
00978 CCAENV1x90::isEventFIFOFull()
00979 {
00980 return ((m_pRegisters.peekw(OffsetW(WEventFIFOStatus)) &
00981 FIFOStatus::EVFIFO_FULL) != 0);
00982 }
00983
00984
00986
00993 void
00994 CCAENV1x90::TriggerMatchMode()
00995 {
00996 m_fTriggerMatching = true;
00997 WriteMicro(CCAENV1x90Opcodes::TRG_MATCH);
00998 WaitMicroWrite();
00999 }
01000
01004 void
01005 CCAENV1x90::ContinuousStorageMode()
01006 {
01007 m_fTriggerMatching = false;
01008 WriteMicro(CCAENV1x90Opcodes::CONT_STOR);
01009 WaitMicroWrite();
01010
01011 }
01028 void
01029 CCAENV1x90::TransferUntilDone()
01030 {
01031 WriteMicro(CCAENV1x90Opcodes::SET_KEEP_TOKEN);
01032 WaitMicroWrite();
01033
01034 }
01040 void
01041 CCAENV1x90::TransferOneAtATime()
01042 {
01043 WriteMicro(CCAENV1x90Opcodes::CLEAR_KEEP_TOKEN);
01044 WaitMicroWrite();
01045
01046 }
01047
01051 void
01052 CCAENV1x90::LoadDefaultConfig()
01053 {
01054 WriteMicro(CCAENV1x90Opcodes::LOAD_DEF_CONFIG);
01055 WaitMicroWrite();
01056
01057 }
01078 void
01079 CCAENV1x90::SaveUserConfig()
01080 {
01081 WriteMicro(CCAENV1x90Opcodes::SAVE_USER_CONFIG);
01082 WaitMicroWrite();
01083 usleep(10000);
01084 }
01091 void
01092 CCAENV1x90::LoadUserConfig()
01093 {
01094 WriteMicro(CCAENV1x90Opcodes::LOAD_USER_CONFIG);
01095 WaitMicroWrite();
01096 }
01104 void
01105 CCAENV1x90::AutoLoadUserConfig()
01106 {
01107 WriteMicro(CCAENV1x90Opcodes::AUTOLOAD_USER_CONFIG);
01108 WaitMicroWrite();
01109 usleep(10000);
01110
01111 }
01122 void
01123 CCAENV1x90::AutoLoadDefaultConfig()
01124 {
01125 WriteMicro(CCAENV1x90Opcodes::AUTOLOAD_DEF_CONFIG);
01126 WaitMicroWrite();
01127 usleep(10000);
01128
01129 }
01141 void
01142 CCAENV1x90::SetWindowWidth(unsigned int nWidth)
01143 {
01144 REQUIRE(nWidth >= MINMATCHWIDTH,
01145 FormatValue("Window width must be > %x",
01146 MINMATCHWIDTH).c_str());
01147 REQUIRE(nWidth <= MAXMATCHWIDTH,
01148 FormatValue(" Window width must be <= 0x%x",
01149 MAXMATCHWIDTH).c_str());
01150
01151 WriteMicro(CCAENV1x90Opcodes::SET_WIN_WIDTH);
01152 WriteMicro(nWidth);
01153 WaitMicroWrite();
01154
01155 }
01167 void
01168 CCAENV1x90::SetWindowOffset(int nOffset)
01169 {
01170 REQUIRE(nOffset >= MINWINDOWOFFSET,
01171 FormatValue("Window offset must be at least %d",
01172 MINWINDOWOFFSET).c_str());
01173 REQUIRE(nOffset <= MAXWINDOWOFFSET,
01174 FormatValue("Window offset must be no greater than %d",
01175 MAXWINDOWOFFSET).c_str());
01176 WriteMicro(CCAENV1x90Opcodes::SET_WIN_OFFS);
01177 WriteMicro(nOffset);
01178 WaitMicroWrite();
01179
01180 }
01181
01198 void
01199 CCAENV1x90::SetExtraSearchMargin(unsigned int nMargin)
01200 {
01201 REQUIRE(nMargin >= 0,
01202 FormatValue(" nMargin must be >=%d",
01203 MINEXTRAMARGIN).c_str());
01204 REQUIRE(nMargin <= 2047,
01205 FormatValue("nMargin must be <= %d",
01206 MAXEXTRAMARGIN).c_str());
01207
01208 WriteMicro(CCAENV1x90Opcodes::SET_SW_MARGIN);
01209 WriteMicro(nMargin);
01210 WaitMicroWrite();
01211
01212
01213 }
01228 void
01229 CCAENV1x90::SetRejectMargin(unsigned int nMargin)
01230 {
01231 REQUIRE(nMargin >= 0,
01232 FormatValue("nMargin must be >= %d",
01233 MINREJECTMARGIN).c_str());
01234 REQUIRE(nMargin <= 2047,
01235 FormatValue("nMargin must be <= %d",
01236 MAXREJECTMARGIN).c_str());
01237
01238 WriteMicro(CCAENV1x90Opcodes::SET_REJ_MARGIN);
01239 WriteMicro(nMargin);
01240 WaitMicroWrite();
01241 }
01249 void
01250 CCAENV1x90::EnableTriggerTimeSubtraction()
01251 {
01252 WriteMicro(CCAENV1x90Opcodes::EN_SUB_TRG);
01253 WaitMicroWrite();
01254 }
01260 void
01261 CCAENV1x90::DisableTriggerTimeSubtraction()
01262 {
01263 WriteMicro(CCAENV1x90Opcodes::DIS_SUB_TRG);
01264 WaitMicroWrite();
01265
01266 }
01267
01291 CCAENV1x90::TriggerConfiguration
01292 CCAENV1x90::GetTriggerConfiguration()
01293 {
01294
01295 TriggerConfiguration config;
01296 MicroTransaction(CCAENV1x90Opcodes::READ_TRG_CONF,
01297 &config, sizeof(config)/sizeof(short));
01298 return config;
01299 }
01313 unsigned int
01314 CCAENV1x90::GetMatchWindow(TriggerConfiguration Config)
01315 {
01316 return (Config.s_MatchWidth & MATCHMASK);
01317 }
01330 int
01331 CCAENV1x90::GetWindowOffset(TriggerConfiguration Config)
01332 {
01333 int nOffset = (Config.s_MatchOffset & WINDOWOFFSETMASK);
01334
01335
01336
01337
01338
01339
01340 if(nOffset & (WINDOWOFFSETMASK & ~(WINDOWOFFSETMASK >> 1))) {
01341 nOffset |= ~(WINDOWOFFSETMASK);
01342 }
01343 return nOffset;
01344 }
01358 unsigned int
01359 CCAENV1x90::GetExtraSearchMargin(TriggerConfiguration Config)
01360 {
01361 return Config.s_MatchExtra & EXTRAMARGINMASK;
01362 }
01363
01375 unsigned int
01376 CCAENV1x90::GetRejectMargin(TriggerConfiguration Config)
01377 {
01378 return Config.s_RejectMargin & REJECTMARGINMASK;
01379 }
01395 bool
01396 CCAENV1x90::isTriggerTimeSubtracted(TriggerConfiguration Config)
01397 {
01398 return ((Config.s_Subtracting & TRUEBIT) != 0);
01399 }
01419 void
01420 CCAENV1x90::SetIndividualLSB(Resolution nResolution)
01421 {
01422
01423
01424
01425 REQUIRE(((nResolution == Res_25ps) ||
01426 (nResolution == Res_100ps) ||
01427 (nResolution == Res_200ps) ||
01428 (nResolution == Res_800ps)),
01429 "Resolution is not a legal value");
01430 if(nResolution == Res_25ps) {
01431 REQUIRE(m_fCanHiRes, "Only 1290 can be put in 25ps resolution");
01432 }
01433
01434 WriteMicro(CCAENV1x90Opcodes::SET_TR_LEAD_LSB);
01435 WriteMicro(nResolution);
01436 WaitMicroWrite();
01437
01438
01439
01440
01441
01442 if(nResolution == Res_25ps) {
01443 m_fIsHiResMode = true;
01444 } else {
01445 m_fIsHiResMode = false;
01446 }
01447
01448 }
01449
01450
01473 void
01474 CCAENV1x90::SetEdgeDetectMode(EdgeMode nEdgeMode)
01475 {
01476
01477
01478 REQUIRE( ((nEdgeMode == EdgeMode_Pair) ||
01479 (nEdgeMode == EdgeMode_Trailing) ||
01480 (nEdgeMode == EdgeMode_Leading) ||
01481 (nEdgeMode == EdgeMode_Both)),
01482 "Invalid edge mode");
01483 if(m_fCanHiRes & m_fIsHiResMode) {
01484 REQUIRE(nEdgeMode != EdgeMode_Pair,
01485 "Pair mode is not available in High resolution mode");
01486 }
01487
01488
01489
01490 WriteMicro(CCAENV1x90Opcodes::SET_DETECTION);
01491 WriteMicro(nEdgeMode);
01492 WaitMicroWrite();
01493 }
01494
01506 CCAENV1x90::EdgeMode
01507 CCAENV1x90::GetEdgeDetectMode()
01508 {
01509 WriteMicro(CCAENV1x90Opcodes::READ_DETECTION);
01510 unsigned short n = ReadMicro();
01511 n &= EDGEDETECTIONMASK;
01512 return static_cast<EdgeMode>(n);
01513
01514 }
01557 void
01558 CCAENV1x90::SetPairResolutions(LEResolution nLEResolution,
01559 PWResolution nPWResolution)
01560 {
01561
01562
01563 REQUIRE((GetEdgeDetectMode() == EdgeMode_Pair),
01564 "Edge detection mode is not pair");
01565 REQUIRE( ((nLEResolution == LE_100ps) ||
01566 (nLEResolution == LE_200ps) ||
01567 (nLEResolution == LE_400ps) ||
01568 (nLEResolution == LE_800ps) ||
01569 (nLEResolution == LE_1600ps) ||
01570 (nLEResolution == LE_3120ps) ||
01571 (nLEResolution == LE_6250ps) ||
01572 (nLEResolution == LE_12500ps)),
01573 "Leading edge resolution invalid");
01574
01575 REQUIRE( ((nPWResolution == PW_100ps) ||
01576 (nPWResolution == PW_200ps) ||
01577 (nPWResolution == PW_400ps) ||
01578 (nPWResolution == PW_800ps) ||
01579 (nPWResolution == PW_1600ps) ||
01580 (nPWResolution == PW_3200ps) ||
01581 (nPWResolution == PW_6250ps) ||
01582 (nPWResolution == PW_12500ps) ||
01583 (nPWResolution == PW_25ns) ||
01584 (nPWResolution == PW_50ns) ||
01585 (nPWResolution == PW_100ns) ||
01586 (nPWResolution == PW_200ns) ||
01587 (nPWResolution == PW_400ns) ||
01588 (nPWResolution == PW_800ns)),
01589 "Pair width resolution is invalid.");
01590
01591
01592
01593 unsigned short settings = nLEResolution |
01594 (nPWResolution << PWRESOLUTIONRSHIFT);
01595
01596
01597
01598 WriteMicro(CCAENV1x90Opcodes::SET_PAIR_RES);
01599 WriteMicro(settings);
01600 WaitMicroWrite();
01601
01602 }
01620 unsigned short
01621 CCAENV1x90::GetResolution()
01622 {
01623 WriteMicro(CCAENV1x90Opcodes::READ_RES);
01624 return ReadMicro();
01625
01626 }
01644 CCAENV1x90::Resolution
01645 CCAENV1x90::InterpretEdgeResolution(unsigned short nResolution)
01646 {
01647
01648
01649 REQUIRE(GetEdgeDetectMode() != EdgeMode_Pair,
01650 "Edge resolution asked for when module in pair mode");
01651
01652
01653
01654 unsigned short nMask = nResolution &
01655 EDGERESOLUTIONMASK;
01656 return static_cast<Resolution>(nMask);
01657 }
01679 CCAENV1x90::LEResolution
01680 CCAENV1x90::InterpretLEResolution(unsigned short nResolution)
01681 {
01682
01683
01684 REQUIRE(GetEdgeDetectMode() == EdgeMode_Pair,
01685 "LE resolution requested with module not in pair mode");
01686
01687
01688
01689 unsigned short nMask = nResolution & LERESOLUTIONMASK;
01690 return static_cast<LEResolution>(nMask);
01691
01692 }
01721 CCAENV1x90::PWResolution
01722 CCAENV1x90::InterpretWidthResolution(unsigned short nResolution)
01723 {
01724
01725
01726 REQUIRE(GetEdgeDetectMode() == EdgeMode_Pair,
01727 "PW resolution requested when not in pair mode");
01728
01729
01730 unsigned short nMask = (nResolution & PWRESOLUTIONMASK) >>
01731 PWRESOLUTIONRSHIFT;
01732 return static_cast<PWResolution>(nMask);
01733 }
01749 void
01750 CCAENV1x90::SetDoubleHitResolution(DeadTime nDeadTime)
01751 {
01752
01753
01754 REQUIRE((nDeadTime == DT_5ns) ||
01755 (nDeadTime == DT_10ns) ||
01756 (nDeadTime == DT_30ns) ||
01757 (nDeadTime == DT_100ns),
01758 "Invalid dead time value");
01759
01760 WriteMicro(CCAENV1x90Opcodes::SET_DEAD_TIME);
01761 WriteMicro(nDeadTime);
01762 WaitMicroWrite();
01763
01764 }
01776 CCAENV1x90::DeadTime
01777 CCAENV1x90::GetDoubleHitResolution()
01778 {
01779 WriteMicro(CCAENV1x90Opcodes::READ_DEAD_TIME);
01780 unsigned short nMask = ReadMicro();
01781 nMask &= 3;
01782 return static_cast<DeadTime>(nMask);
01783
01784 }
01789 void
01790 CCAENV1x90::EnableTDCEncapsulation()
01791 {
01792 WriteMicro(CCAENV1x90Opcodes::EN_HEADER_TRAILER);
01793 WaitMicroWrite();
01794 }
01795
01800 void
01801 CCAENV1x90::DisableTDCEncapsulation()
01802 {
01803 WriteMicro(CCAENV1x90Opcodes::DIS_HEADER_TRAILER);
01804 WaitMicroWrite();
01805 }
01814 bool
01815 CCAENV1x90::isTDCEncapsulationOn()
01816 {
01817 WriteMicro(CCAENV1x90Opcodes::READ_HEADER_TRAILER);
01818 return (ReadMicro() & TRUEBIT) != 0;
01819
01820 }
01843 void
01844 CCAENV1x90::SetMaxHitsPerEvent(HitMax nHits)
01845 {
01846
01847
01848 REQUIRE((nHits == HITS_0) ||
01849 (nHits == HITS_1) ||
01850 (nHits == HITS_2) ||
01851 (nHits == HITS_4) ||
01852 (nHits == HITS_8) ||
01853 (nHits == HITS_16) ||
01854 (nHits == HITS_32) ||
01855 (nHits == HITS_64) ||
01856 (nHits == HITS_128) ||
01857 (nHits == HITS_UNLIMITED),
01858 "Invalid nHits parameter value");
01859
01860
01861
01862 WriteMicro(CCAENV1x90Opcodes::SET_EVENT_SIZE);
01863 WriteMicro(static_cast<unsigned short>(nHits));
01864 WaitMicroWrite();
01865 }
01882 CCAENV1x90::HitMax
01883 CCAENV1x90::GetMaxHitsPerEvent()
01884 {
01885 WriteMicro(CCAENV1x90Opcodes::READ_EVENT_SIZE);
01886 unsigned short nMask = ReadMicro();
01887 return static_cast<HitMax>(nMask);
01888 }
01889
01895 void
01896 CCAENV1x90::EnableErrorMark()
01897 {
01898 WriteMicro(CCAENV1x90Opcodes::EN_ERROR_MARK);
01899 WaitMicroWrite();
01900 }
01905 void
01906 CCAENV1x90::DisableErrorMark()
01907 {
01908 WriteMicro(CCAENV1x90Opcodes::DIS_ERROR_MARK);
01909 WaitMicroWrite();
01910 }
01915 void
01916 CCAENV1x90::EnableBypassOnError()
01917 {
01918 WriteMicro(CCAENV1x90Opcodes::EN_ERROR_BYPASS);
01919 WaitMicroWrite();
01920 }
01925 void
01926 CCAENV1x90::DisableBypassOnError()
01927 {
01928 WriteMicro(CCAENV1x90Opcodes::DIS_ERROR_BYPASS);
01929 WaitMicroWrite();
01930 }
01957 void
01958 CCAENV1x90::SetErrorEnables(unsigned short nErrors)
01959 {
01960
01961
01962 REQUIRE((nErrors & ~( ERR_VERNIER &
01963 ERR_SELECT &
01964 ERR_L1PARITY &
01965 ERR_TFIFOPARITY &
01966 ERR_MATCHERROR &
01967 ERR_RFIFOPARITY &
01968 ERR_RDOSTATE &
01969 ERR_SUPPARITY &
01970 ERR_CTLPARITY &
01971 ERR_JTAGPARITY)),
01972 "Error mask contains extra set bits.");
01973
01974
01975
01976 WriteMicro(CCAENV1x90Opcodes::SET_ERROR_TYPES);
01977 WriteMicro(nErrors);
01978 WaitMicroWrite();
01979 }
01980
01987 unsigned short
01988 CCAENV1x90::GetErrorEnables()
01989 {
01990 WriteMicro(CCAENV1x90Opcodes::READ_ERROR_TYPES);
01991 return ReadMicro();
01992 }
01993
01994
02013 void
02014 CCAENV1x90::SetL1Size(L1Size nL1Size)
02015 {
02016
02017
02018 REQUIRE((nL1Size == L1_2wds) ||
02019 (nL1Size == L1_4wds) ||
02020 (nL1Size == L1_8wds) ||
02021 (nL1Size == L1_16wds) ||
02022 (nL1Size == L1_32wds) ||
02023 (nL1Size == L1_64wds) ||
02024 (nL1Size == L1_128wds) ||
02025 (nL1Size == L1_256wds),
02026 "L1 size selector is invalid");
02027
02028
02029
02030 WriteMicro(CCAENV1x90Opcodes::SET_FIFO_SIZE);
02031 WriteMicro(nL1Size);
02032 WaitMicroWrite();
02033
02034
02035 }
02041 CCAENV1x90::L1Size
02042 CCAENV1x90::GetL1Size()
02043 {
02044 WriteMicro(CCAENV1x90Opcodes::READ_FIFO_SIZE);
02045 return static_cast<L1Size>(ReadMicro());
02046 }
02047
02064 void
02065 CCAENV1x90::EnableChannel(unsigned short nChannel)
02066 {
02067 REQUIRE(nChannel < m_nChannels, "Channel number out of range");
02068
02069
02070 WriteMicro(CCAENV1x90Opcodes::EN_CHANNEL | nChannel);
02071 WaitMicroWrite();
02072 }
02086 void
02087 CCAENV1x90::DisableChannel(unsigned short nChannel)
02088 {
02089 REQUIRE(nChannel < m_nChannels, "Channel Number out of range");
02090
02091
02092
02093 WriteMicro(CCAENV1x90Opcodes::DIS_CHANNEL | nChannel);
02094 WaitMicroWrite();
02095
02096 }
02097
02101 void
02102 CCAENV1x90::EnableAllChannels()
02103 {
02104 WriteMicro(CCAENV1x90Opcodes::EN_ALL_CH);
02105 WaitMicroWrite();
02106 }
02110 void
02111 CCAENV1x90::DisableAllChannels()
02112 {
02113 WriteMicro(CCAENV1x90Opcodes::DIS_ALL_CH);
02114 WaitMicroWrite();
02115 }
02128 void
02129 CCAENV1x90::SetChannelEnables(vector<unsigned short> nMask)
02130 {
02131
02132
02133 REQUIRE(nMask.size() == m_nChannels/(sizeof(short)*8),
02134 "Enables mask is not the right size.");
02135
02136
02137
02138 unsigned short* pWords = new unsigned short[nMask.size() + 1];
02139
02140 pWords[0] = CCAENV1x90Opcodes::WRITE_EN_PATTERN;
02141 for(int i =0; i < nMask.size(); i++) {
02142 pWords[i+1] = nMask[i];
02143 }
02144
02145 WriteMicroBlock(pWords, nMask.size()+1);
02146 WaitMicroWrite();
02147
02148 delete []pWords;
02149
02150 }
02166 void
02167 CCAENV1x90::GetChannelEnables(vector<unsigned short>& masks)
02168 {
02169 unsigned int nMasks = m_nChannels/(sizeof(short)*8);
02170
02171 unsigned short* localMasks = new unsigned short[nMasks];
02172
02173 MicroTransaction(CCAENV1x90Opcodes::READ_EN_PATTERN,
02174 localMasks, nMasks);
02175
02176 for(int i =0; i < nMasks; i++) {
02177 masks.push_back(localMasks[i]);
02178 }
02179 delete []localMasks;
02180
02181 }
02182
02198 void
02199 CCAENV1x90::SetChipEnables(unsigned short nChip,
02200 unsigned int nMask)
02201 {
02202
02203
02204 REQUIRE(nChip < m_nChipCount,
02205 "Chip number is not valid for this model");
02206
02207
02208
02209
02210
02211 unsigned short wordMask;
02212
02213 WriteMicro(CCAENV1x90Opcodes::WRITE_EN_PATTERN32 | nChip);
02214
02215 wordMask = LO(nMask);
02216 WriteMicro(wordMask);
02217
02218 wordMask = HI(nMask);
02219 WriteMicro(wordMask);
02220 WaitMicroWrite();
02221
02222 }
02223
02239 unsigned int
02240 CCAENV1x90::GetChipEnables(unsigned short nChip)
02241 {
02242
02243
02244 REQUIRE(nChip < m_nChipCount,
02245 FormatValue("Invalid chip number %d",
02246 nChip).c_str());
02247
02248
02249
02250
02251 unsigned int mask;
02252
02253 WriteMicro(CCAENV1x90Opcodes::READ_EN_PATTERN32 | nChip);
02254
02255 mask = (static_cast<unsigned int>(ReadMicro())) & 0xffff;
02256 unsigned int top = ReadMicro();
02257 mask |= (top << 16);
02258
02259
02260 return mask;
02261
02262 }
02279 void
02280 CCAENV1x90::SetGlobalOffset(unsigned short nCoarse,
02281 unsigned short nVernier)
02282 {
02283
02284
02285 REQUIRE(nCoarse <= COARSEMAX,
02286 FormatValue("Global offset coarse value %d",
02287 nCoarse).c_str());
02288 REQUIRE(nVernier <= VERNIERMAX,
02289 FormatValue("Vernier offset is invalid: %d",
02290 nVernier).c_str());
02291
02292
02293
02294 WriteMicro(CCAENV1x90Opcodes::SET_GLOB_OFFS);
02295 WriteMicro(nCoarse);
02296 WriteMicro(nVernier);
02297 WaitMicroWrite();
02298
02299 }
02300
02313 void
02314 CCAENV1x90::ReadGlobalOffset(unsigned short& nCoarse,
02315 unsigned short& nVernier)
02316 {
02317 WriteMicro(CCAENV1x90Opcodes::READ_GLOB_OFFS);
02318 nCoarse = (ReadMicro() & COARSEMASK);
02319 nVernier= (ReadMicro() & VERNIERMASK);
02320
02321 }
02322
02338 void
02339 CCAENV1x90::SetChannelOffset(unsigned short nChannel,
02340 unsigned short nOffset)
02341 {
02342
02343
02344 REQUIRE(nChannel < m_nChannels,
02345 " Channel number out of range");
02346 REQUIRE(nOffset <= CHANOFFSETMAX,
02347 FormatValue("Offset value out of range: %d",
02348 nOffset).c_str());
02349
02350
02351
02352 WriteMicro(CCAENV1x90Opcodes::SET_ADJUST_CH | nChannel);
02353 WriteMicro(nOffset);
02354 WaitMicroWrite();
02355 }
02370 unsigned short
02371 CCAENV1x90::GetChannelOffset(unsigned int nChannel)
02372 {
02373
02374
02375 REQUIRE(nChannel < m_nChannels,
02376 "Channel number out of range");
02377
02378
02379
02380 WriteMicro(CCAENV1x90Opcodes::READ_ADJUST_CH | nChannel);
02381 return (ReadMicro() & CHANOFFSETMASK);
02382 }
02415 void
02416 CCAENV1x90::CalibrateDelayLine(unsigned short nChip,
02417 unsigned short Tap1Contact,
02418 unsigned short Tap2Contact,
02419 unsigned short Tap3Contact,
02420 unsigned short Tap4Contact)
02421 {
02422
02423
02424 REQUIRE(nChip < m_nChipCount,
02425 "Chip number is not in range");
02426
02427 REQUIRE((Tap1Contact & ~(TAP_CONTACT1 | TAP_CONTACT2 | TAP_CONTACT3)) == 0,
02428 " Tap 1 contact has extra bits");
02429 REQUIRE((Tap2Contact & ~(TAP_CONTACT1 | TAP_CONTACT2 | TAP_CONTACT3)) == 0,
02430 " Tap 1 contact has extra bits");
02431 REQUIRE((Tap3Contact & ~(TAP_CONTACT1 | TAP_CONTACT2 | TAP_CONTACT3)) == 0,
02432 " Tap 1 contact has extra bits");
02433 REQUIRE((Tap4Contact & ~(TAP_CONTACT1 | TAP_CONTACT2 | TAP_CONTACT3)) == 0,
02434 " Tap 1 contact has extra bits");
02435
02436
02437
02438 unsigned short TapMask = (Tap1Contact) |
02439 (Tap2Contact << 3) |
02440 (Tap3Contact << 6) |
02441 (Tap4Contact << 9);
02442
02443
02444 WriteMicro(CCAENV1x90Opcodes::SET_RC_ADJ | nChip);
02445 WriteMicro(TapMask);
02446 WaitMicroWrite();
02447 }
02468 void
02469 CCAENV1x90::GetDelayLineCalibration(unsigned short nChip,
02470 unsigned short& Tap1Contact,
02471 unsigned short& Tap2Contact,
02472 unsigned short& Tap3Contact,
02473 unsigned short& Tap4Contact)
02474 {
02475 WriteMicro(CCAENV1x90Opcodes::READ_RC_ADJ | nChip);
02476 unsigned short TapMask = ReadMicro();
02477
02478 Tap1Contact = (TapMask & TAPCONTACTMASK);
02479 Tap2Contact = (TapMask >> TAPCONTACTRSHIFT) & TAPCONTACTMASK;
02480 Tap3Contact = (TapMask >> (2*TAPCONTACTRSHIFT)) & TAPCONTACTMASK;
02481 Tap4Contact = (TapMask >> (3*TAPCONTACTRSHIFT)) & TAPCONTACTMASK;
02482
02483 }
02490 void
02491 CCAENV1x90::SaveDelayLineCalibrations()
02492 {
02493 WriteMicro(CCAENV1x90Opcodes::SAVE_RC_ADJ);
02494 WaitMicroWrite();
02495
02496 }
02514 unsigned int
02515 CCAENV1x90::GetChipId(unsigned short nChip)
02516 {
02517 REQUIRE(nChip < m_nChipCount,
02518 "Chip number invalid for this board");
02519
02520
02521 WriteMicro(CCAENV1x90Opcodes::READ_TDC_ID | nChip);
02522
02523
02524
02525 unsigned int nId = ReadMicro();
02526 nId |= (static_cast<unsigned int>(ReadMicro())) << 16;
02527 return nId;
02528 }
02529
02530
02545 void
02546 CCAENV1x90::GetuCFirmwareInfo(unsigned short& nRevision,
02547 unsigned short& nDay,
02548 unsigned short& nMonth,
02549 unsigned short& nYear)
02550 {
02551 WriteMicro(CCAENV1x90Opcodes::REV_DATE_MICRO_FW);
02552 nRevision = ReadMicro();
02553 nDay = ReadMicro();
02554 nMonth = ReadMicro();
02555 nYear = ReadMicro();
02556 }
02557
02570 unsigned short
02571 CCAENV1x90::GetChipErrors(unsigned short nChip)
02572 {
02573 REQUIRE(nChip < m_nChipCount,
02574 "Chip number is out of range for this module");
02575
02576 WriteMicro(CCAENV1x90Opcodes::READ_ERROR_STATUS | nChip);
02577
02578 unsigned short nErrors = ReadMicro();
02579
02580 nErrors &= ~(ERR_VERNIER |
02581 ERR_COARSE |
02582 ERR_SELECT |
02583 ERR_L1PARITY |
02584 ERR_TFIFOPARITY |
02585 ERR_MATCHERROR |
02586 ERR_RFIFOPARITY |
02587 ERR_RDOSTATE |
02588 ERR_SUPPARITY |
02589 ERR_CTLPARITY |
02590 ERR_JTAGPARITY);
02591 return nErrors;
02592 }
02608 void
02609 CCAENV1x90::EnableTestMode(unsigned int nValue)
02610 {
02611
02612
02613 REQUIRE((nValue & ~(MAXTESTVALUE)) == 0,
02614 "The data value has extraneous bits");
02615
02616
02617
02618
02619 unsigned short nLow = LO(nValue);
02620 unsigned short nHigh = HI(nValue);
02621
02622 WriteMicro(CCAENV1x90Opcodes::ENABLE_TEST_MODE);
02623 WriteMicro(nLow);
02624 WriteMicro(nHigh);
02625 WaitMicroWrite();
02626
02627 }
02628
02633 void
02634 CCAENV1x90::DisableTestMode()
02635 {
02636 WriteMicro(CCAENV1x90Opcodes::DISABLE_TEST_MODE);
02637 WaitMicroWrite();
02638 }
02639
02641
02661 unsigned int
02662 CCAENV1x90::ReadData(void* pBuffer,
02663 unsigned int nMaxLongs)
02664 {
02665 if(m_fTriggerMatching) {
02666 return ReadPacket(pBuffer, nMaxLongs);
02667 } else {
02668 return ReadValid(pBuffer, nMaxLongs);
02669 }
02670 }
02697 unsigned int
02698 CCAENV1x90::ReadPacket(void* pBuffer,
02699 unsigned int nMaxLongs)
02700 {
02701 unsigned long* pPacket = (unsigned long*)pBuffer;
02702 unsigned int nRead = 0;
02703
02704
02705
02706
02707
02708
02709 bool done(false);
02710 while(!done) {
02711 unsigned long datum = m_pRegisters.peekl(OffsetL(OutputBuffer));
02712 *pPacket = datum;
02713 if(isGlobalTrailer(datum) || isFiller(datum)) {
02714 done = true;
02715 }
02716 if(nRead < nMaxLongs) {
02717 pPacket++;
02718 nRead++;
02719 }
02720 }
02721
02722 return nRead;
02723 }
02738 unsigned int
02739 CCAENV1x90::ReadValid(void* pBuffer, unsigned int nMaxLongs)
02740 {
02741 unsigned long* pLongs = (unsigned long*)pBuffer;
02742 unsigned int nRead = 0;
02743 bool done = false;
02744
02745 while(!done) {
02746 unsigned long datum = m_pRegisters.peekl(OffsetL(OutputBuffer));
02747 *pLongs++ = datum;
02748 nRead++;
02749
02750 if(isGlobalTrailer(datum) ||
02751 isFiller(datum) ||
02752 (nRead == nMaxLongs)) {
02753 done = true;
02754 }
02755 }
02756
02757 return nRead;
02758 }
02759
02761
02779 bool
02780 CCAENV1x90::ValidBoard(CVmeModule& pRom)
02781 {
02782
02783
02784 unsigned long oui = ReadPromLong(pRom, WOUI2);
02785 if(oui != 0x0040e6) {
02786 return false;
02787 }
02788
02789
02790
02791 unsigned long nModel = ReadPromLong(pRom, WModelNumber2);
02792 if((nModel != 1190) && (nModel != 1290)) {
02793 return false;
02794 }
02795
02796
02797
02798 unsigned char nType =
02799 pRom.peekw(OffsetW(WBoardVersion)) & 0xff;
02800
02801 if(nModel == 1190) {
02802 if((nType != ModuleVersion::A) &&
02803 (nType != ModuleVersion::B)) {
02804 return false;
02805 }
02806 }
02807 else {
02808 if((nType != ModuleVersion::A) &&
02809 (nType != ModuleVersion::N)) {
02810 return false;
02811 }
02812 }
02813
02814
02815 return true;
02816 }
02817
02842 void
02843 CCAENV1x90::BoardProperties(CVmeModule& pROM)
02844 {
02845 m_nModel = ReadPromLong(pROM,WModelNumber2);
02846
02847
02848
02849 unsigned short ntype=
02850 pROM.peekw(OffsetW(WBoardVersion)) & 0xff;
02851 if(ntype == ModuleVersion::A) {
02852 m_cVersion = 'A';
02853 }
02854 else if (ntype == ModuleVersion::B) {
02855 m_cVersion = 'B';
02856 }
02857 else if (ntype == ModuleVersion::N) {
02858 m_cVersion = 'N';
02859 }
02860 else {
02861 throw string("Unrecognized module subtype, not A,B, nor N");
02862 }
02863
02864
02865
02866 m_nSerialNumber =
02867 (pROM.peekw(OffsetW(WSerialNumber1)) & 0xff) << 8;
02868 m_nSerialNumber |=
02869 (pROM.peekw(OffsetW(WSerialNumber0)) & 0xff);
02870
02871
02872
02873
02874 m_nBoardRevision = ReadPromLong(pROM, WRevision3);
02875 m_nBoardRevision = (m_nBoardRevision << 8) |
02876 (pROM.peekw(OffsetW(WRevision0)) & 0xff);
02877
02878
02879
02880
02881
02882
02883
02884
02885 if(m_nModel == 1190) {
02886 m_fCanHiRes = false;
02887 if(m_cVersion == 'A') {
02888 m_nChannels = 128;
02889 m_nChipCount= 4;
02890 }
02891 else {
02892 m_nChannels = 64;
02893 m_nChipCount= 2;
02894 }
02895 }
02896 else {
02897 m_fCanHiRes = true;
02898 if(m_cVersion == 'A') {
02899 m_nChannels = 32;
02900 m_nChipCount = 4;
02901 }
02902 else {
02903 m_nChannels = 16;
02904 m_nChipCount = 2;
02905 }
02906 }
02907
02908
02909
02910
02911
02912
02913 unsigned short sr = SR();
02914 m_fTriggerMatching = (sr & StatusRegister::TRG_MATCH) ==
02915 StatusRegister::TRG_MATCH;
02916 m_fIsHiResMode = (sr & StatusRegister::RESOLUTIONMASK) ==
02917 StatusRegister::RES_25ps;
02918
02919 }
02920
02930 unsigned short
02931 CCAENV1x90::SR()
02932 {
02933 return m_pRegisters.peekw(OffsetW(WStatusRegister));
02934 }
02935
02954 bool
02955 CCAENV1x90::isSetSR(unsigned short bitnum)
02956 {
02957 return (SR() & (1 << bitnum)) != 0;
02958 }
02959
02970 void
02971 CCAENV1x90::WriteCR(unsigned short mask)
02972 {
02973 m_pRegisters.pokew(mask, OffsetW(WControlRegister));
02974 }
02975
02984 unsigned short
02985 CCAENV1x90::ReadCR()
02986 {
02987 return m_pRegisters.peekw(OffsetW(WControlRegister));
02988 }
02998 void
02999 CCAENV1x90::BitSetCR(unsigned short bit)
03000 {
03001 unsigned short cr = ReadCR();
03002 cr |= (1 << bit);
03003 WriteCR(cr);
03004 }
03005
03014 void
03015 CCAENV1x90::BitClearCR(unsigned short bit)
03016 {
03017 unsigned short cr = ReadCR();
03018 cr &= ~(1 << bit);
03019 WriteCR(cr);
03020 }
03021
03022
03038 unsigned long
03039 CCAENV1x90::ReadPromLong(CVmeModule& prombase,
03040 unsigned long ByteOffset)
03041 {
03042 unsigned long n;
03043 unsigned long WordOffset = OffsetW(ByteOffset);
03044
03045 n = (prombase.peekw(WordOffset) & 0xff) << 16;
03046 n |= (prombase.peekw(WordOffset+2) & 0xff) << 8;
03047 n |= (prombase.peekw(WordOffset+4) & 0xff);
03048
03049 return n;
03050
03051 }
03055 void
03056 CCAENV1x90::WaitMicroWrite()
03057 {
03058
03059 while((m_pRegisters.peekw(OffsetW(WMicroHandshake)) &
03060 MicroHandshake::WRITE_OK) == 0)
03061 ;
03062
03063 }
03064
03075 void
03076 CCAENV1x90::WriteMicro(unsigned short nWord)
03077 {
03078
03079
03080 WaitMicroWrite();
03081
03082
03083
03084 m_pRegisters.pokew(nWord, OffsetW(WMicroData));
03085
03086 }
03100 unsigned short
03101 CCAENV1x90::ReadMicro()
03102 {
03103
03104
03105 while((m_pRegisters.peekw(OffsetW(WMicroHandshake)) &
03106 MicroHandshake::READ_OK) == 0)
03107 ;
03108
03109
03110
03111 return m_pRegisters.peekw(OffsetW(WMicroData));
03112 }
03126 void
03127 CCAENV1x90::WriteMicroBlock(void* pWords,
03128 unsigned int nWords)
03129 {
03130 unsigned short* pW = (unsigned short*) pWords;
03131
03132 for(int i = 0; i < nWords; i++) {
03133 WriteMicro(*pW++);
03134 }
03135 }
03148 void
03149 CCAENV1x90::ReadMicroBlock(void* pWords,
03150 unsigned int nWords)
03151 {
03152 unsigned short* pW = (unsigned short*) pWords;
03153
03154 for(int i =0; i < nWords; i++) {
03155 *pW++ = ReadMicro();
03156 }
03157 }
03173 void
03174 CCAENV1x90::MicroTransaction(unsigned short opcode,
03175 void* pWords,
03176 unsigned int nWords)
03177 {
03178 WriteMicro(opcode);
03179 ReadMicroBlock(pWords, nWords);
03180 }