Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

skeleton.cpp

Go to the documentation of this file.
00001 /*
00002 ** Ported to Linux and CES/CBD 8210 device driver.
00003 ** At present, the preprocessor symbol __unix__ is used to switch on/off
00004 ** Linux/unix specific  code. #ifndef for it is used to switch off VME 
00005 ** 68K specific code.
00006 **   >>>>This module must be compiled without optimization<<<<
00007 **      Ron Fox
00008 **      January 28, 1999
00009 */
00010 
00011 
00012 /*
00013 **++
00014 **  FACILITY:
00015 **
00016 **      Data acquisition system.
00017 **
00018 **  ABSTRACT:
00019 **
00020 **      skeleton.c  - This file contains an upper level readout skeleton.
00021 **                      This skeleton is called from the evtuser.c skeleton
00022 **                      at even more confined locations than evtuser.c  The
00023 **                      user here is providing routines that tyipcally just do
00024 **                      CAMAC operations and not much else.
00025 **                      Users performing tailoring should read carefully
00026 **                      the areas which begin with the text:
00027 **
00028 **                      INSTRUCTIONS:
00029 **                      -------------
00030 **
00031 **  AUTHORS:
00032 **
00033 **      Ron Fox
00034 **
00035 **
00036 **  CREATION DATE:      6-Mar-1990
00037 **
00038 **  MODIFICATION HISTORY:
00039 **
00040 **--
00041 */
00042 
00043 
00044 /*
00045 **
00046 **  
00047 INCLUDE FILES
00048 **
00049 */
00050 
00051 
00052 #include <stdio.h>
00053 
00054 #ifndef __unix__
00055 #include "cpus.h"
00056 #endif
00057 
00058 #ifdef __unix__
00059 #include <stdlib.h>
00060 #include <daqinterface.h>
00061 #include <spectrodaq.h>
00062 #endif
00063 
00064 #include <lcldaqtypes.h>
00065 #include <camac.h>
00066 #include <macros.h>
00067 #include <slvshared.h>
00068 
00069 #ifdef VME16
00070 #undef VME16
00071 #endif
00072 #if CPU == MICROPROJECT
00073 #define VME16 0 
00074 #endif
00075 
00076 #ifndef __unix__
00077 #include <vme.h>
00078 #endif
00079 #include <buftypes.h>
00080 
00081 /* Short circuit run time evaluation of constant BCNAF's */
00082 
00083 #ifdef __unix__
00084 #undef CAMBAS
00085 extern UINT32 CAMBAS;           /* Filled in by harness after mmapping CAMAC */
00086 #else
00087 #if CPU == IRONICS
00088 #undef CAMBAS
00089 #define CAMBAS  0xFA800000
00090 #endif
00091 
00092 #if CPU == MICROPROJECT
00093 #undef CAMBAS
00094 #define CAMBAS  0xFE800000
00095 #endif
00096 #endif
00097 
00098 #include <TCLVariable.h>
00099 #include <CReadoutMain.h>
00100 #include <CInterpreterShell.h>
00101 #include <CInterpreterStartup.h>
00102 #include <TCLInterpreter.h>
00103 
00104 #include <CDocumentedPacket.h>
00105 
00106 
00107 /*
00108 **  INSTRUCTIONS:
00109 **  -------------
00110 **                          Introduction
00111 **
00112 **      There are several functions that the user is supposed to fill in
00113 **      to tailor this skeleton for a particular experiment.  While the
00114 **      skeleton is written in C, several extensions to the C language have
00115 **      been defined to bring the syntax closer to FORTRAN.  One thing you must
00116 **      be aware of, however is that C is case sensitive, that is, 'if' and
00117 **      'IF' are completely different from each other and 'If'.
00118 **
00119 **                          Functions to fill in:
00120 **
00121 **      The following are the set of functions that need to be filled in:
00122 **
00123 **      Function    Meaning             When Called
00124 **      initevt     Init event readout  Power up Begin run and Resume Run.
00125 **      clrtrig1    Clr trig1 readout   Power up, Begin, resume, end of trig1.
00126 **      iniscl      Init scalers.       Power up Begin run and Resume Run.
00127 **      clearevt    Clear evt readout   Power up, Begin, Resume, end of event.
00128 **      clrtrig1    Clr trig1 readout   Power up, Begin, resume, end of trig1.
00129 **      clrscl      Clear scaler readout Power up, Begin, Resume, end of scaler
00130 **      readevt     Read an event       Event trigger.
00131 **      readscl     REad scaler event   Scaler time.
00132 **      trig1ena    Enable trigger 1    Begin run, resume run.
00133 **      trig1dis    Disable trigger1    End run
00134 **      rdtrig1     Readout for trig 1  User trigger 1 fires.
00135 **      evtmax      Max size of event   Begin run time.
00136 **      trig1max    Max words in trig1  Begin run time.
00137 **
00138 **                      Language elements:
00139 **          Statements:
00140 **      Statements can occur anywhere on a line there can even be multiple
00141 **      statements on a single line. The end of a statement is flagged with
00142 **      a semicolon.  The following are legal statements:
00143 **
00144 **              a = b;
00145 **              camwrite16(0,1,29,0,16,1234);
00146 **
00147 **          Variables:
00148 **      Variables must be declared at the beginning of a function.
00149 **      C variables are the native type, however, the following FORTRAN
00150 **      style variable declarations are supported via definitions in 
00151 **      macros.h
00152 **
00153 **          LOGICAL     - Takes the values TRUE or FALSE
00154 **          WORD        - INTEGER*2 sized word.
00155 **          INTEGER     - INTEGER*4 sized lognword.
00156 **          REAL        - REAL*4 sized real.
00157 **
00158 **      Arrays may be declared, subscripts always go from 0:size-1. In C
00159 **      subscripts are in square brackets not rounded ones. The following
00160 **      are legal variable declarations:
00161 **
00162 **          LOGICAL flag;
00163 **          INTEGER i,j,k[10];
00164 **      Note in the above, the declaration of k is identical to the FORTRAN
00165 **      declaration:
00166 **
00167 **          INTEGER*4 k(0:9)
00168 **
00169 **      Multidimensional arrays are also allowed, but the syntax is a bit
00170 **      different:
00171 **          IINTEGER twod[5][6];
00172 **
00173 **      In C, the last dimension runs sequentially in memory rather than
00174 **      the first (reverse of fortran), and array references require both
00175 **      dimensions to be used as in the declaration e.g., to fill the
00176 **      array above:
00177 **         
00178 **               for(j = 0; j < 5; j++) 
00179 **                  for(i = 0; i < 6; i++)
00180 **                     twod[j][i] = i+j;
00181 **         
00182 **          Expressions:
00183 **      The only FORTRAN operators not allowed are exponentiation (**).
00184 **      the following is a subset of the operators supported:
00185 **          + - * / AND OR EQ NE GT GE LT LE
00186 **      The following assignment statement is an example of an expression:
00187 **          LOGICAL   flag;
00188 **          INTEGER   i1,i2,i3,i4;
00189 **              ...
00190 **          flag = (i1)/(i1+i2) LT (i3+i4)
00191 **
00192 **      Note that operators (e.g. LT above) are case sensitive.
00193 **      Bitwise operator functions IAND, IOR, ISHIFT are defined like in FORTRAN
00194 **      Hexadecimal constants are allowed and the syntax is 0xNNN where NNN is
00195 **      the constant.
00196 **
00197 **          Flow of control:
00198 **
00199 **      The following statements can control the flow of a program.
00200 **              IF
00201 **
00202 **      IF(expresson) <statement>;
00203 **
00204 **              BLOCK IF with optional ELSE clause:
00205 **
00206 **      IF(expression) THEN
00207 **          <statements with trailing ';'s>
00208 **      [ELSE 
00209 **          <statements with trailing ';'s>
00210 **      ]ENDIF
00211 **
00212 **              Top tested DO WHILE loop:
00213 **
00214 **      DO WHILE(expression)
00215 **          <statements>;
00216 **      ENDDO
00217 **
00218 **                  Buffer manipulation:
00219 **      The following functions manipulate the buffer:
00220 **
00221 **      putbufw(w)      - Put w, a 16 bit word to buffer.
00222 **      putbufl(l)      - Put l, a 32 bit longword to the buffer in VAX word 
00223 **                        order.
00224 **
00225 **                  CAMAC operations:
00226 **
00227 **      In the discussion below, b= branch number 0-7, c = crate number 1-7,
00228 **      n = CAMAC slot, a = CAMAC subaddress, f = CAMAC function code.
00229 **      d = CAMAC data transfered.
00230 **      CAMAC operations are implemented as 'pseudo functions' which are
00231 **      expanded in line and hence quite fast (~3usec per transaction).
00232 **
00233 **      camread16(b,c,n,a,f)    - Returns a 16 bit value read from CAMAC
00234 **      camread24(b,c,n,a,f)    - Returns a 24 bit value read from CAMAC format
00235 **                                is 68K format.
00236 **      camwrite16(b,c,n,a,f,d) - Write least significant 16 bits of d to CAMAC
00237 **      camwrite24(b,c,n,a,f,d) - Write least significate 24 bits of d to CAMAC
00238 **      camctl(b,c,n,a,f)       - Perform non data transfer CAMAC cycle.
00239 **      rdtobuf16(b,c,n,a,f)    - Do 16 bit CAMAC read into buffer.
00240 **      rdtobuf24(b,c,n,a,f)    - Do 24 bit CAMAC read into buffer (VAX format).
00241 **      qtst(b)                 - TRUE if most recent CAMAC operation on 
00242 **                                given branch set Q
00243 **      xtst(b)                 - Same as qtst, but tests X status.
00244 **
00245 **              More complex pseudo functions:
00246 **
00247 **      qstop(b,c,n,a,f)        - Performs a Q stop block read into buffer.
00248 **      branchinit(b)           - Initialize branch controller.
00249 **      crateinit(b,c)          - C/Z/Uninhibit crate.
00250 **
00251 **              LAM waiting:
00252 **
00253 **      The Pseudo functions below set up to do LAM busy waiting on a bit
00254 **      register decode:
00255 **
00256 **      BEGINLAM(numbr, numcr)  - Begin LAM mask buildup:
00257 **                                      numbr   - Number of branches involved
00258 **                                                in LAM wait process.
00259 **                                      numcr   - Highest crate number involved
00260 **                                                in LAM wait process.
00261 **      ENDLAM                  - End LAM mask processing.
00262 **      READBIT(b,c,n,a,f,d)    - Read a pattern register pattern register
00263 **                                is put in buffer and in WORD variable
00264 **                                d
00265 **      NEEDLAM(b,c,n)          - Indicate that LAM from given slot is needed.
00266 **      IFTIMEOUT(maxloop)      - Loops maxloop times (>10us/pass) waiting for
00267 **                                lams.  THen looks like IF statment, but
00268 **                                condition is that a timeout has occured.
00269 **      Example use of bit register functions:
00270 **
00271 **      LOGICAL timeout;
00272 **      WORD    brg;
00273 **      ..
00274 **      READDBIT(0,1,20,0,0,brg);
00275 **          ..
00276 **      BEGINLAM
00277 **        IF(IAND(brg, 0x1))NEEDLAM(0,2,3);
00278 **        IF(IAND(brg, 0x2))NEEDLAM(0,2,4);
00279 **        if(IAND(brg, 0x3))NEEDLAM(0,2,5);
00280 **        IFTIMEOUT(100) THEN
00281 **          timeout = TRUE;
00282 **          ENDDO
00283 **        ELSE
00284 **          timeout = FALSE;
00285 **        ENDIF
00286 **      ENDLAM
00287 **
00288 **                  Device specific pseudoroutines:
00289 **      Several device specific in-line routines are defined to make the
00290 **  handling of more common devices easier.  Devices not supported in this set
00291 **  can be managed with the primitive CAMAC operations. NOTE: clear functions
00292 **  are provided for modules which can be front panel cleared just in case 
00293 **  there is the need to clear them from CAMAC as well.
00294 **
00295 **    See the header macros.h for more information.
00296 **
00297 **          User parameters:
00298 **
00299 **      The front end includes three pre-defined arrays:
00300 **
00301 **          INTEGER userints[]  - Front end integer parameters.
00302 **          LOGICAL userflags[] - Front end flag parameters
00303 **          REAL    userreals[] - Front end real paraemters.
00304 **
00305 ** End of instructions... but look for more later in the file.
00306 */
00307 extern INT16 second;
00308 
00309 static int npkt1size=10;        // Default body size of packets 1.
00310 static int npkt2size=10;        // Default body size of pakcket 2.
00311 
00312 static CDocumentedPacket     Type1(0x101,
00313                             string("Type 1 packet"),
00314                             string("This packet contains type 1 data"),
00315                             string("1.0"));
00316 static CDocumentedPacket    Type2(0x202,
00317                            string("Type 2 packet"),
00318                            string("This packet contains type 2 data"),
00319                            string("1.1"));
00320 
00321 /*
00322 **++
00323 **  FUNCTIONAL DESCRIPTION:
00324 **
00325 **      initevt - This function contains code which indicates how to initialize
00326 **                the CAMAC system for event readout.
00327 **
00328 **
00329 **--
00330 */
00331 void
00332 initevt ()
00333 {
00334 /*
00335 **  INSTRUCTIONS:
00336 **  -------------
00337 **
00338 **      Fill in the area below the end of these instructions, but before the
00339 **      curly bracket with code that initializes devices in the event readout
00340 **      section of the device.  Typically what's needed here is to first
00341 **      put all crates on-line and initialize them, and then to clear all
00342 **      digitizers and initialize any programmable devices.  If you have
00343 **      more than one branh highway (not just branch 0), you should initialize
00344 **      that as well before touching crates on that branch. The routine provided
00345 **      shows how to initialize two empty crates on branch 0.  This initializer
00346 **      is the first of the initializers called so it's not a bad idea to do
00347 **      all crate initializations here, unless the crates are functionally
00348 **      broken up.  A bit register is also initialized.  See the #define
00349 **      statments below to tailor the location of that bit register.
00350 **  End instructions... but watch for more further down */
00351 
00352 #define BIT_BRANCH      0                   /* Branch bit register is on. */
00353 #define BIT_CRATE       2                   /* Crate bit register. is in */
00354 #define BIT_SLOT        16                  /* Slot bit register is in. */
00355 #define BIT_SUBADDRESS  0                   /* Subaddress of bit register  */
00356 
00357 
00358   // The tcl variables size1 and size2 allow us to override the default
00359   // values of npkt1size and npkt2size
00360 
00361   CTCLVariable  size1(string("size1"), false);
00362   CTCLVariable  size2(string("size2"), false);
00363   CInterpreterShell* pShell = CReadoutMain::getInstance()->getInterpreter();
00364   CInterpreterStartup* pStartup = pShell->getInterpreter();
00365   CTCLInterpreter&   Interpreter(pStartup->Interp());
00366 
00367   size1.Bind(Interpreter);
00368   size2.Bind(Interpreter);
00369 
00370   const char* pValue = size1.Get(TCL_GLOBAL_ONLY);
00371   if(pValue) {                  // Legal value...
00372     int newsize = atoi(pValue);
00373     if(newsize >= 0) npkt1size = newsize;
00374   }
00375   pValue = size2.Get(TCL_GLOBAL_ONLY);
00376   if(pValue) {
00377     int newsize = atoi(pValue);
00378     if(newsize >= 0) npkt2size = newsize;
00379   }
00380 
00381 }
00382 
00383 
00384 
00385 /*
00386 /*
00387 **++
00388 **  FUNCTIONAL DESCRIPTION:
00389 **
00390 **      initrig1    - This section should be filled in to initialize CAMAC
00391 **                    modules associated with user trigger 1.
00392 **
00393 **--
00394 */
00395 void
00396 initrig1 ()
00397 {
00398 
00399 /*
00400 **  Instructions:
00401 **  -------------
00402 **
00403 **      The section of code between the end of this comment and the the }
00404 **      should be filled in with code that initializes all hardware associated
00405 **      with user trigger1.  This trigger SHOULD NOT BE ENABLED AT THIS TIME
00406 **      since this routine is called at power up as well as at run start.
00407 **      The trigger should only be enabled in trig1ena().
00408 **      The sample provided takes no action to initialize trigger 1.
00409 ** End of instructions, but there's more later...                   */
00410 
00411     
00412 }
00413 
00414 
00415 
00416 /*
00417 **++
00418 **  FUNCTIONAL DESCRIPTION:
00419 **
00420 **      iniscl  - Initialize scaler readout.
00421 **
00422 **
00423 **  IMPLICIT INPUTS:
00424 **
00425 **      The special variable numscalers is the number of scalers.
00426 **
00427 **--
00428 */
00429 void
00430 iniscl ()
00431 {
00432 /*
00433 **  Instructions:
00434 **  -------------
00435 **      This function is called to intialize all scaler modules in the
00436 **      system.  There is a pre-declared variable 'numscalers' which 
00437 **      contains the number of scalers in the system.  The sample code below
00438 **      is written to deal with either a block of 12 channel scalers (LRS2551)
00439 **      or a block of 32 channel scalers (LRS4434), depedning on the definition
00440 **      of the constant SCALER_CHANNELS.  If SCALER_CHANNELS is 12, then
00441 **      code is generated for LRS2551, if SCALER_CHANNELS is 32, then for
00442 **      LRS4434.  Several notes:
00443 **          1. The code below demonstrates the use of C's #define statement
00444 **             for generating symbolic constants (like FORTRAN parameters).
00445 **             Note that #defines must start in column 1.
00446 **          2. The code below demonstrates the use of C's #if statement to
00447 **             do conditional compilation.  There is a big difference between
00448 **            #if and IF. #if controls what code is generated, while
00449 **            IF controls what code is executed.  The false side of the
00450 **            #if statement doesn't exist and therefore cannot be used
00451 **            to do run time control flow.
00452 **          3. If all the user wants to do is modify the starting scaler,
00453 **            or the type of scaler, then the definitions below are all
00454 **            that need to be changed.  More complex changes require coding.
00455 **          4.The % operator is the modulus operator, that is (a % b) is the
00456 **            same as FORTRAN's MOD(A,B).
00457 **          5. Advanced note. #define creates things called MACRO's a MACRO
00458 **             is a stored series of text which is expanded in line when it
00459 **             is invoked.  MACROs can have parameters just like functions
00460 **             and this is how the psuedo functions and FORTRAN like syntax
00461 **             has been layered on to C.  For example, if you would like
00462 **             to define a FORTRAN like MOD pseudo function, then:
00463 **             12345678901234567890123456789012345678901234567890 <- Column
00464 **             #define MOD(a,b)  ((a) % (b))
00465 **  End of instructions for now...                                  */
00466 
00467 #define SCALER_CHANNELS 12                  /* # Channels per module. */
00468 #define SCALER_BRANCH   0                   /* Branch of staring scaler */
00469 #define SCALER_CRATE    2                   /* Crate scaler is in. */
00470 #define SCALER_FIRST_SLOT       6           /* Slot of first scaler */
00471 
00472          
00473     INTEGER slot,                           /* Slot we're working on. */
00474             nslots,                         /* Total number of slots. */
00475             i;                              /* Slot counter */
00476 #ifdef __unix__
00477     unsigned numscalers;
00478     numscalers = daq_GetScalerCount();
00479 #else
00480     extern numscalers;
00481 #endif
00482 
00483         /* First compute the number of slots to init. */
00484 
00485     nslots = numscalers / SCALER_CHANNELS;
00486     IF((numscalers % SCALER_CHANNELS) NE 0) nslots = nslots + 1;
00487     i = 1;
00488     slot = SCALER_FIRST_SLOT;
00489 
00490         /* Select which loop to use to init the scalers. */
00491 
00492 #if SCALER_CHANNELS EQ 12                   /* Code for LRS 2551 follows: */
00493 
00494     DO WHILE(i LE nslots)
00495       INIT2551(SCALER_BRANCH, SCALER_CRATE, slot);
00496       slot = slot+1;
00497       i = i+1;
00498     ENDDO;  
00499 
00500 #else                                       /* Code for LRS 4434 follows: */                */
00501 
00502     DO WHILE(i LE nslots)
00503       INIT4434(SCALER_BRANCH, SCALER_CRATE, slot);
00504       slot = slot+1;
00505       i = i+1;
00506     ENDDO;  
00507 
00508 #endif
00509 }
00510 
00511 
00512 /*
00513 **++
00514 **  FUNCTIONAL DESCRIPTION:
00515 **
00516 **      clearevt    - Clear user events.
00517 **
00518 **
00519 **--
00520 */
00521 void
00522 clearevt ()
00523 {
00524 /*
00525 **  Instructions:
00526 **  -------------
00527 **      This routine should be filled in with the actions needed to clear
00528 **      all digitizers associated with the primary event.  Note that after
00529 **      the readout, of an event, a standard NIM-out is written to with all
00530 **      1's.  This is done in time suitable for clearing devices with front
00531 **      panel clears.  The user need not clear devices which are cleared via
00532 **      this signal.
00533 **      The sample code does nothing.
00534 **  End of instructions... but there's more.                */
00535     
00536 
00537 }
00538 
00539 
00540 
00541 /*
00542 **++
00543 **  FUNCTIONAL DESCRIPTION:
00544 **
00545 **      clrtrig1    - This function is called when a user 1 trigger read out is 
00546 **                    complete.
00547 **
00548 **
00549 **--
00550 */
00551 void
00552 clrtrig1 ()
00553 {
00554 /*
00555 **  Instructions:
00556 **  -------------
00557 **      This function is called to clear the user1 trigger devices.  This
00558 **      should not be used to disable triggers, since we are called at the end
00559 **      of every trigger 1 event.  The entry trig1dis should be used instead.
00560 **      Note when clearing trigger 1 devices, it is assumed that there need not
00561 **      be any connection between trigger 1 and the 'event' trigger.  Therefore,
00562 **      the front panel NIM out clear register is not written to by the uppler
00563 **      levels of the system and must be written to by the user if that's 
00564 **      desired.
00565 **          The sample code below does nothing.
00566 **      End of Instructions for now...                                      */ 
00567     
00568 }
00569 
00570 
00571 
00572 /*
00573 **++
00574 **  FUNCTIONAL DESCRIPTION:
00575 **
00576 **      clrscl  - Clear scalers
00577 **
00578 **
00579 **--
00580 */
00581 void
00582 clrscl ()
00583 {
00584 /*
00585 **  Instructions:
00586 **  -------------
00587 **      This function is called to clear the scalers following readout, on 
00588 **      run start and on run resume.  The sample code below is intended for 
00589 **      use with the sample code given in iniscl(), that is we can deal
00590 **      with either a contiguous block of 32 or 12 channel scalers.
00591 **  End of instructions for now....                             */
00592      
00593     INTEGER slot, nslots, i;
00594 #ifdef __unix__
00595     unsigned numscalers = daq_GetScalerCount();
00596 #endif
00597 
00598         /* First compute the number of slots to init. */
00599 
00600     nslots = numscalers / SCALER_CHANNELS;
00601     IF((numscalers % SCALER_CHANNELS) NE 0) nslots = nslots + 1;
00602     i = 1;
00603     slot = SCALER_FIRST_SLOT;
00604 
00605         /* Select which clear loop to execute. */
00606 
00607 #if SCALER_CHANNELS EQ 12                   /* Code for LRS 2551 follows: */
00608 
00609     DO WHILE(i LE nslots)
00610       CLR2551(SCALER_BRANCH, SCALER_CRATE, slot);
00611       slot = slot+1;
00612       i = i+1;
00613     ENDDO;  
00614 
00615 #else                       /* Code for LRS 4434 follows: */
00616 
00617     DO WHILE(i LE nslots)
00618       CLR4434(SCALER_BRANCH, SCALER_CRATE, slot);
00619       slot = slot+1;
00620       i = i+1;
00621     ENDDO;  
00622 
00623 #endif
00624     
00625 }
00626 
00627 
00628 /*
00629 **++
00630 **  FUNCTIONAL DESCRIPTION:
00631 **
00632 **      readevt - This function is called to read an event.
00633 **
00634 **  FORMAL PARAMETERS:
00635 **
00636 **      INT16 *bufpt    - Pointer to buffer to fill.
00637 **
00638 **
00639 **  FUNCTION VALUE:
00640 **
00641 **      Number of words read.
00642 **
00643 **--
00644 */
00645 WORD
00646 #ifdef __unix__
00647 readevt (DAQWordBufferPtr& bufpt)
00648 #else 
00649 readevt (WORD* bufpt)
00650 #endif
00651 {
00652 #ifdef __unix__
00653     DAQWordBufferPtr _sbufpt = bufpt;
00654 #else
00655     WORD *_sbufpt = bufpt;
00656 #endif
00657     LOGICAL reject;
00658 
00659     reject   = FALSE;
00660     {    
00661 /*------------------------- Begin user code. ----------------------------*/
00662 /*
00663 **  Instructions:
00664 **  -------------
00665 **      This routine must be filled in with code that indicates how to perform
00666 **      the event readout.  Digitizers need not be cleared after readout,
00667 **      that's done by a call back down here to clearevt().  Some points of
00668 **      interest:
00669 **          1. the predefined array _sbufpt can be used to reference the
00670 **             buffer after words have been read, that is, _sbufpt[0] is
00671 **             the first word you read.
00672 **          2. The predefined logical variable reject can be set to TRUE to
00673 **             inform the system that the event is to be thrown away.
00674 **          3. The data the user reads will be prefaced by the system with
00675 **             a word count.
00676 **          The sample code below is a skeleton which cracks a single 16
00677 **          bit register, waits for indicated lams for each bit and then
00678 **          does the read out on the set bits in the register.  If a LAM timeout
00679 **          occured, then the top bit of the bit register is set in the buffer
00680 **          and the readout procedes.  Note the use of #defines to tailor
00681 **          the location of the bit register, the LAM's expected for each bit,
00682 **          and the bits that are actually used in the register.
00683 **          Note how conditional compilation is used to remove tests for bits
00684 **          which are not used by the experiment.
00685 **          Note the use of the pre-defined 2-d array _lammsk in the LAM
00686 **          decoding code below.  Setting the bits all at once is faster
00687 **          than one at a a time (via NEEDLAM).  Note also the difference
00688 **          in the way C addresses 2-d arrays.  The predefined array _lammsk
00689 **          is an array of branch/crate lam masks.
00690 **  End of instructions for now...                              */
00691 
00692 
00693 
00694       bufpt = Type1.Begin(bufpt);
00695       for(int i= 0; i < npkt1size; i++) {
00696         putbufw(i);
00697       }
00698       bufpt = Type1.End(bufpt);
00699 
00700       bufpt = Type2.Begin(bufpt);
00701       for(int i = 0; i < npkt2size; i++) {
00702         putbufw(i*2);
00703       }
00704       bufpt = Type2.End(bufpt);
00705 
00706 /*-------------------------  End of user code. ---------------------------*/
00707 }
00708     IF(reject) return 0;
00709 #ifdef __unix__
00710     return bufpt.GetIndex() - _sbufpt.GetIndex();
00711 #else
00712     return (bufpt - _sbufpt);
00713 #endif
00714 }
00715 
00716 
00717 
00718 /*
00719 **++
00720 **  FUNCTIONAL DESCRIPTION:
00721 **
00722 **      readscl  - Read out scalers.
00723 **
00724 **  FORMAL PARAMETERS:
00725 **
00726 **      UINT32 *bufpt           - buffer pointer.
00727 **      int numscalers          - Number of scalers to read out.
00728 **
00729 
00730 **
00731 **
00732 **--
00733 */
00734 UINT16
00735 readscl (UINT32* buffer,int numscalers)
00736 {
00737     UINT32* _sbufpt = buffer;
00738     UINT16*  bufpt  = (UINT16*)buffer;
00739 
00740 
00741 
00742     {
00743 /*
00744 **  Instructions:
00745 **  -------------
00746 **
00747 **      This section of code must be filled in to read out scalers into a buffer
00748 **      provided by the caller.  The special predeclared array INTEGER _sbufpt[]
00749 **      allows access to the buffer contents by longword number.
00750 **      The sample code below continues the examples of scaler handling shown
00751 **      so far.  If 12 channel scalers are used, we read them out assuming
00752 **      that we've got a contiguous block of them.
00753 **      If 32 channel scalers are used, then we use them instead.
00754 **      The predefined INTEGER numscalers is the number of scaler channels
00755 **      to be read out (set by SET SCALERS command).
00756 **        NOTES:
00757 **          1. After the scalers have been read out, the upper levels of code
00758 **              will call the scaler clear routine so it is not necessary
00759 **              to clear scalers at this level.
00760 **          2.  Do not molest the code below the dashed line as it is necessary
00761 **              to the correct operation of the system.
00762 ** End of instructions for now:                         */
00763 
00764         INTEGER slot, nslots, i;
00765         INTEGER oddregs;                /* Odd # of registers */
00766         INTEGER oddscaler;              /* Channel from odd scalers. */
00767 
00768         /* Compute number of slots and partial register count: */
00769          
00770         nslots = numscalers / SCALER_CHANNELS;
00771         oddregs= numscalers % SCALER_CHANNELS;
00772 
00773         /* Initialize the loop variables for the readout loop: */
00774 
00775         i = 1;
00776         slot = SCALER_FIRST_SLOT;
00777 
00778 #if SCALER_CHANNELS EQ 12                   /* Use 12 channel scalers: */
00779 
00780         DO WHILE(i LE nslots)               /* Read full slots: */
00781             READALL2551(SCALER_BRANCH, SCALER_CRATE, slot);
00782             slot = slot+1;
00783             i    = i+1;
00784         ENDDO;
00785 
00786         i = 0;                              /* i will be subaddress */
00787         DO WHILE(i LT oddregs)
00788             READ2551(SCALER_BRANCH, SCALER_CRATE, slot, i);
00789             i = i+1;
00790         ENDDO;
00791 #else                                       /* Use 32 channel scalers. */
00792 
00793         DO WHILE(i LE nslots)               /* Read full slots: */
00794             READALL4434(SCALER_BRANCH, SCALER_CRATE, slot);
00795             slot = slot+1;
00796             i    = i+1;
00797         ENDDO;
00798 
00799         i = 0;                              /* i will be subaddress */
00800         DO WHILE(i LT oddregs)
00801             READ4434(SCALER_BRANCH, SCALER_CRATE, slot, i);
00802             i = i+1;
00803         ENDDO;
00804 #endif
00805 
00806 /*-------------------------------END USER CODE ---------------------------*/
00807     }
00808 
00809      
00810     return (UINT16)((UINT32)bufpt - (UINT32)_sbufpt);
00811 }
00812 
00813 
00814 
00815 /*
00816 **++
00817 **  FUNCTIONAL DESCRIPTION:
00818 **
00819 **      trig1dis    - Disable trigger 1 triggers.
00820 **
00821 **
00822 **--
00823 */
00824 void
00825 trig1dis ()
00826 {
00827 
00828 /*
00829 ** NOTE:
00830 **    >>>>User triggers are not supported in the UNIX readout system<<<<
00831 **  Instructions:
00832 **  -------------
00833 **      The code below is used to turn off user triggers.  At present, the only
00834 **      sort of user triggers supported are time periodic user triggers for
00835 **      user trigger 1.  User triggers are intended to trigger readout events
00836 **      that are not necessarily part of the normal set of event triggers.
00837 **      These might be triggers to readout calibration systems or other
00838 **      monitoring systems.
00839 **        The sample code below is compiled if the #define for USERTRIG1_ENABLE
00840 **      is set to be true.  In that case, the frequency and eventy type produced
00841 **      for user triggers is controlled by the #define statements for
00842 **      USER1_PERIOD    (INTEGER seconds between triggers) and:
00843 **
00844 **  End of instructions for now:    */
00845 
00846 #ifndef __unix__
00847 #define USERTRIG1_ENABLE        FALSE           /* TRUE if triggers desired */
00848 #define USERTRIG1_PERIOD        -1              /* Seconds between triggers */
00849 
00850 #if USERTRIG1_ENABLE
00851 
00852     STOPUSR1TRIG();
00853     
00854 #endif
00855 #endif
00856 }
00857 
00858 
00859 
00860 /*
00861 **++
00862 **  FUNCTIONAL DESCRIPTION:
00863 **
00864 **      trig1ena    - This function is called when user triggers are to be
00865 **                    enabled.
00866 **
00867 **
00868 **--
00869 */
00870 void
00871 trig1ena ()
00872 {
00873 /*
00874 **  NOTE:
00875 **     >>>>User triggers are not supported in the UNIX environment<<<<
00876 **  Instructions:
00877 **  -------------
00878 **      This section of code should be filled in to enable user triggers.
00879 **  The sample code continues the example begun for trig1dis.
00880 **  End of instructions for now:        */
00881 #ifndef __unix__
00882 INTEGER period;
00883 
00884 
00885 #if USERTRIG1_ENABLE
00886     IF(USERTRIG1_PERIOD LE 0) THEN
00887         msg("FATAL - Trigger frequency less than zero in trig1ena()");
00888         newline; newline;
00889         die();
00890     ENDIF
00891 
00892     STARTUSR1TRIG(USERTRIG1_PERIOD);
00893 
00894 #endif
00895 #endif
00896 }
00897 
00898 
00899 
00900 /*
00901 **++
00902 **  FUNCTIONAL DESCRIPTION:
00903 **
00904 **      rdtrig1 - Read out a user trigger.
00905 **
00906 **  FORMAL PARAMETERS:
00907 **
00908 **      INT16 *buffer   - Pointer to buffer to readout.
00909 **
00910 */
00911 int 
00912 rdtrig1 (WORD* bufpt)
00913 {
00914     WORD *_sbufpt;
00915 
00916     _sbufpt = bufpt;
00917     {
00918 /*
00919 **  NOTE:
00920 **    >>>>The UNIX environment does not support user triggers <<<<
00921 **  Instructions:
00922 **  -------------
00923 **      This area should be filled in with code that manages the readout of a
00924 **      user 1 trigger.  The sample code below assumes that if user triggers are
00925 **      enabled, you will want to trigger an action via setting a bit in a NIM
00926 **      out register. 
00927 **        The default event type of the event being read out
00928 **      is USERBUF1 (32).  If not data is read into the buffer, then no event
00929 **      is generated.  Similarly, if the function returns the value zero, then
00930 **      no event is generated.
00931 **      NOTE:
00932 **          1.  The special variable bufpt is a 'pointer' to the event buffer.
00933 **          2.  As before, the predeclared variable WORD _sbufpt[] gives
00934 **              you a way to modify the buffer after readout (e.g. put in
00935 **              a special bit in the bit register.
00936 **          3.  The defines for NIMOUT_xxx allow the CAMAC location of the
00937 **              nimout to be defined, as well as the bit that's actually
00938 **              fired off.
00939 **  End of instructions for now...                  */
00940 #ifndef __unix__
00941 #define NIMOUT_BRANCH   0                           /* Branch nimout is in */
00942 #define NIMOUT_CRATE    2                           /* Crate nimout is in. */
00943 #define NIMOUT_SLOT     20                          /* Slot nimout lives in */
00944 #define NIMOUT_TRIG1    0x800                       /* Bit to set. */
00945 
00946 #if USERTRIG1_ENABLE
00947         NIMOUT(NIMOUT_BRANCH, NIMOUT_CRATE, NIMOUT_SLOT, NIMOUT_TRIG1);
00948 
00949 /* -------------------------- End user code. ----------------------- */
00950 #endif
00951 #endif
00952 
00953     }
00954     return (bufpt - _sbufpt);
00955 }
00956 
00957 
00958 
00959 /*
00960 **++
00961 **  FUNCTIONAL DESCRIPTION:
00962 **
00963 **      evtmax  - Returns the size of the largest physics event.
00964 **
00965 **  FUNCTION VALUE:
00966 **
00967 **      Largest number of words that can be read out by a physics trigger.
00968 ****--
00969 */
00970 WORD 
00971 evtmax ()
00972 {
00973 
00974 /*
00975 **  Instructions:
00976 **  -------------
00977 **      Fill in the #define below to indicate the size of the largest
00978 **      possible physics event in words.
00979 **  End of instructions for now...          */
00980 
00981 #define EVENT_MAXWORDS  40      /* Fill with correct size */
00982 
00983 /*------------------------------ end of user code  -----------------------*/
00984 
00985     IF (EVENT_MAXWORDS LE 0) THEN           /* We crash the program if the */
00986                                             /* user didn't set the size */
00987         fprintf (stderr, "EVENT_MAXWORDS was not properly defined\n");
00988         fprintf (stderr, "Must be .GT. 0 was %d \n", EVENT_MAXWORDS);
00989 #ifdef __unix__
00990         abort();
00991 #else
00992         panic("BUGCHECK");
00993 #endif
00994     ENDIF;
00995     return (EVENT_MAXWORDS);
00996 }
00997 
00998 
00999 
01000 /*
01001 **++
01002 **  FUNCTIONAL DESCRIPTION:
01003 **
01004 **      trig1max    - Returns the number of words readout in a user1 trigger.
01005 **
01006 **  FUNCTION VALUE:
01007 **
01008 **      Number of  words read out.
01009 **
01010 **
01011 **--
01012 */
01013 WORD 
01014 trig1max ()
01015 {
01016 /*
01017 ** NOTE:
01018 **    >>>>The UNIX environment does not support user triggers <<<<
01019 **
01020 **  Instructions:
01021 **  -------------
01022 **      This function should be filled in to indicate the maximum number
01023 **      of words to be read out on a user trigger 1.  The sample code operates
01024 **      as follows, if the #define'd constant USERTRIG1_ENABLE is FALSE, then
01025 **      the value 0 is generated (no words read out), If USERTRIG1_ENABLE is
01026 **      true, then the user should edit the definition of USERTRIG1_MAXWORDS
01027 **      to reflect the largest number of words that can be read out in a
01028 **      user1 trigger.  
01029 **  End of all Instructions for now....                         */
01030 
01031 #define USERTRIG1_MAXWORDS      0           /* Edit to reflect actual count */
01032 
01033 #if USERTRIG1_ENABLE && (!defined(__unix__))
01034     IF (USERTRIG1_MAXWORDS LT 0) THEN
01035         fprintf (stderr, "USERTRIG1_MAXWORDS incorrectly initialized\n");
01036         fprintf (stderr, "Must be GE 0 was %d\n", USERTRIG1_MAXWORDS);
01037         die();
01038         return USERTRIG1_MAXWORDS;
01039     ENDIF;
01040 #else
01041     return 0;
01042 #endif    
01043 
01044 }
01045 

Generated on Fri Nov 8 13:36:50 2002 for Event Readout system. by doxygen1.2.16