From 899c07019b3e1e76543686712a0e4b0e5177d885 Mon Sep 17 00:00:00 2001 From: cvs Date: Tue, 7 Nov 2000 11:59:36 +0000 Subject: [PATCH] sinqhm_srv_filler.c --> SinqHM_srv_filler.c --- sinqhm/sinqhm_srv_filler.c | 972 ------------------------------------- 1 file changed, 972 deletions(-) delete mode 100755 sinqhm/sinqhm_srv_filler.c diff --git a/sinqhm/sinqhm_srv_filler.c b/sinqhm/sinqhm_srv_filler.c deleted file mode 100755 index ac3358ab..00000000 --- a/sinqhm/sinqhm_srv_filler.c +++ /dev/null @@ -1,972 +0,0 @@ -#define IDENT "1C05" -/* -** +--------------------------------------------------------------+ -** | Paul Scherrer Institute | -** | SINQ Division | -** | | -** | This software may be used freely by non-profit organizations.| -** | It may be copied provided that the name of P.S.I. and of the | -** | author is included. Neither P.S.I. nor the author assume any | -** | responsibility for the use of this software outside of P.S.I.| -** +--------------------------------------------------------------+ -** -** Module Name . . . . . . . . : [...SinqHM]SinqHM_srv_filler.c -** -** Author . . . . . . . . . . : D. Maden -** Date of creation . . . . . . : Oct 1996 -** -** Updates: -** 1A01 2-Oct-1996 DM Initial version. -** 1B01 10-Jun-1998 DM Add code for SQMH__TOF mode. -** 1C01 11-Jun-1999 DM Add code for SQMH__HRPT mode. -** 1C03 10-Aug-1999 DM Make Lwl_hdr_daq_mask/Lwl_hdr_daq_soll dependent -** on the instrument. -** -** SinqHM_srv_filler.c forms a child process of the SINQ Histogram Memory -** process. It reads data from the detector via the PCI bus and fills the -** histogram(s). -** -** To compile this module for VxWorks on PSS123, use: -** - ccvx SinqHM_srv_filler.c -** where - ccvx = ccppc -O0 \ - -mcpu=603 \ - -I${WIND_BASE}/target/h \ - -fno-builtin \ - -fno-for-scope \ - -nostdinc \ - -DCPU=PPC603 \ - -D_GNU_TOOL \ - -gdwarf -c -Wimplicit -**==================================================================== -*/ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* -**==================== Global Definitions ===================================== -*/ -#define ESC 27 - -#include "SinqHM_def.h" -#include "SinqHM_gbl.h" -#include "vmio10_def.h" -/*============================================================================== - Global Routines -** -** SinqHM_filler_setup_id - copy some ident information to global variables. -** -** Local Routines -** -** SinqHM_filler_timer_handler - routine to handle timer interrupts. -** -** SinqHM_filler_daq_hm_dig - routine called by SinqHM_filler_daq for -** performing data acquisition in -** SQHM__HM_DIG mode, i.e. for data from -** detectors with digitised read-out -** electronics. -** SinqHM_filler_daq_hrpt - routine called by SinqHM_filler_daq for -** performing data acquisition in -** SQHM__HRPT mode, i.e. for data from -** detectors connected to a CERCA interface -** as in the HRPT instrument. -** SinqHM_filler_daq_tof - routine called by SinqHM_filler_daq for -** performing data acquisition in -** SQHM__TOF mode, i.e. for data from -** time-of-flight detectors. -** -** SinqHM_filler_daq - routine called by SinqHM_filler for -** performing data acquisition. -** -** SinqHM_filler - the main entry point for the FILLER child -** process. -**------------------------------------------------------------------------------ -** -*/ -/*============================================================================== -** Global Routines for Filler -*/ - void SinqHM_filler_setup_id () { -/* ====================== -** Simply copy some ident information to global variables -** for use by the SQHM_IDENT request. -*/ - StrJoin (Sqhm_fill_ident, sizeof (Sqhm_fill_ident), IDENT, ""); - StrJoin (Sqhm_fill_date, sizeof (Sqhm_fill_date), __DATE__, ", "); - StrJoin (Sqhm_fill_date, sizeof (Sqhm_fill_date), Sqhm_fill_date, __TIME__); - } -/*============================================================================== -** Local Routines for Filler -*/ - void SinqHM_filler_timer_handler (int arg) { -/* =========================== -** Routine to handle timer interrupts. -*/ - FillTimer_expired = True; - } -/* -**------------------------------------------------------------------------------ -** -*/ - void SinqHM_filler_daq_hm_dig () { -/* ======================== -** Routine to handle Histogram Mode for -** detectors with single channel digitised -** read-out. -** 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 uint my_lo_bin, my_hi_bin; - register union { - uint ui4; - usint ui2[2]; - uchar ui1[4]; - } lwl_hdr, lwl_data; - uchar my_buff[32]; - int i, is; - char er_eol[] = {ESC, '[', '0', 'J'}; /* Erase to End-of-Line */ - - register uchar *my_char_base; - register usint *my_word_base; - register uint *my_long_base; - - /*----------------------------------------------- - ** Make register copies of some items for speed. - */ - my_lwl_fifo = Lwl_fifo; - my_lo_bin = Lo_bin; - my_hi_bin = Hi_bin; - switch (Bytes_per_bin) { - case 1: my_char_base = (uchar *) Hist_base_addr; break; - case 2: my_word_base = (usint *) Hist_base_addr; break; - default: my_long_base = (uint *) Hist_base_addr; - } - /*-----------------------------------------------*/ - 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_HM_NC_C1) { - /* Histo data, single channel */ - VmioBase[VMIO_PORT_A] = 0xff; /* Set timer level (if present) */ - for (i=0; i<1000; i++) { - lwl_data.ui4 = *Lwl_fifo; /* Get the 16 bits of data */ - 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 histogram data word! Event # = %d\n", - N_events); - }else if ((lwl_hdr.ui4 & Lwl_hdr_daq_mask) != Lwl_hdr_daq_soll) { - /* Some header bits are not what they should be (e.g. NRL 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); - } - }else if (lwl_data.ui4 < my_lo_bin) { /* Check "out-of-rnge" */ - if (Cnts_lo != 0xffffffff) Cnts_lo++; - }else if (lwl_data.ui4 > my_hi_bin) { /* Check "out-of-rnge" */ - if (Cnts_hi != 0xffffffff) Cnts_hi++; - }else { - if (Hm_mode_REFLECT == 0) { /* Calculate bin number */ - lwl_data.ui4 -= my_lo_bin; /* No reflection */ - }else { - lwl_data.ui4 = my_hi_bin - lwl_data.ui4; /* Histogram must be reflected */ - } - switch (Bytes_per_bin) { - case 1: - if (my_char_base[lwl_data.ui4] != 0xff) { /* Check bin ovfl */ - my_char_base[lwl_data.ui4]++; /* Incr the bin */ - }else { - switch (Hm_mode_BO) { /* Bin overflow */ - case SQHM__BO_SMAX: break; /* Stop-at-max */ - case SQHM__BO_CNT: break; /* Not programmed yet */ - default: - my_char_base[lwl_data.ui4] = 0; /* By default, wrap-to-zero */ - } - } - break; - case 2: - if (my_word_base[lwl_data.ui4] != 0xffff) { /* Check bin ovfl */ - my_word_base[lwl_data.ui4]++; /* Incr the bin */ - }else { - switch (Hm_mode_BO) { /* Bin overflow */ - case SQHM__BO_SMAX: break; /* Stop-at-max */ - case SQHM__BO_CNT: break; /* Not programmed yet */ - default: - my_word_base[lwl_data.ui4] = 0; /* By default, wrap-to-zero */ - } - } - break; - default: - if (my_long_base[lwl_data.ui4] != 0xffffffff) { /* Check bin ovfl */ - my_long_base[lwl_data.ui4]++; /* Incr the bin */ - }else { - switch (Hm_mode_BO) { /* Bin overflow */ - case SQHM__BO_SMAX: break; /* Stop-at-max */ - case SQHM__BO_CNT: break; /* Not programmed yet */ - default: - my_long_base[lwl_data.ui4] = 0; /* By default, wrap-to-zero */ - } - } - } - } - VmioBase[VMIO_PORT_A] = 0x00; /* Reset timer level (if present) */ - N_events++; - }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TSI_HM_NC) { - process_no_coinc_tsi (lwl_hdr.ui4); /* We have found a "normal" - ** TSI (Timing-Status-Info) header. Process - ** it. - */ - }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TSI_HM_C) { - process_coinc_tsi (lwl_hdr.ui4); /* We have found a "coincidence" - ** type TSI header. The packet has 10 bytes - ** altogether. Process it. - */ - }else { /* Anything else gets flushed */ - lwl_Packet_Read (lwl_hdr.ui4, my_buff); - } - - if (FillTimer_expired) { - if (Print_hdr) printf ("\nTaking data in Digitised Histogramming Mode\n" - " #-Events #-Skip #-TSI Dead-Time Sync-Status\n"); - Print_hdr = False; - FillTimer_expired = False; - printf ("\r%10u %10u %10u %10u %s", N_events, N_skipped, - (N_no_coin_tsi + N_coin_tsi), Dt_or_dts.dead_time, 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); - } - } - } - /* Our flag has been set. There should be .. - ** .. a message waiting for us. Return to process it. - */ - } -/* -**------------------------------------------------------------------------------ -** -*/ - void SinqHM_filler_daq_hrpt () { -/* ====================== -** Routine to handle Histogram Mode for -** detectors connected to a CERCA interface -** as in the HRPT instrument. -** -** The wires of the detector are read out frame by frame. -** Each wire comes as a 3-word packet (i.e. Hist Mode mit 3 Kanaele). -** The first word is 15-bit Wire Address (0 .. 1601) + Error Bit -** The second word is 10-bit Count -** The third word is 16-bit Frame Number -** -** To avoid skewing the histograms, the data is read out frame by frame -** and the frame is merged with the overall histogram only when it is -** complete and the LWL header information was OK for Wire 0 of the frame. -** -** 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. -** -** Another Note: -** The HRPT detector has 1600 wires numbered 0 to 1599. The physicists -** want these numbers reflected for reasons of their own. -** The CERCA readout also uses wire numbers 1600 and 1601 to present -** time information about the frame. This information is discarded. -*/ - register uint *my_lwl_fifo; - register uint my_lo_bin, my_hi_bin; - register union { - uint ui4; - usint ui2[2]; - uchar ui1[4]; - } lwl_hdr, lwl_data_0, lwl_data_1, lwl_data_2; - uchar my_buff[32]; - uint wire; - int i, j, k, is, my_state; - int n_errors = 0; - char err_txt[128]; - - char er_eol[] = {ESC, '[', '0', 'J'}; /* Erase to End-of-Line */ - - register uchar *my_char_base; - register usint *my_word_base; - register uint *my_long_base; - - register uchar *my_char_frame; - register usint *my_word_frame; - register uint *my_long_frame; - - /*----------------------------------------------- - ** Make register copies of some items for speed. - */ - my_lwl_fifo = Lwl_fifo; - my_lo_bin = Lo_bin; - my_hi_bin = Hi_bin; - switch (Bytes_per_bin) { - case 1: my_char_base = (uchar *) Hist_base_addr; break; - case 2: my_word_base = (usint *) Hist_base_addr; break; - default: my_long_base = (uint *) Hist_base_addr; - } - switch (Bytes_per_bin) { - case 1: my_char_frame = (uchar *) Frame_base_addr; break; - case 2: my_word_frame = (usint *) Frame_base_addr; break; - default: my_long_frame = (uint *) Frame_base_addr; - } - my_state = HRPT__SRCH_FRAME; - /*-----------------------------------------------*/ - 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_HM_NC_C3) { - /* Histo data, three channel -- this is what we are - ** interested in in HRPT mode. Start by reading out - ** the 3 data words which should follow the header. - */ - VmioBase[VMIO_PORT_A] = 0xff; /* Set timer level (if present) */ - for (i=0; i<1000; i++) { - lwl_data_0.ui4 = *Lwl_fifo; /* Get first 16 bits of data */ - if (lwl_data_0.ui4 != LWL_FIFO_EMPTY) break; - taskDelay (0); /* But wait if FIFO is slow! */ - } - if (lwl_data_0.ui4 != LWL_FIFO_EMPTY) { - for (i=0; i<1000; i++) { - lwl_data_1.ui4 = *Lwl_fifo; /* Get second 16 bits of data */ - if (lwl_data_1.ui4 != LWL_FIFO_EMPTY) break; - taskDelay (0); /* But wait if FIFO is slow! */ - } - if (lwl_data_1.ui4 != LWL_FIFO_EMPTY) { - for (i=0; i<1000; i++) { - lwl_data_2.ui4 = *Lwl_fifo; /* Get third 16 bits of data */ - if (lwl_data_2.ui4 != LWL_FIFO_EMPTY) break; - taskDelay (0); /* But wait if FIFO is slow! */ - } - if (Dbg_lev1 && (lwl_data_1.ui4 > 0)) { - printf ("Got address = %d, shifted = %d, counts = %d\n", - lwl_data_0.ui4, (lwl_data_0.ui4 >> 1), lwl_data_1.ui4); - } - } - } - if ((lwl_data_0.ui4 == LWL_FIFO_EMPTY) || - (lwl_data_1.ui4 == LWL_FIFO_EMPTY) || - (lwl_data_2.ui4 == LWL_FIFO_EMPTY)) { - if (n_errors == 0) { - sprintf (err_txt, "Time-out getting the three data words! " - "Event # = %d\n", N_events); - } - n_errors++; - }else { - wire = lwl_data_0.ui4 >> 1; /* Shift out error bit */ - if (wire < my_lo_bin) { /* Out-of-rnge? */ - if (Cnts_lo != 0xffffffff) Cnts_lo++; - }else if (wire == my_lo_bin) { /* Start of new frame? */ - my_state = HRPT__READ_FRAME; /* Yes. Note our new state */ - Frame_hdr = lwl_hdr.ui4; /* Remember hdr for frame */ - Frame_num = lwl_data_2.ui4; - switch (Bytes_per_bin) { - case 1: my_char_frame[0] = lwl_data_1.ui4; break; - case 2: my_word_frame[0] = lwl_data_1.ui4; break; - default: my_long_frame[0] = lwl_data_1.ui4; - } - }else if (wire <= my_hi_bin) { /* In range? */ - if (my_state == HRPT__READ_FRAME) { /* Yes. Check state */ - if (lwl_data_2.ui4 == Frame_num) { /* And check frame # */ - switch (Bytes_per_bin) { - case 1: my_char_frame[wire-my_lo_bin] = lwl_data_1.ui4; break; - case 2: my_word_frame[wire-my_lo_bin] = lwl_data_1.ui4; break; - default: my_long_frame[wire-my_lo_bin] = lwl_data_1.ui4; - } - }else { - if (n_errors == 0) { - sprintf (err_txt, "Frame sequence error: Frame 0x%04x\n" - " Packet: 0x%08x 0x%04x 0x%04x 0x%04x\n", - lwl_hdr.ui4, lwl_data_0.ui4, lwl_data_1.ui4, lwl_data_2.ui4); - } - n_errors++; - } - if (wire == my_hi_bin) { /* End of frame? */ - /* Yes, merge it in if the - ** header bits are OK - */ - if ((Frame_hdr & Lwl_hdr_daq_mask) != Lwl_hdr_daq_soll) { - N_skipped++; - if (Dbg_lev1) { - printf("Skipped frame %d\n" - " Hdr: 0x%08x\n" - " Mask: 0x%08x\n" - " Soll: 0x%08x\n", Frame_num, - Frame_hdr, Lwl_hdr_daq_mask, Lwl_hdr_daq_soll); - } - }else { - N_events++; - k = 0; - for (i = my_lo_bin; i <= my_hi_bin; i++) { - if (Hm_mode_REFLECT == 0) { /* Reflect if necessary */ - j = i - my_lo_bin; - }else { - j = my_hi_bin - i; - } - switch (Bytes_per_bin) { - case 1: my_char_base[j] += my_char_frame[k]; break; - case 2: my_word_base[j] += my_word_frame[k]; break; - default: my_long_base[j] += my_long_frame[k]; - } - k++; - } - } - my_state == HRPT__SRCH_FRAME; - } - } - }else if (wire == (my_hi_bin + 1)) { /* Frame timing #1? */ - continue; /* Yes, ignore */ - }else if (wire == (my_hi_bin + 2)) { /* Frame timing #2? */ - continue; /* Yes, ignore */ - }else if (wire > (my_hi_bin + 2)) { /* Out-of-rnge? */ - if (Cnts_hi != 0xffffffff) Cnts_hi++; - } - } - VmioBase[VMIO_PORT_A] = 0x00; /* Reset timer level (if present) */ - }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TSI_HM_NC) { - process_no_coinc_tsi (lwl_hdr.ui4); /* We have found a "normal" - ** TSI (Timing-Status-Info) header. Process - ** it. - */ - }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TSI_HM_C) { - process_coinc_tsi (lwl_hdr.ui4); /* We have found a "coincidence" - ** type TSI header. The packet has 10 bytes - ** altogether. Process it. - */ - }else { /* Anything else gets flushed */ - lwl_Packet_Read (lwl_hdr.ui4, my_buff); - } - - if (FillTimer_expired) { - if (Print_hdr) printf ("\nTaking data in HRPT Mode\n" - " #-Events #-Skip #-TSI #-Frame Sync-Status\n"); - Print_hdr = False; - FillTimer_expired = False; - printf ("\r%10u %10u %10u %10u %s", N_events, N_skipped, - (N_no_coin_tsi + N_coin_tsi), Frame_num, 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"); - - if (n_errors != 0) { - printf ("\n%d errors occurred in the last time period\n", n_errors); - printf ("The first one was:\n%s\n", err_txt); - n_errors = 0; - } - 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_tof () { -/* ===================== -** 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, lwl_data; - - int i, j, is, ts, left, right, middl, not_finished; - uchar my_buff[32]; - register struct tof_histog *my_tof_descr; - uint *edge_pntr; - char er_eol[] = {ESC, '[', '0', 'J'}; /* Erase to End-of-Line */ - /*----------------------------------------------- - ** 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_TOF_C1) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C2) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C3) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C4) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C5) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C6) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C7) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C8) || - ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TOF_C9)) { - /* We have found a header of the type we are - ** interested in, i.e. a TOF packet. So - ** process it. We must first get the 16 bits - ** of data which give the counter number. - */ - VmioBase[VMIO_PORT_A] = 0xff; /* Set timer level (if present) */ - for (i=0; i<1000; i++) { - lwl_data.ui4 = *Lwl_fifo; /* Get the counter number */ - 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 counter number!\n"); - }else if ((lwl_hdr.ui4 & Lwl_hdr_daq_mask) != Lwl_hdr_daq_soll) { - /* Some header bits are not what they should be (e.g. NRL 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); - } - }else { - /* We have a valid TOF packet. Validate it - ** thoroughly and process it. First check - ** that the counter number is valid. - */ - if (lwl_data.ui4 >= MAX_TOF_CNTR) { - Tof_count_bad_counter_number++; /* It isn't */ - }else { - my_tof_descr = Tof_descr[lwl_data.ui4]; - if (my_tof_descr == NULL) { - Tof_count_bad_counter_number++; /* It isn't */ - }else { - /* The counter number is valid. Process the time-stamp - ** (20-bit quantity) to find which bin to increment. - */ - ts = lwl_hdr.ui4 & LWL_HDR_TS_MASK; - if (ts < my_tof_descr->lo_edge) { - if ((Hm_mode_UD != 0) && - (lwl_hdr.ui4 & LWL_HDR_UD_MASK) == 0) { - my_tof_descr->cnt_early_down++; - }else { - my_tof_descr->cnt_early_up++; - } - }else { - if (ts > my_tof_descr->hi_edge) { - if ((Hm_mode_UD != 0) && - (lwl_hdr.ui4 & LWL_HDR_UD_MASK) == 0) { - my_tof_descr->cnt_late_down++; - }else { - my_tof_descr->cnt_late_up++; - } - }else { - /* Now search the bin boundary list to find the - ** bin to which this event belongs. - */ - edge_pntr = my_tof_descr->bin_edge; - left = 0; - right = my_tof_descr->n_bins; - middl = (left + right)/2; - not_finished = True; - while (not_finished) { - switch (right - left) { - case 0: - not_finished = False; - break; - case 1: - middl = (ts >= edge_pntr[right]) ? right : left; - not_finished = False; - break; - default: - middl = (left + right)/2; - if (ts == edge_pntr[middl]) { - not_finished = False; - }else if (ts > edge_pntr[middl]) { - left = middl; - }else { - right = middl; - } - } - } - if ((Hm_mode_UD != 0) && - ((lwl_hdr.ui4 & LWL_HDR_UD_MASK) != 0)) { - middl += my_tof_descr->n_bins; - } - switch (my_tof_descr->bytes_per_bin) { - case 1: - my_tof_descr->u.b_bin_data[middl]++; break; - case 2: - my_tof_descr->u.w_bin_data[middl]++; break; - default: - my_tof_descr->u.l_bin_data[middl]++; break; - } - } - } - } - } - } - VmioBase[VMIO_PORT_A] = 0x00; /* Reset timer level (if present) */ - N_events++; - }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TSI_HM_NC) { - process_no_coinc_tsi (lwl_hdr.ui4); /* We have found a "normal" - ** TSI (Timing-Status-Info) header. Process - ** it. - */ - }else if ((lwl_hdr.ui4 & LWL_HDR_TYPE_MASK) == LWL_TSI_HM_C) { - process_coinc_tsi (lwl_hdr.ui4); /* We have found a "coincidence" - ** type TSI header. The packet has 10 bytes - ** altogether. Process it. - */ - }else { /* Anything else gets flushed */ - lwl_Packet_Read (lwl_hdr.ui4, my_buff); - } - - if (FillTimer_expired) { - if (Print_hdr) printf ("\nTaking data in TOF Mode\n" - " #-Events #-Skip #-TSI Delay-Time Sync-Status\n"); - Print_hdr = False; - FillTimer_expired = False; - printf ("\r%10u %10u %10u %10u %s", N_events, N_skipped, - (N_no_coin_tsi + N_coin_tsi), 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); - } - } - } - /* Our flag has been set. There should be .. - ** .. a message waiting for us. Return to process it. - */ - } -/* -**----------------------------------------------------------------------------- -*/ - void SinqHM_filler_daq_trans () { -/* ======================= -** Routine to handle Transparent Mode. Data is simply read -** and packed into the buffers. The buffers are used -** cyclically. -** The routine attempts to read packets of data from the -** fibre-optic channel. This code, however, assumes that -** the packets obey the LWL protocol specification. -** 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, lwl_data; - - uint status_info; - int i, j; - register uchar *my_char_nxt; - - /*----------------------------------------------- - ** Make register copies of some items for speed. - */ - my_lwl_fifo = Lwl_fifo; - my_char_nxt = Next_char; - - 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 { - VmioBase[VMIO_PORT_A] = 0xff; /* Set timer level (if present) */ - *my_char_nxt = lwl_Packet_Read (lwl_hdr.ui4, &my_char_nxt[1]); - Bytes_free = Bytes_free - *my_char_nxt - 1; - my_char_nxt = my_char_nxt + *my_char_nxt + 1; - if (Bytes_free < 24) my_char_nxt = selectNewBuffer (my_char_nxt); - VmioBase[VMIO_PORT_A] = 0x00; /* Reset timer level (if present) */ - } - } - /* Our flag has been set. There should be .. - ** .. a message waiting for us. Return to process it. - */ - } -/* -**----------------------------------------------------------------------------- -*/ - void SinqHM_filler_daq () { -/* ================= -*/ - int is; - - switch (Hm_mode & (~SQHM__SUB_MODE_MSK)) { - case SQHM__TRANS: - SinqHM_filler_daq_trans (); /* Do Transparent mode */ - break; - case SQHM__HM_DIG: - SinqHM_filler_daq_hm_dig (); /* Do Digitised-type detectors */ - break; - case SQHM__HRPT: - SinqHM_filler_daq_hrpt (); /* Do HRPT (CERCA) type detectors */ - break; - case SQHM__HM_PSD: - break; - case SQHM__TOF: - SinqHM_filler_daq_tof (); /* Do time-of-flight read-out */ - break; - } - } -/* -**============================================================================= -** Here beginneth the main code for FILLER ... -*/ - int SinqHM_filler (int suspend_flag) { -/* ============= -** FILLER - Scaler Overflow Handler for SinqHM sub-system. -*/ - int status, i, is, j, k, wait_result, indx; - int keep_cycling; - int shm_size; - char recd[80]; - - struct msg_to_filler_struct msg_buff; - - sigset_t proc_sigmask; - struct sigaction sig_action; -/*============================================================================ -*/ - if (suspend_flag != 0) { - printf ("%s: Suspending ...", Filler_name); - taskSuspend (0); /* We've been told to suspend ourself, .. - ** .. presumably for debug reasons. - */ - printf (" suspension ended!\n"); - } -/*============================================================================ -** Create message queue for receiving requests from clients. -*/ - if (MsgQ_to_filler == NULL) { - MsgQ_to_filler = msgQCreate (8, sizeof (msg_buff), MSG_Q_FIFO); - if (MsgQ_to_filler == NULL) { - printf ("%s -- failed to create MsgQ_to_filler message queue.\n", - Filler_name); - exit (KER__BAD_VALUE); - } - if (Dbg_lev1) { - printf ("%s -- created MsgQ_to_filler message queue.\n", Filler_name); - } - } - while (msgQNumMsgs (MsgQ_to_filler) > 0) { /* Ensure Q is empty */ - msgQReceive (MsgQ_to_filler, (char *) &msg_buff, sizeof (msg_buff), - WAIT_FOREVER); - } -/*============================================================================ -** Create message queues for sending replies to servers. -** Note: MsgQ_to_server[0] is used for messages to SinqHM-master. -*/ - for (i = 0; i <= MAX_CLIENTS; i++) { - if (MsgQ_to_server[i] == NULL) { - MsgQ_to_server[i] = msgQCreate (8, sizeof (msg_buff), MSG_Q_FIFO); - if (MsgQ_to_server[i] == NULL) { - printf ("%s -- failed to create MsgQ_to_server[%d] message queue.\n", - Filler_name, i); - exit (KER__BAD_VALUE); - } - if (Dbg_lev1) { - printf ("%s -- created MsgQ_to_server[%d] message queue.\n", - Filler_name, i); - } - } - while (msgQNumMsgs (MsgQ_to_server[i]) > 0) { /* Ensure Q is empty */ - msgQReceive (MsgQ_to_server[i], (char *) &msg_buff, sizeof (msg_buff), - WAIT_FOREVER); - } - } -/*============================================================================*/ - Filler_flag = 0; /* Ensure the communication flag is zero */ - - Server_masks[0] = 0x8000; /* This is our bit in SinqHM_Dsbl_Mask */ - for (i = 1; i <= MAX_CLIENTS; i++) Server_masks[i] = 1 << (i - 1); - - SinqHM_Dsbl_Mask = 0; /* Start up with DAQ enabled */ - - Lwl_fifo = (uint *) 0x80810080; /* Set up address of Fibre Optic */ - Lwl_csr = &Lwl_dummy_csr; /* Set up address of dummy CSR */ -/*============================================================================ -** Define our signal mask first and define an action routine to catch -** the SIGINT signal our parent will send us when he wants us to exit. -*/ - status = sigemptyset (&proc_sigmask); - status = sigprocmask (SIG_SETMASK, &proc_sigmask, NULL); - - status = sigemptyset (&sig_action.sa_mask); - sig_action.sa_handler = catch_int_signal; - sig_action.sa_flags = 0; - if (sigaction (SIGINT, &sig_action, NULL) == -1) { - getErrno (&My_errno); - perror ("sigaction error:"); - exit (KER__BAD_VALUE); - } -/*============================================================================ -** When we can do it, ensure the detector read-out is inhibited and -** flush out any data in the fibre-optic FIFO. -*/ - *Lwl_csr = 0x0001; /* This will (maybe) initialise the fibre-optic FIFO. */ - lwl_Fifo_Flush (); /* Flush the fibre-optic FIFO. */ - -/*============================================================================ -** Initialisation done, release semaphore so that our parent can continue. -*/ - if (Dbg_lev1) printf ("%s -- releasing Sem_Filler semaphore\n", - Filler_name); - is = semGive (Sem_Filler); - if (Dbg_lev1) - printf ("%s -- returned from sem release: %d\n", Filler_name, is); - if (is != OK) { - printf ("%s -- sem release error\n", Filler_name); - exit (KER__BAD_VALUE); - } - taskDelay ((sysClkRateGet())/2); /* Give parent time to display a message */ -/*============================================================================ -** Make a timer to give occasional status on console -*/ - FillTimer_active = False; - FillTimer_expired = False; - if (Hm_mode_NO_STAT != 0) { - printf ("%s -- display of TSI information suppressed\n", Filler_name); - }else { - is = timer_create (CLOCK_REALTIME, NULL, &FillTimerId); - if (is != 0) { - printf ("%s -- timer creation failed\n", Filler_name); - }else { - is = timer_connect (FillTimerId, SinqHM_filler_timer_handler, 0); - if (is != 0) { - printf ("%s -- failed to connect to timer\n", Filler_name); - }else { - FillerTime.it_value.tv_sec = 2; /* Set a 2 second timer */ - FillerTime.it_value.tv_nsec = 0; - FillerTime.it_interval.tv_sec = 0; - FillerTime.it_interval.tv_nsec = 0; - is = timer_settime (FillTimerId, ~TIMER_ABSTIME, &FillerTime, NULL); - if (is != 0) { - printf ("%s -- failed to set timer\n", Filler_name); - } - FillTimer_active = True; - } - } - } -/*============================================================================ -** Loop taking data and waiting for requests from clients. -*/ - for (keep_cycling = True; keep_cycling;) { - if (SinqHM_Dsbl_Mask == 0) { - SinqHM_filler_daq (); /* Start data acquisition .. - ** .. We return here whenever Filler_flag .. - ** .. indicates that a message is waiting .. - ** .. to be processed. - */ - } - is = msgQReceive (MsgQ_to_filler, (char *) &msg_buff, sizeof (msg_buff), - WAIT_FOREVER); - if (is <= 0) { - printf ("%s -- error status from msgQReceive: %d\n", Filler_name, is); - exit (KER__BAD_VALUE); - } - if (Dbg_lev1) printf ("%s -- received a message of %d bytes!\n", - Filler_name, is); - Filler_flag = 0; - indx = msg_buff.u.uu.index; - switch (msg_buff.u.uu.cmnd) { - case DAQ__EXIT: - keep_cycling = False; /* Break out of the loop */ - break; - case DAQ__CLR: - SinqHM_Dsbl_Mask &= (~Server_masks[indx]); /* Clear user's mask bit. */ - break; - case DAQ__GO: - SinqHM_Dsbl_Mask &= (~Server_masks[0]); /* Clear our mask bit */ - break; - case DAQ__INH: - SinqHM_Dsbl_Mask |= Server_masks[indx]; /* Set user's mask bit */ - break; - case DAQ__STOP: - SinqHM_Dsbl_Mask |= Server_masks[0]; /* Set our mask bit. */ - break; - } - msg_buff.u.uu.new_mask = SinqHM_Dsbl_Mask; /* Put new mask in reply */ - is = msgQSend (MsgQ_to_server[indx], /* Tell user to continue */ - (char *) &msg_buff, - sizeof (msg_buff), - WAIT_FOREVER, MSG_PRI_NORMAL); - if (is != OK) { - printf ("%s -- error status from msgQSend: %d\n", Filler_name, is); - exit (KER__BAD_VALUE); - } - } - exit (KER__SUCCESS); - } -/*======================================= End of SinqHM_srv_filler.c ========*/