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 4089 2007-11-27 07:28:17Z ritt@PSI.CH $
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 = 100 * 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 EQUIPMENT equipment[] = {
00080 
00081    {"Trigger",               /* equipment name */
00082     {1, 0,                   /* event ID, trigger mask */
00083      "SYSTEM",               /* event buffer */
00084      EQ_POLLED,              /* equipment type */
00085      LAM_SOURCE(0, 0xFFFFFF),        /* event source crate 0, all stations */
00086      "MIDAS",                /* format */
00087      TRUE,                   /* enabled */
00088      RO_RUNNING |            /* read only when running */
00089      RO_ODB,                 /* and update ODB */
00090      500,                    /* poll for 500ms */
00091      0,                      /* stop run after this event limit */
00092      0,                      /* number of sub events */
00093      0,                      /* don't log history */
00094      "", "", "",},
00095     read_trigger_event,      /* readout routine */
00096     },
00097 
00098    {"Scaler",                /* equipment name */
00099     {2, 0,                   /* event ID, trigger mask */
00100      "SYSTEM",               /* event buffer */
00101      EQ_PERIODIC | EQ_MANUAL_TRIG,   /* equipment type */
00102      0,                      /* event source */
00103      "MIDAS",                /* format */
00104      TRUE,                   /* enabled */
00105      RO_RUNNING | RO_TRANSITIONS |   /* read when running and on transitions */
00106      RO_ODB,                 /* and update ODB */
00107      10000,                  /* read every 10 sec */
00108      0,                      /* stop run after this event limit */
00109      0,                      /* number of sub events */
00110      0,                      /* log history */
00111      "", "", "",},
00112     read_scaler_event,       /* readout routine */
00113     },
00114 
00115    {""}
00116 };
00117 
00118 #ifdef __cplusplus
00119 }
00120 #endif
00121 
00122 /********************************************************************\
00123               Callback routines for system transitions
00124 
00125   These routines are called whenever a system transition like start/
00126   stop of a run occurs. The routines are called on the following
00127   occations:
00128 
00129   frontend_init:  When the frontend program is started. This routine
00130                   should initialize the hardware.
00131 
00132   frontend_exit:  When the frontend program is shut down. Can be used
00133                   to releas any locked resources like memory, commu-
00134                   nications ports etc.
00135 
00136   begin_of_run:   When a new run is started. Clear scalers, open
00137                   rungates, etc.
00138 
00139   end_of_run:     Called on a request to stop a run. Can send
00140                   end-of-run event and close run gates.
00141 
00142   pause_run:      When a run is paused. Should disable trigger events.
00143 
00144   resume_run:     When a run is resumed. Should enable trigger events.
00145 \********************************************************************/
00146 
00147 /*-- Frontend Init -------------------------------------------------*/
00148 
00149 INT frontend_init()
00150 {
00151    /* hardware initialization */
00152 
00153    cam_init();
00154    cam_crate_clear(CRATE);
00155    cam_crate_zinit(CRATE);
00156 
00157    /* enable LAM in IO unit */
00158    camc(CRATE, SLOT_IO, 0, 26);
00159 
00160    /* enable LAM in crate controller */
00161    cam_lam_enable(CRATE, SLOT_IO);
00162 
00163    /* reset external LAM Flip-Flop */
00164    camo(CRATE, SLOT_IO, 1, 16, 0xFF);
00165    camo(CRATE, SLOT_IO, 1, 16, 0);
00166 
00167    /* register CNAF functionality from cnaf_callback.c with debug output */
00168    register_cnaf_callback(1);
00169 
00170    /* print message and return FE_ERR_HW if frontend should not be started */
00171 
00172    return SUCCESS;
00173 }
00174 
00175 /*-- Frontend Exit -------------------------------------------------*/
00176 
00177 INT frontend_exit()
00178 {
00179    return SUCCESS;
00180 }
00181 
00182 /*-- Begin of Run --------------------------------------------------*/
00183 
00184 INT begin_of_run(INT run_number, char *error)
00185 {
00186    /* put here clear scalers etc. */
00187 
00188    return SUCCESS;
00189 }
00190 
00191 /*-- End of Run ----------------------------------------------------*/
00192 
00193 INT end_of_run(INT run_number, char *error)
00194 {
00195    return SUCCESS;
00196 }
00197 
00198 /*-- Pause Run -----------------------------------------------------*/
00199 
00200 INT pause_run(INT run_number, char *error)
00201 {
00202    return SUCCESS;
00203 }
00204 
00205 /*-- Resuem Run ----------------------------------------------------*/
00206 
00207 INT resume_run(INT run_number, char *error)
00208 {
00209    return SUCCESS;
00210 }
00211 
00212 /*-- Frontend Loop -------------------------------------------------*/
00213 
00214 INT frontend_loop()
00215 {
00216    /* if frontend_call_loop is true, this routine gets called when
00217       the frontend is idle or once between every event */
00218    return SUCCESS;
00219 }
00220 
00221 /*------------------------------------------------------------------*/
00222 
00223 /********************************************************************\
00224 
00225   Readout routines for different events
00226 
00227 \********************************************************************/
00228 
00229 /*-- Trigger event routines ----------------------------------------*/
00230 
00231 INT poll_event(INT source, INT count, BOOL test)
00232 /* Polling routine for events. Returns TRUE if event
00233    is available. If test equals TRUE, don't return. The test
00234    flag is used to time the polling */
00235 {
00236    int i;
00237    DWORD lam;
00238 
00239    for (i = 0; i < count; i++) {
00240       cam_lam_read(LAM_SOURCE_CRATE(source), &lam);
00241 
00242       if (lam & LAM_SOURCE_STATION(source))
00243          if (!test)
00244             return lam;
00245    }
00246 
00247    return 0;
00248 }
00249 
00250 /*-- Interrupt configuration ---------------------------------------*/
00251 
00252 INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
00253 {
00254    switch (cmd) {
00255    case CMD_INTERRUPT_ENABLE:
00256       break;
00257    case CMD_INTERRUPT_DISABLE:
00258       break;
00259    case CMD_INTERRUPT_ATTACH:
00260       break;
00261    case CMD_INTERRUPT_DETACH:
00262       break;
00263    }
00264    return SUCCESS;
00265 }
00266 
00267 /*-- Event readout -------------------------------------------------*/
00268 
00269 INT read_trigger_event(char *pevent, INT off)
00270 {
00271    WORD *pdata, a;
00272    INT q, timeout;
00273 
00274    /* init bank structure */
00275    bk_init(pevent);
00276 
00277    /* create structured ADC0 bank */
00278    bk_create(pevent, "ADC0", TID_WORD, &pdata);
00279 
00280    /* wait for ADC conversion */
00281    for (timeout = 100; timeout > 0; timeout--) {
00282       camc_q(CRATE, SLOT_ADC, 0, 8, &q);
00283       if (q)
00284          break;
00285    }
00286    if (timeout == 0)
00287       ss_printf(0, 10, "No ADC gate!");
00288 
00289    /* use following code to read out real CAMAC ADC */
00290    /*
00291       for (a=0 ; a<N_ADC ; a++)
00292       cami(CRATE, SLOT_ADC, a, 0, pdata++);
00293     */
00294 
00295    /* Use following code to "simulate" data */
00296    for (a = 0; a < N_ADC; a++)
00297       *pdata++ = rand() % 1024;
00298 
00299    /* clear ADC */
00300    camc(CRATE, SLOT_ADC, 0, 9);
00301 
00302    bk_close(pevent, pdata);
00303 
00304    /* create variable length TDC bank */
00305    bk_create(pevent, "TDC0", TID_WORD, &pdata);
00306 
00307    /* use following code to read out real CAMAC TDC */
00308    /*
00309       for (a=0 ; a<N_TDC ; a++)
00310       cami(CRATE, SLOT_TDC, a, 0, pdata++);
00311     */
00312 
00313    /* Use following code to "simulate" data */
00314    for (a = 0; a < N_TDC; a++)
00315       *pdata++ = rand() % 1024;
00316 
00317    /* clear TDC */
00318    camc(CRATE, SLOT_TDC, 0, 9);
00319 
00320    bk_close(pevent, pdata);
00321 
00322    /* clear IO unit LAM */
00323    camc(CRATE, SLOT_IO, 0, 10);
00324 
00325    /* clear LAM in crate controller */
00326    cam_lam_clear(CRATE, SLOT_IO);
00327 
00328    /* reset external LAM Flip-Flop */
00329    camo(CRATE, SLOT_IO, 1, 16, 0xFF);
00330    camo(CRATE, SLOT_IO, 1, 16, 0);
00331 
00332    ss_sleep(10);
00333 
00334    return bk_size(pevent);
00335 }
00336 
00337 /*-- Scaler event --------------------------------------------------*/
00338 
00339 INT read_scaler_event(char *pevent, INT off)
00340 {
00341    DWORD *pdata, a;
00342 
00343    /* init bank structure */
00344    bk_init(pevent);
00345 
00346    /* create SCLR bank */
00347    bk_create(pevent, "SCLR", TID_DWORD, &pdata);
00348 
00349    /* read scaler bank */
00350    for (a = 0; a < N_SCLR; a++)
00351       cam24i(CRATE, SLOT_SCLR, a, 0, pdata++);
00352 
00353    bk_close(pevent, pdata);
00354 
00355    return bk_size(pevent);
00356 }

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