frontend.c

Go to the documentation of this file.
00001 /********************************************************************\
00002 
00003   Name:         frontend.c
00004   Created by:   Stefan Ritt
00005 
00006   Contents:     Experiment specific readout code (user part) of
00007                 Midas frontend. This example simulates a "trigger
00008                 event" and a "scaler event" which are filled with
00009                 CAMAC or random data. The trigger event is filled
00010                 with two banks (ADC0 and TDC0), the scaler event
00011                 with one bank (SCLR).
00012 
00013   $Log: frontend.c,v $
00014   Revision 1.24  2004/06/18 11:50:38  midas
00015   Changed ADC0 bank from structured to DWORD
00016 
00017   Revision 1.23  2004/06/08 14:58:18  midas
00018   Fixed strange formatting
00019 
00020   Revision 1.22  2004/01/08 08:40:08  midas
00021   Implemented standard indentation
00022 
00023   Revision 1.21  2003/05/12 15:20:11  midas
00024   Removed test code
00025 
00026   Revision 1.20  2003/05/09 07:40:04  midas
00027   Added extra parameter to cm_get_environment
00028 
00029   Revision 1.19  2003/04/28 15:33:05  midas
00030   Fixed compiler warnings
00031 
00032   Revision 1.18  2003/04/25 14:49:46  midas
00033   Removed HBOOK code
00034 
00035   Revision 1.17  2003/04/23 15:08:43  midas
00036   Decreased N_TDC to 4
00037 
00038   Revision 1.16  2003/04/14 13:31:17  midas
00039   Enabled trigger_bank_list
00040 
00041   Revision 1.15  2003/04/14 13:17:01  midas
00042   Added bank description
00043 
00044   Revision 1.14  2002/05/16 21:09:53  midas
00045   Added max_event_size_frag
00046 
00047   Revision 1.11  2000/08/21 10:32:51  midas
00048   Added max_event_size, set event_buffer_size = 10*max_event_size
00049 
00050   Revision 1.10  2000/03/13 18:53:29  pierre
00051   - Added 2nd arg in readout functions (offset for Super event)
00052 
00053   Revision 1.9  2000/03/02 22:00:00  midas
00054   Added number of subevents as zero
00055 
00056   Revision 1.8  1999/02/24 16:27:01  midas
00057   Added some "real" readout code
00058 
00059   Revision 1.7  1999/01/20 09:03:38  midas
00060   Added LAM_SOURCE_CRATE and LAM_SOURCE_STATION macros
00061 
00062   Revision 1.6  1999/01/19 10:27:30  midas
00063   Use new LAM_SOURCE and LAM_STATION macros
00064 
00065   Revision 1.5  1998/11/09 09:14:41  midas
00066   Added code to simulate random data
00067 
00068   Revision 1.4  1998/10/29 14:27:46  midas
00069   Added note about FE_ERR_HW in frontend_init()
00070 
00071   Revision 1.3  1998/10/28 15:50:58  midas
00072   Changed lam to DWORD
00073 
00074   Revision 1.2  1998/10/12 12:18:58  midas
00075   Added Log tag in header
00076 
00077 
00078 \********************************************************************/
00079 
00080 #include <stdio.h>
00081 #include <stdlib.h>
00082 #include "midas.h"
00083 #include "mcstd.h"
00084 #include "experim.h"
00085 
00086 /* make frontend functions callable from the C framework */
00087 #ifdef __cplusplus
00088 extern "C" {
00089 #endif
00090 
00091 /*-- Globals -------------------------------------------------------*/
00092 
00093 /* The frontend name (client name) as seen by other MIDAS clients   */
00094 char *frontend_name = "Sample Frontend";
00095 /* The frontend file name, don't change it */
00096 char *frontend_file_name = __FILE__;
00097 
00098 /* frontend_loop is called periodically if this variable is TRUE    */
00099 BOOL frontend_call_loop = FALSE;
00100 
00101 /* a frontend status page is displayed with this frequency in ms */
00102 INT display_period = 3000;
00103 
00104 /* maximum event size produced by this frontend */
00105 INT max_event_size = 10000;
00106 
00107 /* maximum event size for fragmented events (EQ_FRAGMENTED) */
00108 INT max_event_size_frag = 5 * 1024 * 1024;
00109 
00110 /* buffer size to hold events */
00111 INT event_buffer_size = 10 * 10000;
00112 
00113 /* number of channels */
00114 #define N_ADC  4
00115 #define N_TDC  4
00116 #define N_SCLR 4
00117 
00118 /* CAMAC crate and slots */
00119 #define CRATE      0
00120 #define SLOT_IO   23
00121 #define SLOT_ADC   1
00122 #define SLOT_TDC   2
00123 #define SLOT_SCLR  3
00124 
00125 /*-- Function declarations -----------------------------------------*/
00126 
00127 INT frontend_init();
00128 INT frontend_exit();
00129 INT begin_of_run(INT run_number, char *error);
00130 INT end_of_run(INT run_number, char *error);
00131 INT pause_run(INT run_number, char *error);
00132 INT resume_run(INT run_number, char *error);
00133 INT frontend_loop();
00134 
00135 INT read_trigger_event(char *pevent, INT off);
00136 INT read_scaler_event(char *pevent, INT off);
00137 
00138 /*-- Equipment list ------------------------------------------------*/
00139 
00140 #undef USE_INT
00141 
00142 EQUIPMENT equipment[] = {
00143 
00144    {"Trigger",               /* equipment name */
00145     {1, 0,                   /* event ID, trigger mask */
00146      "SYSTEM",               /* event buffer */
00147 #ifdef USE_INT
00148      EQ_INTERRUPT,           /* equipment type */
00149 #else
00150      EQ_POLLED,              /* equipment type */
00151 #endif
00152      LAM_SOURCE(0, 0xFFFFFF),        /* event source crate 0, all stations */
00153      "MIDAS",                /* format */
00154      TRUE,                   /* enabled */
00155      RO_RUNNING |            /* read only when running */
00156      RO_ODB,                 /* and update ODB */
00157      500,                    /* poll for 500ms */
00158      0,                      /* stop run after this event limit */
00159      0,                      /* number of sub events */
00160      0,                      /* don't log history */
00161      "", "", "",},
00162     read_trigger_event,      /* readout routine */
00163     },
00164 
00165    {"Scaler",                /* equipment name */
00166     {2, 0,                   /* event ID, trigger mask */
00167      "SYSTEM",               /* event buffer */
00168      EQ_PERIODIC | EQ_MANUAL_TRIG,   /* equipment type */
00169      0,                      /* event source */
00170      "MIDAS",                /* format */
00171      TRUE,                   /* enabled */
00172      RO_RUNNING | RO_TRANSITIONS |   /* read when running and on transitions */
00173      RO_ODB,                 /* and update ODB */
00174      10000,                  /* read every 10 sec */
00175      0,                      /* stop run after this event limit */
00176      0,                      /* number of sub events */
00177      0,                      /* log history */
00178      "", "", "",},
00179     read_scaler_event,       /* readout routine */
00180     },
00181 
00182    {""}
00183 };
00184 
00185 #ifdef __cplusplus
00186 }
00187 #endif
00188 
00189 /********************************************************************\
00190               Callback routines for system transitions
00191 
00192   These routines are called whenever a system transition like start/
00193   stop of a run occurs. The routines are called on the following
00194   occations:
00195 
00196   frontend_init:  When the frontend program is started. This routine
00197                   should initialize the hardware.
00198 
00199   frontend_exit:  When the frontend program is shut down. Can be used
00200                   to releas any locked resources like memory, commu-
00201                   nications ports etc.
00202 
00203   begin_of_run:   When a new run is started. Clear scalers, open
00204                   rungates, etc.
00205 
00206   end_of_run:     Called on a request to stop a run. Can send
00207                   end-of-run event and close run gates.
00208 
00209   pause_run:      When a run is paused. Should disable trigger events.
00210 
00211   resume_run:     When a run is resumed. Should enable trigger events.
00212 \********************************************************************/
00213 
00214 /*-- Frontend Init -------------------------------------------------*/
00215 
00216 INT frontend_init()
00217 {
00218    /* hardware initialization */
00219 
00220    cam_init();
00221    cam_crate_clear(CRATE);
00222    cam_crate_zinit(CRATE);
00223 
00224    /* enable LAM in IO unit */
00225    camc(CRATE, SLOT_IO, 0, 26);
00226 
00227    /* enable LAM in crate controller */
00228    cam_lam_enable(CRATE, SLOT_IO);
00229 
00230    /* reset external LAM Flip-Flop */
00231    camo(CRATE, SLOT_IO, 1, 16, 0xFF);
00232    camo(CRATE, SLOT_IO, 1, 16, 0);
00233 
00234    /* print message and return FE_ERR_HW if frontend should not be started */
00235 
00236    return SUCCESS;
00237 }
00238 
00239 /*-- Frontend Exit -------------------------------------------------*/
00240 
00241 INT frontend_exit()
00242 {
00243    return SUCCESS;
00244 }
00245 
00246 /*-- Begin of Run --------------------------------------------------*/
00247 
00248 INT begin_of_run(INT run_number, char *error)
00249 {
00250    /* put here clear scalers etc. */
00251 
00252    return SUCCESS;
00253 }
00254 
00255 /*-- End of Run ----------------------------------------------------*/
00256 
00257 INT end_of_run(INT run_number, char *error)
00258 {
00259    return SUCCESS;
00260 }
00261 
00262 /*-- Pause Run -----------------------------------------------------*/
00263 
00264 INT pause_run(INT run_number, char *error)
00265 {
00266    return SUCCESS;
00267 }
00268 
00269 /*-- Resuem Run ----------------------------------------------------*/
00270 
00271 INT resume_run(INT run_number, char *error)
00272 {
00273    return SUCCESS;
00274 }
00275 
00276 /*-- Frontend Loop -------------------------------------------------*/
00277 
00278 INT frontend_loop()
00279 {
00280    /* if frontend_call_loop is true, this routine gets called when
00281       the frontend is idle or once between every event */
00282    return SUCCESS;
00283 }
00284 
00285 /*------------------------------------------------------------------*/
00286 
00287 /********************************************************************\
00288 
00289   Readout routines for different events
00290 
00291 \********************************************************************/
00292 
00293 /*-- Trigger event routines ----------------------------------------*/
00294 
00295 INT poll_event(INT source, INT count, BOOL test)
00296 /* Polling routine for events. Returns TRUE if event
00297    is available. If test equals TRUE, don't return. The test
00298    flag is used to time the polling */
00299 {
00300    int i;
00301    DWORD lam;
00302 
00303    for (i = 0; i < count; i++) {
00304       cam_lam_read(LAM_SOURCE_CRATE(source), &lam);
00305 
00306       if (lam & LAM_SOURCE_STATION(source))
00307          if (!test)
00308             return lam;
00309    }
00310 
00311    return 0;
00312 }
00313 
00314 /*-- Interrupt configuration ---------------------------------------*/
00315 
00316 INT interrupt_configure(INT cmd, INT source, PTYPE adr)
00317 {
00318    switch (cmd) {
00319    case CMD_INTERRUPT_ENABLE:
00320       break;
00321    case CMD_INTERRUPT_DISABLE:
00322       break;
00323    case CMD_INTERRUPT_ATTACH:
00324       break;
00325    case CMD_INTERRUPT_DETACH:
00326       break;
00327    }
00328    return SUCCESS;
00329 }
00330 
00331 /*-- Event readout -------------------------------------------------*/
00332 
00333 INT read_trigger_event(char *pevent, INT off)
00334 {
00335    WORD *pdata, a;
00336    INT q, timeout;
00337 
00338    /* init bank structure */
00339    bk_init(pevent);
00340 
00341    /* create structured ADC0 bank */
00342    bk_create(pevent, "ADC0", TID_WORD, &pdata);
00343 
00344    /* wait for ADC conversion */
00345    for (timeout = 100; timeout > 0; timeout--) {
00346       camc_q(CRATE, SLOT_ADC, 0, 8, &q);
00347       if (q)
00348          break;
00349    }
00350    if (timeout == 0)
00351       ss_printf(0, 10, "No ADC gate!");
00352 
00353    /* use following code to read out real CAMAC ADC */
00354    /*
00355       for (a=0 ; a<N_ADC ; a++)
00356       cami(CRATE, SLOT_ADC, a, 0, pdata++);
00357     */
00358 
00359    /* Use following code to "simulate" data */
00360    for (a = 0; a < N_ADC; a++)
00361       *pdata++ = rand() % 1024;
00362 
00363    /* clear ADC */
00364    camc(CRATE, SLOT_ADC, 0, 9);
00365 
00366    bk_close(pevent, pdata);
00367 
00368    /* create variable length TDC bank */
00369    bk_create(pevent, "TDC0", TID_WORD, &pdata);
00370 
00371    /* use following code to read out real CAMAC TDC */
00372    /*
00373       for (a=0 ; a<N_TDC ; a++)
00374       cami(CRATE, SLOT_TDC, a, 0, pdata++);
00375     */
00376 
00377    /* Use following code to "simulate" data */
00378    for (a = 0; a < N_TDC; a++)
00379       *pdata++ = rand() % 1024;
00380 
00381    /* clear TDC */
00382    camc(CRATE, SLOT_TDC, 0, 9);
00383 
00384    bk_close(pevent, pdata);
00385 
00386    /* clear IO unit LAM */
00387    camc(CRATE, SLOT_IO, 0, 10);
00388 
00389    /* clear LAM in crate controller */
00390    cam_lam_clear(CRATE, SLOT_IO);
00391 
00392    /* reset external LAM Flip-Flop */
00393    camo(CRATE, SLOT_IO, 1, 16, 0xFF);
00394    camo(CRATE, SLOT_IO, 1, 16, 0);
00395 
00396    ss_sleep(10);
00397 
00398    return bk_size(pevent);
00399 }
00400 
00401 /*-- Scaler event --------------------------------------------------*/
00402 
00403 INT read_scaler_event(char *pevent, INT off)
00404 {
00405    DWORD *pdata, a;
00406 
00407    /* init bank structure */
00408    bk_init(pevent);
00409 
00410    /* create SCLR bank */
00411    bk_create(pevent, "SCLR", TID_DWORD, &pdata);
00412 
00413    /* read scaler bank */
00414    for (a = 0; a < N_SCLR; a++)
00415       cam24i(CRATE, SLOT_SCLR, a, 0, pdata++);
00416 
00417    bk_close(pevent, pdata);
00418 
00419    return bk_size(pevent);
00420 }

Midas DOC Version 1.9.3 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Suzannah Daviel - Doxygen - Peter Green - Greg Hackman - Gertjan Hofman - Paul Knowles - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk