MIDAS
Loading...
Searching...
No Matches
wdfe.cxx File Reference
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include "midas.h"
#include "mfe.h"
#include "experim.h"
#include "WDBLib.h"
#include "DCBLib.h"
Include dependency graph for wdfe.cxx:

Go to the source code of this file.

Namespaces

namespace  WD
 

Functions

INT frontend_init (void)
 Frontend initialization.
 
INT frontend_exit (void)
 Frontend exit.
 
INT begin_of_run (INT run_number, char *error)
 Begin of Run.
 
INT end_of_run (INT run_number, char *error)
 End of Run.
 
INT pause_run (INT run_number, char *error)
 Pause Run.
 
INT resume_run (INT run_number, char *error)
 Resume Run.
 
INT frontend_loop (void)
 Frontend loop.
 
INT read_trigger_event (char *pevent, INT off)
 
INT read_periodic_event (char *pevent, INT off)
 
INT poll_event (INT source, INT count, BOOL test)
 Polling routine for events.
 
INT interrupt_configure (INT cmd, INT source, POINTER_T adr)
 Interrupt configuration (not implemented)
 

Variables

const charfrontend_name = "WD Frontend"
 The frontend name (client name) as seen by other MIDAS clients.
 
const charfrontend_file_name = __FILE__
 The frontend file name, don't change it.
 
BOOL frontend_call_loop = FALSE
 frontend_loop is called periodically if this variable is TRUE
 
INT display_period = 3000
 a frontend status page is displayed with this frequency in ms
 
INT max_event_size = 1024 * 1014
 maximum event size produced by this frontend
 
INT max_event_size_frag = 5 * max_event_size
 maximum event size for fragmented events (EQ_FRAGMENTED)
 
INT event_buffer_size = 5 * max_event_size
 buffer size to hold events
 
BOOL equipment_common_overwrite = TRUE
 
EQUIPMENT equipment []
 Main structure for midas equipment.
 
std::vector< WDB * > WD::wdb
 
WPWD::wp
 
std::vector< WDEvent * > WD::wde
 

Function Documentation

◆ begin_of_run()

INT begin_of_run ( INT  run_number,
char error 
)

Begin of Run.

Called every run start transition. Set equipment status in ODB, start acquisition on the modules.

Parameters
[in]run_numberNumber of the run being started
[out]errorCan be used to write a message string to midas.log

Definition at line 244 of file wdfe.cxx.

245{
246 // start DRS for first event
247 for (auto b: WD::wdb) {
248 b->ResetDrsControlFsm();
249 b->ResetEventCounter();
250 b->SetDaqSingle(true);
251 }
252
253 return SUCCESS;
254}
#define SUCCESS
Definition mcstd.h:54
Definition wdfe.cxx:103
std::vector< WDB * > wdb
Definition wdfe.cxx:106

◆ end_of_run()

INT end_of_run ( INT  run_number,
char error 
)

End of Run.

Called every stop run transition. Set equipment status in ODB, stop acquisition on the modules.

Parameters
[in]run_numberNumber of the run being ended
[out]errorCan be used to write a message string to midas.log

Definition at line 258 of file wdfe.cxx.

259{
260 return SUCCESS;
261}

◆ frontend_exit()

INT frontend_exit ( void  )

Frontend exit.

Runs at frontend shutdown. Disconnect hardware and set equipment status in ODB

Returns
Midas status code

Definition at line 237 of file wdfe.cxx.

238{
239 return SUCCESS;
240}

◆ frontend_init()

INT frontend_init ( void  )

Frontend initialization.

Runs once at application startup. We initialize the hardware and optical interfaces and set the equipment status in ODB. We also lock the frontend to once physical cpu core.

Returns
Midas status code

Definition at line 118 of file wdfe.cxx.

