/** Hook to the event builder task after the reception of all fragments of the same serial number. The destination event has already the final EVENT_HEADER setup with the data size set to 0. It is than possible to add private data at this point using the proper bank calls. The ebch[] array structure points to nfragment channel structure with the following content: \code typedef struct { char name[32]; // Fragment name (Buffer name). DWORD serial; // Serial fragment number. char *pfragment; // Pointer to fragment (EVENT_HEADER *) ... } EBUILDER_CHANNEL; \endcode The correct code for including your own MIDAS bank is shown below where \b TID_xxx is one of the valid Bank type starting with \b TID_ for midas format or \b xxx_BKTYPE for Ybos data format. \b bank_name is a 4 character descriptor. \b pdata has to be declared accordingly with the bank type. Refers to the ebuser.c source code for further description. <strong> It is not possible to mix within the same destination event different event format! </strong> \code // Event is empty, fill it with BANK_HEADER // If you need to add your own bank at this stage bk_init(pevent); bk_create(pevent, bank_name, TID_xxxx, &pdata); *pdata++ = ...; *dest_size = bk_close(pevent, pdata); pheader->data_size = *dest_size + sizeof(EVENT_HEADER); \endcode For YBOS format, use the following example. \code ybk_init(pevent); ybk_create(pevent, "EBBK", I4_BKTYPE, &pdata); *pdata++ = 0x12345678; *pdata++ = 0x87654321; *dest_size = ybk_close(pevent, pdata); *dest_size *= 4; pheader->data_size = *dest_size + sizeof(YBOS_BANK_HEADER); \endcode @param nfrag Number of fragment. @param mismatch Midas Serial number mismatch flag. @param ebch Structure to all the fragments. @param pheader Destination pointer to the header. @param pevent Destination pointer to the bank header. @param dest_size Destination event size in bytes. @return EB_SUCCESS */ INT eb_user(INT nfrag, BOOL mismatch, EBUILDER_CHANNEL * ebch , EVENT_HEADER * pheader, void *pevent, INT * dest_size) { if (mismatch){ printf("Serial number do not match across fragments\n"); for (int i = 0; i < nfrag; i++) { int serial = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; printf("Ser[%i]:%d ", i + 1, serial); } printf("\n"); return EB_USER_ERROR; } // Initialize output event bk_init32(pevent); // Loop over the event fragments, performing compression into the output event for(int i = 0; i < nfrag; i++) { void *fragment = ebch[i].pfragment; if(fragment != NULL) { compress_event(((EVENT_HEADER *) fragment) + 1, pevent); pheader->serial_number = ((EVENT_HEADER *) ebch[i].pfragment)->serial_number; } } // Set the size of the output event properly pheader->data_size = *dest_size = bk_size(pevent); // printf("Returning size %d\n", pheader->data_size); return EB_SUCCESS; }
//fill mbank from /equip/environ/variables INT read_periodic_event(char *pevent, INT off){ printf("Reading Periodic Event\n"); HNDLE hDB; cm_get_experiment_database(&hDB, NULL); HNDLE hkey; float temp1[3]; INT size; // get key handle for temp db_find_key(hDB, 0, "/Equipment/Temperature/Variables/Input", &hkey); // return temp size = sizeof(temp1); db_get_data(hDB, hkey, &temp1, &size, TID_FLOAT); //char *pevent; bk_init(pevent); float *pdata; // *pdata = temp1[0]; // create SCLR bank bk_create(pevent, "NEW1", TID_FLOAT, &pdata); // *pdata = 29.3; printf("%f\n",temp1[0]); // close SCLR bank bk_close(pevent, pdata); printf("eo fB\n"); return bk_size(pevent); }
INT read_trigger_event(char *pevent, INT off) { WORD *pdata, a; INT j; /* init bank structure */ bk_init(pevent); /* create structured ADC0 bank */ bk_create(pevent, "ADC0", TID_WORD, &pdata); /* Use following code to "simulate" data */ for (a = 0; a < 3; a++) *pdata++ = rand() % 1024; rs232(CMD_GETS, info, strin, 256, 0, 500); for (j=0;j<256;j++) { if (strin[j] != 0) *pdata++ = strin[j]; } bk_close(pevent, pdata); /* create variable length TDC bank */ bk_create(pevent, "TDC0", TID_WORD, &pdata); /* Use following code to "simulate" data */ for (a = 0; a < 3; a++) *pdata++ = rand() % 1024; bk_close(pevent, pdata); return bk_size(pevent); }
INT read_tiny_event(char *pevent, INT offset) { static WORD *pdata = NULL; static WORD sub_counter = 0; // Super event structure if (offset == 0) { // FIRST event of the Super event bk_init(pevent); bk_create(pevent, "SUPR", TID_WORD, &pdata); sub_counter = 1; } else if (offset == -1) { // CLOSE Super event bk_close(pevent, pdata); return bk_size(pevent); } // READ event *pdata++ = 0xB0E; *pdata++ = sub_counter++; *pdata++ = 0xE0E; if (offset == 0) { // Compute the proper event length on the FIRST event in the Super Event // NWORDS correspond to the !! NWORDS WORD above !! // sizeof(BANK_HEADER) + sizeof(BANK) will make the 16 bytes header // sizeof(WORD) is defined by the TID_WORD in bk_create() return NWORDS * sizeof(WORD) + sizeof(BANK_HEADER) + sizeof(BANK); } else { // Return the data section size only // sizeof(WORD) is defined by the TID_WORD in bk_create() return NWORDS * sizeof(WORD); } }
/* ********************************************************************* */ INT rpc_end_of_cycle(INT index, void *prpc_param[]) { INT cycle_number = CINT(0); INT event_number = CINT(1); diag_print(2, "Cycle ended: RAM %d, event %d\n", cycle_number, event_number); // first send out "fake" zero-length events for those cycles // where we didn't participate for(INT fake_evnum=last_event_number+1; fake_evnum < event_number; fake_evnum++) { diag_print(2, "Sending fake catch-up event for %d\n", fake_evnum); char fake_event[sizeof(EVENT_HEADER) + sizeof(BANK_HEADER)]; char *pevent = fake_event + sizeof(EVENT_HEADER); rpc_flush_event(); bk_init32(pevent); bm_compose_event((EVENT_HEADER *) fake_event, equipment[0].info.event_id, 0, bk_size(pevent), fake_evnum); bm_send_event(equipment[0].buffer_handle, fake_event, sizeof(fake_event), SYNC); bm_flush_cache(equipment[0].buffer_handle, SYNC); } event_ended = true; last_cycle = cycle_number; last_event_number = event_number; return SUCCESS; }
INT cd_fgd_read(char *pevent, int offset) { float *pdata; FGD_INFO *fgd_info; EQUIPMENT *pequipment; pequipment = *((EQUIPMENT **) pevent); fgd_info = (FGD_INFO *) pequipment->cd_info; if (fgd_info->format == FORMAT_FIXED) { memcpy(pevent, fgd_info->demand, sizeof(float) * fgd_info->num_channels); pevent += sizeof(float) * fgd_info->num_channels; memcpy(pevent, fgd_info->measured, sizeof(float) * fgd_info->num_channels); pevent += sizeof(float) * fgd_info->num_channels; return 2 * sizeof(float) * fgd_info->num_channels; } else if (fgd_info->format == FORMAT_MIDAS) { bk_init(pevent); /* create VDMD bank */ bk_create(pevent, "VDMD", TID_FLOAT, &pdata); memcpy(pdata, fgd_info->demand, sizeof(float) * fgd_info->num_channels); pdata += fgd_info->num_channels; bk_close(pevent, pdata); /* create IMES bank */ bk_create(pevent, "IMES", TID_FLOAT, &pdata); memcpy(pdata, fgd_info->measured, sizeof(float) * fgd_info->num_channels); pdata += fgd_info->num_channels; bk_close(pevent, pdata); /* create TEMP1 bank */ bk_create(pevent, "TEM1", TID_FLOAT, &pdata); memcpy(pdata, fgd_info->temp1, sizeof(float) * fgd_info->num_channels); pdata += fgd_info->num_channels; bk_close(pevent, pdata); /* create TEMP2 bank */ bk_create(pevent, "TEM2", TID_FLOAT, &pdata); memcpy(pdata, fgd_info->temp2, sizeof(float) * fgd_info->num_channels); pdata += fgd_info->num_channels; bk_close(pevent, pdata); /* create TEMP1 bank */ bk_create(pevent, "TEM3", TID_FLOAT, &pdata); memcpy(pdata, fgd_info->temp3, sizeof(float) * fgd_info->num_channels); pdata += fgd_info->num_channels; bk_close(pevent, pdata); return bk_size(pevent); } else if (fgd_info->format == FORMAT_YBOS) { printf("Not implemented\n"); return 0; } else return 0; }
INT read_scaler_event(char *pevent, INT off) { DWORD *pdata, a; /* init bank structure */ bk_init(pevent); /* create SCLR bank */ bk_create(pevent, "SCLR", TID_DWORD, &pdata); /* read scaler bank */ for (a = 0; a < N_SCLR; a++) cam24i(CRATE, SLOT_SCLR, a, 0, pdata++); bk_close(pevent, pdata); return bk_size(pevent); }
INT readout(char* pevent, INT off) { DWORD *pdata; bk_init32(pevent); bk_create(pevent,"INPT",TID_DWORD,&pdata); int val = 98; HNDLE hDB; HNDLE hKey; INT size; cm_get_experiment_database(&hDB,NULL); db_find_key(hDB,0,"/Equipment/Environment 2/Variables/Secret",&hKey); size = sizeof(val); db_get_data(hDB,hKey,&val,&size,TID_INT); *pdata++ = val; struct timeval t; int status; status = gettimeofday(&t,NULL); printf(" t_tv.sec: %d",t.tv_sec); printf(" ro: val is %d",val); val++; db_set_value(hDB,0,"/Equipment/Environment 2/Variables/Secret",&val,sizeof(val),1,TID_INT); bk_close(pevent,pdata); return bk_size(pevent); }
/* * NAME: cmdbuf->put() * DESCRIPTION: put a block in the edit buffer */ int cb_put(cmdbuf *cb) { block b; if (isalpha(cb->a_buffer)) { /* 'a' and 'A' both refer to buffer 'a' */ b = cb->zbuf[tolower(cb->a_buffer) - 'a']; } else { b = cb->buf; } if (b == (block) 0) { error("Nothing in buffer"); } cb_do(cb, cb->first); add(cb, cb->first, b, bk_size(cb->edbuf->lb, b)); cb->edit++; return RET_FLAGS; }
INT cd_gen_read(char *pevent, int offset) { float *pdata; GEN_INFO *gen_info; EQUIPMENT *pequipment; #ifdef HAVE_YBOS DWORD *pdw; #endif pequipment = *((EQUIPMENT **) pevent); gen_info = (GEN_INFO *) pequipment->cd_info; if (gen_info->format == FORMAT_FIXED) { memcpy(pevent, gen_info->demand, sizeof(float) * gen_info->num_channels); pevent += sizeof(float) * gen_info->num_channels; memcpy(pevent, gen_info->measured, sizeof(float) * gen_info->num_channels); pevent += sizeof(float) * gen_info->num_channels; return 2 * sizeof(float) * gen_info->num_channels; } else if (gen_info->format == FORMAT_MIDAS) { bk_init(pevent); /* create DMND bank */ bk_create(pevent, "DMND", TID_FLOAT, (void **)&pdata); memcpy(pdata, gen_info->demand, sizeof(float) * gen_info->num_channels); pdata += gen_info->num_channels; bk_close(pevent, pdata); /* create MSRD bank */ bk_create(pevent, "MSRD", TID_FLOAT, (void **)&pdata); memcpy(pdata, gen_info->measured, sizeof(float) * gen_info->num_channels); pdata += gen_info->num_channels; bk_close(pevent, pdata); return bk_size(pevent); } else if (gen_info->format == FORMAT_YBOS) { #ifdef HAVE_YBOS ybk_init((DWORD *) pevent); /* create EVID bank */ ybk_create((DWORD *) pevent, "EVID", I4_BKTYPE, (DWORD *) (&pdw)); *(pdw)++ = EVENT_ID(pevent); /* Event_ID + Mask */ *(pdw)++ = SERIAL_NUMBER(pevent); /* Serial number */ *(pdw)++ = TIME_STAMP(pevent); /* Time Stamp */ ybk_close((DWORD *) pevent, pdw); /* create DMND bank */ ybk_create((DWORD *) pevent, "DMND", F4_BKTYPE, (DWORD *) & pdata); memcpy(pdata, gen_info->demand, sizeof(float) * gen_info->num_channels); pdata += gen_info->num_channels; ybk_close((DWORD *) pevent, pdata); /* create MSRD bank */ ybk_create((DWORD *) pevent, "MSRD", F4_BKTYPE, (DWORD *) & pdata); memcpy(pdata, gen_info->measured, sizeof(float) * gen_info->num_channels); pdata += gen_info->num_channels; ybk_close((DWORD *) pevent, pdata); return ybk_size((DWORD *) pevent); #else assert(!"YBOS support not compiled in"); #endif } return 0; }
/** * Event readout routine. * * @param pevent * @param off offset (for subevents) * * @return */ INT read_trigger_event(char *pevent, INT off) { // DWORD *pdata; char bk_name[8]; int status; data_avail = FALSE; /* init bank structure */ bk_init32(pevent); /* create structured bank */ // //sprintf(bk_name,"SI%02i",frontend_index); // Just one VME crate, we don't use frontend_index #if 0 sprintf(bk_name,"FD%02i",frontend_index); bk_create(pevent, bk_name, TID_DWORD, &pdata); // all udp data received. copy data to midas bank /** \todo check data size */ //pthread_mutex_lock( &buf_packet_gl_mutex ); /*TG memcpy(pdata,gpu_data,gpu_data_size); pdata += gpu_data_size/sizeof(pdata[0]); */ int fake_data_size = 12*10*1000; //originally 10*1000 *pdata++ = (DWORD) 0x1CEB00DA; pdata += fake_data_size/sizeof(pdata[0]); bk_close(pevent, pdata); #endif #if 0 // unlock udp threads for (int i=0; i<udp_thread_num; i++) { pthread_mutex_unlock( &udp_thread_info[i].mutex ); } #endif #if 0 // read out tempratures sensord of SIS3350 boards sprintf(bk_name,"ST%02i",frontend_index); WORD *tdata; bk_create(pevent, bk_name, TID_WORD, &tdata); for (int i=0; i<SIS3350_NUM; i++) { if ( ! sis3350_info[i].board.enabled ) continue; unsigned int t; sis3350_ReadTemperature(i, &t); *tdata++ = (WORD)sis3350_info[i].SN; *tdata++ = (WORD)t; short int *ts = (short int*)&t; float tf = *ts; tf /= 4; printf("Board %i temperature: %f\n",sis3350_info[i].SN,tf); } bk_close(pevent, tdata); #endif #if 0 // timing struct timeval t; DWORD *tr_data; sprintf(bk_name,"CS%02i",frontend_index); bk_create(pevent, bk_name, TID_DWORD, &tr_data); status = gettimeofday( &t, NULL); if ( status != 0) { printf("ERROR! gettimeofday() failed\n"); t.tv_sec = 0; t.tv_usec = 0; } trigger_info.time_slave_got_data_s = t.tv_sec; trigger_info.time_slave_got_data_us = t.tv_usec; *tr_data++ = trigger_info.trigger_nr; *tr_data++ = trigger_info.trigger_mask; *tr_data++ = trigger_info.time_master_got_eof_s; *tr_data++ = trigger_info.time_master_got_eof_us; *tr_data++ = trigger_info.time_slave_got_eof_s; *tr_data++ = trigger_info.time_slave_got_eof_us; *tr_data++ = trigger_info.time_tcp_finish_data_read_s; *tr_data++ = trigger_info.time_tcp_finish_data_read_us; bk_close(pevent, tr_data); long int dt_s = trigger_info.time_slave_got_data_s; dt_s -= trigger_info.time_slave_got_eof_s; long int dt_us = trigger_info.time_slave_got_data_us; dt_us -= trigger_info.time_slave_got_eof_us; if ( dt_us < 0 ) { dt_s -= 1; dt_us += 1000000; } printf("Readout: trigger dt = %li s %li us\n", dt_s, dt_us); printf("Bank size: %i\n", bk_size(pevent)); #endif #if 1 struct timeval start_READY_time, end_READY_time; gettimeofday(&start_READY_time, NULL); rpc_g2_ready( frontend_index + frontend_index_offset ); gettimeofday(&end_READY_time, NULL); dt_READY = dt_READY + toddiff(&end_READY_time, &start_READY_time); n_dt_READYs++; printf("n READYs, dt READY average, dt %d %f %f\n", n_dt_READYs, dt_READY/n_dt_READYs, toddiff(&end_READY_time, &start_READY_time)); #endif return bk_size(pevent); }
/*---- Scaler event --------------------------------*/ INT read_scaler_event( char *pevent, INT off ) { return bk_size(pevent); /* return bank size ... */ }
INT read_trigger_event(char *pevent, INT off) { WORD *pdata, a; INT q, timeout; /* init bank structure */ bk_init(pevent); /* create structured ADC0 bank */ bk_create(pevent, "ADC0", TID_WORD, &pdata); /* wait for ADC conversion */ for (timeout = 100; timeout > 0; timeout--) { camc_q(CRATE, SLOT_ADC, 0, 8, &q); if (q) break; } if (timeout == 0) ss_printf(0, 10, "No ADC gate!"); /* use following code to read out real CAMAC ADC */ /* for (a=0 ; a<N_ADC ; a++) cami(CRATE, SLOT_ADC, a, 0, pdata++); */ /* Use following code to "simulate" data */ for (a = 0; a < N_ADC; a++) *pdata++ = rand() % 1024; /* clear ADC */ camc(CRATE, SLOT_ADC, 0, 9); bk_close(pevent, pdata); /* create variable length TDC bank */ bk_create(pevent, "TDC0", TID_WORD, &pdata); /* use following code to read out real CAMAC TDC */ /* for (a=0 ; a<N_TDC ; a++) cami(CRATE, SLOT_TDC, a, 0, pdata++); */ /* Use following code to "simulate" data */ for (a = 0; a < N_TDC; a++) *pdata++ = rand() % 1024; /* clear TDC */ camc(CRATE, SLOT_TDC, 0, 9); bk_close(pevent, pdata); /* clear IO unit LAM */ camc(CRATE, SLOT_IO, 0, 10); /* clear LAM in crate controller */ cam_lam_clear(CRATE, SLOT_IO); /* reset external LAM Flip-Flop */ camo(CRATE, SLOT_IO, 1, 16, 0xFF); camo(CRATE, SLOT_IO, 1, 16, 0); ss_sleep(10); return bk_size(pevent); }
INT cd_multi_read(char *pevent, int offset) { float *pdata; MULTI_INFO *m_info; EQUIPMENT *pequipment; #ifdef HAVE_YBOS DWORD *pdw; #endif pequipment = *((EQUIPMENT **) pevent); m_info = (MULTI_INFO *) pequipment->cd_info; if (m_info->format == FORMAT_FIXED) { memcpy(pevent, m_info->var_input, sizeof(float) * m_info->num_channels_input); pevent += sizeof(float) * m_info->num_channels_input; memcpy(pevent, m_info->var_output, sizeof(float) * m_info->num_channels_output); pevent += sizeof(float) * m_info->num_channels_output; return sizeof(float) * (m_info->num_channels_input + m_info->num_channels_output); } else if (m_info->format == FORMAT_MIDAS) { bk_init(pevent); /* create INPT bank */ if (m_info->num_channels_input) { bk_create(pevent, "INPT", TID_FLOAT, (void **)&pdata); memcpy(pdata, m_info->var_input, sizeof(float) * m_info->num_channels_input); pdata += m_info->num_channels_input; bk_close(pevent, pdata); } /* create OUTP bank */ if (m_info->num_channels_output) { bk_create(pevent, "OUTP", TID_FLOAT, (void **)&pdata); memcpy(pdata, m_info->var_output, sizeof(float) * m_info->num_channels_output); pdata += m_info->num_channels_output; bk_close(pevent, pdata); } return bk_size(pevent); } else if (m_info->format == FORMAT_YBOS) { #ifdef HAVE_YBOS ybk_init((DWORD *) pevent); /* create EVID bank */ ybk_create((DWORD *) pevent, "EVID", I4_BKTYPE, (DWORD *) (&pdw)); *(pdw)++ = EVENT_ID(pevent); /* Event_ID + Mask */ *(pdw)++ = SERIAL_NUMBER(pevent); /* Serial number */ *(pdw)++ = TIME_STAMP(pevent); /* Time Stamp */ ybk_close((DWORD *) pevent, pdw); /* create INPT bank */ ybk_create((DWORD *) pevent, "INPT", F4_BKTYPE, (DWORD *) & pdata); memcpy(pdata, m_info->var_input, sizeof(float) * m_info->num_channels_input); pdata += m_info->num_channels_input; ybk_close((DWORD *) pevent, pdata); /* create OUTP bank */ ybk_create((DWORD *) pevent, "OUTP", F4_BKTYPE, (DWORD *) & pdata); memcpy(pdata, m_info->var_output, sizeof(float) * m_info->num_channels_output); pdata += m_info->num_channels_output; ybk_close((DWORD *) pevent, pdata); return ybk_size((DWORD *) pevent); #lese assert(!"YBOS support not compiled in"); #endif } return 0; }
/** * Event readout routine. * * @param pevent * @param off offset (for subevents) * * @return */ INT read_trigger_event(char *pevent, INT off) { int status; short *pdata; DWORD *hdata; char bk_name[8]; dbprintf("Begin read_trigger_event!\n"); // get data ready time struct timeval t_lock_data; status = gettimeofday( &t_lock_data, NULL); trigger_info.time_slave_lock_dataready_s = t_lock_data.tv_sec; trigger_info.time_slave_lock_dataready_us = t_lock_data.tv_usec; // store timing information and current TCPfillnumber, GPUfillnumber in header databank gpu_data_header[13] = t_lock_data.tv_sec; gpu_data_header[14] = t_lock_data.tv_usec; //AMC13 fill number unsigned int AMC13fillcounter = ( be32toh ( gpu_data_header[0] ) & 0x00FFFFFF ); /* init bank structure */ bk_init32(pevent); dbprintf("event serial_number %d\n", SERIAL_NUMBER(pevent)); // header bank wrote last in order to complete the timing data // make trailer databank sprintf(bk_name,"EC%02i",frontend_index); bk_create(pevent, bk_name, TID_DWORD, (void**)&hdata); // TID_DWORD unsigned int of four bytes memcpy( hdata, gpu_data_tail, gpu_data_tail_size); hdata += gpu_data_tail_size / sizeof(hdata[0]); bk_close(pevent, hdata); dbprintf("%s(%d): made trailer databank %s size 0x%08x, tail[0] 0x%08x, readout electronics fill number %d\n", __func__, __LINE__, bk_name, gpu_data_tail_size, *gpu_data_tail, gpu_data_header[1]); // make raw databank if ( amc13_settings_odb.store_raw && !( ( AMC13fillcounter + amc13_settings_odb.prescale_offset_raw ) % amc13_settings_odb.prescale_raw ) ) { sprintf(bk_name,"RC%02i",frontend_index); bk_create(pevent, bk_name, TID_SHORT, (void**)&pdata); // TID_SHORT signed int of two bytes printf("created raw bank %s, now do memcpy\n",bk_name); memcpy( pdata, gpu_data_raw, gpu_data_raw_size); printf("raw data memcpy complete\n"); pdata += gpu_data_raw_size / sizeof(pdata[0]); bk_close(pevent, pdata); dbprintf("%s(%d): made raw databank %s size 0x%08x, *data %p, data[0] 0x%04x, readout electronics fill number %d\n", __func__, __LINE__, bk_name, gpu_data_raw_size, gpu_data_raw, *gpu_data_raw, gpu_data_header[1]); } #ifdef USE_GPU // make processed databank if ( amc13_settings_odb.TQ_on ) { dbprintf("%s(%d): fill FC data bank\n",__func__, __LINE__); sprintf(bk_name,"FC%02i",frontend_index); bk_create(pevent, bk_name, TID_SHORT, (void**)&pdata); dbprintf("%s(%d): gpu_data_proc: 0x%08x gpu_data_proc_size: %d\n",__func__,__LINE__,*gpu_data_proc,gpu_data_proc_size); memcpy(pdata, gpu_data_proc, gpu_data_proc_size); dbprintf("%s(%d): sizeof(pdata): %d\n",__func__,__LINE__,sizeof(pdata)); if(sizeof(pdata) != 0) pdata += gpu_data_proc_size / sizeof(pdata[0]); bk_close(pevent, pdata); dbprintf("%s(%d): made processed databank %s size %d\n", __func__, __LINE__, bk_name, gpu_data_proc_size); // make histogram databank printf("gpu_data_his_size = %d\n",gpu_data_his_size); if ( amc13_settings_odb.store_hist && !( (AMC13fillcounter + amc13_settings_odb.flush_offset_hist) % amc13_settings_odb.flush_hist ) ) { dbprintf("%s(%d): fill HC data bank\n",__func__, __LINE__); sprintf(bk_name,"HC%02i",frontend_index); dbprintf("1\n"); bk_create(pevent, bk_name, TID_DWORD, (void**)&hdata); dbprintf("2 gpu_data_hiz_size = %d\n",gpu_data_his_size); memcpy( hdata, gpu_data_his, gpu_data_his_size); dbprintf("3\n"); hdata += gpu_data_his_size / sizeof(hdata[0]); dbprintf("4\n"); bk_close(pevent, hdata); dbprintf("%s(%d): made histogram databank %s size 0x%08x, data[0] 0x%08x, readout electronics fill number %d\n", __func__, __LINE__, bk_name, gpu_data_his_size, *gpu_data_his, gpu_data_header[1]); } } #endif // USE_GPU struct timeval t_got_data; status = gettimeofday( &t_got_data, NULL); trigger_info.time_slave_got_data_s = t_got_data.tv_sec; trigger_info.time_slave_got_data_us = t_got_data.tv_usec; // make header databank gpu_data_header[15] = t_got_data.tv_sec; gpu_data_header[16] = t_got_data.tv_usec; gpu_data_header[17] = TCPfillnumber; gpu_data_header[18] = GPUfillnumber; sprintf(bk_name,"BC%02i",frontend_index); bk_create(pevent, bk_name, TID_DWORD, (void**)&hdata); // TID_DWORD unsigned int of FOUR bytes memcpy( hdata, gpu_data_header, gpu_data_header_size); hdata += gpu_data_header_size / sizeof(hdata[0]); bk_close(pevent, hdata); dbprintf("%s(%d): made header databank %s size 0x%08x, header[0] 0x%08x, readout electronics fill number %d\n", __func__, __LINE__, bk_name, gpu_data_header_size, *gpu_data_header, gpu_data_header[1]); // unlocking gpu thread access to GPU output buffer pthread_mutex_unlock( &(gpu_thread_1_info.mutex) ); // fill timing info into SR databank DWORD *tr_data; sprintf(bk_name,"SR%02i",frontend_index); bk_create(pevent, bk_name, TID_DWORD, (void**)&tr_data); *tr_data++ = trigger_info.trigger_nr; // trigger number (via RPC message from master) *tr_data++ = trigger_info.trigger_mask; // trigger mask (via RPC message from master) *tr_data++ = trigger_info.time_master_got_eof_s; // master EOF trigger time (via RPC message from master), secs *tr_data++ = trigger_info.time_master_got_eof_us; // master EOF trigger time (via RPC message from master), usecs *tr_data++ = trigger_info.time_slave_got_eof_s; // slave EOF trigger time called from master via RPC message, secs *tr_data++ = trigger_info.time_slave_got_eof_us; // slave EOF trigger time called from master via RPC message, usecs // tcp_thread *tr_data++ = trigger_info.time_tcp_start_read_s; // start time of tcp read in tcp_thread, secs *tr_data++ = trigger_info.time_tcp_start_read_us; // start time of tcp read in tcp_thread, usecs *tr_data++ = trigger_info.time_tcp_finish_header_read_s; // finish time of tcp read in tcp_thread, secss *tr_data++ = trigger_info.time_tcp_finish_header_read_us; // finish time of tcp read in tcp_thread, usecs *tr_data++ = trigger_info.time_tcp_finish_data_read_s; // finish time of tcp read in tcp_thread, secs *tr_data++ = trigger_info.time_tcp_finish_data_read_us; // finish time of tcp read in tcp_thread, usecs // gpu_thread *tr_data++ = trigger_info.time_gputhread_started_s; ///< woke-up gpu_thread for processing, secs *tr_data++ = trigger_info.time_gputhread_started_us; ///< woke-up gpu_thread for processing, usecs *tr_data++ = trigger_info.time_gputhread_copytogpu_done_s; ///<woke-up gpu_thread for processing, secs *tr_data++ = trigger_info.time_gputhread_copytogpu_done_us; ///< woke-up gpu_thread for processing, usecs *tr_data++ = trigger_info.time_gputhread_finished_s; ///< gpu_thread finished processing, secs *tr_data++ = trigger_info.time_gputhread_finished_us; ///< gpu_thread finished processing, usecs // MFE_thread *tr_data++ = trigger_info.time_slave_lock_dataready_s; // slave locked waiting on data, secs *tr_data++ = trigger_info.time_slave_lock_dataready_us; // slave locked waiting on data, usecs *tr_data++ = trigger_info.time_slave_got_data_s; // slave got data fron tcp_thread and unloacked tcp_thread, secs *tr_data++ = trigger_info.time_slave_got_data_us; // slave got data fron tcp_thread and unloacked tcp_thread, usecs bk_close(pevent, tr_data); // dt1 time between start, finish of tcp_thread read() of data long int dt1_s = trigger_info.time_slave_got_data_s; dt1_s -= trigger_info.time_gputhread_finished_s; long int dt1_us = trigger_info.time_slave_got_data_us; dt1_us -= trigger_info.time_gputhread_finished_us; if ( dt1_us < 0 ) { dt1_s -= 1; dt1_us += 1000000; } // dt2 time between tcp_thread read completion and read_trigger_event unlocked long int dt2_s = trigger_info.time_slave_got_data_s; dt2_s -= trigger_info.time_tcp_finish_data_read_s; long int dt2_us = trigger_info.time_slave_got_data_us; dt2_us -= trigger_info.time_tcp_finish_data_read_us; if ( dt2_us < 0 ) { dt2_s -= 1; dt2_us += 1000000; } // dt3 total duration of readout through TCP, GPU, midas FE threads long int dt3_s = trigger_info.time_slave_got_data_s; dt3_s -= trigger_info.time_tcp_finish_header_read_s; long int dt3_us = trigger_info.time_slave_got_data_us; dt3_us -= trigger_info.time_tcp_finish_header_read_us; if ( dt3_us < 0 ) { dt3_s -= 1; dt3_us += 1000000; } //dbprintf("%s(%d): EOF master-slave propogation time: dt = %li s %li us\n", __func__, __LINE__, dt0_s, dt0_us); dbprintf("%s(%d): gpu done to MFE done duration: dt = %li s %li us\n", __func__, __LINE__, dt1_s, dt1_us); dbprintf("%s(%d): tcp got data to MFE done duration: dt = %li s %li us\n", __func__, __LINE__, dt2_s, dt2_us); dbprintf("%s(%d): tcp got header to MFE done duration: dt = %li s %li us\n", __func__, __LINE__, dt3_s, dt3_us); dbprintf("%s(%d): midas bank size: %i\n", __func__, __LINE__, bk_size(pevent)); // used for hardware debugging #ifdef USE_PARALLEL_PORT printf("read_trigger_event: write pulse to parallel port address 0x%08x\n", pp_addr); outb( 0xff, pp_addr); usleep(20); outb( 0x00, pp_addr); #endif return bk_size(pevent); }
INT ge_ln2_read(char *pevent, INT off) { static INT status, size; static DWORD lastfilled, now, timelimit; static BOOL justfilled; static DWORD *timesincefill; bk_init(pevent); timesincefill = NULL; // Get recent values size = sizeof(lastfilled); status = db_get_value(hDB, 0, sLastFilled, &lastfilled, &size, TID_DWORD, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR, "ge_ln2_read", "Error getting last filled time"); return 0; } size = sizeof(justfilled); status = db_get_value(hDB, 0, sJustFilled, &justfilled, &size, TID_BOOL, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR, "ge_ln2_read", "Error getting just filled status"); return 0; } size = sizeof(timelimit); status = db_get_value(hDB, 0, sTimeLimit, &timelimit, &size, TID_DWORD, FALSE); if (status != DB_SUCCESS) { cm_msg(MERROR, "ge_ln2_read", "Error getting time limit between fills"); return 0; } // If just filled, write time to ODB if (justfilled == TRUE) { lastfilled = (DWORD)time(NULL); status = db_set_value(hDB, 0, sLastFilled, &lastfilled, sizeof(lastfilled), 1, TID_DWORD); if (status != DB_SUCCESS) { cm_msg(MERROR, "gn_ln2_read", "Error setting last filled time"); return 0; } justfilled = FALSE; status = db_set_value(hDB, 0, sJustFilled, &justfilled, sizeof(justfilled), 1, TID_BOOL); if (status != DB_SUCCESS) { cm_msg(MERROR, "gn_ln2_read", "Error setting just filled status"); return 0; } al_reset_alarm(sAlarmName); bk_create(pevent, "LN2F", TID_DWORD, ×incefill); *timesincefill = 0; bk_close(pevent, ++timesincefill); return bk_size(pevent); } // Check the status bk_create(pevent, "LN2F", TID_DWORD, ×incefill); now = (DWORD) time(NULL); *timesincefill = now - lastfilled; if (*timesincefill > timelimit) { al_trigger_alarm(sAlarmName, "Germanium must be filled!", "Alarm", "", AT_INTERNAL); printf("Alarm!\n"); } bk_close(pevent, ++timesincefill); return bk_size(pevent); }