From 96e2fc44c0739318a8d4d2c762adeff60108029d Mon Sep 17 00:00:00 2001 From: cvs Date: Wed, 24 Jan 2001 11:03:14 +0000 Subject: [PATCH] - Added support for EMBL PSD detectors for TRIS and AMOR. --- sinqhm/Makefile | 2 +- sinqhm/SinqHM_bootParamsConfig.c | 77 ++++- sinqhm/SinqHM_def.h | 22 ++ sinqhm/SinqHM_gbl.h | 20 ++ sinqhm/SinqHM_srv_filler.c | 208 +++++++++++- sinqhm/SinqHM_srv_main.c | 6 +- sinqhm/SinqHM_srv_routines.c | 551 ++++++++++++++++++++++++++++++- sinqhm/bld | 4 +- sinqhm/hist_mem_spec.tex | 76 ++++- sinqhm/lwl_client.c | 4 +- sinqhm/sinqhm_ctrl.c | 135 +++++++- 11 files changed, 1077 insertions(+), 28 deletions(-) diff --git a/sinqhm/Makefile b/sinqhm/Makefile index 55ef34bf..ddb3e470 100644 --- a/sinqhm/Makefile +++ b/sinqhm/Makefile @@ -13,7 +13,7 @@ FF = f90 CC = cc CFLAGS = -std -g -I. -I../hardsup -I$(PGPLOT_DIR) -I/data/koenneck/include -BIN = $(HOME)/bin +BIN = ../bin LFLAGS = -L../hardsup -L$PGPLOT_DIR #------------ for Linux ## FF = g77 diff --git a/sinqhm/SinqHM_bootParamsConfig.c b/sinqhm/SinqHM_bootParamsConfig.c index 723a413f..a99667b2 100755 --- a/sinqhm/SinqHM_bootParamsConfig.c +++ b/sinqhm/SinqHM_bootParamsConfig.c @@ -232,8 +232,8 @@ int i, port, sub_mode; int nbins, nhists, ncntrs, bytes_per_bin, compress; int lo_bin, lo_cntr, span, delay, status, my_errno; + int xSize, xOff, xFac, ySize, yOff, yFac; int hm_mode, nbuffs, nbytes; - char *arg4_txt; int bytes_to_come, skt; char *nxt_byte; @@ -361,11 +361,47 @@ printf (" First bin = %d\n", lo_bin); if ((hm_mode & SQHM__REFLECT) != 0) printf (" Histogram reflection requested\n"); - }else if (mode == SQHM__HM_PSD) { - /* SQHM__HM_PSD still needs to be programmed */ - printf (" Histogramming mode = SQHM__HM_PSD\n"); - printf (" Not yet supported!\n"); - return False; + }else if (mode == SQHM__HM_PSD) { /* xSize*/ + if ((sscanf (p_arg1, "%i", &xSize) != 1) || (xSize <= 0)) { + sprintf (errmsg, "The value for <#-xSize>, \"%s\", is illegal!\n" + "It must be a positive integer.", p_arg1); + sbpc_showHelp (errmsg); + return False; + } /* xOff*/ + if ((sscanf (p_arg2, "%i", &xOff) != 1) || (xOff <= 0)) { + sprintf (errmsg, "The value for <#-xOff>, \"%s\", is illegal!\n" + "It must be a positive integer.", p_arg1); + sbpc_showHelp (errmsg); + return False; + } /* xFac */ + if ((sscanf (p_arg3, "%i", &xFac) != 1) || (xFac <= 0)) { + sprintf (errmsg, "The value for <#-xFac>, \"%s\", is illegal!\n" + "It must be a positive integer.", p_arg1); + sbpc_showHelp (errmsg); + return False; + } + /* ySize */ + if ((sscanf (p_arg4, "%i", &ySize) != 1) || (ySize <= 0)) { + sprintf (errmsg, "The value for <#-ySize>, \"%s\", is illegal!\n" + "It must be a positive integer.", p_arg1); + sbpc_showHelp (errmsg); + return False; + } /* yOff*/ + if ((sscanf (p_arg5, "%i", &yOff) != 1) || (yOff <= 0)) { + sprintf (errmsg, "The value for <#-yOff>, \"%s\", is illegal!\n" + "It must be a positive integer.", p_arg1); + sbpc_showHelp (errmsg); + return False; + } /* yFac */ + if ((sscanf (p_arg6, "%i", &yFac) != 1) || (yFac <= 0)) { + sprintf (errmsg, "The value for <#-yFac>, \"%s\", is illegal!\n" + "It must be a positive integer.", p_arg1); + sbpc_showHelp (errmsg); + return False; + } + printf("\tHistogramming Mode = SINQHM_PSD\n"); + printf("\txSize, xOff, yFac = %5d, %5d, %5d\n",xSize, xOff, xFac); + printf("\tySize, yOff, yFac = %5d, %5d, %5d\n",ySize, yOff, yFac); }else if (mode == SQHM__TOF) { /*---------- <#-cntrs> */ if (p_arg1 == NULL) { @@ -501,11 +537,29 @@ req_buff.u.cnfg.u.hm_dig.bytes_per_bin = htonl (bytes_per_bin); req_buff.u.cnfg.u.hm_dig.compress = htonl (compress); }else if (mode == SQHM__HM_PSD) { - req_buff.u.cnfg.u.hm_dig.n_hists = htonl (1); - req_buff.u.cnfg.u.hm_dig.lo_bin = htonl (0); - req_buff.u.cnfg.u.hm_dig.num_bins = htonl (1024); - req_buff.u.cnfg.u.hm_dig.bytes_per_bin = htonl (4); - req_buff.u.cnfg.u.hm_dig.compress = htonl (0); + req_buff.u.cnfg.u.psd.n_extra_bytes = htonl (0); + req_buff.u.cnfg.u.psd.n_edges = htons (1); + req_buff.u.cnfg.u.psd.n_banks = htons (1); + req_buff.u.cnfg.u.psd.xOffset = htonl (xOff); + req_buff.u.cnfg.u.psd.yOffset = htonl (yOff); + req_buff.u.cnfg.u.psd.xFactor = htonl (xFac); + req_buff.u.cnfg.u.psd.yFactor = htonl (yFac); + req_buff.u.cnfg.u.psd.xSize = htons (xSize); + req_buff.u.cnfg.u.psd.ySize = htons (ySize); + + + req_buff.u.cnfg.u.psd.edge_0.n_bins = htonl (1); + req_buff.u.cnfg.u.psd.edge_0.flag = htonl (0); /* Fixed bin span */ + + req_buff.u.cnfg.u.psd.edge_0.edges[0] = htonl (0); + req_buff.u.cnfg.u.psd.edge_0.edges[1] = htonl (10000); + req_buff.u.cnfg.u.psd.preset_delay = htonl (0); + + req_buff.u.cnfg.u.psd.bank_0.first = htons (0); + req_buff.u.cnfg.u.psd.bank_0.n_cntrs = htons (xSize*ySize); + req_buff.u.cnfg.u.psd.bank_0.edge_indx = htons (0); + req_buff.u.cnfg.u.psd.bank_0.bytes_per_bin = htons (4); + }else if (mode == SQHM__TOF) { req_buff.u.cnfg.u.tof.n_extra_bytes = htonl (0); req_buff.u.cnfg.u.tof.n_edges = htons (1); @@ -591,6 +645,7 @@ ** .. SinqHM_srv to do its printing. */ printf ("\nSinqHM_srv has been configured.\n"); + return 1; } /* **--------------------------------------------------------------------------*/ diff --git a/sinqhm/SinqHM_def.h b/sinqhm/SinqHM_def.h index 168d0514..b1dfaa72 100755 --- a/sinqhm/SinqHM_def.h +++ b/sinqhm/SinqHM_def.h @@ -23,6 +23,7 @@ #define MAX_CLIENTS 8 /* The maximum number of active clients */ #define MAX_TOF_CNTR 1024 /* The maximum number of individual counters .. ** which can be handled in TOF mode */ +#define MAX_PSD_CNTR 65536 /* maximum number of PSD elements */ #define MAX_TOF_NBINS 32768 /* The maximum number of bins in a TOF histog */ #define MAX_TOF_EDGE 16 /* The maximum number of TOF edge arrays */ #define VMIO_BASE_ADDR 0x1900 /* VME address of a (possible) VMIO10 module */ @@ -212,6 +213,13 @@ #define LWL_TOF_C8 (0x08000000) /* TOF-Mode 8 chan dgrm hdr */ #define LWL_TOF_C9 (0x09000000) /* TOF-Mode 9 chan dgrm hdr */ +#define LWL_PSD_TSI 0x0E000000 /* PSD-Mode TSI datagram */ +#define LWL_PSD_DATA 0x13000000 /* PSD-mode data datagram */ +#define LWL_PSD_PWF 0x20000000 /* PSD-mode Power Fail bit */ +#define LWL_PSD_TIME 0x000fffff /* PSD-mode time stamp extraction + mask */ +#define LWL_PSD_FLASH_MASK 0x00ff /* mask for flash count + #define LWL_SM_NC (0x10000000) /* Strobo-Mode/No-Coinc 0 chan dgrm hdr */ #define LWL_SM_NC_C1 (0x11000000) /* Strobo-Mode/No-Coinc 1 chan dgrm hdr */ #define LWL_SM_NC_C2 (0x12000000) /* Strobo-Mode/No-Coinc 2 chan dgrm hdr */ @@ -332,6 +340,20 @@ struct tof_edge_arr edge_0; struct tof_bank bank_0; } tof; + struct { + uint n_extra_bytes; + usint n_edges; + usint n_banks; + uint preset_delay; + usint xFactor; + usint yFactor; + usint xOffset; + usint yOffset; + usint xSize; + usint ySize; + struct tof_edge_arr edge_0; + struct tof_bank bank_0; + } psd; } u; } cnfg; diff --git a/sinqhm/SinqHM_gbl.h b/sinqhm/SinqHM_gbl.h index 9e53d9f9..130a452b 100755 --- a/sinqhm/SinqHM_gbl.h +++ b/sinqhm/SinqHM_gbl.h @@ -172,6 +172,20 @@ uchar Vmio_Dummy[64]; /* Dummy VMIO10 addr space, in case absent */ jmp_buf Vmio_trap_env; +/*========================================================================== + Special variables for decoding PSD data: The PSD detector position is + calculated as: coord = TXPOS*calibfactor + caliboffset. Thus we need two + factors for each direction. In addition we need to keep track of flashes + and hits on the detector for diagnostic reasons. + ---------------------------------------------------------------------------*/ + int psdXOffset; + int psdYOffset; + int psdXFactor; + int psdYFactor; + int psdFlashCount; + int psdHitCount; + int psdXSize; + int psdYSize; /*========================== Define the function prototypes ================*/ void catch_int_signal ( @@ -228,6 +242,10 @@ int skt, struct req_buff_struct *request, struct rply_buff_struct *reply); + int do_SQHM__PSD_alloc ( + int skt, + struct req_buff_struct *request, + struct rply_buff_struct *reply); int do_SQHM__TRANS_alloc ( struct req_buff_struct *request, struct rply_buff_struct *reply); @@ -273,6 +291,8 @@ int nbytes); void process_coinc_tsi ( uint hdr); + void process_psd_tsi ( + uint hdr); void process_no_coinc_tsi ( uint hdr); int rply_status_send ( diff --git a/sinqhm/SinqHM_srv_filler.c b/sinqhm/SinqHM_srv_filler.c index ac3358ab..8a9caf54 100755 --- a/sinqhm/SinqHM_srv_filler.c +++ b/sinqhm/SinqHM_srv_filler.c @@ -84,6 +84,10 @@ ** performing data acquisition in ** SQHM__TOF mode, i.e. for data from ** time-of-flight detectors. +** SinqHM_filler_daq_psd - routine called by SinqHM_filler_daq for +** performing data acquisition in +** SQHM__HM_PSD mode, i.e. for data from +** EMBL detectors. ** ** SinqHM_filler_daq - routine called by SinqHM_filler for ** performing data acquisition. @@ -511,7 +515,7 @@ ** .. a message waiting for us. Return to process it. */ } -/* +/* **----------------------------------------------------------------------------- */ void SinqHM_filler_daq_tof () { @@ -692,6 +696,207 @@ if ((Tsi_flags & STATUS_FLAGS__UD) != 0) printf (" UD"); if ((Tsi_flags & STATUS_FLAGS__GU) != 0) printf (" GU"); + is = timer_settime (FillTimerId, ~TIMER_ABSTIME, &FillerTime, NULL); + if (is != 0) { + printf ("%s -- failed to set timer\n", Filler_name); + } + } + } + /* Our flag has been set. There should be .. + ** .. a message waiting for us. Return to process it. + */ + } +/* +**----------------------------------------------------------------------------- +*/ + void SinqHM_filler_daq_psd () { +/* ===================== +** Routine to handle Time-of-flight Mode +** Note: +** Lwl_fifo could, in principle, be accessed via a register for better +** efficiency. However, this can cause trouble with the GDB debugger +** when single stepping. I think this is probably connected with +** instruction pipe-lining. +** For the time being, the register copy of Lwl_fifo will NOT be used. +*/ + register uint *my_lwl_fifo; + register union { + uint ui4; + usint ui2[2]; + uchar ui1[4]; + } lwl_hdr, xData, yData; + + int xPos, yPos, iTime, dataPos; + int i, j, is, ts, left, right, middl, not_finished; + uint *edge_pntr; + char er_eol[] = {ESC, '[', '0', 'J'}; /* Erase to End-of-Line */ + uchar my_buff[32]; + uint *histlPtr = (uint *)Hist_base_addr; + usint *histsPtr = (usint *)Hist_base_addr; + uchar *histcPtr = (uchar *)Hist_base_addr; + + /*----------------------------------------------- + ** Make register copies of some items for speed. + */ + my_lwl_fifo = Lwl_fifo; + /*-----------------------------------------------*/ + while (Filler_flag == 0) { /* Loop till flag gets set */ + + lwl_hdr.ui4 = *Lwl_fifo; /* Read a header from the FIFO */ + + if (lwl_hdr.ui4 == LWL_FIFO_EMPTY) { + taskDelay (0); /* If FIFO is empty, we can take a breather! */ + + }else if ( (lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_PSD_DATA) { + /* + we have located a PSD data packet. Let us read the xPos and + yPos packes. + */ + VmioBase[VMIO_PORT_A] = 0xff; /* Set timer level (if present) */ + + for (i=0; i<1000; i++) { + xData.ui4 = *Lwl_fifo; /* Get the x Position */ + if (xData.ui4 != LWL_FIFO_EMPTY) break; + taskDelay (0); /* But wait if FIFO is slow! */ + } + if (xData.ui4 == LWL_FIFO_EMPTY) { + printf ("Time-out getting X position !\n"); + continue; + } + + for (i=0; i<1000; i++) { + yData.ui4 = *Lwl_fifo; /* Get the y Position */ + if (yData.ui4 != LWL_FIFO_EMPTY) break; + taskDelay (0); /* But wait if FIFO is slow! */ + } + if (yData.ui4 == LWL_FIFO_EMPTY) { + printf ("Time-out getting Y position!\n"); + continue; + } + + /* + check if data aquisition is active + */ + if ((lwl_hdr.ui4 & Lwl_hdr_daq_mask) != Lwl_hdr_daq_soll) { + /* Some header bits are not what they should be (e.g. NRL + ** ow PWF may be set) so skip the event. + */ + N_skipped++; + if (Dbg_lev1) { + printf("Skipped header: 0x%08x\n" + " Mask: 0x%08x\n" + " Soll: 0x%08x\n", + lwl_hdr.ui4, Lwl_hdr_daq_mask, Lwl_hdr_daq_soll); + } + continue; + } + /* + We have a valid PSD packet. Find and check positions. + */ + xPos = (xData.ui2[1] - psdXOffset)/psdXFactor; + yPos = (yData.ui2[1] - psdYOffset)/psdYFactor; + if(xPos < 0 || xPos > psdXSize) + { + printf("X position out of range: %d, alllowed 0 - %d\n", + xPos, psdXSize); + continue; + } + if(yPos < 0 || yPos > psdYSize) + { + printf("Y position out of range: %d, alllowed 0 - %d\n", + yPos, psdYSize); + continue; + } + + /* + Extract time stamp and match to the appropriate time bin. + */ + iTime = lwl_hdr.ui4 & LWL_PSD_TIME; + if(Dbg_lev1){ + printf("Received detector hit at x,y, time: %d, %d, %d\n", + xPos, yPos, iTime); + } + + edge_pntr = Tof_edges[0]->edges; + left = 0; + right = Tof_edges[0]->n_bins; + middl = (left + right)/2; + not_finished = True; + iTime -= Tof_dts_soll; + while (not_finished) { + switch (right - left) { + case 0: + not_finished = False; + break; + case 1: + middl = (iTime >= edge_pntr[right]) ? right : left; + not_finished = False; + break; + default: + middl = (left + right)/2; + if (iTime == edge_pntr[middl]) { + not_finished = False; + }else if (iTime > edge_pntr[middl]) { + left = middl; + }else { + right = middl; + } + } + } + if(Dbg_lev1){ + printf("Matched time stamp %d into bin %d\n", iTime,middl); + } + + /* + calculate histogram position to update + */ + dataPos = yPos*psdXSize*Tof_edges[0]->n_bins + + xPos*Tof_edges[0]->n_bins + middl; + switch(Bytes_per_bin) + { + case 1: + histcPtr[dataPos]++; + break; + case 2: + histsPtr[dataPos]++; + break; + case 4: + histlPtr[dataPos]++; + break; + } + + VmioBase[VMIO_PORT_A] = 0x00; /* Reset timer level (if present) */ + N_events++; + }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_PSD_TSI) { + /* + we have located a PSD style TSI telegram + */ + process_psd_tsi(lwl_hdr.ui4); + }else { + /* Anything else gets flushed */ + lwl_Packet_Read (lwl_hdr.ui4, my_buff); + } + + if (FillTimer_expired) { + if (Print_hdr) printf ("\nTaking data in PSD Mode\n" + " #-Events #-Skip #-TSI #-Hits %s", + "#-Flash Delay-Time Sync-Status\n"); + Print_hdr = False; + FillTimer_expired = False; + printf ("\r%10u %10u %10u %10u %10u %10u %s", N_events, N_skipped, + (N_no_coin_tsi + N_coin_tsi), psdHitCount, + psdFlashCount, Dt_or_dts.dts, er_eol); + if (Daq_active) printf (" DAQ"); + if ((Tsi_flags & STATUS_FLAGS__PF) != 0) printf (" PF"); + if ((Tsi_flags & STATUS_FLAGS__SWC) != 0) printf (" SWC"); + if (Nrl_active) printf (" NRL"); + if ((Tsi_flags & STATUS_FLAGS__SYNC3) != 0) printf (" SYNC3"); + if ((Tsi_flags & STATUS_FLAGS__SYNC2) != 0) printf (" SYNC2"); + if ((Tsi_flags & STATUS_FLAGS__SYNC1) != 0) printf (" SYNC1"); + if ((Tsi_flags & STATUS_FLAGS__SYNC0) != 0) printf (" SYNC0"); + if ((Tsi_flags & STATUS_FLAGS__UD) != 0) printf (" UD"); + if ((Tsi_flags & STATUS_FLAGS__GU) != 0) printf (" GU"); + is = timer_settime (FillTimerId, ~TIMER_ABSTIME, &FillerTime, NULL); if (is != 0) { printf ("%s -- failed to set timer\n", Filler_name); @@ -774,6 +979,7 @@ SinqHM_filler_daq_hrpt (); /* Do HRPT (CERCA) type detectors */ break; case SQHM__HM_PSD: + SinqHM_filler_daq_psd (); /* Do PSD readout */ break; case SQHM__TOF: SinqHM_filler_daq_tof (); /* Do time-of-flight read-out */ diff --git a/sinqhm/SinqHM_srv_main.c b/sinqhm/SinqHM_srv_main.c index 0ddc8b39..3d6880bd 100755 --- a/sinqhm/SinqHM_srv_main.c +++ b/sinqhm/SinqHM_srv_main.c @@ -268,12 +268,10 @@ printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "HRPT"); Lwl_hdr_daq_mask = LWL_HDR_SYNC0_MASK | LWL_HDR_SYNC2_MASK; Lwl_hdr_daq_soll = LWL_HDR_SYNC2_MASK; - }else if (strcmp (INST, "TRICS") == 0) { + }else if (strcmp (INST, "TRICS") == 0 || strcmp(INST,"AMOR") == 0) { printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "TriCS"); - Lwl_hdr_daq_mask = LWL_HDR_NRL_MASK; + Lwl_hdr_daq_mask = LWL_HDR_NRL_MASK | LWL_PSD_PWF; Lwl_hdr_daq_soll = 0; - printf ("%s: Warning -- Lwl_hdr_daq_mask and Lwl_hdr_daq_soll are " - "provisional!\n", Tsk_name[0]); }else if (strcmp (INST, "POLDI") == 0) { printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "POLDI"); Lwl_hdr_daq_mask = LWL_HDR_NRL_MASK; diff --git a/sinqhm/SinqHM_srv_routines.c b/sinqhm/SinqHM_srv_routines.c index 5643b8b2..99845351 100755 --- a/sinqhm/SinqHM_srv_routines.c +++ b/sinqhm/SinqHM_srv_routines.c @@ -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 ( /* ==================== diff --git a/sinqhm/bld b/sinqhm/bld index ae4d4be7..64f31899 100755 --- a/sinqhm/bld +++ b/sinqhm/bld @@ -21,7 +21,7 @@ if ("`whoami`" == "maden") then set src = "maden@lnsa06:sinqhm/" else if ("`whoami`" == "sinqhm") then - set src = "koenneck@lnsa06:src/sics/sinqhm/" + set src = "koenneck@lnsa17:src/sics/sinqhm/" else echo Sorry, you are not recognised by this script. exit @@ -145,7 +145,7 @@ #----- set instr = TriCS set defn = '-DINST="TRICS" -DTRICS' - set direc = TRICS/NEW + set direc = TRICS goto comn poldi: #----- diff --git a/sinqhm/hist_mem_spec.tex b/sinqhm/hist_mem_spec.tex index b646fef7..1527bb4b 100755 --- a/sinqhm/hist_mem_spec.tex +++ b/sinqhm/hist_mem_spec.tex @@ -1509,8 +1509,80 @@ % \label{SubSect-PSD} % - Position Sensitive Detector operation of the histogram memory has still - to be defined. + The instruments TRICS and AMOR use 2D position sensitive detectors + provided by the EMBL at ILL. These detectors have a delay line + readout. This means the detector readout for each neutron is two + delay values. From these values the actual detector positions can be + calculated from the formula: + \begin{equation} + pos = \frac{(delay - offset)}{factor} + \end{equation} + Thus the configuration message must carry two additional values for each + of the two detector dimensions. + + AMOR will be operated in time--of--flight mode. For TRICS this is not + necessary. However, as the data telegrams coming from the fibre optic + link contain the time binning information in any case it was decided + to treat both conditions equally as a variation of the time--of--flight + case. For a description of the edge and bank data structures + involved see \ref{SubSect-TOF}. TRICS detectors will then be + treated as a time--of--flight detector with a single huge timebin. + + Thus the SQHM{\usc}{\usc}HM{\usc}PSD configuration command looks as follows: + \begin{center}\begin{picture}(125,105)(0,-105) + \linethickness{0.15mm} \put(0,0){ + \put(0, -7){\Topbox{big-end-id}} + \put(0,-14){\Midbox{SQHM{\usc}CONFIG}} + \put(0,-21){\Midbox{SQHM{\usc}{\usc}HM{\usc}{\usc}PSD}} + \put(0,-28){\Midbox{extra-bytes}} + \put(0,-35){\Midwordbox{n-banks}{n-edges}} + \put(0,-42){\Midbox{preset-delay}} + \put(0,-49){\Midwordbox{x-Factor}{y-Factor}} + \put(0,-56){\Midwordbox{X Offset}{Y Offset}} + \put(0,-63){\Midwordbox{x Size}{y Size}} + \put(0,-70){\Midbox{}} + \put(0,-76){\Midbodydashed{edge[0] $\ldots$ edge[n-edges]}} + \put(0,-84){\Botbody{}} + \put(0,-91){\Midbox{}} + \put(0,-98){\Midbodydashed{bank[0] $\ldots$ bank[n-banks]}} + \put(0,-105){\Botbody{}} + } + \end{picture}\end{center} +% + \begin{center}\begin{tabular}{|llp{68mm}|} \hline + \Tabrow{\textbf{Field}}{Symbol Name}{\textbf{Description}} \hline + \Tabrow{big-end-id}{bigend}{See Section~\ref{Sect-sinqhm-comm}} + \Tabrow{SQHM{\usc}CONFIG}{cmnd}{Command verb} + \Tabrow{SQHM{\usc}{\usc}HM{\usc}{\usc}PSD}{mode}{The selected mode} + \Tabrow{extra-bytes}{$<$prefix$>$.n{\usc}extra{\usc}bytes}{Number of + extra bytes to read.} + \Tabrow{n-edges}{$<$prefix$>$.n{\usc}edges}{Number of edge arrays + following.} + \Tabrow{n-banks}{$<$prefix$>$.n{\usc}banks}{Number of counter banks + following.} + \Tabrow{preset-delay}{$<$prefix$>$.preset{\usc}delay}{Time delay for + sending to multi-detector interface.} + + \Tabrow{x-Factor}{$<$prefix$>$.xFactor}{Division factor for +calculating x position.} + \Tabrow{y-factor}{$<$prefix$>$.yFactor}{Division factor for +calculating y position.} + + \Tabrow{x Offset}{$<$prefix$>$.xOffset}{Offset value for +calculating x position.} + \Tabrow{y Offset}{$<$prefix$>$.yOffset}{Offset value for +calculating y position.} + + \Tabrow{xSize}{$<$prefix$>$.xSize}{Number of detector wires in +x direction.} + \Tabrow{ySize}{$<$prefix$>$.ySize}{Number of detector wires in +y direction.} + \Tabrow{edge[i]}{$<$prefix$>$.edge{\usc}0}{An edge array.} + \Tabrow{bank[j]}{$<$prefix$>$.bank{\usc}0}{A counter bank.} + \hline + \end{tabular}\end{center} + + % \newpage % diff --git a/sinqhm/lwl_client.c b/sinqhm/lwl_client.c index 99d699b7..ca71c9b8 100755 --- a/sinqhm/lwl_client.c +++ b/sinqhm/lwl_client.c @@ -89,8 +89,8 @@ #define DFLT_PORT 3501 #define NIL '\0' #define NL '\n' -#define MAXARR 8192 -#define MAXREC 512 +#define MAXARR 4000000 +#define MAXREC 65563 /*------------------------------------------------------------ ** Definitions for the LWL Datagrams */ diff --git a/sinqhm/sinqhm_ctrl.c b/sinqhm/sinqhm_ctrl.c index 76400bf4..670ef561 100755 --- a/sinqhm/sinqhm_ctrl.c +++ b/sinqhm/sinqhm_ctrl.c @@ -222,6 +222,12 @@ int Delay_time_to_start; /* The DTS for the MDI in TOF mode */ int Nbuff; /* The # buffers in TRANS mode */ int Buff_size; /* The buffer size in TRANS mode */ + int xOff; /* X Offset in PSD mode */ + int yOff; /* Y Offset in PSD mode */ + int xFac; /* X factor in PSD mode */ + int yFac; /* Y factor in PSD mode */ + int xSize; /* xSize in PSD mode */ + int ySize; /* ySize in PSD mode */ struct dsc__descriptor_s Name_desc; @@ -260,6 +266,12 @@ {"-nbuff", ".sqhmNbuff", XrmoptionSepArg, (XPointer) NULL}, {"-buff_size",".sqhmBuffSize", XrmoptionSepArg, (XPointer) NULL}, {"-harsh", ".sqhmHarsh", XrmoptionNoArg, (XPointer) "1"}, + {"-xoff", ".sqhmxoff", XrmoptionNoArg, (XPointer) "1"}, + {"-yoff", ".sqhmyoff", XrmoptionNoArg, (XPointer) "1"}, + {"-xfac", ".sqhmxfac", XrmoptionNoArg, (XPointer) "1"}, + {"-yfac", ".sqhmyfac", XrmoptionNoArg, (XPointer) "1"}, + {"-xsize", ".sqhmxsize", XrmoptionNoArg, (XPointer) "1"}, + {"-ysize", ".sqhmyszie", XrmoptionNoArg, (XPointer) "1"}, }; extern int C_gbl_status; /* Return status from C_... routines */ @@ -659,7 +671,97 @@ printf (" \"-buff_size %s\" is invalid!\n", value.addr); exit (EXIT_FAILURE); } -/*----------------------------------------------------------*/ +/*---------------------------------------------------------- -xoff */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmxoff"), + "ProgramName.Values", + &type, &value); + if (!status) { + xOff = 100; + }else if (sscanf (value.addr, "%d", &xOff) != 1) { + printf (" \"-xoff %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (xOff <= 0) { + printf (" \"-xoff %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -yoff */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmyoff"), + "ProgramName.Values", + &type, &value); + if (!status) { + yOff = 100; + }else if (sscanf (value.addr, "%d", &yOff) != 1) { + printf (" \"-yoff %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (yOff <= 0) { + printf (" \"-yoff %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -yfac */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmyfac"), + "ProgramName.Values", + &type, &value); + if (!status) { + yFac = 10; + }else if (sscanf (value.addr, "%d", &yFac) != 1) { + printf (" \"-yfac %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (yFac <= 0) { + printf (" \"-yfac %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -xfac */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmxfac"), + "ProgramName.Values", + &type, &value); + if (!status) { + xFac = 10; + }else if (sscanf (value.addr, "%d", &xFac) != 1) { + printf (" \"-xfac %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (xFac <= 0) { + printf (" \"-xfac %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -xsize */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmxsize"), + "ProgramName.Values", + &type, &value); + if (!status) { + xSize = 256; + }else if (sscanf (value.addr, "%d", &xSize) != 1) { + printf (" \"-xsize %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (xSize <= 0) { + printf (" \"-xsize %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*---------------------------------------------------------- -ysize */ + status = XrmGetResource (*db, + StrJoin (buff, sizeof (buff), + appName, ".sqhmxsize"), + "ProgramName.Values", + &type, &value); + if (!status) { + ySize = 256; + }else if (sscanf (value.addr, "%d", &ySize) != 1) { + printf (" \"-ysize %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + }else if (ySize <= 0) { + printf (" \"-ysize %s\" is invalid!\n", value.addr); + exit (EXIT_FAILURE); + } +/*----------------------------------------------------------------------*/ return True; } /* @@ -1440,6 +1542,14 @@ sh_basic: is1 = !EXIT_SUCCESS; opt = "-span"; } + }else if((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_PSD){ + if(xSize <= 0) { + is1 = !EXIT_SUCCESS; + opt = "-xsize"; + }else if(ySize <= 0) { + is1 = !EXIT_SUCCESS; + opt = "-ysize"; + } }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TRANS) { }else { is1 = !EXIT_SUCCESS; @@ -1486,6 +1596,29 @@ sh_basic: Req_buff.u.cnfg.u.tof.bank_0.n_cntrs = htons (Ncntrs); Req_buff.u.cnfg.u.tof.bank_0.edge_indx = htons (0); Req_buff.u.cnfg.u.tof.bank_0.bytes_per_bin = htons (Bytes_per_bin); + }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__HM_PSD) { + Req_buff.u.cnfg.u.psd.n_extra_bytes = htonl (0); + Req_buff.u.cnfg.u.psd.n_edges = htons (1); + Req_buff.u.cnfg.u.psd.n_banks = htons (1); + Req_buff.u.cnfg.u.psd.xOffset = htons (xOff); + Req_buff.u.cnfg.u.psd.yOffset = htons (yOff); + Req_buff.u.cnfg.u.psd.xFactor = htons (xFac); + Req_buff.u.cnfg.u.psd.yFactor = htons (yFac); + Req_buff.u.cnfg.u.psd.xSize = htons (xSize); + Req_buff.u.cnfg.u.psd.ySize = htons (ySize); + + + Req_buff.u.cnfg.u.psd.edge_0.n_bins = htonl (Nbins); + Req_buff.u.cnfg.u.psd.edge_0.flag = htonl (0); /* Fixed bin span */ + + Req_buff.u.cnfg.u.psd.edge_0.edges[0] = htonl (0); + Req_buff.u.cnfg.u.psd.edge_0.edges[1] = htonl (Span); + Req_buff.u.cnfg.u.psd.preset_delay = htonl (Delay_time_to_start); + + Req_buff.u.cnfg.u.psd.bank_0.first = htons (Lo_cntr); + Req_buff.u.cnfg.u.psd.bank_0.n_cntrs = htons (xSize*ySize); + Req_buff.u.cnfg.u.psd.bank_0.edge_indx = htons (0); + Req_buff.u.cnfg.u.psd.bank_0.bytes_per_bin = htons (Bytes_per_bin); }else if ((Hm_mode & ~SQHM__SUB_MODE_MSK) == SQHM__TRANS) { Req_buff.u.cnfg.u.trans.n_buffs = htonl (Nbuff); Req_buff.u.cnfg.u.trans.n_bytes = htons (Buff_size);