/************************************************************************* * * vme_list.c - Library of routines for readout and buffering of * events using a JLAB Trigger Interface V3 (TI) with * a Linux VME controller. * */ #define BUFFERLEVEL 20 // default BLOCKLEVEL; gets modified (=1) if in RAW mode int BLOCKLEVEL=100; /* Event Buffer definitions */ #define MAX_EVENT_POOL 20*BLOCKLEVEL /* Should be at least BLOCKLEVEL*BUFFERLEVEL */ #define MAX_EVENT_LENGTH 1024*250 /* 8*BLOCKLEVEL*500 */ /* Size in Bytes */ /* Define Interrupt source and address */ #define TI_MASTER #define TI_READOUT TI_READOUT_EXT_POLL /* Poll for available data, external triggers */ #define TI_ADDR (4<<19) /* GEO slot 4 */ /* Decision on whether or not to readout the TI for each block - Comment out to disable readout */ #define TI_DATA_READOUT #define FIBER_LATENCY_OFFSET 0x4A /* measured longest fiber length */ #include "dmaBankTools.h" #include "tiprimary_list.c" /* source required for CODA */ #include "fadcLib.h" #include "SIS3800.h" /* scaler library */ #define FADC250MODE 3 /* mode 1(RAW) 3(PulseIntegral) */ #define WINDOW 30 /* normally 30 for pulse-integral mode, ~500 for raw */ /* FADC Library Variables */ extern int fadcA32Base; int FA_SLOT; #define SCAL_ADDR 0xab2000 int use_scaler=0; static struct SIS3800CSREG *pScaler; /* Redefine tsCrate according to TI_MASTER or TI_SLAVE */ #ifdef TI_SLAVE int tsCrate=0; #else #ifdef TI_MASTER int tsCrate=1; #endif #endif /* function prototype */ void rocTrigger(int arg); /**************************************** * DOWNLOAD ****************************************/ void rocDownload() { int res, mode; unsigned long laddr; unsigned short iflag; /* Setup Address and data modes for DMA transfers * * vmeDmaConfig(addrType, dataType, sstMode); * * addrType = 0 (A16) 1 (A24) 2 (A32) * dataType = 0 (D16) 1 (D32) 2 (BLK32) 3 (MBLK) 4 (2eVME) 5 (2eSST) * sstMode = 0 (SST160) 1 (SST267) 2 (SST320) */ vmeDmaConfig(2,5,1); /***************** * TI SETUP *****************/ int overall_offset=0x80; #ifndef TI_DATA_READOUT /* Disable data readout */ tiDisableDataReadout(); /* Disable A32... where that data would have been stored on the TI */ tiDisableA32(); #endif /* Set crate ID */ tiSetCrateID(0x01); /* ROC 1 */ /* tiSetTriggerSource(TI_TRIGGER_TSINPUTS); */ tiSetTriggerSource(TI_TRIGGER_FPTRG); /* Set needed TS input bits */ tiEnableTSInput( TI_TSINPUT_1 ); /* Load the trigger table that associates pins 21/22 | 23/24 | 25/26 : trigger1 pins 29/30 | 31/32 | 33/34 : trigger2 */ tiLoadTriggerTable(0); tiSetTriggerHoldoff(4,4,1); /* /\* Set the sync delay width to 0x40*32 = 2.048us *\/ */ tiSetSyncDelayWidth(0x54, 0x40, 1); /* Set the busy source to non-default value (no Switch Slot B busy) */ tiSetBusySource(TI_BUSY_LOOPBACK,1); /* tiSetFiberDelay(10,0xcf); */ /* Set number of events per block */ if(FADC250MODE==1){ BLOCKLEVEL=1; } printf("Block level = %d\n",BLOCKLEVEL); tiSetBlockLevel(BLOCKLEVEL); tiSetBlockBufferLevel(BUFFERLEVEL); tiSetBlockLimit(0); tiSetPrescale(0); tiStatus(0); /* scalers */ pScaler = 0; if (use_scaler) { printf("Setting up pScaler - address 0x%x\n",SCAL_ADDR); res = vmeBusToLocalAdrs(0x39,(char *)SCAL_ADDR,(char **)&laddr); if (res != 0) { printf("Scaler: ERROR: vmeBusToLocalAdrs: scaler at offset 0x%x address= 0x%x\n",SCAL_ADDR,laddr); } else { pScaler = (struct SIS3800CSREG *)laddr; vmeWrite32(&pScaler->reset,1); vmeWrite32(&pScaler->csr,0x7000fd00); vmeWrite32(&pScaler->enclk,1); mode = 1; vmeWrite32(&pScaler->csr,0x00000C00); vmeWrite32(&pScaler->csr,mode<<2); vmeWrite32(&pScaler->clear,1); printf("Scaler: Have setup and cleared \n"); } } printf("rocDownload: User Download Executed\n"); } /**************************************** * PRESTART ****************************************/ void rocPrestart() { unsigned short iflag; int stat; int islot; tiStatus(0); /* Program/Init FADC Modules Here */ iflag = 0xee00; /* SDC Board address */ iflag |= 1<<0; /* Front panel sync-reset */ iflag |= 1<<1; /* Front Panel Input trigger source */ iflag |= 0<<4; /* Internal 250MHz Clock source */ /* iflag |= 1<<4; /\* Front Panel 250MHz Clock source *\/ */ printf("iflag = 0x%x\n",iflag); fadcA32Base = 0x08800000; faInit(0xee0000,0x0,1,iflag); FA_SLOT = faSlot(0); /* Setup FADC Programming */ faSetBlockLevel(FA_SLOT,BLOCKLEVEL); /* for Block Reads */ faEnableBusError(FA_SLOT); /* for Single Cycle Reads */ /* faDisableBusError(FA_SLOT); */ if(FADC250MODE==1){ faSetThreshold(FA_SLOT,0,0xffff); } else { printf("Set threshold to 2500\n"); faSetThreshold(FA_SLOT,2500,0xffff); } if(FADC250MODE==3){ printf("Disabling all but 3 channels. FA_SLOT = %d \n",FA_SLOT); faChanDisable(FA_SLOT,0xf7f5); } /* Setup option 1 processing - RAW Window Data <-- */ /* option 2 - RAW Pulse Data */ /* option 3 - Integral Pulse Data */ /* Setup 200 nsec latency (PL = 50) */ /* Setup 80 nsec Window (PTW = 20) */ /* Setup Pulse widths of 36ns (NSB(3)+NSA(6) = 9) */ /* Setup up to 1 pulse processed */ /* Setup for both ADC banks(0 - all channels 0-15) */ /* The following line works and the aforementioned parameters */ /* refer to its call args */ /* faSetProcMode(FA_SLOT,1,50,20,3,6,1,0);*/ /* typically used in Compton setup faSetProcMode(FA_SLOT,FADC250MODE,1950,WINDOW,3,26,1,0);*/ faSetProcMode(FA_SLOT,FADC250MODE,100,WINDOW,3,26,1,0); faClear(FA_SLOT); faStatus(FA_SLOT,0); faGStatus(0); faSDC_Config(1,0); faSDC_Status(0); printf("rocPrestart: User Prestart Executed\n"); } /**************************************** * GO ****************************************/ void rocGo() { int islot; /* Enable modules, if needed, here */ /* Enable FADC */ faEnable(0,0,0); /* Send Sync Reset to SDC */ faSDC_Sync(); /* Show the current block level */ printf("%s: Current Block Level = %d\n", __FUNCTION__,tiGetCurrentBlockLevel()); } /**************************************** * END ****************************************/ void rocEnd() { int islot; tiStatus(0); /* FADC Disable */ faDisable(0,0); /* FADC Event status - Is all data read out */ faGStatus(0); faReset(FA_SLOT,0); printf("rocEnd: Ended after %d blocks\n",tiGetIntCount()); } /**************************************** * TRIGGER ****************************************/ void rocTrigger(int evnum) { int ii, islot, intcnt; int stat, dCnt, len=0, idata, nwords=0; unsigned int datascan; unsigned int busytime,livetime; static int mycount=1; tiSetOutputPort(1,0,0,0); BLOCKOPEN(evnum,BT_BANK,BLOCKLEVEL); #ifdef TI_DATA_READOUT BANKOPEN(4,BT_UI4,0); vmeDmaConfig(2,5,1); dCnt = tiReadBlock(dma_dabufp,80+(3*BLOCKLEVEL),1); if(dCnt<=0) { printf("No data or error. dCnt = %d\n",dCnt); } else { dma_dabufp += dCnt; } BANKCLOSE; #endif /* Bank for fADC250 data */ /* warning: put ONLY FADC data into bank 3 */ /* want something else ? put into another bank */ BANKOPEN(3,BT_UI4,0); /* Check for valid data here */ for(ii=0;ii<1000;ii++) { datascan = faBready(faSlot(0)); if (datascan>0) { break; } } if(datascan>0) { if(FADC250MODE==3) { nwords = faReadBlock(FA_SLOT,dma_dabufp,100+8*BLOCKLEVEL,1); } else { nwords = faReadBlock(FA_SLOT,dma_dabufp,100+8*WINDOW*BLOCKLEVEL,1); } if(nwords < 0) { printf("ERROR: in transfer (event = %d), nwords = 0x%x\n", tiGetIntCount(),nwords); *dma_dabufp++ = LSWAP(0xda000bad); } else { dma_dabufp += nwords; } } else { printf("ERROR: Data not ready in event %d\n",tiGetIntCount()); *dma_dabufp++ = LSWAP(0xda000bad); } BANKCLOSE; BANKOPEN(5,BT_UI4,0); *dma_dabufp++ = LSWAP(0xfb1b1b1b); mycount++; *dma_dabufp++ = LSWAP(mycount); *dma_dabufp++ = LSWAP(tiGetIntCount()); busytime = tiGetBusyTime(); livetime = tiGetLiveTime(); *dma_dabufp++ = LSWAP(busytime); *dma_dabufp++ = LSWAP(livetime); if (use_scaler && pScaler) { *dma_dabufp++ = LSWAP(0xb0b0b444); *dma_dabufp++ = LSWAP(vmeRead32(&pScaler->readCounter[8])); *dma_dabufp++ = LSWAP(vmeRead32(&pScaler->readCounter[9])); *dma_dabufp++ = LSWAP(vmeRead32(&pScaler->readCounter[10])); } BANKCLOSE; BLOCKCLOSE; tiSetOutputPort(0,0,0,0); } void rocCleanup() { int islot=0; printf("%s: Reset all FADCs\n",__FUNCTION__); }