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   $Id: frontend.c 3197 2006-07-31 19:01:21Z ritt $
00014 
00015 \********************************************************************/
00016 
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include "midas.h"
00020 #include "mcstd.h"
00021 #include "experim.h"
00022 
00023 /* make frontend functions callable from the C framework */
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027 
00028 /*-- Globals -------------------------------------------------------*/
00029 
00030 /* The frontend name (client name) as seen by other MIDAS clients   */
00031 char *frontend_name = "Sample Frontend";
00032 /* The frontend file name, don't change it */
00033 char *frontend_file_name = __FILE__;
00034 
00035 /* frontend_loop is called periodically if this variable is TRUE    */
00036 BOOL frontend_call_loop = FALSE;
00037 
00038 /* a frontend status page is displayed with this frequency in ms */
00039 INT display_period = 3000;
00040 
00041 /* maximum event size produced by this frontend */
00042 INT max_event_size = 10000;
00043 
00044 /* maximum event size for fragmented events (EQ_FRAGMENTED) */
00045 INT max_event_size_frag = 5 * 1024 * 1024;
00046 
00047 /* buffer size to hold events */
00048 INT event_buffer_size = 10 * 10000;
00049 
00050 /* number of channels */
00051 #define N_ADC  4
00052 #define N_TDC  4
00053 #define N_SCLR 4
00054 
00055 /* CAMAC crate and slots */
00056 #define CRATE      0
00057 #define SLOT_IO   23
00058 #define SLOT_ADC   1
00059 #define SLOT_TDC   2
00060 #define SLOT_SCLR  3
00061 
00062 /*-- Function declarations -----------------------------------------*/
00063 
00064 INT frontend_init();
00065 INT frontend_exit();
00066 INT begin_of_run(INT run_number, char *error);
00067 INT end_of_run(INT run_number, char *error);
00068 INT pause_run(INT run_number, char *error);
00069 INT resume_run(INT run_number, char *error);
00070 INT frontend_loop();
00071 
00072 INT read_trigger_event(char *pevent, INT off);
00073 INT read_scaler_event(char *pevent, INT off);
00074 
00075 void register_cnaf_callback(int debug);
00076 
00077 /*-- Equipment list ------------------------------------------------*/
00078 
00079 #undef USE_INT
00080 
00081 EQUIPMENT equipment[] = {
00082 
00083    {"Trigger",               /* equipment name */
00084     {1, 0,                   /* event ID, trigger mask */
00085      "SYSTEM",               /* event buffer */
00086 #ifdef USE_INT
00087      EQ_INTERRUPT,           /* equipment type */
00088 #else
00089      EQ_POLLED,              /* equipment type */
00090 #endif
00091      LAM_SOURCE(0, 0xFFFFFF),        /* event source crate 0, all stations */
00092      "MIDAS",                /* format */
00093      TRUE,                   /* enabled */
00094      RO_RUNNING |            /* read only when running */
00095      RO_ODB,                 /* and update ODB */
00096      500,                    /* poll for 500ms */
00097      0,                      /* stop run after this event limit */
00098      0,                      /* number of sub events */
00099      0,                      /* don't log history */
00100      "", "", "",},
00101     read_trigger_event,      /* readout routine */
00102     },
00103 
00104    {"Scaler",                /* equipment name */
00105     {2, 0,                   /* event ID, trigger mask */
00106      "SYSTEM",               /* event buffer */
00107      EQ_PERIODIC | EQ_MANUAL_TRIG,   /* equipment type */
00108      0,                      /* event source */
00109      "MIDAS",                /* format */
00110      TRUE,                   /* enabled */
00111      RO_RUNNING | RO_TRANSITIONS |   /* read when running and on transitions */
00112      RO_ODB,                 /* and update ODB */
00113      10000,                  /* read every 10 sec */
00114      0,                      /* stop run after this event limit */
00115      0,                      /* number of sub events */
00116      0,                      /* log history */
00117      "", "", "",},
00118     read_scaler_event,       /* readout routine */
00119     },
00120 
00121    {""}
00122 };
00123 
00124 #ifdef __cplusplus
00125 }
00126 #endif
00127 
00128 /********************************************************************\
00129               Callback routines for system transitions
00130 
00131   These routines are called whenever a system transition like start/
00132   stop of a run occurs. The routines are called on the following
00133   occations:
00134 
00135   frontend_init:  When the frontend program is started. This routine
00136                   should initialize the hardware.
00137 
00138   frontend_exit:  When the frontend program is shut down. Can be used
00139                   to releas any locked resources like memory, commu-
00140                   nications ports etc.
00141 
00142   begin_of_run:   When a new run is started. Clear scalers, open
00143                   rungates, etc.
00144 
00145   end_of_run:     Called on a request to stop a run. Can send
00146                   end-of-run event and close run gates.
00147 
00148   pause_run:      When a run is paused. Should disable trigger events.
00149 
00150   resume_run:     When a run is resumed. Should enable trigger events.
00151 \********************************************************************/
00152 
00153 /*-- Frontend Init -------------------------------------------------*/
00154 
00155 INT frontend_init()
00156 {
00157    /* hardware initialization */
00158 
00159    cam_init();
00160    cam_crate_clear(CRATE);
00161    cam_crate_zinit(CRATE);
00162 
00163    /* enable LAM in IO unit */
00164    camc(CRATE, SLOT_IO, 0, 26);
00165 
00166    /* enable LAM in crate controller */
00167    cam_lam_enable(CRATE, SLOT_IO);
00168 
00169    /* reset external LAM Flip-Flop */
00170    camo(CRATE, SLOT_IO, 1, 16, 0xFF);
00171    camo(CRATE, SLOT_IO, 1, 16, 0);
00172 
00173    /* register CNAF functionality from cnaf_callback.c with debug output */
00174    register_cnaf_callback(1);
00175 
00176    /* print message and return FE_ERR_HW if frontend should not be started */
00177 
00178    return SUCCESS;
00179 }
00180 
00181 /*-- Frontend Exit -------------------------------------------------*/
00182 
00183 INT frontend_exit()
00184 {
00185    return SUCCESS;
00186 }
00187 
00188 /*-- Begin of Run --------------------------------------------------*/
00189 
00190 INT begin_of_run(INT run_number, char *error)
00191 {
00192    /* put here clear scalers etc. */
00193 
00194    return SUCCESS;
00195 }
00196 
00197 /*-- End of Run ----------------------------------------------------*/
00198 
00199 INT end_of_run(INT run_number, char *error)
00200 {
00201    return SUCCESS;
00202 }
00203 
00204 /*-- Pause Run -----------------------------------------------------*/
00205 
00206 INT pause_run(INT run_number, char *error)
00207 {
00208    return SUCCESS;
00209 }
00210 
00211 /*-- Resuem Run ----------------------------------------------------*/
00212 
00213 INT resume_run(INT run_number, char *error)
00214 {
00215    return SUCCESS;
00216 }
00217 
00218 /*-- Frontend Loop -------------------------------------------------*/
00219 
00220 INT frontend_loop()
00221 {
00222    /* if frontend_call_loop is true, this routine gets called when
00223       the frontend is idle or once between every event */
00224    return SUCCESS;
00225 }
00226 
00227 /*------------------------------------------------------------------*/
00228 
00229 /********************************************************************\
00230 
00231   Readout routines for different events
00232 
00233 \********************************************************************/
00234 
00235 /*-- Trigger event routines ----------------------------------------*/
00236 
00237 INT poll_event(INT source, INT count, BOOL test)
00238 /* Polling routine for events. Returns TRUE if event
00239    is available. If test equals TRUE, don't return. The test
00240    flag is used to time the polling */
00241 {
00242    int i;
00243    DWORD lam;
00244 
00245    for (i = 0; i < count; i++) {
00246       cam_lam_read(LAM_SOURCE_CRATE(source), &lam);
00247 
00248       if (lam & LAM_SOURCE_STATION(source))
00249          if (!test)
00250             return lam;
00251    }
00252 
00253    return 0;
00254 }
00255 
00256 /*-- Interrupt configuration ---------------------------------------*/
00257 
00258 INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
00259 {
00260    switch (cmd) {
00261    case CMD_INTERRUPT_ENABLE:
00262       break;
00263    case CMD_INTERRUPT_DISABLE:
00264       break;
00265    case CMD_INTERRUPT_ATTACH:
00266       break;
00267    case CMD_INTERRUPT_DETACH:
00268       break;
00269    }
00270    return SUCCESS;
00271 }
00272 
00273 /*-- Event readout -------------------------------------------------*/
00274 
00275 INT read_trigger_event(char *pevent, INT off)
00276 {
00277    WORD *pdata, a;
00278    INT q, timeout;
00279 
00280    /* init bank structure */
00281    bk_init(pevent);
00282 
00283    /* create structured ADC0 bank */
00284    bk_create(pevent, "ADC0", TID_WORD, &pdata);
00285 
00286    /* wait for ADC conversion */
00287    for (timeout = 100; timeout > 0; timeout--) {
00288       camc_q(CRATE, SLOT_ADC, 0, 8, &q);
00289       if (q)
00290          break;
00291    }
00292    if (timeout == 0)
00293       ss_printf(0, 10, "No ADC gate!");
00294 
00295    /* use following code to read out real CAMAC ADC */
00296    /*
00297       for (a=0 ; a<N_ADC ; a++)
00298       cami(CRATE, SLOT_ADC, a, 0, pdata++);
00299     */
00300 
00301    /* Use following code to "simulate" data */
00302    for (a = 0; a < N_ADC; a++)
00303       *pdata++ = rand() % 1024;
00304 
00305    /* clear ADC */
00306    camc(CRATE, SLOT_ADC, 0, 9);
00307 
00308    bk_close(pevent, pdata);
00309 
00310    /* create variable length TDC bank */
00311    bk_create(pevent, "TDC0", TID_WORD, &pdata);
00312 
00313    /* use following code to read out real CAMAC TDC */
00314    /*
00315       for (a=0 ; a<N_TDC ; a++)
00316       cami(CRATE, SLOT_TDC, a, 0, pdata++);
00317     */
00318 
00319    /* Use following code to "simulate" data */
00320    for (a = 0; a < N_TDC; a++)
00321       *pdata++ = rand() % 1024;
00322 
00323    /* clear TDC */
00324    camc(CRATE, SLOT_TDC, 0, 9);
00325 
00326    bk_close(pevent, pdata);
00327 
00328    /* clear IO unit LAM */
00329    camc(CRATE, SLOT_IO, 0, 10);
00330 
00331    /* clear LAM in crate controller */
00332    cam_lam_clear(CRATE, SLOT_IO);
00333 
00334    /* reset external LAM Flip-Flop */
00335    camo(CRATE, SLOT_IO, 1, 16, 0xFF);
00336    camo(CRATE, SLOT_IO, 1, 16, 0);
00337 
00338    //ss_sleep(10);
00339 
00340    //return bk_size(pevent);
00341    return 1000;
00342 }
00343 
00344 /*-- Scaler event --------------------------------------------------*/
00345 
00346 INT read_scaler_event(char *pevent, INT off)
00347 {
00348    DWORD *pdata, a;
00349 
00350    /* init bank structure */
00351    bk_init(pevent);
00352 
00353    /* create SCLR bank */
00354    bk_create(pevent, "SCLR", TID_DWORD, &pdata);
00355 
00356    /* read scaler bank */
00357    for (a = 0; a < N_SCLR; a++)
00358       cam24i(CRATE, SLOT_SCLR, a, 0, pdata++);
00359 
00360    bk_close(pevent, pdata);
00361 
00362    return bk_size(pevent);
00363 }

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