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 }