- Added support for EMBL PSD detectors for TRIS and AMOR.

This commit is contained in:
cvs
2001-01-24 11:03:14 +00:00
parent e64773949d
commit 96e2fc44c0
11 changed files with 1077 additions and 28 deletions

View File

@@ -87,6 +87,7 @@
** do_SQHM__HM_DIG_alloc: SQHM__HM_DIG aux routine for chk_config_alloc.
** do_SQHM__HRPT_alloc : SQHM__HRPT aux routine for chk_config_alloc.
** do_SQHM__TOF_alloc : SQHM__TOF aux routine for chk_config_alloc.
** do_SQHM__PSD_alloc : SQHM__PSD aux routine for chk_config_alloc.
** do_SQHM__TRANS_alloc : SQHM__TRANS aux routine for chk_config_alloc.
** do_command : Routine to handle a network command.
** do_daq : Action routine for SINQHM_DAQ command.
@@ -248,10 +249,8 @@
break;
/*----------------------------*/
case SQHM__HM_PSD:
printf ("\nchk_config_alloc: "
"histogramming mode SQHM__HM_PSD is not yet supported.\n");
rply_status_setup (reply, KER__BAD_VALUE, 0, "Unsupported hist mem mode");
return ERROR;
s_stat = do_SQHM__PSD_alloc (skt, request, reply);
if (s_stat != OK) return ERROR;
break;
/*----------------------------*/
case SQHM__TOF:
@@ -1167,6 +1166,489 @@
return OK;
}
/*
**--------------------------------------------------------------------------*/
int do_SQHM__PSD_alloc (
/* ==================
*/ int skt,
struct req_buff_struct *request,
struct rply_buff_struct *reply) {
/*
** Routine to allocate memory for the SQHM__PSD
** configure request.
**
** Definitions:
** Edge-Array
** An 'edge-array' is a structure which specifies the lower edge
** of each bin in the histogram. This is to allow variable width
** histogram bins.
** Counter Bank
** A 'counter bank' is a contiguous group of counters, all of
** which share the same parameters. In particular, all the counters
** in the bank have the same number of bins and same bin edges.
*/
int i, j, k, n_bytes_got;
uint n_extra_bytes, n_banks, com2, nchar;
uint first, n_cntrs, edge_indx, bytes_per_bin;
uint n_bins, flag, edge_0, edge_1, bin_span, top_edge;
uint bytes_needed, sizeof_edge_arr;
uint time_span, n_total_bins;
struct tof_edge_info *edge_info_pntr;
struct tof_edge_arr *edge_arr_pntr;
struct tof_bank *bank_pntr;
void *nxt_hist_addr;
struct req_buff_struct *my_rqst;
char *p_addr, buff[64];
Total_bytes = 0;
/*
switch debugging on by default
Dbg_lev1 = 1;
*/
/*
read additional configuration information
*/
n_extra_bytes = ntohl (request->u.cnfg.u.psd.n_extra_bytes); /* The # of
** extra bytes needed to be read from
** the client to complete the configure
** request.
*/
if (n_extra_bytes == 0) {
my_rqst = request;
}else {
/*
** There is extra data to be read. Get buffer space for the
** extra stuff plus space to copy over what has already been
** read so that everything is in a contiguous buffer.
*/
bytes_needed = n_extra_bytes + sizeof (*request);
bytes_needed = (bytes_needed + 3) & (~3); /* Round up to multiple of 4 */
p_addr = calloc (bytes_needed, sizeof (char));
if (p_addr == NULL) {
printf ("\007do_SQHM__PSD_alloc:\n"
" cannot allocate memory for extra config data!\n");
net_flush (skt, n_extra_bytes);
rply_status_setup (reply, KER__BAD_ALLOC, 0,
"Failed to get buffer for extra config data");
return ERROR;
}
memcpy (p_addr, request, sizeof (*request)); /* Copy in what has already
** been read.
*/
my_rqst = (struct req_buff_struct *) p_addr;
bytes_needed = n_extra_bytes; /* And read the rest */
p_addr = p_addr + sizeof (*request);
while (bytes_needed > 0) {
n_bytes_got = recv (skt, p_addr, bytes_needed, 0);
if (n_bytes_got <= 0) break;
Rw_bytes_got += n_bytes_got;
bytes_needed -= n_bytes_got;
p_addr += n_bytes_got;
}
if (n_bytes_got < 0) {
printf ("\007"
"%s -- R/W-Socket recv error\n", Tsk_name[0]);
printf ("%s -- Connection will be closed.\n", Tsk_name[0]);
rply_status_setup (reply, KER__BAD_VALUE, 0, "recv failed");
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
}
printf ("\n Histogramming mode is \"SQHM__PSD\"\n");
/*
decode general configuration information
*/
if (Hm_mode_UD != 0)
printf (" Up/Down mode selected\n");
if (Hm_mode_STROBO != 0)
printf (" Stroboscopic mode selected\n");
printf (" Bin-overflow action is ");
switch (Hm_mode_BO) {
case SQHM__BO_IGN: printf ("\"Ignore\"\n"); break;
case SQHM__BO_SMAX: printf ("\"Stop-at-Max\"\n"); break;
case SQHM__BO_CNT: printf ("\"Count\"\n"); break;
default: printf ("\"Undefined\"\n");
}
N_tof_edges = ntohs (my_rqst->u.cnfg.u.psd.n_edges); /* The # of
** different 'edge-arrays' which are
** to be defined.
*/
printf (" Number of Edge Arrays = %2d\n", N_tof_edges);
if (N_tof_edges > MAX_TOF_EDGE) {
printf ("do_SQHM__PSD_alloc: Illegal number of edge-arrays: %u.\n",
N_tof_edges);
rply_status_setup (reply, KER__BAD_VALUE, 0, "Too many edge-arrays");
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
n_banks = ntohs (my_rqst->u.cnfg.u.psd.n_banks); /* The # of
** 'banks' of counters which are
** to be defined.
*/
printf (" Number of Counter Banks = %2d\n", n_banks);
if (n_banks == 0) {
rply_status_setup (reply, KER__BAD_VALUE, 0, "Illegal n_banks");
printf ("do_SQHM__PSD_alloc: Illegal number of banks: %u.\n",
n_banks);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
psdXOffset = ntohs(my_rqst->u.cnfg.u.psd.xOffset);
psdXFactor = ntohs(my_rqst->u.cnfg.u.psd.xFactor);
printf("\tX-Offset = %4d, X-Factor = %4d\n",
psdXOffset, psdXFactor);
psdYOffset = ntohs(my_rqst->u.cnfg.u.psd.yOffset);
psdYFactor = ntohs(my_rqst->u.cnfg.u.psd.yFactor);
printf("\tY-Offset = %4d, Y-Factor = %4d\n",
psdYOffset, psdYFactor);
psdFlashCount = 0;
psdHitCount = 0;
psdXSize = ntohs(my_rqst->u.cnfg.u.psd.xSize);
psdYSize = ntohs(my_rqst->u.cnfg.u.psd.ySize);
printf("\txSize = %4d, ySize = %4d\n",
psdXSize, psdYSize);
Tof_dts_soll = ntohl (my_rqst->u.cnfg.u.psd.preset_delay); /* The
** required "Delay-Time-to-Start" */
if ((Tof_dts_soll & (~LWL_TSI_DTS_MSK)) != 0) {
rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad Delay-Time-to-Start");
printf ("do_SQHM__PSD_alloc: Delay-Time-to-Start illegal: 0x%x\n",
Tof_dts_soll);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
/*
send DTS to MDI through COM2 port. But only if we have more then one
time channel. Else we are operating in non-TOF mode.
*/
if(N_tof_edges > 1) {
com2 = open ("/tyCo/1", O_RDWR, 0);
if (com2 == ERROR) {
rply_status_setup (reply, KER__BAD_VALUE, 0, "COM2 open failed");
printf ("do_SQHM__PSD_alloc: error opening COM2 port. "
"Delay-Time-to-Start not set.\n");
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}else {
ioctl (com2, FIOBAUDRATE, 9600);
write (com2, "\r", 1);
write (com2, "RMT 1\r", 6);
nchar = sprintf (buff, "DT %d\r", Tof_dts_soll);
if (write (com2, buff, nchar) != nchar) {
rply_status_setup (reply, KER__BAD_VALUE, 0,
"Setting D-T-to-S failed");
printf ("do_SQHM__PSD_alloc: error setting Delay-Time-to-Start.\n");
if (n_extra_bytes != 0) free (my_rqst);
close (com2);
return ERROR;
}else {
printf (" Delay-Time-to-Start = %d\n", Tof_dts_soll);
}
close (com2);
}
}
/*
** Loop over all the edge arrays
*/
edge_arr_pntr = &my_rqst->u.cnfg.u.psd.edge_0;
for (i = 0; i < N_tof_edges; i++) {
n_bins = ntohl (edge_arr_pntr->n_bins);
flag = ntohl (edge_arr_pntr->flag);
edge_0 = ntohl (edge_arr_pntr->edges[0]);
edge_1 = ntohl (edge_arr_pntr->edges[1]);
printf (" Edge Array %d:\n", i);
printf (" Number of bins = %5d\n", n_bins);
printf (" Flag = %5d\n", flag);
printf (" Lower edge = %5d\n", edge_0);
if ((n_bins == 0) || (n_bins > MAX_TOF_NBINS)) {
printf ("do_SQHM__PSD_alloc: Illegal # bins: %u.\n",
n_bins);
rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad number of bins");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
if ((edge_0 & (~LWL_HDR_TS_MASK)) != 0) {
printf ("do_SQHM__PSD_alloc: histog start is > 20 bits: %u\n",
edge_0);
rply_status_setup (reply, KER__BAD_VALUE, 0,
"Bin edges overflow 20 bits");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
if ((edge_1 & (~LWL_HDR_TS_MASK)) != 0) {
printf ("do_SQHM__PSD_alloc: first bin is > 20 bits: %u\n",
edge_1);
rply_status_setup (reply, KER__BAD_VALUE, 0,
"First bin overflows 20 bits");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
bytes_needed = OffsetOf (struct tof_edge_info, edges) +
((n_bins + 1) * sizeof (int));
Tof_edges[i] = calloc (bytes_needed, sizeof (char)); /* Allocate space for
** edge-array structure */
if (Tof_edges[i] == NULL) {
printf ("do_SQHM__PSD_alloc: unable to alloc memory for edge array.\n");
rply_status_setup (reply, KER__BAD_ALLOC, 0,
"Failed to get memory for edge-array");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
Tof_edges[i]->n_bins = n_bins;
Tof_edges[i]->flag = flag;
if ((flag & FLAG__VAR_BIN) == 0) { /* Fixed width bins? */
printf (" Bin width = %5d\n", (edge_1 - edge_0));
if (edge_0 >= edge_1) { /* Yes. Check bin width */
printf ("do_SQHM__PSD_alloc: bin width is zero or negative!\n");
rply_status_setup (reply, KER__BAD_VALUE, 0, "illegal bin width");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
bin_span = edge_1 - edge_0;
Tof_edges[i]->bin_span = bin_span;
top_edge = edge_0 + (n_bins * bin_span) - 1;
if ((top_edge & (~LWL_HDR_TS_MASK)) != 0) {
printf ("do_SQHM__PSD_alloc: histog last bin is > 20 bits: %u\n",
top_edge);
rply_status_setup (reply, KER__BAD_VALUE, 0,
"Last bin overflows 20 bits");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
for (j=0; j <= n_bins; j++) Tof_edges[i]->edges[j] = edge_0+j*bin_span;
Tof_edges[i]->hi_edge = top_edge;
sizeof_edge_arr = OffsetOf (struct tof_edge_arr, edges) +
2 * sizeof (uint);
}else {
/* Variable width bins */
bin_span = edge_1 - edge_0; /* Note: even though the edges are
** defined as variable, they may, in
** fact, all be the same width. Check
** for this so that we can make a brief
** report rather than listing all
** the bin edges.
*/
Tof_edges[i]->bin_span = 0;
Tof_edges[i]->edges[0] = edge_0;
for (j = 1; j <= n_bins; j++) {
Tof_edges[i]->edges[j] = ntohl (edge_arr_pntr->edges[j]);
if ((Tof_edges[i]->edges[j] & (~LWL_HDR_TS_MASK)) != 0) {
printf ("do_SQHM__PSD_alloc: histog bin is > 20 bits: %d %u\n",
j, Tof_edges[i]->edges[j]);
rply_status_setup (reply, KER__BAD_VALUE, 0,
"Bin edge overflows 20 bits");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
if (Tof_edges[i]->edges[j-1] >= Tof_edges[i]->edges[j]) {
printf ("do_SQHM__PSD_alloc: bin edges are not in sequence: %d %d\n",
i, j);
rply_status_setup (reply, KER__BAD_VALUE, 0,
"Bin edges not in sequence");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
if ((Tof_edges[i]->edges[j] - Tof_edges[i]->edges[j-1]) != bin_span)
bin_span = 0; /* Set bin_span to zero if bin widths really are
** variable */
}
if (bin_span != 0) {
printf (" Variable width bins but width of all bins = %d\n",
bin_span);
}else {
printf (" Variable width bins. Upper bin edges are:\n");
for (j = 1; j <= n_bins; j += 10) {
for (k = 0; ((k + j) <= n_bins) && (k < 10); k++)
printf ("%7d", Tof_edges[i]->edges[j+k]);
printf ("\n");
}
}
Tof_edges[i]->hi_edge = Tof_edges[i]->edges[n_bins] - 1;
sizeof_edge_arr = OffsetOf (struct tof_edge_arr, edges) +
((n_bins + 1) * sizeof (uint));
}
edge_arr_pntr = (struct tof_edge_arr *) ( /* Move to next edge array */
(char *) edge_arr_pntr + sizeof_edge_arr);
}
/*
** Loop over all the counter banks
*/
bank_pntr = (struct tof_bank *) edge_arr_pntr;
for (i = 0; i < n_banks; i++) {
first = ntohs (bank_pntr->first);
n_cntrs = psdXSize*psdYSize;
edge_indx = ntohs (bank_pntr->edge_indx);
bytes_per_bin = ntohs (bank_pntr->bytes_per_bin);
Bytes_per_bin = bytes_per_bin; /* update global var */
printf (" Counter Bank %d:\n", i);
printf (" Number of counters = %5d\n", n_cntrs);
printf (" First counter = %5d\n", first);
if (N_tof_edges > 1) {
printf (" Edge array #%d\n", edge_indx);
}
printf (" Bytes per bin = %5d\n", bytes_per_bin);
if (first >= MAX_PSD_CNTR) {
printf ("do_SQHM__PSD_alloc: Illegal first counter number: %u.\n",
first);
rply_status_setup (reply, KER__BAD_VALUE, 0,
"Bad first counter number");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
if ((n_cntrs == 0) || ((first+n_cntrs) > MAX_PSD_CNTR)) {
printf ("do_SQHM__PSD_alloc: Illegal # counters: %u %u.\n",
first, n_cntrs);
rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad # counters");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
if (edge_indx >= N_tof_edges) {
printf ("do_SQHM__PSD_alloc: Illegal edge index: %u.\n",
edge_indx);
rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad edge-array index");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
edge_info_pntr = Tof_edges[edge_indx];
n_bins = edge_info_pntr->n_bins;
flag = edge_info_pntr->flag;
if (bytes_per_bin == 0) bytes_per_bin = 4;
if ((bytes_per_bin != 1) &&
(bytes_per_bin != 2) &&
(bytes_per_bin != 4)) {
printf ("do_SQHM__PSD_alloc: Illegal bytes per bin: %d.\n",
bytes_per_bin);
rply_status_setup (reply, KER__BAD_VALUE, 0, "Bad bytes-per-bin");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
Total_bytes += (n_cntrs * n_bins * bytes_per_bin);
if (Hm_mode_UD != 0) Total_bytes += (n_cntrs * n_bins * bytes_per_bin);
/* This is useful,but a waste of memory for a PSD. It would need
2.6MB. Let us try if we can live without it.
for (j = first; j < (first + n_cntrs); j++) {
if (Tof_descr[j] != NULL) {
printf ("do_SQHM__PSD_alloc: Doubly defined counter: %d.\n",
(j));
rply_status_setup (reply, KER__BAD_VALUE, 0, "Doubly defined counter");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
Tof_descr[j] = calloc (1, sizeof (struct tof_histog));
if (Tof_descr[j] == NULL) {
printf ("do_SQHM__PSD_alloc: unable to alloc memory for "
"histogram structure.\n");
rply_status_setup (reply, KER__BAD_ALLOC, 0,
"Failed to get buffer for Tof_descr structure");
free_HM_memory (NULL);
if (n_extra_bytes != 0) free (my_rqst);
return ERROR;
}
Tof_descr[j]->cntr_nmbr = first + j;
Tof_descr[j]->lo_edge = edge_info_pntr->edges[0];
Tof_descr[j]->hi_edge = edge_info_pntr->hi_edge;
Tof_descr[j]->flag = flag;
Tof_descr[j]->bytes_per_bin = bytes_per_bin;
Tof_descr[j]->n_bins = n_bins;
Tof_descr[j]->cnt_early_up = 0;
Tof_descr[j]->cnt_late_up = 0;
Tof_descr[j]->cnt_early_down = 0;
Tof_descr[j]->cnt_late_down = 0;
Tof_descr[j]->bin_edge = edge_info_pntr->edges;
Tof_descr[j]->u.b_bin_data = NULL;
}
*/
if (i == 0) { /* Use the first counter bank to define some .. */
N_hists = n_cntrs; /* .. globals since we expect there usually to .. */
/* .. be only 1 counter bank. */
N_bins = n_bins;
Lo_cntr = first;
Lo_bin = edge_info_pntr->edges[0];
Hi_bin = edge_info_pntr->hi_edge;
Compress = ((flag & FLAG__VAR_BIN) == 0) ?
edge_info_pntr->edges[1] - edge_info_pntr->edges[0] :
0;
Bytes_per_bin = bytes_per_bin;
Cnts_lo = Cnts_hi = 0;
}
bank_pntr++; /* Move to next counter bank */
}
if (n_extra_bytes != 0) free (my_rqst);
i = memFindMax (); /* Get size of biggest free memory block */
if (i > Total_bytes) {
Hist_base_addr = calloc (Total_bytes, sizeof (char));
}else {
Hist_base_addr = NULL;
}
if (Hist_base_addr == NULL) {
printf ("\007do_SQHM__PSD_alloc:\n"
" Unable to reserve %d bytes of memory!\n"
" Largest block available = %d.\n", Total_bytes, i);
rply_status_setup (reply, KER__BAD_ALLOC, i,
"Failed to get buffer for histograms");
reply->sub_status = htonl (i);
return ERROR;
}
/* as wee decided not to use Tof_descr, this is surplus as well.
nxt_hist_addr = Hist_base_addr;
for (i = 0; i < MAX_PSD_CNTR; i++) {
if (Tof_descr[i] != NULL) {
Tof_descr[i]->u.b_bin_data = nxt_hist_addr;
j = Tof_descr[i]->n_bins * Tof_descr[i]->bytes_per_bin;
if (Hm_mode_UD != 0) j = j * 2;
nxt_hist_addr += j;
}
}
*/
Cnts_lo = Cnts_hi = 0;
N_events = N_skipped = N_no_coin_tsi = N_coin_tsi = 0;
Print_hdr = True;
printf (" Histogram base address = 0x%08x\n", Hist_base_addr);
printf (" SQHM__PSD mode configured.\n");
return OK;
}
/*
**--------------------------------------------------------------------------*/
int do_command (
/* ==========
@@ -2489,6 +2971,12 @@
lwl_Fifo_Flush (); /* Ensure the fibre-optic FIFO is empty */
/*
clear PSD counts
*/
psdHitCount = 0;
psdFlashCount = 0;
if (my_daq_save == 0) {
do_daq (&dummy_rply, index, DAQ__CLR); /* Remove our inhibit on Filler */
}
@@ -3014,6 +3502,61 @@
Num_bad_events = lwl_data.ui4;
}
/*
**--------------------------------------------------------------------------*/
void process_psd_tsi (
/* =================
*/ uint hdr) {
/* Routine to process a PSD Timing-Status-Info
** Packet. These packets have 10 bytes altogether. The first
** 4 bytes are in hdr.
*/
int i, j, is;
register union {
uint ui4;
usint ui2[2];
uchar ui1[4];
} lwl_data;
usint words[3];
for (j=0; j<3; j++) { /* Get the remaining 6 bytes */
for (i=0; i<1000; i++) {
lwl_data.ui4 = *Lwl_fifo; /* Get the last 16 bits */
if (lwl_data.ui4 != LWL_FIFO_EMPTY) break;
taskDelay (0); /* But wait if FIFO is slow! */
}
if (lwl_data.ui4 == LWL_FIFO_EMPTY) {
printf ("Time-out getting last 6 bytes of a PSD "
"TSI packet!\n");
return;
}
words[j] = lwl_data.ui2[1];
}
N_coin_tsi++;
Dt_or_dts.both = hdr & LWL_TSI_DT_MSK;
Nrl_active = ((hdr & LWL_HDR_NRL_MASK) != 0) ? True : False;
Daq_active = ((hdr & Lwl_hdr_daq_mask) == Lwl_hdr_daq_soll) ? True : False;
Tsi_status_info = words[0];
Tsi_flags = (Nrl_active) ? STATUS_FLAGS__NRL : 0;
if ((hdr & LWL_PSD_PWF) != 0) Tsi_flags |= STATUS_FLAGS__PF;
if ((hdr & LWL_HDR_SWC_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SWC;
if (Daq_active) Tsi_flags |= STATUS_FLAGS__DAQ;
if ((hdr & LWL_HDR_SYNC0_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC0;
if ((hdr & LWL_HDR_SYNC1_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC1;
if ((hdr & LWL_HDR_SYNC2_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC2;
if ((hdr & LWL_HDR_SYNC3_MASK) != 0) Tsi_flags |= STATUS_FLAGS__SYNC3;
/*
if ((hdr & LWL_HDR_UD_MASK) != 0) Tsi_flags |= STATUS_FLAGS__UD;
if ((hdr & LWL_HDR_GU_MASK) != 0) Tsi_flags |= STATUS_FLAGS__GU;
*/
psdHitCount += words[1];
psdFlashCount += words[2] & LWL_PSD_FLASH_MASK;
}
/*
**--------------------------------------------------------------------------*/
void process_no_coinc_tsi (
/* ====================