119{
120 std::string drs_calib_path;
121
122 // set calibration path according to WDBSYS
123 const char *wavedaqpath = getenv("WDBSYS");
124 if (wavedaqpath != nullptr) {
126 drs_calib_path += "/sw/wds/";
127 } else {
128 cm_msg(MINFO, "frontend_init", "Calibration filepath set to current directory. "\
129 "Use WDBSYS environnement variable to point to your wavedaq repository");
130 drs_calib_path = "./";
131 }
132
133 // create WDB object
134 WDB *b = new WDB("wd026");
135 try {
136 b->SetVerbose(true); // change for debugging
137 b->Connect(); // connect to board, throws exception if unsuccessful
138 b->ReceiveControlRegisters();
139
140 // Reset DRS FSM
141 b->ResetDrsControlFsm();
142 b->ResetPackager();
143
144 // Stop DRS
145 b->SetDaqSingle(false);
146 b->SetDaqAuto(false);
147 b->SetDaqNormal(false);
148
149 b->SetSendBlock(true); // update all control registers together
150
151 //---- readout settings
152 b->SetDrsChTxEn(0xFFFF); // enable all DRS readout
153 b->SetAdcChTxEn(0); // disable ADC readout
154 b->SetTdcChTxEn(0); // disable TDC readout
155 b->SetSclTxEn(0); // disable scaler readout
156
157 //---- board settings
158 b->SetDaqClkSrcSel(1); // select on-board clock oscillator
159 b->SetDrsSampleFreq(1000); // Sampling speed 1 GSPS
160 b->SetFeGain(-1, 1); // set FE gain to 1
161 b->SetFePzc(-1, false); // disable pole-zero cancellation
162 b->SetInterPkgDelay(0x753); // minimum inter-packet delay
163 b->SetFeMux(-1, WDB::cFeMuxInput); // set multiplexer to input
164
165 //---- trigger settings
166 b->SetExtAsyncTriggerEn(false); // disable external trigger
167 b->SetTriggerDelay(0); // minimal inter-packet delay
168 b->SetLeadTrailEdgeSel(0); // trigger on leading edge
169 b->SetPatternTriggerEn(true); // enable internal pattern trigger
170 b->SetDacTriggerLevelV(-1, -0.02); // set trigger level to -20 mV for all channels
171
172 b->SetTrgSrcPolarity(0xFFFF); // negative signals
173 b->SetTrgPtrnEn(0xFFFF); // enable 16 trigger patterns
174 // b->SetTrgPtrnEn(0x0001); // enable first trigger pattern
175 for (int i=0 ; i<16 ; i++) {
176 b->SetTrgSrcEnPtrn(i, (1<<i)); // set individual channel as only source for pattern
177 b->SetTrgStatePtrn(i, (1<<i)); // set trigger coincidence for single channel
178 }
179
180 // now send all changes in one packet
181 b->SetSendBlock(false);
182 b->SendControlRegisters();
183
184 // check if PLLs are locked
185 b->ResetAllPll();
186 sleep_ms(100);
187 b->GetPllLock(true);
188 if (!b->GetLmkPllLock() || !b->GetDaqPllLock()) {
189 cm_msg(MERROR, "frontend_init", "PLLs not locked on board %s. Mask = 0x%04X",
190 b->GetName().c_str(), b->GetPllLock(false));
191 return FE_ERR_HW;
192 }
193
194 // read all status registers
195 b->ReceiveStatusRegisters();
196
197 if (b->IsVerbose()) {
198 std::cout << std::endl << "========== Board Info ==========" << std::endl;
199 b->PrintVersion();
200 }
201
202 // load calibration data for this board
203 b->LoadVoltageCalibration(b->GetDrsSampleFreqMhz(), drs_calib_path);
204 b->LoadTimeCalibration(b->GetDrsSampleFreqMhz(), drs_calib_path);
205
206 // create event storage for this board
207 WD::wde.push_back(new WDEvent(b->GetSerialNumber()));
208
209 } catch (std::runtime_error &e) {
210 std::cout << std::endl;
211 cm_msg(MERROR, "frontend_init", "%s", e.what());
212 cm_msg(MERROR, "frontend_init", "Cannot initialize %s, aborting.", b->GetName().c_str());
213 return FE_ERR_HW;
214 }
215
216 WD::wdb.push_back(b);
217
218 // instantiate waveform processor
219 WD::wp = new WP();
220 WD::wp->SetAllCalib(true);
221 WD::wp->SetWDBList(WD::wdb);
222 WD::wp->SetRequestedBoard(WD::wdb);
223
224 // set destination port after waveform processor has been initialized
225 for (auto b: WD::wdb)
227
228 // start DRS for first event
229 for (auto b: WD::wdb)
230 b->SetDaqSingle(true);
231
232 return SUCCESS;
233}
#define FE_ERR_HW
Definition midas.h:719
#define MINFO
Definition midas.h:560
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
INT i
Definition mdump.cxx:32
std::vector< WDEvent * > wde
Definition wdfe.cxx:112
WP * wp
Definition wdfe.cxx:109
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:

