9 #include <daq/rawdata/modules/copper.h>
10 #include <daq/rawdata/modules/DeSerializerCOPPER.h>
11 #include <rawdata/dataobjects/PreRawCOPPERFormat_latest.h>
13 #include <sys/ioctl.h>
15 #define CHECKEVT 10000
30 int g_run_resuming = 0;
47 setDescription(
"Encode DataStore into RingBuffer");
50 addParam(
"FinesseBitFlag", m_finesse_bit_flag,
"finesse (A,B,C,D) -> bit (0,1,2,3)", 15);
53 B2INFO(
"DeSerializerCOPPER: Constructor done.");
54 m_prev_ftsweve32 = 0xFFFFFFFF;
60 DeSerializerCOPPERModule::~DeSerializerCOPPERModule()
64 void DeSerializerCOPPERModule::initialize()
66 B2INFO(
"DeSerializerCOPPER: initialize() started.");
68 for (
int i = 0 ; i < NUM_PREALLOC_BUF; i++) {
69 m_bufary[i] =
new int[ BUF_SIZE_WORD ];
71 m_buffer =
new int[ BUF_SIZE_WORD ];
76 for (
int i = 0 ; i < NUM_PREALLOC_BUF; i++) {
77 memset(m_bufary[i], 0, BUF_SIZE_WORD *
sizeof(
int));
81 m_eventMetaDataPtr.registerInDataStore();
85 raw_dblkarray.registerInDataStore();
87 if (m_dump_fname.size() > 0) {
90 memset(time_array0, 0,
sizeof(time_array0));
91 memset(time_array1, 0,
sizeof(time_array1));
92 memset(time_array2, 0,
sizeof(time_array2));
93 memset(time_array3, 0,
sizeof(time_array3));
94 memset(time_array4, 0,
sizeof(time_array4));
95 memset(time_array5, 0,
sizeof(time_array5));
104 if (m_nodename.size() == 0 || m_nodeid < 0) {
107 printf(
"nodename = %s\n", m_nodename.c_str());
108 g_status.open(m_nodename, m_nodeid);
109 g_status.reportReady();
117 B2INFO(
"DeSerializerCOPPER: initialize() done.");
123 void DeSerializerCOPPERModule::initializeCOPPER()
130 if ((m_finesse_bit_flag & 0x1) == 1) {
132 m_use_slot |= 1 << slot_shift;
135 if (((m_finesse_bit_flag >> 1) & 0x1) == 1) {
137 m_use_slot |= 1 << slot_shift;
140 if (((m_finesse_bit_flag >> 2) & 0x1) == 1) {
142 m_use_slot |= 1 << slot_shift;
145 if (((m_finesse_bit_flag >> 3) & 0x1) == 1) {
147 m_use_slot |= 1 << slot_shift;
153 char err_buf[100] =
"[FATAL] Slot is not specified. Exiting...";
154 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
159 for (slot = 0; slot < 4; slot++) {
160 if (m_use_slot & (1 << slot)) printf(
" %c",
'A' + slot);
169 B2INFO(
"Opening COPPER...");
181 int* DeSerializerCOPPERModule::readOneEventFromCOPPERFIFO(
const int ,
int* ,
int* )
185 sprintf(err_buf,
"[FATAL] This function is not supported. Exiting...: \n%s %s %d\n",
186 __FILE__, __PRETTY_FUNCTION__, __LINE__);
187 print_err.PrintError(err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
192 int* temp_buf = m_bufary[ entry ];
193 temp_buf[0] = BUF_SIZE_WORD ;
200 int recvd_byte = (m_pre_rawcpr.tmp_header.RAWHEADER_NWORDS) *
sizeof(
int);
204 if ((read_size = read(m_cpr_fd, (
char*)m_bufary[entry] + recvd_byte,
sizeof(
int) * BUF_SIZE_WORD - recvd_byte)) < 0) {
205 if (errno == EINTR) {
207 }
else if (errno == EAGAIN || errno == EWOULDBLOCK) {
209 if (recvd_byte > (
int)((m_pre_rawcpr.tmp_header.RAWHEADER_NWORDS) *
sizeof(
int))) {
211 sprintf(err_buf,
"[FATAL] EAGAIN return in the middle of an event( COPPER driver should't do this.). Exting...");
212 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
219 callCheckRunPause(err_str);
225 sprintf(err_buf,
"[FATAL] Failed to read data from COPPER. Exiting...");
226 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
230 recvd_byte += read_size;
231 if (recvd_byte - (m_pre_rawcpr.tmp_header.RAWHEADER_NWORDS) *
sizeof(
int) > (
int)(
sizeof(
int) *
232 (m_pre_rawcpr.POS_DATA_LENGTH + 1)))
break;
239 *m_size_word = m_bufary[ entry ][ m_pre_rawcpr.POS_DATA_LENGTH + (m_pre_rawcpr.tmp_header.RAWHEADER_NWORDS) ]
240 + m_pre_rawcpr.SIZE_COPPER_DRIVER_HEADER + m_pre_rawcpr.SIZE_COPPER_DRIVER_TRAILER
241 + m_pre_rawcpr.tmp_header.RAWHEADER_NWORDS +
242 m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS;
247 if ((
int)((*m_size_word - m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS) *
sizeof(
int)) > recvd_byte) {
250 if (*m_size_word > BUF_SIZE_WORD) {
252 temp_buf =
new int[ *m_size_word ];
253 memcpy(temp_buf, m_bufary[ entry ], recvd_byte);
254 recvd_byte += readFD(m_cpr_fd, (
char*)temp_buf + recvd_byte,
255 (*m_size_word - m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS) *
sizeof(
int) - recvd_byte, *delete_flag);
258 recvd_byte += readFD(m_cpr_fd, (
char*)(m_bufary[ entry ]) + recvd_byte,
259 (*m_size_word - m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS) *
sizeof(
int) - recvd_byte, *delete_flag);
262 if ((
int)((*m_size_word - m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS) *
sizeof(
int)) != recvd_byte) {
265 sprintf(err_buf,
"[FATAL] CORRUPTED DATA: Read less bytes(%d) than expected(%d:%d). Exiting...\n",
267 *m_size_word *
sizeof(
int) - m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS *
sizeof(
int),
268 m_bufary[ entry ][ m_pre_rawcpr.POS_DATA_LENGTH ]);
269 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
272 }
else if ((
int)((*m_size_word - m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS) *
sizeof(
int)) < recvd_byte) {
274 sprintf(err_buf,
"[FATAL] CORRUPTED DATA: Read more than data size. Exiting...: %d %d %d %d %d\n",
275 recvd_byte, *m_size_word *
sizeof(
int), m_pre_rawcpr.tmp_trailer.RAWTRAILER_NWORDS *
sizeof(
int),
276 m_bufary[ entry ][ m_pre_rawcpr.POS_DATA_LENGTH ], m_pre_rawcpr.POS_DATA_LENGTH);
277 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
284 *m_size_word = 256 + entry;
285 m_bufary[entry][0] = *m_size_word;
291 temp_buf[ 0 ] = *m_size_word;
295 if (n_basf2evt >= 50000 && n_basf2evt < 50500) {
296 cur_time = getTimeSec();
297 time_array2[ n_basf2evt - 50000 ] = cur_time - m_start_time;
302 unsigned int checksum = 0;
303 for (
int i = 0; i < m_bufary[entry][0]; i++) {
304 if (i != 2) checksum += m_bufary[entry][i];
306 m_bufary[entry][2] = checksum;
315 void DeSerializerCOPPERModule::openCOPPER()
318 if (m_cpr_fd != -1) {
325 if ((m_cpr_fd = open(
"/dev/copper/copper", O_RDONLY)) == -1) {
327 sprintf(err_buf,
"[FATAL] Failed to open /dev/copper/copper. Exiting... ");
328 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
334 ioctl(m_cpr_fd, CPRIOSET_LEF_WA_FF, &set_regval);
335 ioctl(m_cpr_fd, CPRIOSET_LEF_WB_FF, &set_regval);
336 ioctl(m_cpr_fd, CPRIOSET_LEF_WC_FF, &set_regval);
337 ioctl(m_cpr_fd, CPRIOSET_LEF_WD_FF, &set_regval);
338 ioctl(m_cpr_fd, CPRIOSET_FINESSE_STA, &m_use_slot,
sizeof(m_use_slot));
342 ioctl(m_cpr_fd, CPRIOSET_LEF_WA_AF, &v,
sizeof(v));
343 ioctl(m_cpr_fd, CPRIOSET_LEF_WB_AF, &v,
sizeof(v));
344 ioctl(m_cpr_fd, CPRIOSET_LEF_WC_AF, &v,
sizeof(v));
345 ioctl(m_cpr_fd, CPRIOSET_LEF_WD_AF, &v,
sizeof(v));
348 B2INFO(
"DeSerializerCOPPER: openCOPPER() done.");
354 int DeSerializerCOPPERModule::readFD(
int fd,
char* buf,
int data_size_byte,
int )
360 if ((read_size = read(fd, (
char*)buf + n, data_size_byte - n)) < 0) {
361 if (errno == EINTR) {
363 }
else if (errno == EAGAIN || errno == EWOULDBLOCK) {
366 sprintf(err_buf,
"[FATAL] Return due to EAGAIN in the middle of an event( COPPER driver would't do this.). Exting...");
367 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
374 callCheckRunPause(err_str);
375 }
catch (
string err_str) {
378 B2WARNING(
"Delete buffer before going to Run-pause state");
388 printf(
"[ERROR] Failed to read data from COPPER. %s %s %d",
389 __FILE__, __PRETTY_FUNCTION__, __LINE__);
390 string err_str =
"RUN_ERROR";
394 sprintf(err_buf,
"[FATAL] Failed to read data from COPPER. %s %s %d",
395 __FILE__, __PRETTY_FUNCTION__, __LINE__);
396 print_err.PrintError(m_shmflag, &g_status, err_buf, __FILE__, __PRETTY_FUNCTION__, __LINE__);
401 if (n == data_size_byte)
break;
408 void DeSerializerCOPPERModule::resumeRun()
412 printf(
"###########(DesCpr) Resume from PAUSE ###############\n");
423 void DeSerializerCOPPERModule::waitResume()
426 if (g_run_pause == 0 && g_run_error == 1) {
430 printf(
"###########(DesCpr) Error stop. Waiting for RUNPAUSE ###############\n");
434 if (checkRunPause())
break;
440 if (m_cpr_fd != -1) close(m_cpr_fd);
443 if (checkRunRecovery()) {
451 printf(
"###########(DesCpr) Resume detected ###############\n");
459 printf(
"###########(DesCpr) Waiting for RESUME ###############\n");
470 void DeSerializerCOPPERModule::event()
475 if (g_run_pause > 0 || g_run_error > 0) {
477 m_eventMetaDataPtr.create();
482 if (m_start_flag == 0) {
485 if (g_status.isAvailable()) {
486 B2INFO(
"DeSerializerCOPPER: Waiting for Start...\n");
487 g_status.reportRunning();
490 m_start_time = getTimeSec();
493 B2INFO(
"Opening COPPER...");
502 for (
int j = 0; j < NUM_EVT_PER_BASF2LOOP_COPPER; j++) {
505 if (m_start_flag == 0) {
506 B2INFO(
"DeSerializerCOPPER: Reading the 1st event from COPPER FIFO...");
511 temp_buf = readOneEventFromCOPPERFIFO(j, &delete_flag, &m_size_word);
512 g_status.copyEventHeader(temp_buf);
513 }
catch (
string err_str) {
516 if (err_str ==
"RUN_PAUSE" || err_str ==
"RUN_ERROR") {
518 m_eventMetaDataPtr.create();
522 print_err.PrintError(m_shmflag, &g_status, err_str);
526 if (m_start_flag == 0) {
527 B2INFO(
"DeSerializerCOPPER: Done. the size of the 1st event is " << m_size_word <<
"words");
531 const int num_nodes = 1;
532 const int num_events = 1;
534 temp_rawdblk->
SetBuffer(temp_buf, m_size_word, delete_flag, num_events, num_nodes);
538 temp_rawcopper.
SetBuffer(temp_buf, m_size_word, 0, num_events, num_nodes);
542 m_prev_ftsweve32 = temp_rawcopper.
FillTopBlockRawHeader(m_nodeid, m_prev_ftsweve32, m_prev_exprunsubrun_no, &m_exprunsubrun_no);
543 m_prev_exprunsubrun_no = m_exprunsubrun_no;
545 }
catch (
string err_str) {
546 print_err.PrintError(m_shmflag, &g_status, err_str);
550 if (m_dump_fname.size() > 0) {
551 dumpData((
char*)temp_buf, m_size_word *
sizeof(
int));
553 m_totbytes += m_size_word *
sizeof(int);
560 m_eventMetaDataPtr.create();
561 m_eventMetaDataPtr->setExperiment(0);
562 m_eventMetaDataPtr->setRun(0);
563 m_eventMetaDataPtr->setEvent(n_basf2evt);
568 if (max_nevt >= 0 || max_seconds >= 0.) {
569 if ((n_basf2evt * NUM_EVT_PER_BASF2LOOP_PC >= max_nevt && max_nevt > 0)
570 || (getTimeSec() - m_start_time > max_seconds && max_seconds > 0.)) {
571 printf(
"[DEBUG] RunPause was detected. ( Setting: Max event # %d MaxTime %lf ) Processed Event %d Elapsed Time %lf[s]\n",
572 max_nevt, max_seconds, n_basf2evt * NUM_EVT_PER_BASF2LOOP_PC, getTimeSec() - m_start_time);
573 m_eventMetaDataPtr->setEndOfData();
581 if (n_basf2evt % 100 == 0) {
582 RateMonitor(m_prev_ftsweve32, m_prev_exprunsubrun_no & RawHeader_latest::SUBRUNNO_MASK,
583 (m_prev_exprunsubrun_no & RawHeader_latest::RUNNO_MASK) >> RawHeader_latest::RUNNO_SHIFT);
586 if (g_status.isAvailable()) {
587 g_status.setInputNBytes(m_totbytes);
588 g_status.setInputCount(m_prev_ftsweve32 + 1);
A class definition of an input module for Sequential ROOT I/O.
A class definition of an input module for Sequential ROOT I/O.
The RawDataBlock class Base class for rawdata handling.
virtual void SetBuffer(int *bufin, int nwords, int delete_flag, int num_events, int num_nodes)
set buffer ( delete_flag : m_buffer is freeed( = 0 )/ not freeed( = 1 ) in Destructer )
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.