/* **++ ** FACILITY: ** slave processor user routine for AYEball + Large Ion Chamber at FMA ** ** ABSTRACT: ** evtuser.c - This file is a skeleton which can be filled in ** to tailor the data acquisition slave for user ** experiments. The tailorable routines are: ** usrini - One time user initialization when system starts. ** usrbegin - User special begin run processing ** usrresume - User special resume run processing ** usrgetevt - Acquire a physics event. ** usrgetmax - Return the maximum number of words in an ** event (MUST be a correct upper bound). ** usrrdscl - Read scalers. ** userper1 - User special actions called at the frequency ** with which snapshot scalers are read out. ** userper2 - User special actions called at the frequency ** with which taped scalers are read. ** usrend - User special end run processing. ** usrpause - User special pause run handling. ** usrtrig1 - User trigger 1. ** usrtrig2 - Process user trigger 2. ** ** For many cases, the default processing performed by ** all but usrgetevt and usrgetmax is sufficient, nonetheless, ** some special experiments may have special requirements. ** See the comment headers of each routine for more details. ** ** It may be that the user will need to make use of some ** of the settable parameters (that's what there here for ** after all). These are accessable as the arrays: ** ** userints[0]..userints[NUMIPAR] - Integer parameters ** userflags[0]..userflags[NUMFPAR] - Boolean flag parameters ** userfloats[0]..userfloats[NUMRPAR]- Floating point params. ** AUTHORS: ** Ron Fox, and you ** ** CREATION DATE: 25-Aug-1988 ** MODIFIED: 13-Jul-1995 (DJB) **-- **/ /* ** INCLUDE FILES /kt/ do not modify this sequence of ifdefs and includes **/ #if CPU == MICROPROJECT #define VME16 0 #endif /* CAEN C257 scalers. */ #define INIT257(b, c, n) camctl((b),(c),(n),0,9) #define CLR257(b, c, n) INIT257((b),(c),(n)) #define READ257(b, c, n, a) *((INT32 *)bufpt)++ = \ camread24((b),(c),(n),(a),0) #define READALL257(b, c, n) { INT16 _a; \ for(_a = 0; _a < 16; _a++) \ *((INT32 *)bufpt)++ = \ camread24((b),(c),(n),(_a), 0); \ } #include "types.h" #include "slvshared.h" #include "vme.h" /* Define VME access */ #include "psosdef.h" #include "evpool.h" #include "camac.h" #include "macros.h" #include "evtsevents.h" /* Event definitions. */ #include #ifdef VME16 #undef VME16 #endif #undef CAMBAS #if CPU == IRONICS #define CAMBAS 0xFA800000 #endif #if CPU == MICROPROJECT #define CAMBAS 0xFE800000 #endif /* The following macros trigger user events: */ extern union evtsevtflags actionflags; #define TRIGGER11 actionflags.flags.usertrig1 = 1 #define TRIGGER2 actionflags.flags.usertrig2 = 1 /* The following defines the interrupt vector and interrupt service rtn */ /* for the Camac BRANCH driver. */ #define CAMVEC 103 /* CAMAC vector. */ #define CAMIPL 2 /* CAMAC IPL. */ int camacisr(); /* CAMAC interrupt service rtn. */ int vmeon(); /* Enables acceptance of vme ints. */ /* ** ** The line below can be used as a simplified way to tailor ** usrgetmax. The actual maximum event length depends on the ** number of scalers as well as the sizes of various headers, ** and the maximum number of words in a physics data event. ** If you don't want to worry about all of this, and just let ** the default usrmaxevt return the maximum event size, then ** just alter the definition below to indicate the largest number ** of words that will be read out in physics data: ** */ #define STDEVTHEADER 4 /* Touch this and die. */ #define STDSCLHEADER 5 /* Touch this and die too. */ /* The typedef below defines a CAMAC register: */ typedef INT16 *CAMREG; /* Declare the cbdptr function: */ CAMREG cbdptr(); /* This defines a table of integer digits in ascii strings. */ char *digit[10] = {" 0 ", " 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 " }; #define SECOND 64 /* Number of ticks/second */ /* The definition below gives the number of branches to be initted. */ #define NUMBR 1 /* The initialized array below indicates the number of crates in each */ /* Branch. We assume the user has set the crate numbers so that each */ /* branch begins with crate 1 and there are no holes in the crate numbering */ /* scheme. */ static int syscrates[NUMBR] = { 3 }; #define SYSOUTREG 16 #define SYSOUTREG_CRAT 1 #define SSET_SYSOUTREG CBDPTR(0,SYSOUTREG_CRAT,SYSOUTREG,0,20,CAM16) #define SCLR_SYSOUTREG CBDPTR(0,SYSOUTREG_CRAT,SYSOUTREG,0,22,CAM16) #define PULS_SYSOUTREG CBDPTR(0,SYSOUTREG_CRAT,SYSOUTREG,0,17,CAM16) /* ** The first eight outputs on the Jorway Model 41 output register are... ** The last four outputs are available for the user. Note there are 2 ** STOPPED_OUT outputs. */ #define CLRLATCH_OUT 1 #define STOPPED_OUT 6 #define EVTRD_OUT 8 #define SCLRD_OUT 16 #define NULLEVT_OUT 32 #define SYS_RESERVED1 64 #define SYS_RESERVED2 128 #define CLRADC_OUT 1024 /* This is a good place to define our user stuff: */ /*------------------------------------------------------------------------*/ /* crate and slot assignments */ /*------------------------------------------------------------------------*/ #define PPAC_CRAT 1 #define GE_CRAT 2 #define N_CRAT 3 /* DSDSDS */ #define GE_SCL 11 /* scalers */ #define PPAC_SCL 13 #define N_SCL 1 /* DSDSDS */ #define EVTYPE 1 /* pattern register for event type (BiRa 2351) */ #define PPACTDC 3 /* PPAC TDC */ #define CAENADC 5 /* CAEN adc for monitor and PPAC */ #define ICADC 7 /* Silena adc for Ion Chamber */ #define PUREG 9 /* pile-up bit register for PPAC + IC */ #define GEPAT 10 /* coincidence register #1 (Ge pattern) */ #define GETDC1 13 /* Ge TDC slot # 1 */ #define GETDC2 15 /* Ge TDC slot # 2 */ #define MUX1 18 /* PW multiplexer */ #define MUX2 21 /* PW multiplexer */ #define PLD1 8 /* programmable delay */ #define PLD2 9 /* DSDSDS */ #define NCFD1 3 /* n-det CFD#1 */ #define NCFD2 4 /* n-det CFD#2 */ #define NDEL 5 /* n-det delay */ #define NCR 6 /* n-det coinc reg */ #define NTDC 8 /* n-det TDC */ #define NQDC1 10 /* n-det QDC#1 - total energy */ #define NQDC2 12 /* n-det QDC#2 - slow component */ /* DSDSDS */ #define NGE1 10 /* # EUROGAM detectors */ #define NGE2 10 /* # TESSA detectors */ #define NN 12 /* # neutron detectors */ /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** donothing - A local function with the purpose of inserting some ** time between CAMAC write/control pairs to work around ** an error in the CES board which causes that board to ** generate a bus error on the control part of that pair. **-- **/ static donothing() {} /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrlights - This function puts a spinning pattern of lights in the ** system crate dataway display register. The speed ** depends on what else is happening in the world. ** The pattern is governed by the ltsarray initialization ** and PATTSIZE constant. ** ** /kt/ we dont have a dataway display in slot 1, so... **-- **/ usrlights() {} /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrini - This function is called at power up initialization ** (When slave has just been loaded and started). It is ** called exactly once. The user should: ** ** 1. Initialize all CAMAC branch drivers. ** 2. If desired, C/Z all CAMAC crates. ** 3. Remove the inhibits from all CAMAC crates. ** 4. Program gate generator to latch mode. **-- **/ usrini() { int crate, branch; /* loop counters */ CAMREG reg; /* CAMAC pointer */ int panic(); /* 1. Initialize all CAMAC branch driver interfaces */ /* our standard initialization takes each branch */ /* driver, clears the IT interrupts, zeroes the branch */ /* and sets the interrupt masks to mask all interrupts */ for (branch = 0; branch < NUMBR; branch++) { reg = cbdptr(branch, 0, 29, 0, 0, CAM16); /* Branch CSR. */ CAMWR16(reg, (MNOX | MTO |MLAM | MIT2 | MIT4)); /* Mask interrupts */ reg = cbdptr(branch, 0, 29, 0, 4, CAM16); /* Interrupt flag reg */ CAMWR16(reg, 0); /* Clear interrupts */ reg = cbdptr(branch, 0, 29, 0, 9, CAM16); /* Branch zero reg */ CAMWR16(reg, 0); /* Zero branch */ pause_p(2); /* Wait for zero. */ } /* 2. C/Z the CAMAC crates we care to C/Z */ /* 3. Remove the inhibits from all CAMAC crates. */ /* We loop until missing or offline crates are made good */ for (branch = 0; branch < NUMBR ; branch ++) for (crate = 1; crate <= syscrates[branch]; crate++) { reg = cbdptr(branch, 0, 29, 0, 9, CAM16); /* Online mask */ while ( (CAMRD16(reg) & (1 << crate)) == 0) /* check online */ { dbgdisplay("Crate number: "); dbgdisplay(digit[crate]); dbgdisplay("is offline or missing"); dbgcrlf(); pause_p(SECOND*5); /* Try again in 5 sec */ } reg = cbdptr(branch, crate, 28, 9, 26, CAM16); CAMCTL(reg); /* C the crate. */ donothing(); reg = cbdptr(branch, crate, 28, 8, 26, CAM16); CAMCTL(reg); /* Z the crate. */ donothing(); reg = cbdptr(branch, crate, 30, 9, 24, CAM16); CAMCTL(reg); /* Remove inhibit. */ donothing(); } CAMWR16(SSET_SYSOUTREG, STOPPED_OUT); /* set stopped */ /* 5. Plug the interrupt vector for the CAMAC event trigger. */ *((INT32 *)(CAMVEC << 2)) = (INT32)camacisr; #if CPU == IRONICS /* IRONICS boards need to enable VME */ /* Interrupts on the CAMAC IPL. */ vmeon(CAMIPL); /* Enable VME interrupt reception. */ #endif /* /kt/ add whatever power-up initializations here */ } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrbegin - This function is called at the beginning of each ** run. The begin run buffer is already on its way to ** the VAX. Users may inject other events into the ** event stream by calling allocevt(), filling in the event ** and doing a call to putevt(). They had damned well ** better know what they're doing if they choose to do ** this however... or they could easily crash the system. ** ** Typical tailoring that must be done at this time ** is whatever code is needed to enable the acquisition. ** This consists of the following: ** 1. Load thresholds etc. into programmable devices. ** 2. Clear devices. ** 3. Enable LAMS on devices. ** 4. Enable the event trigger interrupt. ** 5. Clear the dead time gate. ** ** This skeleton includes sample code to enable event ** trigger inputs using the Branch 1 branch driver INT2 ** input to indicate event startup. **-- **/ usrbegin() { int conreg,i,j,lt,ut,off,comthr,ped,thr,widA,widB,del; int freq; CAMREG reg; usrini(); /* In case crates were off. */ /*-----------------------------------------------------------------------*/ /* 2. Clear all data acquisition devices and scalers. */ /*-----------------------------------------------------------------------*/ camctl(0,GE_CRAT,GEPAT,0,9); /* clear Ge coinc. reg. (pattern) */ camctl(0,GE_CRAT,GEPAT,1,9); /* clear Ge coinc. reg. (pattern) */ camctl(0,GE_CRAT,GETDC1,3,11); /* clear germanium TDC1 */ camctl(0,GE_CRAT,GETDC2,3,11); /* clear germanium TDC2 */ camctl(0,GE_CRAT,MUX1,0,9); /* clear the MUX */ camctl(0,GE_CRAT,MUX2,0,9); /* clear the MUX */ camctl(0,PPAC_CRAT,PPACTDC,3,11); /* ppac tdc */ camctl(0,PPAC_CRAT,CAENADC,0,9); /* CAEN adc */ camctl(0,PPAC_CRAT,ICADC,0,9); /* Silena adc */ CLR4434(0,GE_CRAT,GE_SCL); /* clear scalers */ CLR257(0,PPAC_CRAT,PPAC_SCL); /* DSDSDS */ camctl(0,N_CRAT,NCFD1,0,9); /* clear neutron CFD1 */ camctl(0,N_CRAT,NCFD2,0,9); /* clear neutron CFD2 */ camctl(0,N_CRAT,NCR,1,9); /* clear neutron coinc reg */ camctl(0,N_CRAT,NTDC,3,11); /* clear neutron TDC */ camctl(0,N_CRAT,NQDC1,0,9); /* clear neutron QDC#1 */ camctl(0,N_CRAT,NQDC2,0,9); /* clear neutron QDC#2 */ CLR4434(0,N_CRAT,N_SCL); /* clear neutron scaler */ /* DSDSDS */ /*-----------------------------------------------------------------------*/ /* 3. Program Modules */ /*-----------------------------------------------------------------------*/ lt=userints[4]; /* phillips */ ut=userints[5]; ped=userints[6]; /**** Ge TDC #1 ****/ camwrite16(0,GE_CRAT,GETDC1,0,19,7); /* write control reg */ camwrite16(0,GE_CRAT,GETDC1,0,17,0); /* sel ped */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,GETDC1,j,20,ped); /* write ped */ camwrite16(0,GE_CRAT,GETDC1,1,17,0); /* sel lt */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,GETDC1,j,20,lt); /* write lt */ camwrite16(0,GE_CRAT,GETDC1,2,17,0); /* sel ut */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,GETDC1,j,20,ut); /* write ut */ /**** Ge TDC #2 ****/ camwrite16(0,GE_CRAT,GETDC2,0,19,7); /* write control reg */ camwrite16(0,GE_CRAT,GETDC2,0,17,0); /* sel ped */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,GETDC2,j,20,ped); /* write ped */ camwrite16(0,GE_CRAT,GETDC2,1,17,0); /* sel lt */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,GETDC2,j,20,lt); /* write lt */ camwrite16(0,GE_CRAT,GETDC2,2,17,0); /* sel ut */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,GETDC2,j,20,ut); /* write ut */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,PLD1,j,16,15); /* prog delay #1 to MAX */ for (j=0;j<16;j++) camwrite16(0,GE_CRAT,PLD2,j,16,15); /* prog delay #2 to MAX */ /* PPAC TDC */ camwrite16(0,PPAC_CRAT,PPACTDC,0,19,7); /* write control reg */ camwrite16(0,PPAC_CRAT,PPACTDC,0,17,0); /* sel ped */ for (j=0;j<16;j++) camwrite16(0,PPAC_CRAT,PPACTDC,j,20,ped); /* write ped */ camwrite16(0,PPAC_CRAT,PPACTDC,1,17,0); /* sel lt */ for (j=0;j<16;j++) camwrite16(0,PPAC_CRAT,PPACTDC,j,20,lt); /* write lt */ camwrite16(0,PPAC_CRAT,PPACTDC,2,17,0); /* sel ut */ for (j=0;j<16;j++) camwrite16(0,PPAC_CRAT,PPACTDC,j,20,ut); /* write ut */ lt=userints[7]; /* CAEN adc */ ut=userints[8]; conreg=userints[9]; camwrite16(0,PPAC_CRAT,CAENADC,0,17,conreg); /* reset caen contr reg */ camwrite16(0,PPAC_CRAT,CAENADC,1,17,conreg); /* reset caen contr reg */ camwrite16(0,PPAC_CRAT,CAENADC,2,17,conreg); /* since usrini is called */ camwrite16(0,PPAC_CRAT,CAENADC,3,17,conreg); camwrite16(0,PPAC_CRAT,CAENADC,4,17,conreg); camwrite16(0,PPAC_CRAT,CAENADC,5,17,conreg); camwrite16(0,PPAC_CRAT,CAENADC,6,17,conreg); camwrite16(0,PPAC_CRAT,CAENADC,7,17,conreg); /* above here and it Z's the */ /* crate which upset the CAEN */ camwrite16(0,PPAC_CRAT,CAENADC,0,20,lt); /* also do LT */ camwrite16(0,PPAC_CRAT,CAENADC,2,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,4,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,6,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,8,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,10,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,12,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,14,20,lt); camwrite16(0,PPAC_CRAT,CAENADC,1,20,ut); /* also do UT */ camwrite16(0,PPAC_CRAT,CAENADC,3,20,ut); camwrite16(0,PPAC_CRAT,CAENADC,5,20,ut); camwrite16(0,PPAC_CRAT,CAENADC,7,20,ut); camwrite16(0,PPAC_CRAT,CAENADC,9,20,ut); camwrite16(0,PPAC_CRAT,CAENADC,11,20,ut); camwrite16(0,PPAC_CRAT,CAENADC,13,20,ut); camwrite16(0,PPAC_CRAT,CAENADC,15,20,ut); lt=userints[0]; /* silena adc */ ut=userints[1]; off=userints[2]; comthr=userints[3]; /* silena for ION CHAMBER */ conreg = 0x0815; /* stat reg (addressed read) */ camwrite16(0,PPAC_CRAT,ICADC,14,20,conreg); camwrite16(0,PPAC_CRAT,ICADC,9,20,comthr); /* common thresh */ for (j=0;j<8;j++) { camwrite16(0,PPAC_CRAT,ICADC,j,17,ut); /* ut */ camwrite16(0,PPAC_CRAT,ICADC,j+8,17,lt); /* lt */ camwrite16(0,PPAC_CRAT,ICADC,j,20,off); /* offset */ } /* DSDSDS */ lt=userints[10]; /* neutron TDCs */ ut=userints[11]; ped=userints[12]; camwrite16(0,N_CRAT,NTDC,0,19,7); /* write control reg */ camwrite16(0,N_CRAT,NTDC,0,17,0); /* sel ped */ for (j=0;j<16;j++) camwrite16(0,N_CRAT,NTDC,j,20,ped); /* write ped */ camwrite16(0,N_CRAT,NTDC,1,17,0); /* sel lt */ for (j=0;j<16;j++) camwrite16(0,N_CRAT,NTDC,j,20,lt); /* write lt */ camwrite16(0,N_CRAT,NTDC,2,17,0); /* sel ut */ for (j=0;j<16;j++) camwrite16(0,N_CRAT,NTDC,j,20,ut); /* write ut */ thr=userints[13]; /* neutron CFD's */ widA=userints[14]; widB=userints[15]; del=userints[16]; camwrite16(0,N_CRAT,NCFD1,2,17,0); /* neutron CFD#1 */ camwrite16(0,N_CRAT,NCFD1,0,17,widA); camwrite16(0,N_CRAT,NCFD1,1,17,widB); for (j=0;j<8;j++) camwrite16(0,N_CRAT,NCFD1,j,16,thr); camwrite16(0,N_CRAT,NCFD2,2,17,0); /* neutron CFD#2 */ camwrite16(0,N_CRAT,NCFD2,0,17,widA); camwrite16(0,N_CRAT,NCFD2,1,17,widB); for (j=0;j<8;j++) camwrite16(0,N_CRAT,NCFD2,j,16,thr); for (j=0;j<16;j++) /* neutron delay */ camwrite16(0,N_CRAT,NDEL,j,16,del); /* DSDSDS */ /*-----------------------------------------------------------------------*/ /* 4. Enable the event trigger interrupt. */ /*-----------------------------------------------------------------------*/ reg = cbdptr(0, 0, 29, 0, 4, CAM16); /* Interrupt flag register. */ CAMWR16(reg, 0); /* Clear pending interrupts. */ reg = cbdptr(0, 0, 29, 0, 0, CAM16); /* Branch CSR. */ CAMWR16(reg, (MNOX | MTO |MLAM | MIT4)); /* Allow IT2 */ donothing(); actionflags.flags.takeevent = 0; /* Clear take event flag.... */ donothing(); CAMWR16(PULS_SYSOUTREG, CLRLATCH_OUT); /* clear Busy */ donothing(); CAMWR16(SCLR_SYSOUTREG, STOPPED_OUT); /* indicate acquiring */ } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrresume - This function is called whenever a run is to be ** resumed after a pause. The routine is called after ** the resume buffer is already on it's way to the ** VAX. Users may inject other events into the event stream ** by calling allocevt(), filling in the event and doing a ** call to putevt(). They had damned well better know what ** they're doing if they do this... or they could easily ** crash the system. ** Typical actions on resums are identical to those ** done at usrbegin. The default action of this routine ** is therefore just to call usrbegin(). **-- **/ usrresume() { usrbegin(); } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrgetevt - This routine is called when an event trigger is ** detected. The user is handed a pointer to a buffer ** which is gaurenteed to be large enough to hold the ** largest event that could be taken (assuming the ** user was honest in tailoring usrgetmax... if they're ** dishonest, then system crashes are almost certain). ** The following is typically done to read out an event: ** ** 1. Read a pattern register from CAMAC and put it in ** the buffer. ** 2. Based on the pattern register, compute the set ** of required LAMS, wait for them for some period ** of time in excess of the conversion time of the ** devices. If all LAMS are not in in time, then ** declare a LAM timeout. ** 3. Read out the event, and clear the digitizers. ** 4. Clear the computer busy signal and return the number ** of words read. ** Note that the user must return the number of words ** that were actually read out. This must be ** accurate. ** Note If zero or less is returned from this procedure, then ** no event is put in the buffer. This allows filtering ** of events to be done at this level. ** ** FORMAL PARAMETERS: ** ** buffer - Pointer to the event buffer. ** ** FUNCTION VALUE: ** ** words actually read from CAMAC. Include all words that were ** put in the buffer (bit registers lam masks the works. This word ** count will be prepended to the event as seen by the VAX so that ** the whole thing will look like this: ** ** +--------------------------------+ ** | word count returned from here | ** +--------------------------------+ ** | All the words you read | ** | into the buffer here. | ** + ... + **-- **/ /* --------------------------------------------------------------------------- Event program for AYEball + PPAC + IC + neutron detectors --------------------------------------------------------------------------- event type bit pattern (bit # 1-7: monitor,ppac,g,R-g,gg,R-gg,IC) monitor event emon 0xDEAD if any type of gamma bit set (3,4,5,6), after the evtype we have: EG bit register (bits 1-9 for detectors 1-9) TESSA bit register (bits 1-9 for detectors 11-19) (E,t) for each det which has a bit set neutron bit register (t,Q1,Q2) for each det which has a bit set if any type of focal plane bit set (2,4,6,7), after the evtype we have: PPAC R L U D cathode DE PPAC-IC TOF (from tdc on 400 ns f.s.) PPAC-IC TAC (from tac on sev us f.s.) PPAC-RF TOF (from tdc) R-g TAC pileup bit register (bit # 1/2 set if ppac/IC piled up) IC DE1 DE2 DE3 position */ /* redefine this to the largest possible event size in words */ #define EVENT_MAXWORDS 500 int usrgetevt(buffer) INT16 *buffer; /* Buffer pointer is treated as a word. */ { int evtsiz,type,epat,wrd,ge_pat1,ge_pat2,npat,i,junk; static int bincode[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; static int m =0; INT16 *bufpt; /* moving pointer */ /*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/ bufpt = (INT16*) buffer; evtsiz = 0; /* reset evtsiz */ /*--------------------------*/ /* read the event type */ /*--------------------------*/ READBIT(0,PPAC_CRAT,EVTYPE,0,2,epat); /*-------------------------------------------------------------*/ /* read the Monitor stuff */ /*-------------------------------------------------------------*/ if ( (epat&1) != 0 ) /* bit 1 */ { rdtobuf16(0,PPAC_CRAT,CAENADC,0,2); /* e monitor energy */ rdtobuf16(0,PPAC_CRAT,ICADC,0,0); /* e monitor energy from silena */ junk=camread16(0,PPAC_CRAT,CAENADC,1,2); /* dummy read to clear chans */ junk=camread16(0,PPAC_CRAT,CAENADC,2,2); junk=camread16(0,PPAC_CRAT,CAENADC,3,2); junk=camread16(0,PPAC_CRAT,CAENADC,4,2); junk=camread16(0,PPAC_CRAT,CAENADC,5,2); junk=camread16(0,PPAC_CRAT,CAENADC,6,2); junk=camread16(0,PPAC_CRAT,CAENADC,7,2); /* not used in this ev type */ } /*-------------------------------------------------------------*/ /* read the germanium and neutron stuff */ /*-------------------------------------------------------------*/ if ( (epat&60) != 0 ) /* bit 3,4,5,or 6 */ { READBIT(0,GE_CRAT,GEPAT,0,0,ge_pat1); READBIT(0,GE_CRAT,GEPAT,1,0,ge_pat2); for (i = 0; i < NGE1; i++) /*** EUROGAM GERMAMIUMS ***/ if ( (ge_pat1&bincode[i]) == bincode[i] ) { wrd = camread16(0,GE_CRAT,MUX1,i+1,3); /* latch adc and read MUX register */ if (qtst(0)) { putbufw(wrd); /* output the energy */ rdtobuf16(0,GE_CRAT,GETDC1,i,0); /* read and out germanium time */ } else { putbufw(8200); /* output some dummy values for bad Q */ putbufw(4100); } } for (i = 0; i < NGE2; i++) /*** TESSA GERMANIUMS ***/ if ( (ge_pat2&bincode[i]) == bincode[i] ) { if ( i <= 6 ) /* first 7 chan read in sequence */ wrd = camread16(0,GE_CRAT,MUX2,i+1,3); /* latch adc and read MUX register */ else /* skip 2 chan in mux */ wrd = camread16(0,GE_CRAT,MUX2,i+3,3); /* latch adc, read MUX register */ if (qtst(0)) { putbufw(wrd); /* output the energy */ rdtobuf16(0,GE_CRAT,GETDC2,i,0); /* read and out germanium time */ } else { putbufw(8200); /* output some dummy values for bad Q */ putbufw(4100); } } /* DSDSDS */ npat = camread16(0,N_CRAT,NCR,1,0); /*** neutron detectors ***/ putbufw(npat); if ( (npat) != 0 ) { for (i = 0; i < NN; i++) if ( (npat&bincode[i]) == bincode[i] ) { wrd = camread16(0,N_CRAT,NTDC,i,0); putbufw(wrd); wrd = camread16(0,N_CRAT,NQDC1,i,0); putbufw(wrd); wrd = camread16(0,N_CRAT,NQDC2,i,0); putbufw(wrd); } } /* DSDSDS */ } /* end of Ge readout */ /*-------------------------------------------------------------*/ /* read the PPAC + Ionization Chamber */ /*-------------------------------------------------------------*/ if ( (epat&106) != 0 ) /* bit 2,4,6, or 7 */ { rdtobuf16(0,PPAC_CRAT,PPACTDC,1,0); /* right */ rdtobuf16(0,PPAC_CRAT,PPACTDC,3,0); /* left */ rdtobuf16(0,PPAC_CRAT,PPACTDC,5,0); /* up */ rdtobuf16(0,PPAC_CRAT,PPACTDC,7,0); /* down */ donothing(); rdtobuf16(0,PPAC_CRAT,CAENADC,1,2); /* DE */ donothing(); rdtobuf16(0,PPAC_CRAT,PPACTDC,9,0); /* IC tof */ donothing(); rdtobuf16(0,PPAC_CRAT,CAENADC,2,2); /* IC tac */ donothing(); rdtobuf16(0,PPAC_CRAT,PPACTDC,11,0); /* rf tof */ donothing(); rdtobuf16(0,PPAC_CRAT,CAENADC,3,2); /* rec-gamma tac */ donothing(); rdtobuf16(0,PPAC_CRAT,PUREG,0,2); /* pile-up bit register */ donothing(); rdtobuf16(0,PPAC_CRAT,CAENADC,4,2); /* DE1 */ rdtobuf16(0,PPAC_CRAT,CAENADC,5,2); /* DE2 */ rdtobuf16(0,PPAC_CRAT,CAENADC,6,2); /* DE3 */ rdtobuf16(0,PPAC_CRAT,CAENADC,7,2); /* POSITION */ junk=camread16(0,PPAC_CRAT,CAENADC,1,2); /* not used in this ev type */ } /*--------------------------------------------------------------------*/ /* end of readout */ /*--------------------------------------------------------------------*/ putbufw(0xDEAD); /* end of event marker to make dumps readable */ /*--------------------------------------------------------------------*/ /* compute evtsiz in words */ /*--------------------------------------------------------------------*/ evtsiz = bufpt - buffer; /*--------------------------------------------------------------------*/ /* clear modules */ /*--------------------------------------------------------------------*/ CAMWR16(PULS_SYSOUTREG,CLRADC_OUT); /* clear adc's */ donothing(); camctl(0,GE_CRAT,GEPAT,0,9); /* clear Ge coinc. registers */ camctl(0,GE_CRAT,GEPAT,1,9); camctl(0,GE_CRAT,GETDC1,0,9); /* clear germanium TDC1 */ camctl(0,GE_CRAT,GETDC2,0,9); /* clear germanium TDC2 */ camctl(0,GE_CRAT,MUX1,0,9); /* clear all ADC'S on PW MUX */ camctl(0,GE_CRAT,MUX2,0,9); /* clear all ADC'S on PW MUX */ camctl(0,PPAC_CRAT,PPACTDC,3,11); /* Phillips tdc */ camctl(0,PPAC_CRAT,ICADC,0,9); /* Silena adc */ /* DSDSDS */ camctl(0,N_CRAT,NCR,1,9); /* clear neutron coinc reg */ camctl(0,N_CRAT,NTDC,0,9); /* clear neutron TDC */ camctl(0,N_CRAT,NQDC1,0,9); /* clear neutron QDC#1 */ camctl(0,N_CRAT,NQDC2,0,9); /* clear neutron QDC#2 */ /* DSDSDS */ CAMWR16(PULS_SYSOUTREG, CLRLATCH_OUT); /* clear busy-latch */ donothing(); return evtsiz; } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrgetmax - This function should return the maximum number ** of words which can be put into an event of any kind. ** By default, we compute this from what we know about ** physics event maximum sizes, the number of scalers read, ** and the sizes of the various fixed sized events. ** ** IMPLICIT INPUTS: ** ** MAXPHYSICS - Maximum size of physics data. ** STDEVTHEADER - Event pool header size. ** STDSCLHEADER - Event pool scaler event header. ** numscalers - Number of scalers being read out. ** **-- **/ int usrgetmax() { int nwds1, nwds2; if (EVENT_MAXWORDS < 0 ) die(); nwds1 = EVENT_MAXWORDS + STDEVTHEADER; /* Biggest physics event. */ nwds2 = STDSCLHEADER + STDEVTHEADER + (numscalers << 1); /* Biggest scaler evt. */ /* Return the largest of the two sizes. */ if (nwds1 > nwds2) return nwds1; else return nwds2; } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrrdscl - This function reads out a scaler event. The layers of ** code above us take care of the summing and interval ** computations needed to deal with snapshot scalers and ** similar nonsense. The only thing we need to do is: ** ** 1. If desired, indicated scaler readout in progress. ** 2. Read and clear the scalers into the event. ** 3. If 1. done, then indicate scaler readout completed. ** 4. Return the number of scaler words actually read ** This return value indicates the actual number ** of words that will be considered part of the ** event. Normally, this is just 2 * num_scalers ** However, if the user wants to inject some other ** non summed, non scaler data into scaler buffers, ** making nwds larger makes this possible. Upper layers ** will ignore these words, but pass them on to the ** VAX. ** NOTE: Scalers are normally 32 bits long and therefore ** require 2 words per scaler. ** ** FORMAL PARAMETERS: ** ** buffer - Pointer to a buffer guarenteed to be large enough to hold your ** scalers, assuming usrgetmax was coded honestly. ** numscalers - Number of scalers to read out. ** ** ** FUNCTION VALUE: ** ** The number of WORDS actually use. Normally this is ** numscalers << 1 **-- **/ int usrrdscl(bufpt, numscalers) WORD *bufpt; int numscalers; { INT32 *_sbufpt; _sbufpt = (INT32*) bufpt; READALL4434(0, GE_CRAT, GE_SCL); CLR4434(0, GE_CRAT, GE_SCL); READALL257(0,PPAC_CRAT,PPAC_SCL); CLR257(0,PPAC_CRAT,PPAC_SCL); READALL4434(0, N_CRAT, N_SCL); CLR4434(0, N_CRAT, N_SCL); /*-------------------------------END USER CODE ---------------------------*/ return (bufpt - (WORD *)_sbufpt); } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrper1 - This function is called at the same frequency that ** snap shot scalers are called and is a mechanism for ** the user to take periodic arbitrary actions. ** The user can inject data into the event stream at this point ** by calling allocevt(), filling in the event, and calling ** putevt(), but if you do you had better know what you're ** doing or you can easily crash the system. ** Other things that could be done here would be to periodically ** refresh/monitor programmable devices or whatever else you feel ** like doing. ** NOTE: Unless the programmer explicitly inhibits event ** acquisition, the system is live at this point. **-- **/ usrper1() { } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrper2 - This function is called at the same frequency that ** scalers are called and is a mechanism for ** the user to take periodic arbitrary actions. ** The user can inject data into the event stream at this point ** by calling allocevt(), filling in the event, and calling ** putevt(), but if you do you had better know what you're ** doing or you can easily crash the system. ** Other things that could be done here would be to periodically ** refresh/monitor programmable devices or whatever else you feel ** like doing. ** NOTE: Unless the programmer explicitly inhibits event ** acquisition, the system is live at this point. **-- **/ usrper2() { } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrend - This function is called to allow user specific actions ** at the end of a run. The procedure is called before the ** end run scalers and end run buffer are constructed and ** sent to the vax. Thus it's possible to inject events ** into the event stream at this point and they'll wind ** up on the tape file corresponding to the run being ended. ** All caveats about knowing what you're doing apply here. ** Normally, you must: ** ** 1. Disable event trigger interrupts. ** 2. Turn off LAMs on acquisition devices. **-- **/ usrend() { CAMREG reg; /* indicate stopped; STOPPED_OUT is OR'ed with busy-latch to block front-end electronics. */ CAMWR16(SSET_SYSOUTREG, STOPPED_OUT); /* 2. Turn off event trigger interrupts. */ reg = cbdptr(0, 0, 29, 0, 0, CAM16); /* Branch CSR. */ CAMWR16(reg, (MNOX | MTO |MLAM | MIT2 | MIT4)); /* Mask interrupts */ } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrpause - This function is called to allow users specific actions ** when runs pause. Like usrend, it's called before the ** pause scaler buffer and pause buffer are formatted ** and sent to the VAX. Therefore, any data added to ** the event stream at this point will appear on event ** tapes before the pause buffer. ** Normally, the actions performed here are the same ** as for end of runs, so the default action is to ** call usrend() **-- **/ usrpause() { usrend(); } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrupdate - This function is called whenever the master ** issues an update request. The update request ** is intended to be used by systems which want to ** batch a bunch of parameter changes and then apply ** them all in a bunch. **-- **/ usrupdate() { } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrnewint - Is called to indicate that a SET INTEGER command ** has been processed. ** ** FORMAL PARAMETERS: ** ** int intnum - Number of the parameter modified. ** int oldval - Old value of the parameter. **-- **/ usrnewint(intnum, oldval) int intnum; int oldval; { } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrnewreal - This function is called when a SET REAL command has ** been processed. ** ** FORMAL PARAMETERS: ** ** int floatnum - The floating point parameter number that changed ** double oldfloat - The previous value of the floating point value. **-- **/ usrnewreal(floatnum, oldfloat) int floatnum; double oldfloat; { } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrnewflag - This routine is called when a SET FLAG command is ** executed. ** ** FORMAL PARAMETERS: ** ** int flagnum - Number of flag parameter. ** int oldflag - Previous value of flag parameter. **-- **/ usrnewflag(flagnum, oldflag) int flagnum; int oldflag; { } /*------------------------------------------------------------------------*/ /* This section needs only to be filled if the user is implementing */ /* slave command processing. */ /* Below is the definition of a function to allow the slave command */ /* processor to pass a reply data block back to the master at the end */ /* of command processing. The size of this data is limited to 64bytes */ /* at present. However, there's nothing to stop a single master command */ /* to invoke more than one slave command should more data need to be passed */ /* the main point to keep in mind is that the command mailbox region is meant */ /* for low bandwidth communications. */ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** setreturn - This function sets data into the CMDDAT part of the ** register area. This function is used by command ** operations which return data to the master. ** ** FORMAL PARAMETERS: ** ** INT8 *data - Pointer to the data to send to master. ** int count - Number of bytes to move, at most 64. ** ** **-- **/ extern INT16 setreturn; /*** setreturn(data, count); ***/ /* Newer compilers don't like this declaration */ /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** slvusrcmd - This function processes user slave commands. ** ** FORMAL PARAMETERS: ** ** int code - The command code sent from the master. ** INT8 *data - Pointer to the command data. ** ** FUNCTION VALUE: ** ** 0 - If the command can be successfully handled else ** 1 - If the command cannot be handled. ** **-- **/ int slvusrcmd(code, data) int code; INT8 *data; { return 0; } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrtrig1 - This processes user 1 triggers. **-- */ usrtrig1 () { } /*------------------------------------------------------------------------*/ /* **++ ** FUNCTIONAL DESCRIPTION: ** ** usrtrig2 - This processes user2 triggers. **-- */ usrtrig2 () { }