◆ frontend_loop()

INT frontend_loop ( void  )

Frontend loop.

If frontend_call_loop is true, this routine gets called when the frontend is idle or once between every event.

Returns
Midas status code

Definition at line 279 of file wdfe.cxx.

280{
281 /* if frontend_call_loop is true, this routine gets called when
282 the frontend is idle or once between every event */
283 return SUCCESS;
284}

◆ interrupt_configure()

INT interrupt_configure ( INT  cmd,
INT  source,
POINTER_T  adr 
)

Interrupt configuration (not implemented)

Routine for interrupt configuration if equipment is set in EQ_INTERRUPT mode. Not implemented right now, returns SUCCESS.

Parameters
[in]cmdCommand for interrupt events (see midas.h)
[in]sourceEquipment index number
[in]adrInterrupt routine (see mfe.c)
Returns
Midas status code

Definition at line 318 of file wdfe.cxx.

319{
320 switch (cmd) {
322 break;
324 break;
326 break;
328 break;
329 }
330 return SUCCESS;
331}
#define CMD_INTERRUPT_ATTACH
Definition midas.h:822
#define CMD_INTERRUPT_DISABLE
Definition midas.h:821
#define CMD_INTERRUPT_ENABLE
Definition midas.h:820
#define CMD_INTERRUPT_DETACH
Definition midas.h:823

◆ pause_run()

INT pause_run ( INT  run_number,
char error 
)

Pause Run.

Called every pause run transition.

Parameters
[in]run_numberNumber of the run being ended
[out]errorCan be used to write a message string to midas.log
Returns
Midas status code

Definition at line 265 of file wdfe.cxx.

266{
267 return SUCCESS;
268}

◆ poll_event()

INT poll_event ( INT  source,
INT  count,
BOOL  test 
)

Polling routine for events.

Parameters
[in]sourceEvent source (LAM/IRQ)
[in]countLoop count for event polling timeout
[in]testflag used to time the polling
Returns
1 if event is available, 0 if done polling (no event). If test equals TRUE, don't return.

Definition at line 296 of file wdfe.cxx.

300{
301 int i;
302 bool flag;
303
304 for (i = 0; i < count; i++) {
305 /* poll hardware and set flag to TRUE if new event is available */
306 flag = WD::wp->WaitNewEvent(10);
307
308 if (flag)
309 if (!test)
310 return TRUE;
311 }
312
313 return 0;
314}
double count
Definition mdump.cxx:33
#define TRUE
Definition midas.h:182
program test
Definition miniana.f:6
Here is the call graph for this function:

◆ read_periodic_event()

INT read_periodic_event ( char pevent,
INT  off 
)

Definition at line 378 of file wdfe.cxx.

379{
380 DWORD *pdata;
381
382 std::vector<unsigned long long> scaler;
383 WD::wdb[0]->GetScalers(scaler, true);
384
385 // init bank structure
386 bk_init(pevent);
387
388 // create SCLR bank
389 bk_create(pevent, "SCLR", TID_DWORD, (void **)&pdata);
390
391 for (int i = 0; i < scaler.size(); i++)
392 *pdata++ = scaler[i];
393
394 bk_close(pevent, pdata);
395
396 return bk_size(pevent);
397}
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16780
void bk_init(void *event)
Definition midas.cxx:16406
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16561
INT bk_size(const void *event)
Definition midas.cxx:16495
unsigned int DWORD
Definition mcstd.h:51
#define TID_DWORD
Definition midas.h:336
double scaler[32]
Definition scaler.cxx:47
Here is the call graph for this function:

◆ read_trigger_event()

INT read_trigger_event ( char pevent,
INT  off 
)

Definition at line 335 of file wdfe.cxx.

