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