00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 static const char* Copyright= "(C) Copyright Michigan State University 2008, All rights reserved";
00015
00016 #include <config.h>
00017
00018 #include <CADC2530.h>
00019 #include <string>
00020 #include <unistd.h>
00021 #include <string.h>
00022 #include <math.h>
00023
00024 #include <assert.h>
00025
00026 #ifdef HAVE_STD_NAMESPACE
00027 using namespace std;
00028
00029 #endif
00030
00031
00032 #define swaplong(n) (((n >> 16) & 0xffff) | ((n & 0xffff) << 16))
00033
00034
00035 #define Offset(structname, field) ((unsigned int)&(((structname*)0x0)->field))
00036
00037
00038 #define ShortOffset(structname, field) (Offset(structname,field)/sizeof(short))
00039 #define LongOffset(structname, field) (Offset(structname,field)/sizeof(long))
00040
00041
00042 #define VME_CRATE_SIZE 24 // Slots in a VME crate.
00043
00044
00045 #define CADC2530_REGSIZE 0xC0 // Size of register set.
00046 #define CADC2530_MEMSIZE 0x200000 // Size of all histo/list memory.
00047 #define CADC2530_HISTOMEMSIZE 0x40000 // Size of histogram memory.
00048 #define CADC2530_HISTOCHANSIZE 0x2000 // Size of histogram channel in longs.
00049
00050
00051
00052 #define CADC2530_CSRMASK 0x00FF8A
00053
00054
00055
00056 #define CADC2530_CTRMASK 0x00810F
00057
00058
00059 #define IS_LIST_HEADER(x) (((((x>>24)&0x07) == 0x2)) ? true : false)
00060 #define IS_LIST_EOB(x) (((((x>>24)&0x07) == 0x4)) ? true : false)
00061 #define IS_LIST_CHANNEL(x) ((((x>>24)&0x07) == 0x0)) ? true : false)
00062 #define GET_LIST_CHANCOUNT(x) (((x>>8)&0x07)+1)
00063 #define GET_LIST_CHANNUM(x) (((x>>16)&0x07)+1)
00064 #define GET_LIST_CHANDATA(x) (x&0x1FFF)
00065 #define GET_LIST_EVENTCOUNT(x) (x&0x00FFFFFF)
00066
00067
00068 typedef struct ADCregisters_struct {
00069 unsigned short ManufacturerId;
00070 unsigned short DeviceType;
00071 unsigned short CSR;
00072 unsigned short MemoryOffset;
00073 unsigned short ListAddressLS;
00074 unsigned short ListAddressMS;
00075 unsigned short InterruptVector;
00076 unsigned short CTR;
00077 unsigned short FullnessFlag;
00078 unsigned short InterruptMask;
00079 unsigned short LowerLevelDisc;
00080 unsigned short UpperLevelDisc;
00081 unsigned short EventCounterLS;
00082 unsigned short EventCounterMS;
00083 unsigned short Conversion;
00084 unsigned short SlidingScaleTest;
00085 unsigned short NotUsed2[16];
00086 unsigned short SerialNumber;
00087 unsigned short DataInNonVolatileMem[63];
00088 } ADCregisters_t;
00089
00090
00091 typedef union ADCcsr_union {
00092 unsigned short csrval;
00093 struct bit_struct {
00094 unsigned char RSTBSY : 1;
00095 unsigned char SS : 1;
00096 unsigned char DR : 1;
00097 unsigned char SC : 1;
00098 unsigned char FFCLR : 1;
00099 unsigned char ACM : 1;
00100 unsigned char IS : 1;
00101 unsigned char IE : 1;
00102 unsigned char ARM : 1;
00103 unsigned char IPL : 3;
00104 unsigned char FHE : 1;
00105 unsigned char ZE : 1;
00106 unsigned char GE : 1;
00107 unsigned char HE : 1;
00108 } bits;
00109 } ADCcsr_t;
00110
00111
00112 typedef union ADCctr_union {
00113 unsigned short ctrval;
00114 struct bit_struct {
00115 unsigned char M012 : 3;
00116 unsigned char MEN : 1;
00117 unsigned char D04 : 1;
00118 unsigned char D05 : 1;
00119 unsigned char D06 : 1;
00120 unsigned char D07 : 1;
00121 unsigned char DISC : 1;
00122 unsigned char D09 : 1;
00123 unsigned char D10 : 1;
00124 unsigned char D11 : 1;
00125 unsigned char D12 : 1;
00126 unsigned char D13 : 1;
00127 unsigned char D14 : 1;
00128 unsigned char DEAC : 1;
00129 } bits;
00130 } ADCctr_t;
00131
00132
00133 typedef union ADCfullnessflag_union {
00134 unsigned short flags;
00135
00136 struct byte_struct {
00137 unsigned char HALFFULL : 8;
00138 unsigned char FULL : 8;
00139 } bytes;
00140
00141 struct bit_struct {
00142 unsigned char F1 : 1;
00143 unsigned char F2 : 1;
00144 unsigned char F3 : 1;
00145 unsigned char F4 : 1;
00146 unsigned char F5 : 1;
00147 unsigned char F6 : 1;
00148 unsigned char F7 : 1;
00149 unsigned char F8 : 1;
00150 unsigned char HF1 : 1;
00151 unsigned char HF2 : 1;
00152 unsigned char HF3 : 1;
00153 unsigned char HF4 : 1;
00154 unsigned char HF5 : 1;
00155 unsigned char HF6 : 1;
00156 unsigned char HF7 : 1;
00157 unsigned char HF8 : 1;
00158 } bits;
00159 } ADCfullnessflag_t;
00160
00161
00182 CADC2530::CADC2530(int crateNum,long nBase) :
00183 my_nCrate(crateNum),
00184 my_nBase(nBase),
00185 my_nMemOffset(nBase),
00186 my_pModule(NULL),
00187 my_pMemory(NULL),
00188 my_nCardId(0),
00189 my_nCardType(0),
00190 my_nModFd(0),
00191 my_nMemFd(0),
00192 my_eventmode(false),
00193 my_cureventpos(0)
00194 {
00195 assert(sizeof(ADCregisters_t) == CADC2530_REGSIZE);
00196 slotInit();
00197 }
00198
00199
00211 CADC2530::CADC2530(const CADC2530& card) :
00212 my_nCrate(card.my_nCrate),
00213 my_nBase(card.my_nBase),
00214 my_nMemOffset(card.my_nMemOffset),
00215 my_nCardId(card.my_nCardId),
00216 my_nCardType(card.my_nCardType),
00217 my_pModule(NULL),
00218 my_pMemory(NULL),
00219 my_nModFd(0),
00220 my_nMemFd(0),
00221 my_eventmode(false),
00222 my_cureventpos(0)
00223 {
00224 mapCard();
00225 }
00226
00227
00239 CADC2530& CADC2530::operator=(const CADC2530& card) {
00240 if (this != (&card)) {
00241 if (this->my_pModule != NULL) destroyCard();
00242 my_nCrate = card.my_nCrate;
00243 my_nBase = card.my_nBase;
00244 my_nMemOffset = card.my_nMemOffset;
00245 my_eventmode = card.my_eventmode;
00246 my_cureventpos= card.my_cureventpos;
00247 my_nMemFd = 0;
00248 my_nModFd = 0;
00249 my_pModule = NULL;
00250 my_pMemory = NULL;
00251 mapCard();
00252 }
00253 return *this;
00254 }
00255
00256
00265 CADC2530::~CADC2530() {
00266 destroyCard();
00267 }
00268
00269
00288 bool CADC2530::checkCard(int nCrate,long nBase,unsigned short &rType, unsigned short &rManId) {
00289
00290 int crate = nCrate & 0xff;
00291
00292
00293
00294 void *fd = NULL;
00295 rType = 0;
00296 rManId = 0;
00297
00298 #ifndef HAVE_VME_MAPPING
00299 CVmeModule *adcmod = new CVmeModule(CVmeModule::a24d32,nBase,CADC2530_REGSIZE,crate);
00300 #else
00301 fd = CVMEInterface::Open(CVMEInterface::A24,crate);
00302 volatile unsigned short *adcmod = (volatile unsigned short*)CVMEInterface::Map(fd,nBase,CADC2530_REGSIZE);
00303 #endif
00304
00305 #ifndef HAVE_VME_MAPPING
00306 rType = adcmod->peekw(ShortOffset(ADCregisters_t,DeviceType));
00307 rManId = adcmod->peekw(ShortOffset(ADCregisters_t,ManufacturerId));
00308 delete adcmod;
00309 #else
00310 rType = ((volatile ADCregisters_t*)adcmod)->DeviceType;
00311 rManId = ((volatile ADCregisters_t*)adcmod)->ManufacturerId;
00312 CVMEInterface::Unmap(fd,(void*)adcmod,CADC2530_REGSIZE);
00313 CVMEInterface::Close(fd);
00314 #endif
00315
00316 adcmod = NULL;
00317 fd = NULL;
00318
00319 if ((rManId != 0x8063)||(rType != 2530)) return false;
00320 else return true;
00321 }
00322
00323
00339 unsigned short CADC2530::volt2lld(double volt) {
00340 unsigned short sval = 0;
00341 if (volt < 0) {
00342 sval = 0x0;
00343 } else if (volt > 0.8191) {
00344 sval = 0x3FFC;
00345 } else {
00346 int val = (int)((volt/3.2764)/(0.25/4095));
00347 sval = (unsigned short)((val << 2)&0x00003FFC);
00348 }
00349
00350 return sval;
00351 }
00352
00353
00370 unsigned short CADC2530::volt2uld(double volt) {
00371 unsigned short sval = 0;
00372
00373 if (volt < 0) {
00374 sval = 0x0;
00375 } else if (volt > 8.191) {
00376 sval = 0x3FFC;
00377 } else {
00378 int val = (unsigned int)trunc(((volt/3.2764)-2)/(0.5/4095));
00379 sval = (unsigned short)((val << 2)&0x00003FFC);
00380 }
00381
00382 return sval;
00383 }
00384
00385
00396 const std::string& CADC2530::toString() {
00397 static string namstr;
00398 static char buffer[256];
00399 sprintf(buffer,"ADC2530 in crate %d at base 0x%x with memory offset 0x%x",my_nCrate,my_nBase,my_nMemOffset);
00400 namstr = buffer;
00401 return namstr;
00402 }
00403
00404
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00450 int CADC2530::readListEvent(void* buf,int lngsLeft) {
00451 int lngcnt = 0;
00452 unsigned int *lptr = (unsigned int*)buf;
00453
00454
00455 if (lngsLeft < 2) return(0);
00456
00457 #ifndef HAVE_VME_MAPPING
00458 m_pMemory->readl(lptr,my_cureventpos,1);
00459 #else
00460 lptr[lngcnt] = ((volatile unsigned long*)my_pMemory)[my_cureventpos];
00461 #endif
00462
00463 int chans = GET_LIST_CHANCOUNT(lptr[0]);
00464
00465
00466
00467 if ((chans+2) < lngsLeft) {
00468 lngcnt++;
00469 my_cureventpos++;
00470
00471 #ifndef HAVE_VME_MAPPING
00472 m_pMemory->readl(&(lptr[lngcnt]),my_cureventpos*4,chans+1);
00473 lngcnt += (chans+1);
00474 my_cureventpos += (chans+1);
00475 #else
00476 for (int i = 0; i < (chans+1); i++) {
00477 lptr[lngcnt] = ((volatile unsigned long*)my_pMemory)[my_cureventpos];
00478 my_cureventpos++;
00479 lngcnt++;
00480 }
00481 #endif
00482 }
00483
00484 return lngcnt*sizeof(unsigned int);
00485 }
00486
00487
00504 int CADC2530::readListEvents(void* buf,int& nEvents) {
00505 int lngcnt = 0;
00506 unsigned int *lptr = (unsigned int*)buf;
00507
00508
00509 unsigned int listaddr = getListAddress();
00510 if (listaddr == 0) {
00511 if (dataReady()) listaddr = (CADC2530_MEMSIZE/sizeof(unsigned int));
00512 }
00513
00514
00515 int eventsread = 0;
00516 for (int i = 0; i < nEvents; i++) {
00517 int bytes = readListEvent((void*)lptr,listaddr-my_cureventpos);
00518 if (bytes <= 0) break;
00519 eventsread++;
00520
00521 lptr += (bytes/sizeof(unsigned int));
00522 lngcnt += (bytes/sizeof(unsigned int));
00523 }
00524
00525 nEvents = eventsread;
00526 return lngcnt*sizeof(unsigned int);
00527 }
00528
00529
00546 int CADC2530::readHistogramChannel(void* buf,int channum) {
00547 if ((channum < 1)||(channum > 8)) {
00548 char buffer[256];
00549 sprintf(buffer, "CADC2530::readHistogramChannel(): the channel number specified must be in the range [1-8]. A channel number of %d was specified\n",channum);
00550 throw string(buffer);
00551 }
00552
00553 int chstart = (channum - 1) * CADC2530_HISTOCHANSIZE;
00554 unsigned int *lptr = (unsigned int*)buf;
00555
00556 #ifndef HAVE_VME_MAPPING
00557 m_pMemory->readl(lptr,chstart*sizeof(unsigned int),CADC2530_HISTOCHANSIZE);
00558 #else
00559 for (int i = 0; i < CADC2530_HISTOCHANSIZE; i++) {
00560 lptr[i] = ((volatile unsigned long*)my_pMemory)[chstart+i];
00561 }
00562 #endif
00563
00564 return (CADC2530_HISTOCHANSIZE * sizeof(unsigned int));
00565 }
00566
00567
00580 void CADC2530::slotInit() {
00581 mapCard();
00582 resetCard();
00583 clearHistogramMemory();
00584 }
00585
00586
00596 unsigned short CADC2530::cardType() {
00597 if (!my_nCardType) {
00598 #ifndef HAVE_VME_MAPPING
00599 my_nCardType = my_pModule->peekw(ShortOffset(ADCregisters_t,DeviceType));
00600 #else
00601 my_nCardType = ((volatile ADCregisters_t*)my_pModule)->DeviceType;
00602 #endif
00603 }
00604 return my_nCardType;
00605 }
00606
00607
00617 unsigned short CADC2530::manufacturerId() {
00618 if (!my_nCardId) {
00619 #ifndef HAVE_VME_MAPPING
00620 my_nCardId = my_pModule->peekw(ShortOffset(ADCregisters_t,ManufacturerId));
00621 #else
00622 my_nCardId = ((volatile ADCregisters_t*)my_pModule)->ManufacturerId;
00623 #endif
00624 }
00625 return my_nCardId;
00626 }
00627
00628
00640 unsigned long CADC2530::setMemoryOffset(unsigned long memoset) {
00641 unsigned long lval = (memoset >> 16);
00642 unsigned short sval = (lval & 0xFFE0);
00643
00644 #ifndef HAVE_VME_MAPPING
00645 my_pModule->pokew(sval,ShortOffset(ADCregisters_t,MemoryOffset));
00646 lval = my_pModule->peekw(ShortOffset(ADCregister_t,MemoryOffset));
00647 #else
00648 ((volatile ADCregisters_t*)my_pModule)->MemoryOffset = sval;
00649 lval = ((volatile ADCregisters_t*)my_pModule)->MemoryOffset;
00650 #endif
00651
00652 return (lval << 16);
00653 }
00654
00655
00665 unsigned long CADC2530::calcMemoryOffset(unsigned long base) {
00666 unsigned long regset = ((base >> 8) & 0xFFE0);
00667 return (regset << 16);
00668 }
00669
00670
00684 void CADC2530::mapModule() {
00685
00686 if (my_pModule != NULL) {
00687 char buffer[256];
00688 sprintf(buffer, "CADC2530::mapModule(): The Card in crate %d at base 0x%x already has a register memory map.\n",my_nCrate,my_nBase);
00689 throw string(buffer);
00690 }
00691
00692
00693 my_nCrate = my_nCrate & 0xff;
00694
00695
00696
00697 void *fd = NULL;
00698
00699 #ifndef HAVE_VME_MAPPING
00700 my_pModule = new CVmeModule(CVmeModule::a24d32,my_nBase,
00701 CADC2530_REGSIZE,my_nCrate);
00702 #else
00703 fd = CVMEInterface::Open(CVMEInterface::A24, my_nCrate);
00704 my_pModule = (volatile unsigned short*)CVMEInterface::Map(fd,my_nBase,
00705 CADC2530_REGSIZE);
00706 #endif
00707
00708
00709
00710 my_nCardId = manufacturerId();
00711 my_nCardType = cardType();
00712
00713 if ((my_nCardId != 0x8063)||(my_nCardType != 2530)) {
00714 #ifndef HAVE_VME_MAPPING
00715 delete my_pModule;
00716 #else
00717 CVMEInterface::Unmap(fd,(void*)my_pModule,CADC2530_REGSIZE);
00718 CVMEInterface::Close(fd);
00719 #endif
00720 my_pModule = NULL;
00721 char buffer[256];
00722 sprintf(buffer, "CADC2530::mapModule(): Card in crate %d at base 0x%x is not a Hytec 2530 ADC or is missing type=%d id=0x%0x\n",my_nCrate,my_nBase,my_nCardType,my_nCardId);
00723 throw string(buffer);
00724 }
00725
00726 my_nModFd = fd;
00727 }
00728
00729
00743 void CADC2530::mapMemory() {
00744
00745 if (my_pModule == NULL) {
00746 char buffer[256];
00747 sprintf(buffer, "CADC2530::mapMemory(): Cannot map list/histogram memory without first mapping the ADC2530 registers for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase);
00748 throw string(buffer);
00749 }
00750
00751
00752 if (my_pMemory != NULL) {
00753 char buffer[256];
00754 sprintf(buffer, "CADC2530::mapMemory(): The Card in crate %d at base 0x%x already has a list/histogram memory map.\n",my_nCrate,my_nBase);
00755 throw string(buffer);
00756 }
00757
00758
00759 my_nCrate = my_nCrate & 0xff;
00760
00761
00762
00763 void *fd = NULL;
00764
00765
00766 unsigned long nmemoset = calcMemoryOffset(my_nBase);
00767 my_nMemOffset = setMemoryOffset(nmemoset);
00768
00769
00770
00771 if (nmemoset != my_nMemOffset) {
00772 char buffer[256];
00773 sprintf(buffer, "CADC2530::mapMemory(): Error setting list/histogram memory offset for ADC2530 card in crate %d at base 0x%x (written=0x%x, read=0x%x)\n",my_nCrate,my_nBase,nmemoset,my_nMemOffset);
00774 throw string(buffer);
00775 }
00776
00777
00778 #ifndef HAVE_VME_MAPPING
00779 my_pMemory = new CVmeModule(CVmeModule::a32d32,my_nMemOffset,
00780 CADC2530_MEMSIZE,my_nCrate);
00781 #else
00782 fd = CVMEInterface::Open(CVMEInterface::A32, my_nCrate);
00783 my_pMemory = (volatile unsigned int*)CVMEInterface::Map(fd,my_nMemOffset,
00784 CADC2530_MEMSIZE);
00785 #endif
00786
00787 my_nMemFd = fd;
00788 }
00789
00790
00799 void CADC2530::destroyMemory() {
00800 if (my_pMemory == NULL) return;
00801
00802 #ifndef HAVE_VME_MAPPING
00803 delete my_pMemory;
00804 #else
00805 CVMEInterface::Unmap(my_nMemFd,(void*)my_pMemory,CADC2530_MEMSIZE);
00806 CVMEInterface::Close(my_nMemFd);
00807 #endif
00808
00809 my_pMemory = NULL;
00810 my_nMemFd = NULL;
00811 }
00812
00813
00823 void CADC2530::clearMemory() {
00824
00825 if (my_pMemory == NULL) {
00826 char buffer[256];
00827 sprintf(buffer, "CADC2530::clearMemory(): Cannot clear list/histogram memory without first having a memory map for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase);
00828 throw string(buffer);
00829 }
00830
00831 for (int i = 0x0; i < (CADC2530_MEMSIZE/4); i++) {
00832 #ifndef HAVE_VME_MAPPING
00833 my_pMemory->pokel((unsigned int)0x0,i);
00834 #else
00835 ((volatile unsigned int*)my_pMemory)[i] = (unsigned int)0x0;
00836 #endif
00837 }
00838 }
00839
00840
00853 void CADC2530::clearHistogramMemory() {
00854
00855 if (my_pMemory == NULL) {
00856 char buffer[256];
00857 sprintf(buffer, "CADC2530::clearHistogramMemory(): Cannot clear histogram memory without first having a memory map for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase);
00858 throw string(buffer);
00859 }
00860
00861 for (int i = 0x0; i < (CADC2530_HISTOMEMSIZE/4); i++) {
00862 #ifndef HAVE_VME_MAPPING
00863 my_pMemory->pokel((unsigned int)0x0,i);
00864 #else
00865 ((volatile unsigned int*)my_pMemory)[i] = (unsigned int)0x0;
00866 #endif
00867 }
00868 }
00869
00870
00884 void CADC2530::resetCard() {
00885
00886 if (my_pModule == NULL) {
00887 char buffer[256];
00888 sprintf(buffer, "CADC2530::resetCard(): Cannot reset this card without first having a memory map for card in crate %d at base 0x%x.\n",my_nCrate,my_nBase);
00889 throw string(buffer);
00890 }
00891
00892 disarm();
00893 resetCTR();
00894 setLLD(0x0);
00895 setULD(0x0);
00896 setInterruptVector(0x0);
00897 setInterruptMask(0x0);
00898 fastClear();
00899 resetCSR();
00900 clearEventCounter();
00901 clearListAddress();
00902 clearFullnessFlags();
00903 modeHistogram(false);
00904 }
00905
00906
00916 void CADC2530::destroyModule() {
00917 if (my_pModule == NULL) return;
00918
00919 resetCard();
00920
00921 #ifndef HAVE_VME_MAPPING
00922 delete my_pModule;
00923 #else
00924 CVMEInterface::Unmap(my_nModFd,(void*)my_pModule,CADC2530_REGSIZE);
00925 CVMEInterface::Close(my_nModFd);
00926 #endif
00927
00928 my_pModule = NULL;
00929 my_nModFd = NULL;
00930 }
00931
00932
00947 void CADC2530::mapCard() {
00948 mapModule();
00949 mapMemory();
00950 }
00951
00952
00961 void CADC2530::destroyCard() {
00962 destroyMemory();
00963 destroyModule();
00964 }
00965
00966
00976 void CADC2530::arm() {
00977 ADCcsr_t csr;
00978 csr.csrval = 0;
00979 csr.bits.ARM = 1;
00980 setCSRbits(csr.csrval,csr.csrval);
00981 }
00982
00983
00993 void CADC2530::disarm() {
00994 ADCcsr_t csr;
00995 csr.csrval = 0;
00996 csr.bits.ARM = 1;
00997 resetCSRbits(csr.csrval);
00998 }
00999
01000
01012 void CADC2530::dataReadyOnEvent() {
01013 my_eventmode = true;
01014 ADCcsr_t csr;
01015 csr.csrval = 0;
01016 csr.bits.DR = 1;
01017 csr.bits.FHE = 1;
01018 setCSRbits(csr.csrval,csr.csrval);
01019 }
01020
01021
01032 void CADC2530::dataReadyOnFullness() {
01033 my_eventmode = false;
01034 ADCcsr_t csr;
01035 csr.csrval = 0;
01036 csr.bits.DR = 1;
01037 csr.bits.FHE = 1;
01038 resetCSRbits(csr.csrval);
01039 }
01040
01041
01050 void CADC2530::enableGate() {
01051 ADCcsr_t csr;
01052 csr.csrval = 0;
01053 csr.bits.GE = 1;
01054 setCSRbits(csr.csrval,csr.csrval);
01055 }
01056
01057
01066 void CADC2530::disableGate() {
01067 ADCcsr_t csr;
01068 csr.csrval = 0;
01069 csr.bits.GE = 1;
01070 resetCSRbits(csr.csrval);
01071 }
01072
01073
01082 void CADC2530::enableZeroCnv() {
01083 ADCcsr_t csr;
01084 csr.csrval = 0;
01085 csr.bits.ZE = 1;
01086 setCSRbits(csr.csrval,csr.csrval);
01087 }
01088
01089
01098 void CADC2530::disableZeroCnv() {
01099 ADCcsr_t csr;
01100 csr.csrval = 0;
01101 csr.bits.ZE = 1;
01102 resetCSRbits(csr.csrval);
01103 }
01104
01105
01115 void CADC2530::enableCalibration() {
01116 ADCcsr_t csr;
01117 csr.csrval = 0;
01118 csr.bits.SC = 1;
01119 setCSRbits(csr.csrval,csr.csrval);
01120 }
01121
01122
01132 void CADC2530::disableCalibration() {
01133 ADCcsr_t csr;
01134 csr.csrval = 0;
01135 csr.bits.SC = 1;
01136 resetCSRbits(csr.csrval);
01137 }
01138
01139
01149 void CADC2530::enableSlidingScale() {
01150 ADCcsr_t csr;
01151 csr.csrval = 0;
01152 csr.bits.SS = 1;
01153 resetCSRbits(csr.csrval);
01154 }
01155
01156
01166 void CADC2530::disableSlidingScale() {
01167 ADCcsr_t csr;
01168 csr.csrval = 0;
01169 csr.bits.SS = 1;
01170 setCSRbits(csr.csrval,csr.csrval);
01171 }
01172
01173
01185 void CADC2530::enableInterrupt() {
01186 ADCcsr_t csr;
01187 csr.csrval = 0;
01188 csr.bits.IE = 1;
01189 setCSRbits(csr.csrval,csr.csrval);
01190 }
01191
01192
01204 void CADC2530::disableInterrupt() {
01205 ADCcsr_t csr;
01206 csr.csrval = 0;
01207 csr.bits.IE = 1;
01208 resetCSRbits(csr.csrval);
01209 }
01210
01211
01220 bool CADC2530::isArmed() {
01221 ADCcsr_t csr;
01222 csr.csrval = getCSR();
01223 return (csr.bits.ARM == 1);
01224 }
01225
01226
01237 void CADC2530::modeHistogram(bool indgates) {
01238 ADCcsr_t csr;
01239
01240 csr.csrval = 0;
01241 csr.bits.HE = 1;
01242 setCSRbits(csr.csrval,csr.csrval);
01243
01244 if (indgates) {
01245 csr.csrval = 0;
01246 csr.bits.GE = 1;
01247 setCSRbits(csr.csrval,csr.csrval);
01248 } else {
01249 csr.csrval = 0;
01250 csr.bits.GE = 1;
01251 resetCSRbits(csr.csrval);
01252 }
01253
01254 dataReadyOnFullness();
01255 }
01256
01257
01267 void CADC2530::modeGate() {
01268 ADCcsr_t csr;
01269 csr.csrval = 0;
01270 csr.bits.HE = 1;
01271 resetCSRbits(csr.csrval);
01272 csr.csrval = 0;
01273 csr.bits.GE = 1;
01274 setCSRbits(csr.csrval,csr.csrval);
01275 dataReadyOnEvent();
01276 }
01277
01278
01288 unsigned int CADC2530::getEventCounter() {
01289 #ifndef HAVE_VME_MAPPING
01290 unsigned short ecls = my_pModule->peekw(ShortOffset(ADCregisters_t,EventCounterLS));
01291 unsigned short ecms = my_pModule->peekw(ShortOffset(ADCregisters_t,EventCounterMS));
01292 #else
01293 unsigned short ecls = ((volatile ADCregisters_t*)my_pModule)->EventCounterLS;
01294 unsigned short ecms = ((volatile ADCregisters_t*)my_pModule)->EventCounterMS;
01295 #endif
01296
01297 unsigned int evtcnt = ((ecms&0x00FF)<<16)|(ecls&0x0000FFFF);
01298 return evtcnt;
01299 }
01300
01301
01310 void CADC2530::clearEventCounter() {
01311 my_cureventpos= 0;
01312
01313 #ifndef HAVE_VME_MAPPING
01314 my_pModule->pokew(0x0,ShortOffset(ADCregisters_t,EventCounterLS));
01315 my_pModule->pokew(0x0,ShortOffset(ADCregisters_t,EventCounterMS));
01316 #else
01317 ((volatile ADCregisters_t*)my_pModule)->EventCounterLS = 0x0;
01318 ((volatile ADCregisters_t*)my_pModule)->EventCounterMS = 0x0;
01319 #endif
01320 }
01321
01322
01333 unsigned int CADC2530::getListAddress() {
01334 #ifndef HAVE_VME_MAPPING
01335 unsigned short lals = my_pModule->peekw(ShortOffset(ADCregisters_t,ListAddressLS));
01336 unsigned short lams = my_pModule->peekw(ShortOffset(ADCregisters_t,ListAddressMS));
01337 #else
01338 unsigned short lals = ((volatile ADCregisters_t*)my_pModule)->ListAddressLS;
01339 unsigned short lams = ((volatile ADCregisters_t*)my_pModule)->ListAddressMS;
01340 #endif
01341
01342 unsigned int lstaddr = ((lams&0x0000FFFF)<<16)|(lals&0x0000FFFF);
01343 return lstaddr;
01344 }
01345
01346
01356 void CADC2530::clearListAddress() {
01357 #ifndef HAVE_VME_MAPPING
01358 my_pModule->pokew(0x0,ShortOffset(ADCregisters_t,ListAddressLS));
01359 my_pModule->pokew(0x0,ShortOffset(ADCregisters_t,ListAddressMS));
01360 #else
01361 ((volatile ADCregisters_t*)my_pModule)->ListAddressLS = 0x0;
01362 ((volatile ADCregisters_t*)my_pModule)->ListAddressMS = 0x0;
01363 #endif
01364 }
01365
01366
01376 bool CADC2530::isBusy() {
01377 ADCcsr_t csr;
01378 csr.csrval = getCSR();
01379 return (csr.bits.RSTBSY == 1);
01380 }
01381
01382
01391 void CADC2530::clearFullnessFlags() {
01392 #ifndef HAVE_VME_MAPPING
01393 my_pModule->pokew(0x0,ShortOffset(ADCregisters_t,FullnessFlag));
01394 #else
01395 ((volatile ADCregisters_t*)my_pModule)->FullnessFlag = 0x0;
01396 #endif
01397 }
01398
01399
01410 unsigned short CADC2530::getFullnessFlags() {
01411 unsigned short flags = 0;
01412 #ifndef HAVE_VME_MAPPING
01413 flags = my_pModule->peekw(ShortOffset(ADCregisters_t,FullnessFlag));
01414 #else
01415 flags = ((volatile ADCregisters_t*)my_pModule)->FullnessFlag;
01416 #endif
01417 return flags;
01418 }
01419
01420
01433 bool CADC2530::isChannelFull(unsigned short aChan) {
01434 if ((aChan < 1)||(aChan > 8)) {
01435 char buffer[256];
01436 sprintf(buffer, "CADC2530::isChannelFull(): When checking channel fullness, the channel specified must be in the range [1-8] (channel == %d).\n",aChan);
01437 throw string(buffer);
01438 }
01439
01440 ADCfullnessflag_t fflags;
01441 fflags.flags = getFullnessFlags();
01442 unsigned char mask = 0x1;
01443 mask = (mask << (aChan - 1));
01444 return ((fflags.bytes.FULL & mask) > 0);
01445 }
01446
01447
01460 bool CADC2530::channelHasData(unsigned short aChan) {
01461 if ((aChan < 1)||(aChan > 8)) {
01462 char buffer[256];
01463 sprintf(buffer, "CADC2530::channelHasData(): When checking channel fullness, the channel specified must be in the range [1-8] (channel == %d).\n",aChan);
01464 throw string(buffer);
01465 }
01466
01467 ADCfullnessflag_t fflags;
01468 fflags.flags = getFullnessFlags();
01469 unsigned char mask = 0x1;
01470 mask = (mask << (aChan - 1));
01471 return ((fflags.bytes.HALFFULL & mask) > 0);
01472 }
01473
01474
01486 bool CADC2530::isListFull() {
01487 ADCfullnessflag_t fflags;
01488 fflags.flags = getFullnessFlags();
01489 unsigned char mask = 0x1;
01490 return ((fflags.bytes.FULL & mask) > 0);
01491 }
01492
01493
01505 bool CADC2530::isListHalfFull() {
01506 ADCfullnessflag_t fflags;
01507 fflags.flags = getFullnessFlags();
01508 unsigned char mask = 0x1;
01509 return ((fflags.bytes.HALFFULL & mask) > 0);
01510 }
01511
01512
01529 void CADC2530::setSSTR(unsigned short sstrval) {
01530 unsigned short val = (sstrval&0x3FFC);
01531 #ifndef HAVE_VME_MAPPING
01532 my_pModule->pokew(val,ShortOffset(ADCregisters_t,SlidingScaleTest));
01533 #else
01534 ((volatile ADCregisters_t*)my_pModule)->SlidingScaleTest= val;
01535 #endif
01536 }
01537
01538
01552 unsigned short CADC2530::getSSTR() {
01553 unsigned short sstrval = 0;
01554 #ifndef HAVE_VME_MAPPING
01555 sstrval = my_pModule->peekw(ShortOffset(ADCregisters_t,SlidingScaleTest));
01556 #else
01557 sstrval = ((volatile ADCregisters_t*)my_pModule)->SlidingScaleTest;
01558 #endif
01559 return sstrval;
01560 }
01561
01562
01573 bool CADC2530::hasInterrupt() {
01574 ADCcsr_t csr;
01575 csr.csrval = getCSR();
01576 return (csr.bits.IS == 1);
01577 }
01578
01579
01589 bool CADC2530::dataReady() {
01590 ADCcsr_t csr;
01591 csr.csrval = getCSR();
01592 return (csr.bits.DR == 1);
01593 }
01594
01595
01604 void CADC2530::resetCSR() {
01605 ADCcsr_t csr;
01606 csr.csrval = getCSR();
01607 csr.bits.RSTBSY = 1;
01608 setCSR(csr.csrval);
01609 setCSR((unsigned short)0x0);
01610 my_eventmode = false;
01611 }
01612
01613
01622 void CADC2530::resetCTR() {
01623 setCTR((unsigned short)0x0);
01624 }
01625
01626
01635 void CADC2530::fastClear() {
01636 ADCcsr_t csr;
01637 csr.csrval = getCSR();
01638 csr.bits.FFCLR = 1;
01639 setCSR(csr.csrval);
01640 }
01641
01642
01653 void CADC2530::setIPL(unsigned short iplval) {
01654 ADCcsr_t csr;
01655 ADCcsr_t mask;
01656
01657 csr.csrval = 0;
01658 csr.bits.IPL = (iplval & 0x07);
01659
01660 mask.csrval = 0;
01661 mask.bits.IPL = 0x7;
01662
01663 setCSRbits(csr.csrval,mask.csrval);
01664 }
01665
01666
01675 unsigned short CADC2530::getIPL() {
01676 ADCcsr_t csr;
01677 csr.csrval = getCSR();
01678 unsigned short iplval = csr.bits.IPL;
01679 return iplval;
01680 }
01681
01682
01696 void CADC2530::setLLD(unsigned short lldval) {
01697 #ifndef HAVE_VME_MAPPING
01698 my_pModule->pokew(lldval,ShortOffset(ADCregisters_t,LowerLevelDisc));
01699 #else
01700 ((volatile ADCregisters_t*)my_pModule)->LowerLevelDisc = lldval;
01701 #endif
01702 }
01703
01704
01721 unsigned short CADC2530::getLLD() {
01722 unsigned short lldval = 0;
01723 #ifndef HAVE_VME_MAPPING
01724 lldval = my_pModule->peekw(ShortOffset(ADCregisters_t,LowerLevelDisc));
01725 #else
01726 lldval = ((volatile ADCregisters_t*)my_pModule)->LowerLevelDisc;
01727 #endif
01728 return lldval;
01729 }
01730
01731
01745 void CADC2530::setULD(unsigned short uldval) {
01746 #ifndef HAVE_VME_MAPPING
01747 my_pModule->pokew(uldval,ShortOffset(ADCregisters_t,UpperLevelDisc));
01748 #else
01749 ((volatile ADCregisters_t*)my_pModule)->UpperLevelDisc = uldval;
01750 #endif
01751 }
01752
01753
01770 unsigned short CADC2530::getULD() {
01771 unsigned short uldval = 0;
01772 #ifndef HAVE_VME_MAPPING
01773 uldval = my_pModule->peekw(ShortOffset(ADCregisters_t,UpperLevelDisc));
01774 #else
01775 uldval = ((volatile ADCregisters_t*)my_pModule)->UpperLevelDisc;
01776 #endif
01777 return uldval;
01778 }
01779
01780
01789 void CADC2530::setInterruptVector(unsigned short ivect) {
01790 #ifndef HAVE_VME_MAPPING
01791 my_pModule->pokew(ivect,ShortOffset(ADCregisters_t,InterruptVector));
01792 #else
01793 ((volatile ADCregisters_t*)my_pModule)->InterruptVector = ivect;
01794 #endif
01795 }
01796
01797
01806 unsigned short CADC2530::getInterruptVector() {
01807 unsigned short ivect = 0;
01808 #ifndef HAVE_VME_MAPPING
01809 ivect = my_pModule->peekw(ShortOffset(ADCregisters_t,InterruptVector));
01810 #else
01811 ivect = ((volatile ADCregisters_t*)my_pModule)->InterruptVector;
01812 #endif
01813 return ivect;
01814 }
01815
01816
01825 void CADC2530::setInterruptMask(unsigned short imask) {
01826 #ifndef HAVE_VME_MAPPING
01827 my_pModule->pokew(imask,ShortOffset(ADCregisters_t,InterruptMask));
01828 #else
01829 ((volatile ADCregisters_t*)my_pModule)->InterruptMask = imask;
01830 #endif
01831 }
01832
01833
01842 unsigned short CADC2530::getInterruptMask() {
01843 unsigned short imask = 0;
01844 #ifndef HAVE_VME_MAPPING
01845 imask = my_pModule->peekw(ShortOffset(ADCregisters_t,InterruptMask));
01846 #else
01847 imask = ((volatile ADCregisters_t*)my_pModule)->InterruptMask;
01848 #endif
01849 return imask;
01850 }
01851
01852
01864 void CADC2530::setCTRchannel(unsigned short chanval) {
01865 if ((chanval < 1)||(chanval > 8)) {
01866 char buffer[256];
01867 sprintf(buffer, "CADC2530::setCTRchannel(): The specified channel value must be in the range [1-8]\n");
01868 throw string(buffer);
01869 }
01870
01871 ADCctr_t ctr;
01872 ADCctr_t mask;
01873
01874 ctr.ctrval = 0;
01875 ctr.bits.M012 = ((chanval-1) & 0x07);
01876
01877 mask.ctrval = 0;
01878 mask.bits.M012 = 0x7;
01879
01880 setCTRbits(ctr.ctrval,mask.ctrval);
01881 }
01882
01883
01894 unsigned short CADC2530::getCTRchannel() {
01895 ADCctr_t ctr;
01896 ctr.ctrval = getCTR();
01897 unsigned short chanval = ctr.bits.M012;
01898 return (chanval+1);
01899 }
01900
01901
01911 void CADC2530::enableAutoFastClear() {
01912 ADCctr_t ctr;
01913 ctr.ctrval = 0;
01914 ctr.bits.DEAC = 1;
01915 resetCTRbits(ctr.ctrval);
01916 }
01917
01918
01928 void CADC2530::disableAutoFastClear() {
01929 ADCctr_t ctr;
01930 ctr.ctrval = 0;
01931 ctr.bits.DEAC = 1;
01932 setCTRbits(ctr.ctrval,ctr.ctrval);
01933 }
01934
01935
01945 void CADC2530::enableCompensation() {
01946 ADCctr_t ctr;
01947 ctr.ctrval = 0;
01948 ctr.bits.DISC = 1;
01949 resetCTRbits(ctr.ctrval);
01950 }
01951
01952
01962 void CADC2530::disableCompensation() {
01963 ADCctr_t ctr;
01964 ctr.ctrval = 0;
01965 ctr.bits.DISC = 1;
01966 setCTRbits(ctr.ctrval,ctr.ctrval);
01967 }
01968
01969
01982 void CADC2530::enableMUXswitch() {
01983 ADCctr_t ctr;
01984 ctr.ctrval = 0;
01985 ctr.bits.MEN = 1;
01986 setCTRbits(ctr.ctrval,ctr.ctrval);
01987 }
01988
01989
02001 void CADC2530::disableMUXswitch() {
02002 ADCctr_t ctr;
02003 ctr.ctrval = 0;
02004 ctr.bits.MEN = 1;
02005 resetCTRbits(ctr.ctrval);
02006 }
02007
02008
02017 unsigned short CADC2530::getCSR() {
02018 unsigned short csrval = 0;
02019 #ifndef HAVE_VME_MAPPING
02020 csrval = my_pModule->peekw(ShortOffset(ADCregisters_t,CSR));
02021 #else
02022 csrval = ((volatile ADCregisters_t*)my_pModule)->CSR;
02023 #endif
02024 return csrval;
02025 }
02026
02027
02038 void CADC2530::setCSR(unsigned short csrval) {
02039 ADCcsr_t csr;
02040 csr.csrval = csrval;
02041 if (csr.bits.DR) my_eventmode = true;
02042 else my_eventmode = false;
02043
02044 #ifndef HAVE_VME_MAPPING
02045 my_pModule->pokew(csrval,ShortOffset(ADCregisters_t,CSR));
02046 #else
02047 ((volatile ADCregisters_t*)my_pModule)->CSR = csrval;
02048 #endif
02049 }
02050
02051
02064 void CADC2530::setCSRbits(unsigned short nBits,unsigned short nMask) {
02065 ADCcsr_t csr;
02066 csr.csrval = getCSR();
02067 csr.csrval = (csr.csrval & CADC2530_CSRMASK);
02068 if (my_eventmode) csr.bits.DR = 1;
02069 csr.csrval = (csr.csrval & (~nMask));
02070 csr.csrval = (csr.csrval | nBits);
02071
02072 #ifndef HAVE_VME_MAPPING
02073 my_pModule->pokew(csr.csrval,ShortOffset(ADCregisters_t,CSR));
02074 #else
02075 ((volatile ADCregisters_t*)my_pModule)->CSR = csr.csrval;
02076 #endif
02077 }
02078
02079
02092 void CADC2530::resetCSRbits(unsigned short nBits) {
02093 ADCcsr_t csr;
02094 csr.csrval = getCSR();
02095 csr.csrval = (csr.csrval & CADC2530_CSRMASK);
02096 if (my_eventmode) csr.bits.DR = 1;
02097 csr.csrval = (csr.csrval & (~nBits));
02098
02099 #ifndef HAVE_VME_MAPPING
02100 my_pModule->pokew(csr.csrval,ShortOffset(ADCregisters_t,CSR));
02101 #else
02102 ((volatile ADCregisters_t*)my_pModule)->CSR = csr.csrval;
02103 #endif
02104 }
02105
02106
02115 unsigned short CADC2530::getCTR() {
02116 unsigned short ctrval = 0;
02117 #ifndef HAVE_VME_MAPPING
02118 ctrval = my_pModule->peekw(ShortOffset(ADCregisters_t,CTR));
02119 #else
02120 ctrval = ((volatile ADCregisters_t*)my_pModule)->CTR;
02121 #endif
02122 return ctrval;
02123 }
02124
02125
02134 void CADC2530::setCTR(unsigned short ctrval) {
02135 #ifndef HAVE_VME_MAPPING
02136 my_pModule->pokew(ctrval,ShortOffset(ADCregisters_t,CTR));
02137 #else
02138 ((volatile ADCregisters_t*)my_pModule)->CTR = ctrval;
02139 #endif
02140 }
02141
02142
02155 void CADC2530::setCTRbits(unsigned short nBits,unsigned short nMask) {
02156 unsigned short ctrval = getCTR();
02157 ctrval = (ctrval & CADC2530_CTRMASK);
02158 ctrval = (ctrval & (~nMask));
02159 ctrval = (ctrval | nBits);
02160
02161 #ifndef HAVE_VME_MAPPING
02162 my_pModule->pokew(ctrval,ShortOffset(ADCregisters_t,CTR));
02163 #else
02164 ((volatile ADCregisters_t*)my_pModule)->CTR = ctrval;
02165 #endif
02166 }
02167
02168
02179 void CADC2530::resetCTRbits(unsigned short nBits) {
02180 unsigned short ctrval = getCTR();
02181 ctrval = (ctrval & CADC2530_CTRMASK);
02182 ctrval = (ctrval & (~nBits));
02183
02184 #ifndef HAVE_VME_MAPPING
02185 my_pModule->pokew(ctrval,ShortOffset(ADCregisters_t,CTR));
02186 #else
02187 ((volatile ADCregisters_t*)my_pModule)->CTR = ctrval;
02188 #endif
02189 }
02190