336{
337 float *pdata;
338 WDEvent event(WD::wdb[0]->GetSerialNumber());
339
340 // read current event
341 bool bNewEvent = WD::wp->GetLastEvent(WD::wdb[0], 500, event);
342
343 // start DRS for next event
344 WD::wdb[0]->SetDaqSingle(true);
345
346 if (!bNewEvent)
347 return 0;
348
349 // init bank structure
350 bk_init32(pevent);
351
352 // store time arrays for all channels on first event
353 if (SERIAL_NUMBER(pevent) == 0) {
354 bk_create(pevent, "DRST", TID_FLOAT, (void **) &pdata);
355 for (int i = 0; i < 16; i++) {
356 memcpy(pdata, event.mWfTDRS[i], sizeof(float) * 1024);
357 pdata += 1024;
358 }
359 bk_close(pevent, pdata);
360 }
361
362 // create calibrated time array
363 bk_create(pevent, "DRS0", TID_FLOAT, (void **) &pdata);
364
365 // copy over 16 channels
366 for (int i=0 ; i<16 ; i++) {
367 memcpy(pdata, event.mWfUDRS[i], sizeof(float)*1024);
368 pdata += 1024;
369 }
370
371 bk_close(pevent, pdata);
372
373 return bk_size(pevent);
374}
void bk_init32(void *event)
Definition midas.cxx:16469
#define TID_FLOAT
Definition midas.h:341
#define SERIAL_NUMBER(e)
Definition midas.h:880
Here is the call graph for this function:

◆ resume_run()

INT resume_run ( INT  run_number,
char error 
)

Resume Run.

Called every resume run transition.

Parameters
[in]run_numberNumber of the run being ended
[out]errorCan be used to write a message string to midas.log
Returns
Midas status code

Definition at line 272 of file wdfe.cxx.

273{
274 return SUCCESS;
275}

Variable Documentation

◆ display_period

INT display_period = 3000

a frontend status page is displayed with this frequency in ms

Definition at line 33 of file wdfe.cxx.

◆ equipment

EQUIPMENT equipment[]

Main structure for midas equipment.

Definition at line 65 of file wdfe.cxx.

65 {
66
67 {"Trigger", /* equipment name */
68 {1, 0, /* event ID, trigger mask */
69 "SYSTEM", /* event buffer */
70 EQ_POLLED, /* equipment type */
71 0, /* event source */
72 "MIDAS", /* format */
73 TRUE, /* enabled */
74 RO_RUNNING, /* read only when running */
75 100, /* poll for 100ms */
76 0, /* stop run after this event limit */
77 0, /* number of sub events */
78 0, /* don't log history */
79 "", "", "",},
80 read_trigger_event, /* readout routine */
81 },
82
83 {"Periodic", /* equipment name */
84 {2, 0, /* event ID, trigger mask */
85 "SYSTEM", /* event buffer */
86 EQ_PERIODIC, /* equipment type */
87 0, /* event source */
88 "MIDAS", /* format */
89 TRUE, /* enabled */
90 RO_RUNNING | RO_TRANSITIONS | /* read when running and on transitions */
91 RO_ODB, /* and update ODB */
92 1000, /* read every sec */
93 0, /* stop run after this event limit */
94 0, /* number of sub events */
95 TRUE, /* log history */
96 "", "", "",},
97 read_periodic_event, /* readout routine */
98 },
99
100 {""}
101};
#define EQ_POLLED
Definition midas.h:415
#define RO_ODB
Definition midas.h:438
#define EQ_PERIODIC
Definition midas.h:414
#define RO_TRANSITIONS
Definition midas.h:434
#define RO_RUNNING
Definition midas.h:426
INT read_periodic_event(char *pevent, INT off)
Definition wdfe.cxx:378
INT read_trigger_event(char *pevent, INT off)
Definition wdfe.cxx:335

◆ equipment_common_overwrite

BOOL equipment_common_overwrite = TRUE

Definition at line 63 of file wdfe.cxx.

◆ event_buffer_size

INT event_buffer_size = 5 * max_event_size

buffer size to hold events

Definition at line 42 of file wdfe.cxx.

◆ frontend_call_loop

BOOL frontend_call_loop = FALSE

frontend_loop is called periodically if this variable is TRUE

Definition at line 30 of file wdfe.cxx.

◆ frontend_file_name

const char* frontend_file_name = __FILE__

The frontend file name, don't change it.

Definition at line 27 of file wdfe.cxx.

◆ frontend_name

const char* frontend_name = "WD Frontend"

The frontend name (client name) as seen by other MIDAS clients.

Definition at line 25 of file wdfe.cxx.

◆ max_event_size

INT max_event_size = 1024 * 1014

maximum event size produced by this frontend

Definition at line 36 of file wdfe.cxx.

◆ max_event_size_frag

INT max_event_size_frag = 5 * max_event_size

maximum event size for fragmented events (EQ_FRAGMENTED)

Definition at line 39 of file wdfe.cxx.