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

Midas DOC Version 2.0.1 ---- 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