00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <config.h>
00019 #include "CAENcard_767.h"
00020
00021
00022
00023 #include <string>
00024 #include <Iostream.h>
00025 #include <CVMEInterface.h>
00026
00027 #ifdef HAVE_STD_NAMESPACE
00028 using namespace std;
00029 #endif
00030
00031
00032
00055 CAENcard_767::CAENcard_767(int slotNum, int crateNum,
00056 bool fisGeo, unsigned long nBase) :
00057 slot(0),
00058 m_pSpace(0)
00059
00060 {
00061 if(slotInit(slotNum, crateNum, fisGeo, nBase) < 0) {
00062 throw string("CAENcard_767 construction failed!");
00063 }
00064
00065 };
00066
00078 CAENcard_767::CAENcard_767(const CAENcard_767& card) :
00079 slot(card.slot),
00080 m_pSpace(card.m_pSpace)
00081 {
00082
00083 };
00084
00093 CAENcard_767&
00094 CAENcard_767::operator=(const CAENcard_767& card)
00095 {
00096 if(this != &card) {
00097 slot = card.slot;
00098 m_pSpace = card.m_pSpace;
00099 }
00100 return *this;
00101
00102 };
00103
00125 int CAENcard_767::slotInit(int slotNum, int crateNum,
00126 bool fisGeo, unsigned long nBase)
00127 {
00128
00129
00130
00131
00132 slot = slotNum;
00133
00134
00135 if((slot > VME_CRATE_SIZE) || (slot <= 0))
00136 {
00137 perror("Invalid slot number specified to slotInit(). ");
00138 return(-1);
00139 }
00140
00141
00142
00143
00144
00145
00146 CVmeModule::Space space;
00147 unsigned long base;
00148
00149
00150
00151 if (fisGeo) {
00152 space = CAEN_GEO24;
00153 base = slot << 19;
00154 }
00155 else {
00156 space = CAEN_A32D16;
00157 base = nBase;
00158 }
00159
00160 try {
00161 m_pSpace = new CVmeModule(space, base, CAEN_767_CARD_MMAP_LEN, crateNum);
00162 }
00163 catch (string& msg) {
00164 cerr << "Could not map crate: " << crateNum << " slot: " << slot
00165 << " : " << msg << endl;
00166 return(-6);
00167 }
00168
00169
00170
00171 if( !( (0x0040e6 == mfgId()) &&
00172 (767 == cardType()) &&
00173 (((short int)slot == (0x001F & m_pSpace->peekw(CAEN_767_ADDR_GEO))) ||
00174 !fisGeo))) {
00175
00176 printf( "\n767 Card %d is not inserted or is of an incompatable type!\n", slotNum);
00177 printf(" One of the following tests has failed\n");
00178 printf(" 0x0040e6 = 0x%6.6X\n", mfgId());
00179 printf(" 767 == %d\n", cardType());
00180 printf(" 0x%4.4X == 0x%4.4X & 0x001F\n", slot,
00181 m_pSpace->peekw(CAEN_767_ADDR_GEO));
00182
00183 delete m_pSpace;
00184 m_pSpace = NULL;
00185 return(-7);
00186 }
00187
00188
00189 reset();
00190
00191
00192 if(!fisGeo) {
00193 m_pSpace->pokew(slot,CAEN_767_ADDR_GEO);
00194 }
00195
00196
00197
00198 if( ( writeOpcode(0x1900, 1000000) < 0 ) || ( opcodeWait(1000000) < 0 ) )
00199 {
00200 delete m_pSpace;
00201 m_pSpace = NULL;
00202 return(-10);
00203 }
00204
00205
00206
00207
00208
00209 if(fisGeo) {
00210 m_pSpace->pokew(slot, CAEN_767_ADDR_32);
00211 m_pSpace->pokew(0, CAEN_767_ADDR_24);
00212 m_pSpace->pokew(1<<4, CAEN_767_BIT_SET);
00213
00214 delete m_pSpace;
00215 m_pSpace = NULL;
00216 try {
00217 m_pSpace = new CVmeModule(CAEN_A32D16, slot << 24,
00218 CAEN_767_CARD_MMAP_LEN, crateNum);
00219 }
00220 catch (string& msg) {
00221 cerr << "Unable to create relocated address for CAEN-767 "
00222 << msg << endl;
00223 return -11;
00224 }
00225
00226 }
00227
00228
00229
00230
00231
00232
00233 if(cardType() == 767) {
00234 if( ( writeOpcode(0x1500, 1000000) < 0 ) || ( opcodeWait(1000000) < 0 ) )
00235 {
00236 delete m_pSpace;
00237 m_pSpace = NULL;
00238 return(-14);
00239 }
00240 }
00241 sleep(5);
00242
00243 return(0);
00244 };
00245
00250 CAENcard_767::~CAENcard_767()
00251 {
00252 m_pSpace->pokew(1 << 4, CAEN_767_BIT_CLEAR);
00253 delete m_pSpace;
00254 };
00255
00267 int CAENcard_767::readOpcode(unsigned short int *value, int maxRetry)
00268 {
00269 int i;
00270 for( i = 0; i < maxRetry; ++i ) {
00271 if( m_pSpace->peekw(CAEN_767_OPCODE_STATUS) & (1 << 0) ) {
00272
00273 break;
00274 }
00275 }
00276
00277 if( i >= maxRetry ) {
00278
00279 return(-1);
00280 }
00281
00282
00283
00284 usleep(10000);
00285
00286
00287 *value = m_pSpace->peekw(CAEN_767_OPCODE);
00288 return( i );
00289 }
00290
00300 int
00301 CAENcard_767::writeOpcode(unsigned short int value, int maxRetry)
00302 {
00303 int i = opcodeWait(maxRetry);
00304
00305 if (i >= 0) {
00306
00307
00308
00309 usleep(10000);
00310
00311
00312
00313 m_pSpace->pokew(value, CAEN_767_OPCODE);
00314 }
00315 return( i );
00316
00317 };
00327 int CAENcard_767::opcodeWait(int maxRetry)
00328 {
00329 int i;
00330 for( i = 0; i < maxRetry; ++i ) {
00331 if( m_pSpace->peekw(CAEN_767_OPCODE_STATUS) & (1 << 1) ) {
00332
00333 break;
00334 }
00335 }
00336
00337 if( i == maxRetry ) {
00338
00339 return(-2);
00340 }
00341
00342
00343
00344 usleep(10000);
00345
00346 return( i );
00347
00348 }
00349
00354 int CAENcard_767::cardType()
00355 {
00356 return (( (int)m_pSpace->peekw(CAEN_767_BOARD_ID) << 24) |
00357 ( (int)m_pSpace->peekw(CAEN_767_BOARD_ID+2) << 16) |
00358 ( (int)m_pSpace->peekw(CAEN_767_BOARD_ID+4) << 8) |
00359 ( (int)m_pSpace->peekw(CAEN_767_BOARD_ID+6)));
00360 };
00361
00365 void CAENcard_767::clearData()
00366 {
00367 m_pSpace->pokew(1, CAEN_767_CLEAR);
00368
00369 };
00370
00371
00372 void CAENcard_767::reset()
00373 {
00374 m_pSpace->pokew(1, CAEN_767_SS_RESET);
00375 sleep(2);
00376
00377 };
00378
00390 int CAENcard_767::dataPresent()
00391 {
00392
00393 unsigned short s1 = m_pSpace->peekw(CAEN_767_STATUS_1);
00394
00395 return ((s1 & 5) == 1 );
00396
00397 };
00398
00413 int CAENcard_767::readEvent(void* buf)
00414 {
00415 int temp, n = dataPresent();
00416 if(n > 0) {
00417 n = 0;
00418
00419 temp = m_pSpace->peekl(0);
00420 while( (temp & CAEN_767_DATUM_TYPE) != CAEN_767_INVALID ) {
00421 *(((int*)buf) + n) = temp;
00422 ++n;
00423 temp = m_pSpace->peekl(0);
00424 }
00425 n *= 4;
00426 }
00427
00428 return(n);
00429 };
00430
00446 int CAENcard_767::readEvent(DAQWordBuffer& wbuf, int offset)
00447 {
00448 int n = dataPresent();
00449 union{
00450 int dword;
00451 struct{
00452 short int low;
00453 short int high;
00454 } word;
00455 } temp;
00456
00457 if(n > 0) {
00458 n = 0;
00459
00460 temp.dword = m_pSpace->peekl(0);
00461
00462 while( (temp.dword & CAEN_767_DATUM_TYPE) != CAEN_767_FOOTER ) {
00463 wbuf[offset] = temp.word.high;
00464 wbuf[offset+1] = temp.word.low;
00465 ++n;
00466 temp.dword = m_pSpace->peekl(0);
00467 }
00468 if( (temp.dword & CAEN_767_DATUM_TYPE) == CAEN_767_FOOTER ) {
00469 wbuf[offset] = temp.word.high;
00470 wbuf[offset + 1] = temp.word.low;
00471 ++n;
00472 }
00473
00474 n *= 2;
00475 }
00476 return(n);
00477 };
00478
00494 int CAENcard_767::readEvent(DAQWordBufferPtr& wp)
00495 {
00496 int n = dataPresent();
00497 union{
00498 int dword;
00499 struct{
00500 short int low;
00501 short int high;
00502 } word;
00503 } temp;
00504
00505 if(n > 0)
00506 {
00507 n = 0;
00508 temp.dword = m_pSpace->peekl(0);
00509 while( (temp.dword & CAEN_767_DATUM_TYPE) != CAEN_767_INVALID )
00510 {
00511 *wp = temp.word.high;
00512 wp++;
00513 *wp = temp.word.low;
00514 wp++;
00515 ++n;
00516 temp.dword = m_pSpace->peekl(0);
00517 }
00518
00519 n *= 2;
00520 }
00521 return(n);
00522 };
00523
00539 int CAENcard_767::readEvent(DAQDWordBuffer& dwbuf, int offset)
00540 {
00541 int temp, n = dataPresent();
00542 if(n > 0)
00543 {
00544 n = 0;
00545 temp = m_pSpace->peekl(0);
00546 while( (temp & CAEN_767_DATUM_TYPE) != CAEN_767_INVALID )
00547 {
00548 dwbuf[offset + n] = temp;
00549 ++n;
00550 temp = m_pSpace->peekl(0);
00551 }
00552 }
00553 return(n);
00554 };
00555
00572 int CAENcard_767::readEvent(DAQDWordBufferPtr& dwp)
00573 {
00574 int temp, n = dataPresent();
00575 if(n > 0)
00576 {
00577 n = 0;
00578 temp = m_pSpace->peekl(0);
00579 while( (temp & CAEN_767_DATUM_TYPE) != CAEN_767_INVALID )
00580 {
00581 *dwp = temp;
00582 dwp++;
00583 ++n;
00584 temp = m_pSpace->peekl(0);
00585 }
00586 }
00587 return(n);
00588 };
00589
00590
00596 int
00597 CAENcard_767::tempSetup()
00598 {
00599
00600
00601 if( writeOpcode(0x1200, 1000000) < 0 )
00602 {
00603 return(-1);
00604 }
00605
00606
00607 if( writeOpcode(0x7000, 1000000) < 0 )
00608 {
00609 return(-2);
00610 }
00611
00612
00613 if( writeOpcode(0x4300, 1000000) < 0)
00614 {
00615 return(-3);
00616 }
00617 opcodeWait(1000000);
00618
00619 return(0);
00620 }
00626 int
00627 CAENcard_767::SetRisingEdgeStart()
00628 {
00629 if(writeOpcode(0x6400, 1000000) < 0) {
00630 return -1;
00631 }
00632 opcodeWait(1000000);
00633 return 0;
00634 }
00640 int
00641 CAENcard_767::SetFallingEdgeStart()
00642 {
00643 if(writeOpcode(0x6500, 100000) < 0) {
00644 return -1;
00645 }
00646 opcodeWait(100000);
00647 return 0;
00648 }
00652 int
00653 CAENcard_767::SetRisingEdgeAll()
00654 {
00655 if(writeOpcode(0x6000, 1000000) < 0) {
00656 return -1;
00657 }
00658 opcodeWait(1000000);
00659 return 0;
00660 }
00664 int
00665 CAENcard_767::SetFallingEdgeAll()
00666 {
00667 if(writeOpcode(0x6100, 1000000) < 0) {
00668 return -1;
00669 }
00670 opcodeWait(1000000);
00671 return 0;
00672 }
00677 int
00678 CAENcard_767::getStartEdge() {
00679 unsigned short edges[3];
00680 int stat = readEdgeConfiguration(edges);
00681 if (stat < 0) {
00682 return stat;
00683 }
00684 return edges[2];
00685 }
00689 int
00690 CAENcard_767::getEdgeEven()
00691 {
00692 unsigned short edges[3];
00693 int stat = readEdgeConfiguration(edges);
00694 if (stat < 0) {
00695 return stat;
00696 }
00697 return edges[0];
00698 }
00702 int
00703 CAENcard_767::getEdgeOdd()
00704 {
00705 unsigned short edges[3];
00706 int stat = readEdgeConfiguration(edges);
00707 if (stat < 0) {
00708 return stat;
00709 }
00710 return edges[1];
00711 }
00715 unsigned short CAENcard_767::getSr2()
00716 {
00717 return m_pSpace->peekw(CAEN_767_STATUS_2);
00718 }
00722 int
00723 CAENcard_767::mfgId()
00724 {
00725 return ((m_pSpace->peekw(CAEN_767_MANUFACT_ID) << 16) |
00726 (m_pSpace->peekw(CAEN_767_MANUFACT_ID+2) << 8) |
00727 (m_pSpace->peekw(CAEN_767_MANUFACT_ID+4)));
00728 }
00729
00730
00734 int
00735 CAENcard_767::readEdgeConfiguration(unsigned short* values)
00736 {
00737 if (writeOpcode(0x6700, 10000) < 0) {
00738 return -1;
00739 }
00740 opcodeWait(1000000);
00741 if (readOpcode(values, 1000) < 0) {
00742 return -2;
00743 }
00744 *values &= CAEN_767_EDGE_BOTH;
00745 values++;
00746 if (readOpcode(values, 1000) < 0) {
00747 return -3;
00748 }
00749 *values &= CAEN_767_EDGE_BOTH;
00750 values++;
00751 if (readOpcode(values, 1000) < 0) {
00752 return -4;
00753 }
00754 *values &= CAEN_767_EDGE_BOTH;
00755 return 0;
00756 }