/* **********************************************************************
 * *                                                                    *
 * *          Parameter and Structure Definitions for the RVP8          *
 * *                                                                    *
 * **********************************************************************
 * File: include/rvp8.h
 *
 *                     COPYRIGHT (c) 2001, 2005  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#ifndef SIGMET_RVP8_H
#define SIGMET_RVP8_H 1

#define RVP8_UNIQUE( VERSION, MINOREV, BUILD ) \
  ( ((BUILD) << 16) | ((MINOREV) << 8) | (VERSION) )
#define RVP8_UNIQUE_VERSION( UNIQUE ) (  (UNIQUE)        & 0x00FF )
#define RVP8_UNIQUE_MINOREV( UNIQUE ) ( ((UNIQUE) >>  8) & 0x00FF )
#define   RVP8_UNIQUE_BUILD( UNIQUE ) ( ((UNIQUE) >> 16) & 0xFFFF )

/* RVP8 version numbers follow overall RDA numbering scheme
 */
#define RVP8_VERSION RDA_VERSION
#define RVP8_MINOREV RDA_MINOREV
#define RVP8_BUILD   RDA_BUILD

/* *********************
 * *                   *
 * * Tunable Constants *
 * *                   *
 * *********************
 */
#define RVP8MINPULSES      1	/* Min and Max pulses/bin */
#define RVP8MAXPULSES   1024

#define RVP8MAXBINS     3072	/* Max # bins permitted in range mask */

#define NFILTS         8	/* Number of filters supported */
#define RVP8NPWIDS    16	/* Number of pulse widths supported */

#define MAXPROCS       4	/* Max number of compute threads */
#define DFLTPROCS      2	/*   and default number to start */

#define RVP8ASTABSIZE   1024	/* Max size of antenna sync table */

/* The maximum number of higher order trips that we'll ever try to
 * recover in any of the major modes.
 */
#define MAXTRIPS       6	/* Max higher order trips */

/* Both the user triggers and the polarization triggers are allocated
 * from an array of NTRIGS available lines.  The user triggers grow up
 * from the bottom, and the polarization lines grow down from the top.
 */
#define NTRIGS        12	/* Max number of user triggers */
#define NPOLARS        2	/*   and polarization control lines. */

#define POLARTRIG( IPOL ) ( (NTRIGS-1) - (IPOL) )

#define COPOLRXCHAN ( iCoPolRxChan \
  ( GM->iRxMode, GM->nv.lCoPolOnPriRx, POL_FROM_OPF( GM->nv.opprm.iflags ) ) )

/* The maximum number of (I,Q) vectors per bin.  This can also be
 * interpreted as the maximum number of receive channels that the
 * radar can have.
 */
#define MAXVIQPERBIN   2	/* Use two for standard Dual-Pol */

/* The minimum and maximum FIR passband width in MHz.  These are
 * bounds on the traditional bandpass filters that the RVP8 can
 * design.
 */
#define MINFIRWIDTH  0.005	/*  5KHz (just to be nonzero) */
#define MAXFIRWIDTH 10.000	/* 10MHz (unlikely to need more) */

/* The minimum and maximum intermediate frequency in MHz.
 */
#define MININTERMEDFREQ   6.0
#define MAXINTERMEDFREQ  90.0

/* The maximum number of (I,Q) vectors per pulse is simply the product
 * of the maximum number of receive channels and the maximum bin count
 * plus one (for the burst sample).  The maximum number of vectors per
 * ray would ordinarily be the product of that value with the maximum
 * sample size, but this turns out to be impractically large. So we
 * impose a somewhat lower bound instead, based on how much data might
 * reasonably need to be handled per CPI.
 */
#define MAXVIQPERPULSE ((RVP8MAXBINS+1) * MAXVIQPERBIN)
#define MAXVIQPERRAY  1050000	/* e.g., 256 pulses, 2 receivers, 2048 bins */

/* Bounds on PRF, trigger timing, and overall data rate.  Note that
 * the DSP_RVP8_MINPRF and DSP_RVP8_MINPRF values are inherited from
 * the DSP driver definitions.
 */
#define FMAXNOISEPRF  1250.0	/* To prevent overruns in noise_sample() */

#define TGDLIM        5000.0	/* Trigger delay limits (usec) */

#define MINFEXTDELAY     1.5	/* Bounds on external trigger delay (usec) */
#define MAXFEXTDELAY   500.0

#define MAXRAYSPERSEC    150	/* Max Rays/Second, just for sanity */

/* Noise sampling parameters
 */
#define NSEBINS     256		/* Total number of bins collected */
#define NSESAMPS    256		/* Number of pulses to sample */

/* Definitions for headroom expansion to make a reasonable guess of
 * the power in a saturated IF waveform.
 */
#define HEADTABSIZE    100	/* Number of elements in the table, and */
#define HEADTABMAXPOW  1.6	/*   measured power of highest element. */

/* ********************************************
 * *                                          *
 * *  Trigger and Pulse Sequence Definitions  *
 * *                                          *
 * ********************************************
 */
/* Parameters defining one of the trigger lines
 */
struct rvp8Tgline {		/* Activity on a single trigger line */
  FLT4  fStart ;		/*   Start of trigger edge, fixed usec, */
  FLT4  fStartPRT ;		/*     plus fraction of the  PRT */
  FLT4  fWidth ;		/*   Width of trigger pulse (usec) */

  UINT4 tgtype ;		/*   Type of waveform */
#define TGTYPE_RISE  0x01	/*     Line rises at the start (else falls) */
#define TGTYPE_EDGE  0x02	/*     Single edge transition (else pulse) */
} ;

/* Overall trigger line definitions.  Since some of these lines are
 * assigned to hardwired functions on the board, this structure must
 * match the line definitions in the FPGA file 'rda.inc'.
 */
struct rvp8Tglines {		/* Ensemble activity on all trigger lines */
  struct rvp8Tgline trigs[NTRIGS] ;  /* 11- 0 User-definable triggers */
  struct rvp8Tgline txpulses[2] ;    /* 13-12 Transmit pulse modulation timing */
  struct rvp8Tgline txphase ;	     /* 14    Transmit phase switch point */
  struct rvp8Tgline pad15x3[3] ;     /* 17-15 */
  struct rvp8Tgline burst ;	     /* 18    Burst pulse selection window */
  struct rvp8Tgline ifdata ;	     /* 19    Select window for IF data samples */
  struct rvp8Tgline rngstart ;	     /* 20    Range mask startup */
  struct rvp8Tgline rngstop ;        /* 21    Range mask shutdown */
  struct rvp8Tgline pipegap ;        /* 22    Pipelined interpulse gap */
  struct rvp8Tgline secsync ;        /* 23    Sync pretrigger to secondary Rx */
  struct rvp8Tgline banksel ;        /* 24    Internal bank change/select gate */
  struct rvp8Tgline ifdata_aux ;     /* 25    Auxiliary Direct IF data */
} ;
#define TGL_IFDATA       19	/* Entry number of IFDATA line */
#define TGL_SECSYNC      23	/* Entry number of SECSYNC line */
#define TGL_BANKSEL      24	/* Entry number of BANKSEL line */
#define TGL_NUMHARDW     25	/* Number of hardware trigger lines */

#define TGL_IFDATA_AUX   25	/* Entry number of IFDATA_AUX line */
#define TGL_NUMTOTAL     26	/*   and number of structure entries. */

/* Bank numbers (RX8BANKBITS wide) for various trigger generator
 * waveforms.
 */
#define TBANK_NORM      0	/* Normal triggers */
#define TBANK_TIMEOUT   1	/* Keep-alive during timeouts (MUST BE #1) */
#define TBANK_LOWPRF    2	/* Low PRF (Long PRT) triggers */
#define TBANK_RESERVED  3	/* (Reserved for future use) */
#define TBANK_NOISE     4	/* Special noise sampling triggers */
#define TBANK_BPHUNT    5	/* Hunt for missing burst pulse */
#define TBANK_CUSTOM    6	/* Start of custom trigger definitions */

#define RX8BANKBITS        6	/* Number of bits to represent trigger */
#define RX8PHASEBITS       8	/*   bank and phase modulation. */

struct rvp8TgPulse {		/* Definition of a single pulse within a bank */
  FLT4  fPeriodUSec ;		/*   Period (to next pulse) in microseconds */
  BIN2  iTxPhase ;		/*   Phase angle of transmit data */
  UINT1 iPolarBits ;		/*   State of polarization control bits */
  UINT1 iFlags ;		/*   Control and option flags */
#define TGPFLG_INTERRUPTIBLE 0x01 /*   Trigger bank can change after this pulse */
#define TGPFLG_LOOPBACKPULSE 0x02 /*   Overall sequence loops back to this pulse */
  FLT4  fBeginUSec ;		/*   Time offset of pulse waveform (filled in */
				/*     when pulse is written to trigger RAM) */
} ;

/* *************************************
 * *                                   *
 * * Saved Setup Structure Definitions *
 * *                                   *
 * *************************************
 */

/* Specification parameters that are passed to the transmiter waveform
 * design routines.
 */
struct rvp8TxWaveSpecs {	/* Description of a transmitted waveform */
  SINT4 iWaveType ;	        /* Type of waveform being transmitted */
#define WAVETYPE_CWPULSE    0	/*   Simple fixed frequency (gated CW) pulse */
#define WAVETYPE_LINEARFM   1	/*   Linear-FM compressed waveform */
#define WAVETYPE_NONLINFM   2	/*   Non-Linear-FM compressed waveform */
#define WAVETYPE_RESERV_A   3	/*   Reserved slots for future waveforms */
#define WAVETYPE_RESERV_B   4	/*     native to the RVP8. */
#define WAVETYPE_RESERV_C   5
#define WAVETYPE_RESERV_D   6
#define WAVETYPE_CUSTOM_A   7	/*   Slots for custom user waveforms */
#define WAVETYPE_CUSTOM_B   8
#define WAVETYPE_CUSTOM_C   9
#define WAVETYPE_CUSTOM_D  10
#define WAVETYPE_NUMWAVES    11

  FLT4 fPulseLenUSec ;		/* Pulse length in microseconds */
  FLT4 fBandWidthMHz ;		/* Bandwidth in megaHertz */

#define TXWAVETUNES 3		/* Number of tuning parameters */
#define TXWAVEMINTUNE -100.0	/* Absolute minimum and maximum values */
#define TXWAVEMAXTUNE  100.0
  FLT4 fTunes[ TXWAVETUNES ] ;	/* Algorithm specific tuning parameters */
  FLT4 fMinTunes[ TXWAVETUNES ] ; /* Numerical bounds within which each */
  FLT4 fMaxTunes[ TXWAVETUNES ] ; /*   tuning parameter may vary. */
} ;

/* The maximum number of Tx waveform points is somewhat arbitrarily
 * set according to the maximum impulse response length.  This
 * presumes some maximum ratio of TX/AQ crystal frequencies.
 */
#define MINTXPOINTS  8
#define MAXTXPOINTS ( 3 * MAX( MAXIMPLENGTH_AB, MAXIMPLENGTH_C/2 ) )

/* Parameters that define each pulsewidth
 */
struct rvp8Pwdef {		/* Parameters specific to a pulse width */
  struct rvp8Tgline		/*   Array of user-definable triggers (may be */
    trigs[ NTRIGS ] ;		/*     used for timing and/or polarization). */
  FLT4  fminprf ;		/*   Minimum number of pulses / second */
  FLT4  fmaxprf ;		/*   Maximum number of pulses / second */
  FLT4  fMaxInstPrf ;		/*   Maximum instantaneous PRF (1 / min(PRT)) */
  FLT4  fifreq ;		/*   Intermediate Frequency (MHz) */
  FLT4  fextdelay ;		/*   Pretrigger delay to range zero (usec) */
  FLT4  fpol_switch[NPOLARS] ;	/*   Times of polarization line flips (usec) */
  SINT4 ipwcode ;		/*   4-bit code to select this PW  */
  FLT4  fRangeMaskRes ;		/*   Spacing between range bins (meters) */
  SINT4 implength ;		/*   FIR impulse response length (taps) */
  FLT4  firwidth ;		/*   FIR filter width (MHz) */
  FLT4  fPriNoiseDbm ;		/*   Primary receiver default noise (dBm) */
  FLT4  fSecNoiseDbm ;		/*   Secondary receiver default noise (dBm) */
  SINT4 ibfelength ;		/*   Burst Frequency Estimator subset */
  SINT4 ibfestart ;		/*     of FIR points to incorporate.  */
  FLT4  fphase_load ;		/*   Load time of phase control outputs (usec) */
  struct rvp8TxWaveSpecs	/*   Specification of the waveform optionally */
    txSpecs ;			/*     being transmitted for this PW. */
  FLT4  fTxZeroOffsUSec[2] ;	/*   Transmitted pulse range zero offset (usec) */
} ;

/* Spectral clutter filter definitions
 */
struct rvp8SpecFilt {
  SINT4 iType ;			/* Spectral Filter Type */
#define SPFILT_FIXED      0	/*   Fixed width filter */
#define SPFILT_VARIABLE   1	/*   Variable width based on slope */
#define SPFILT_VARLSQ     2	/*   Variable width, least squares */
#define SPFILT_GMAP       3	/*   Gaussian Model Adaptive Processing */
#define SPFILT_NUMCODES     4

  SINT4 iMinWidth ;		/* Minimum width (center plus one side) */
  SINT4 iSlopePts ;		/* Additional central points to consider */
  SINT4 iEdgePts ;		/* Edge points for determining interpolation */
#define SPFILTMAXPTS 30		/*   Max filter width (center plus one side) */

  FLT4  fClutWidthMS ;		/* Clutter width (m/sec) for Gaussian model */
  UINT4 iWinType ;		/* Override of data window (one of WIN_XXX), */
#define SPFILT_USEWIN 0x0100	/*   but only if this flag bit is also set. */
} ;

struct rvp8SpecFiltIO {		/* DSP I/O version */
  SINT2 iType ;			/*   Filter Type (Must be first in I/O list) */
  SINT2 iMinWidth ;		/*   Minimum width (center plus one side) */
  SINT2 iSlopePts ;		/*   Additional central points to consider */
  SINT2 iEdgePts ;		/*   Edge points for determining interpolation */
  UINT2 iClutWidthMMS ;		/*   Clutter width (mm/sec) for Gaussian model */
  UINT2 iWinType ;		/*   Flag + Override of data window */
} ;

/* Filter selections for each range bin within a prescribed AZ/EL
 * solid angle sector.
 */
struct rvp8SectorFilters {
  SINT4 nBins ;			/* Number of bins in 'binFilters' */
  BIN2 iAzLo, iAzHi ;		/* AZ angle limits */
  BIN2 iElLo, iElHi ;		/* EL angle limits */
  UINT1 binFilters		/* Table of clutter filter choices for */
    [ RVP8MAXBINS ] ;		/*   each possible range bin. */
} ;

/* Sector blanking definitions
 */
struct rvp8SectorBlank {
  UINT1 lInUse ;		/* Include this sector */
  UINT1 lPedAngles ;		/* Used pedestal angles rather than Earth */
  char pad2x2[2] ;
  FLT4 fAzLo, fAzHi ;		/* AZ angle limits */
  FLT4 fElLo, fElHi ;		/* EL angle limits */
} ;

/* One waveform channel of an RVP8/Tx card
 */
struct rvp8TxChanSetup {
  SINT4 iMode ;			/* How this channel is configured */
#define TXCSMODE_UNUSED      0	/*   Unused (no signal is output) */
#define TXCSMODE_FIXEDFREQ   1	/*   Freerunning numerically controlled oscillator */
#define TXCSMODE_TXWAVEFORM  2	/*   Actual synthesized Tx waveform */
#define TXCSMODE_NUM       3

  FLT4  fFreqMHz ;		/* Desired NCO frequency (MHz) */
  UINT4 lPhaseMod ;		/* Phase modulate the NCO sinewave, or */
  FLT4  fPhaseDeg ;		/*   relative phase (Degrees) if unmodulated */
  UINT4 lAbruptPH ;		/* Make abrupt phase changes (else smooth) */
  FLT4  fPowerdBm ;		/* Output power level (dBm), expressed either */
  UINT4 lPeakPower ;		/*   as peak power or average power in pulse. */
} ;

/* Batch mode parameters configuration
 */
struct rvp8BatchSetup {
  UINT4 lAvailable ;		/* Provide BATCH major mode */
  FLT4  fLoPrfScl ;		/* Scale and offset for computing the low */
  FLT4  fLoPrfOff ;		/*   PRF from the high PRF. */
  FLT4  fSampsScl ;		/* Scale and offset for computing the number */
  FLT4  fSampsOff ;		/*   of low PRF pulses from high PRF pulses. */
  FLT4  fMaxUnfoldKM ;		/* Maximum range to unfold (km) */
  SINT4 iLoPrfAvgSide ;		/* Additional bins range averaged on each side */
  FLT4  fdBOverRefl ;		/* Power differences (in dB) required to declare */
  FLT4  fdBOverVel ;		/*   unobscured echos for reflectivity, velocity, */
  FLT4  fdBOverWid ;		/*   and width. */
  FLT4  fdBAddNseThr ;		/* Amount to increase low PRF noise threshold */
} ;

/* ------------------------------
 * This structure holds setup information that can be changed by
 * the user. Setup values are permitted to change at run time.
 * Many of the parameters will be overridden by user interface
 * commands.  Put any variable here if that variable is to have a
 * power-up value that can be changed by the user, or which is to
 * be preserved across startups.
 */
struct rvp8NV {
  char sVersion[8] ;		/* IRIS version when saved */

  SINT4 version ;		/* Major/Minor versions of the RVP8 */
  SINT4 minorev ;		/*   code that did the last save. */

  /* Physical PCI board (unit number) assignments.  Negative value
   * denotes that a card is not to be used.
   */
  SINT4 iIo62Card ;		/* Which I/O-62 card number to use (0-3) */
  SINT4 iRvp8RxCard ;		/* Primary receiver card number (0-1) */
  SINT4 iRvp8TxCard ;		/* Primary transmitter card number (0-1) */

  UINT4 lIo62LineDiags ;	/* Run external line diagnostics */
  UINT4 lPCIResetOnShutdown ;	/* Reset all PCI cards upon shutdown */

  UINT4 lRpcIrisServer ;	/* Provide IRIS RPC network status server */

  /* RVP8/Rx card faceplate I/O options
   */
  SINT4 iRxRS422Funcs[4] ;	/* Functions assigned to 9-pin connector, */
  UINT1 lRxRS422Comps[4] ;	/*   and which I/O pins to complement. */

  SINT4 iGps1ppsTickNS ;	/* Nanosecond offset of GPS 1-pps tick */

  /* The fundamental receiver mode (one of RXM_xxx) defines how the
   * RVP8 and RVP8/Rx cards are configured for data acquisition and
   * processing.  This parameter is not allowed to change once the
   * RVP8 is booted, and should not be referenced directly (See the
   * LRVP8_xxx macros).
   */
  SINT4 __iRxMode ;		/* Receiver mode, don't use directly */

  /* IFD sampling and configuration parameters
   */
  FLT4  fSyClk ;		/* IFD system clock frequency (MHz) */

  UINT4 ifdconf ;		/* IFD and Uplink configuration */
#define IFDCONF_AFCMFC   0x01	/*   Enable AFC/MFC functions */
#define IFDCONF_CLKLOCK  0x02	/*   Use phase locked acquisition clock */
#define IFDCONF_AFCXMIT  0x04	/*   Send AFC information on uplink */
#define IFDCONF_CDPROTO  0x08	/*   Use Cmd/Data protocol (else old 16-bit) */

  FLT4  fDitherPower ;		/* Desired A/D dither power level (dBm) */

  SINT4 iPllNumer ;		/* Numerator and Denominator for IFD */
  SINT4 iPllDenom ;		/*   phase locked loop */
  UINT4 lPllPosFreqDev ;	/* PLL has positive frequency deviation */

  SINT4 iwaveguide_length ;	/* 2-way total waveguide length (meters) */

  SINT4 iIFDAuxMode ;		/* How to use the auxiliary J4 clock */
#define IFDAUXM_UNUSED   0	/*   Not used at all */
#define IFDAUXM_CLKOUT   1	/*   Reference clock output */

  SINT4 iIFDAuxClkDiv ;		/* Clock divisor for IFDAUXM_CLKOUT mode */
#define IFDAUX_MINDIV    2
#define IFDAUX_MAXDIV  128

  /* I/Q pre-processing options
   */
  UINT4 iPhLock ;		/* Lock to Burst Pulse phase */
#define BPLOCK_NEVER      0	/*   Options are never to lock to the phase */
#define BPLOCK_ALWAYS     1	/*   of the burst, to always lock to it, or to */
#define BPLOCK_AUTO       2	/*   lock only when burst power really is present. */

  UINT4 lampc_inuse ;		/* Apply amplitude correction to incoming data */
  UINT4 iampc_expulses ;	/* Exponential decay pulse count */

  FLT4  fdbhead ;		/* Additional linearized saturation headroom */

  FLT4 fWideChanSepDB ;		/* Wide Dynamic Range Hi/Lo chan relative */
  FLT4 fWideChanSepDeg ;	/*   gain and phase difference. */
  FLT4 fWideChanErrDB ;		/* Maximum allowable error deviation from */
  FLT4 fWideChanErrDeg ;	/*   the above nominal values. */
  FLT4 fWideOverlapDB ;		/* Overlap/interpolate interval (dB) */

  /* Command interpreter settings
   */
  UINT4 pwinfo_ok ;		/* User PWINFO command can modify params */
  UINT4 trigwf_ok ;		/* User TRIGWF command can modify trigger timing */

  /* Trigger and pulsewidth definitions
   */
  SINT4 nTrigs ;		/* Actual number of user triggers */
  SINT4 nPolars ;		/*   and polarization control lines. */

  SINT4 nPWidths ;		/* Number of active pulsewidths */

  struct rvp8Pwdef pwdefs[RVP8NPWIDS] ; /* Pulse width definitions */

  UINT4 lextrig ;		/* Use external Pretrigger */
  UINT4 lextrig_rising ;	/* Pretrigger active on rising edge */
  UINT4 lextrig_synch ;		/* Pretrigger is synchronous with AQ clock */
  UINT4 lextrig_xmits ;		/* Pretrigger fires the xmitter (not RVP7 trigger) */

  UINT4 lAbsTrigs ;		/* Align triggers to absolute time */

  FLT4  fprf ;			/* PRF (Hertz) */
  SINT4 ipwidth ;		/* Pulsewidth index */

  UINT4 lpol_vhigh[2] ;		/* POLAR0/1 high for vertical polarization */

  SINT4 iPrtQuantMpy ;		/* Multiplier and Offset for PRT quantization */
  SINT4 iPrtQuantOff ;

  UINT4 tblank ;		/* Trigger blanking options */
                                /*   Low bits are mask of trigs to blank */
#define TBLANK_EXTSTS  0x10000	/*   Blank based on 'sTrigBlank' softplane input */
#define TBLANK_ANGLES  0x20000	/*   Blank according to AZ/EL angles */
#define TBLANK_NOISE   0x40000	/*   Blank during noise measurements */
#define TBLANK_AFFECTSDATA (TBLANK_EXTSTS | TBLANK_ANGLES)

#define RVP8SECTORBLANKS 8	/* Number of blanked sectors */
  struct rvp8SectorBlank sectorBlanks[ RVP8SECTORBLANKS ] ;

  UINT4 iRxTrigs ;		/* Bit mask of trigs defined relative to burst pulse */
#define RXTRIG_TRIG0           0    /* Low NTRIGS bits are user triggers */
#define RXTRIG_POLAR0  (NTRIGS+0)   /* Polarization switch points */
#define RXTRIG_TXPHASE (NTRIGS+NPOLARS) /* Tx phase line switch point */

  UINT4 lTrigMerge ;		/* Enable flag for trigger merging */
  UINT4 iTrigMerges[NTRIGS] ;	/* Bit masks of other triggers to merge into */

  /* Burst Pulse analysis and control parameters
   */
  UINT4 lifsign ;		/* IF increases for an approaching target */

  SINT4 iburst_window ;		/* Window to use for FIR design & burst analysis */

  FLT4  fburst_minpwr ;		/* Minimum power for valid burst (dBm) */
  FLT4  fburst_settle ;		/* Settling time (to 1%) of burst estimator */

  UINT4 lEnableBPT ;		/* Burst Pulse Tracking is enabled */

  UINT4 lBpHuntEnable ;		/* Enable Time/Freq hunt for missing burst */
  SINT4 iBpHuntFreqs ;		/* Number of frequency intervals to search */
  FLT4  fBpHuntSettle ;		/* Settling time when changing AFC */
  UINT4 lBpHuntAutoEnable ;	/* Enable automatic hunting on powerup */
  FLT4  fBpHuntAutoPeriod ;	/* Period of automatic hunts (sec) */

  UINT4 lsimburst ;		/* Simulate burst pulse samples */
  FLT4  fafc_simlo ;		/* Simulated AFC low and high limits (Mhz) */
  FLT4  fafc_simhi ;

  /* Automatic Frequency Control (AFC) parameters
   */
  SINT4 iAfcServoType ;		/* Type of AFC feedback loop */
#define AFCSERVOTYPE_DC     0	/*   Direct Current frequency vs voltage */
#define AFCSERVOTYPE_MOTOR  1	/*   Motor/Integrator actuator */

  FLT4  fafc_hist0 ;		/* Inner and outer hysteresis zones (KHz) */
  FLT4  fafc_hist1 ;
  FLT4  fafc_fwide ;		/* Wider error tolerance during data processing */
  FLT4  fafc_maxslew ;		/* Maximum slew rate and slope of AFC.  Physical */
  FLT4  fafc_slope ;		/*   units vary for different types of AFC servos. */
  FLT4  fafc_warmup ;		/* Delay time before applying AFC (sec) */
  UINT4 lafc_freqinc ;		/* Burst frequency increases with positive voltage */
  FLT4  fafc_minslew ;		/* Minimum AFC slew rate (See comments above) */

  UINT4 iafc_format ;		/* Coding format for the AFC level */
#define AFCFMT_FMTMASK   0x0F	/* Format is encoded in these bits */
#define AFCFMT_BINARY    0x00	/*   Straight Binary */
#define AFCFMT_BCD       0x01	/*   Straight BCD */
#define AFCFMT_8BIN4BCD  0x02	/*   (8-bit binary) , (4-digit BCD)  */
#define AFCFMT_ACTLOW    0x10	/* Bits are active low */

  SINT4 iafc_lolimit ;		/* -100% --> low limit value */
  SINT4 iafc_hilimit ;		/* +100% --> high limit value */

  /* RVP8/Tx transmitter card configuration.
   */
  FLT4  fTxClk ;		/* Transmit synthesizer clock frequency (MHz) */
  UINT4 lTxClkLock ;		/* Lock the transmit clock to an external reference */
  SINT4 iTxNumer, iTxDenom ;	/* P/Q for internal VCXO clock locking */
  SINT4 iTxPllSource ;		/* Source for external reference 0:BNC 1:RxClk */
  SINT4 iTxModeBNC ;		/* BNC Mode (follows TX8BNCMODE_XXX) */
  SINT4 iTxClkDivBNC ;		/* BNC output clock divider */
  FLT4  fTxOpAmpFix ;		/* Obscure, see pcicards/rvp8tx_wave.c */

  struct rvp8TxChanSetup txChans[2] ;

#define NPULSEDTXCHANS \
  ( ( ( GM->nv.txChans[0].iMode == TXCSMODE_TXWAVEFORM ) ? 1 : 0 ) + \
    ( ( GM->nv.txChans[1].iMode == TXCSMODE_TXWAVEFORM ) ? 1 : 0 ) )

#define LTXCOMPRESSED( PWDEF ) \
  ( NPULSEDTXCHANS && ((PWDEF)->txSpecs.iWaveType != WAVETYPE_CWPULSE) )

  /* Transmit phase control
   */
  UINT4 lphcode_inuse ;		/* Provide transmission phase coding */
  UINT4 iphcode_nbits ;		/* Number of binary angle bits to use */
  FLT4  fphcode_idle ;		/* Phase angle to use during idle fixed phase */
  SINT4 iphcode_seq ;		/* Phase code sequence (one of PHSEQ_xxx) */

  /* Signal processing options
   */
  struct opprm opprm ;		/* Operational Parameters */
#if SOPRM_TOTAL_ARGS & 1	/* Pad out to a multiple of four whenever */
  UINT2 padOpprm ;		/*   we're a UINT2 short. */
#endif

  SINT4 iMinRayHoldoff ;	/* Minimum ray holdoff (percent of dwell) */

  FLT4  fCltSigSlope[2] ;	/* Residual clutter noise rejection margin */
  FLT4  fCltSigBegDB[2] ;	/*   slope (dB/dB) and beginning Clut/Nse (dB). */

  UINT4 force_window ;		/* Force selection of window multiplier */
  UINT4 force_r2 ;		/* Force R0/R1/R2 processing */
  UINT4 force_avgcth ;		/* Force clutter thresholding when range averaging */
  UINT4 force_ctrigok ;		/* Force custom triggers okay in normal algorithms */
  UINT4 force_unfdiff ;		/* Force velocity unfolding by simple differences */
  UINT4 force_2Dpass ;		/* Force 2D speckle/unfold final pass */

  struct rvp8SpecFilt spfilts[NFILTS] ; /* Spectral filter parameters */
  UINT4 lAnySizeSpec ;		/* Spectrum sizes need not be powers of two */

  FLT4  fnoise_sim ;		/* Simulated noise level (dB down from top) */
  FLT4  fnoise_prf ;		/* Noise sampling PRF (Hertz) */
  FLT4  fnoise_range ;		/* Noise sampling range (Km) */

  UINT4 lIQPackHiSNR ;		/* Using High-SNR packed (I,Q) format */

  /* Interference filter parameters
   */
  SINT4 iIntFlt ;		/* Interference filter currently running */
#define INTFLTJMA1  1		/*   Traditional JMA filter */
#define INTFLTJMA2  2		/*   Variation for additive interference */
#define INTFLTJMA3  3		/*   Variation with better statistics */
#define INTFLTNUM   3		/*   Number of available filters */
  FLT4  fIntFltP1 ;		/* Interference filter parameter #1 */
  FLT4  fIntFltP2 ;		/* Interference filter parameter #2 */

  /* Whitening filter parameters
   */
  FLT4  fwht_sqi_slope ;	/* Secondary SQI calculated from primary */
  FLT4  fwht_sqi_offset ;	/*   using this slope and offset. */

  FLT4  fwht_szFlatness ;	/* Max power dissimilarity left/right octants */
  FLT4  fwht_szHiPowReject ;	/* Reject octants with this much power above min */
  FLT4  fwht_szMaxPhaseErr ;	/* Maximum KEY phase error for success */

  UINT4 lwht_revertSZ ;		/* Revert SZ algorithms to random phase */

  /* Setup parameters for custom major modes, and special setup
   * parameters for odd cases within standard modes.
   */
  struct rvp8BatchSetup batch ;	/* BATCH mode configuration */
  UINT4 lNonFilteredPPP ;	/* Use timedomain (non-filtered) PulsePair */

  /* Simple legacy simulator of output ray byte codes
   */
  UINT4 isr_inuse ;		/* Simulate output rays w/bands of data */
  SINT4 isr_startbin ;		/*  Starting bin number */
  SINT4 isr_width ;		/*  Width (in bins) of each band */
  SINT4 isr_count ;		/*  # of bands to insert */
  SINT4 isr_datastart ;		/*  Starting data value */
  SINT4 isr_rangeinc ;		/*  Data increment in range */

  /* Live simulator of physical targets whose (I,Q) samples will be
   * summed into the real or simulated receiver data.
   */
  UINT4 lForcePhysTargSim ;	/* Force target simulation (for debugging) */
  struct dspPhysTargSim physTargSims[ DSPPHYSTARGSIMCOUNT ] ;

  /* LOG Video options
   */
  UINT4 llogvid_inuse ;		/* Optional LOG video output generation */
  FLT4  flogvid_dbmspan ;	/*   Span of the LOG video in dB */
  FLT4  flogvid_dacpcnt ;	/*   Percent of DAC voltage range used */
  UINT4 llogvid_rxsec ;		/*   Data are from secondary receiver */

  /* Real-Time-Monitor (serial health monitor) configuration
   */
  UINT4 lrtm_enab ;		/* Messages enabled */
  char  srtm_device[40] ;	/* TTY or FIFO device name */
  SINT4 irtm_baud ;		/* Baud rate for the TTY */
  FLT4  frtm_rate ;		/* Rate of printing (lines/sec) */
  UINT4 irtm_msgs ;		/* Which messages are selected */
#define RTM_BURSTFREQ     0	/*   Burst frequency estimate */
#define RTM_BURSTLEVEL    1	/*   Burst pulse power level */
#define RTM_AFCINFO       2	/*   AFC information */
#define RTM_PWIDTH        3	/*   Current pulse width */
#define RTM_PRF           4	/*   PRF */
#define RTM_LOGNOISE      5	/*   Noise Level (in LOG units) */
#define RTM_POLAR         6	/*   Polarization */
#define RTM_IFDINFO       7	/*   IFD, uplink, downlink info */
#define RTM_BPTSLEW       8	/*   Burst Pulse Tracker timing slew */
#define RTM_NUMESSAGES    9	/* Total number of possible messages */

  /* These parameters only affect the operation of the plotting
   * commands, and are not used during normal processing.
   */
  SINT4 ibplt_amplz ;		/* Burst Plot - Amplitude zoom factor */

  SINT4 ibplt_tspan ;		/* Burst Plot - Time span of plot (usec) */
#define BMAXTSPAN 5000		/* Max time span (usec) */

  SINT4 ibplt_pcode ;		/* Burst Plot - Which data to plot */
#define BPLCODE_SAMPLES    0
#define BPLCODE_TXWAVE     1
#define BPLCODE_NCODES     2
				/*  -------------------- */
  SINT4 ibspc_navg ;		/* Burst Spectra - Number of pulses averaged */
  SINT4 ibspc_dbscale ;		/* Burst Spectra - Scale factor for data */
  SINT4 ibspc_pcode ;		/* Burst Spectra - Which data to plot */
#define BSPCODE_FILTER     0
#define BSPCODE_BURST      1
#define BSPCODE_BOTH       2
#define BSPCODE_NCODES     3
				/*  -------------------- */
  SINT4 irplt_amplz ;		/* Receiver Plot - Amplitude zoom factor */
  SINT4 irplt_navg ;		/* Receiver Plot - Number of pulses averaged */
  FLT4  frplt_start ;		/* Receiver Plot - Data start range (usec) */

  SINT4 irplt_tspan ;		/* Receiver Plot - Data width (usec) */
#define RMAXTSPAN 1000		/* Max time span (usec) */

  SINT4 irplt_pcode ;		/* Receiver Plot - Which data to plot */
#define RPLCODE_SAMPLES    0
#define RPLCODE_SAMP_POW   1
#define RPLCODE_POWER      2
#define RPLCODE_SPECTRUM   3
#define RPLCODE_NCODES     4
				/*  -------------------- */
  SINT4 iaplt_dopHz ;		/* Ambiguity Plot - Doppler shift in Hertz */
  SINT4 iaplt_peakDB ;		/* Ambiguity Plot - Peak value shown on plot */
  SINT4 iaplt_ptune ;		/* Ambiguity Plot - Which tuning parameter to change */
  SINT4 iaplt_pcode ;		/* Ambiguity Plot - Which data to plot */
#define APLCODE_RANGAMB    0
#define APLCODE_WAVEFORM   1
#define APLCODE_NCODES     2

  UINT4 lplt_secondary_if ;	/* Plot secondary intermediate frequency params */

  /* Front panel display options
   */
  SINT4 iFPDDeciDigitsAZ ;	/* Number of decimal places to show for */
  SINT4 iFPDDeciDigitsEL ;	/*   front panel display AZ/EL angles. */

  /* Angle selection and TAG line modifiers
   */
  SINT4 iDfltAngSrc ;		/* Default source for live measured angles */
#define RVPANGSRC_NONE       0	/*   RVP8 does not sample live angles at all */
#define RVPANGSRC_SIMULATOR  1	/*   Internal angle simulator */
#define RVPANGSRC_TAGS       2	/*   Parallel TAG input lines */
#define RVPANGSRC_SYNCHRO    3	/*   Software S/D converter */
#define RVPANGSRC_NCODES     4

  SINT4 iSynchroFreqHZ ;	/* Frequency of synchro reference voltage */

  UINT4 tinvert0, tinvert1 ;	/* Bits to invert in TAG inputs 0-15 & 16-31 */
  UINT4 iOffPre0, iOffPre1 ;	/* Binang preliminary offset for TAGs */
  FLT4  fMpyAng0, fMpyAng1 ;	/* Angle multiplier for offset TAGs */
  UINT4 toffang0, toffang1 ;	/* Binang offset after multiplication */

  /* Dual Polarization (ZDR/PHIdp/KDP) setup parameters
   */
  UINT4 lCoPolOnPriRx ;	        /* Co-Polarized signal is always on primary Rx */

  FLT4  fkdp_length ;		/* Range interval for least-squares fit */
  FLT4  fphidp_offset ;		/* PHIdp fixed angle offset */

  UINT4 iPolFlags ;		/* Polarization processing flags */
				/*   (See POLFLAG_XXX definitions) */

  /* Customizations for ORDA backpanel and triggers.
   */
  UINT4 iOrdaTPoints[2] ;	/* Trigger selections (One of ORDA_TP_xxx) */

  /* AFC pinmap definitions for uplink snooper.  A signal (Data
   * bit, GND, or +5) is chosen to be attached to each pin of the
   * 25-pin D connector on the RVP7/DAFC.
   */
  SINT4 pinmap[25] ;		/* Assignment of signals to pins */
#define PINMAP_GND 31		/*   Special codes for GND */
#define PINMAP_VCC 30		/*   and VCC. */

  SINT4 faultpin ;		/* Which pin to use as "fault" input */
#define FAULTPIN_MASK    0x001F	/*   Pin 1-25, 0:Unused */
#define FAULTPIN_ACTLOW  0x0020	/*   Active low input */
#define FAULTPIN_MAXVAL (25 | FAULTPIN_ACTLOW)
} ;

/* ******************************************************
 * *                                                    *
 * *  RVP8 Global Configuration/Control Shared Segment  *
 * *                                                    *
 * ******************************************************
 */
/* ---------------------------------------------------
 * Structures customized for RVP8 global shared memory
 * ---------------------------------------------------
 */
/* Structure to hold all of the results from a noise measurement
 */
struct rvp8Noise {
  FLT4 fimean ;			/* Mean value of I   */
  FLT4 fqmean ;			/* Mean value of Q   */
  FLT4 fisqmean ;		/* Mean value of I^2 */
  FLT4 fqsqmean ;		/* Mean value of Q^2 */
  FLT4 fNoiseDbm ;		/* Present noise level in dBm */
  FLT4 fNoiseStdvDB ;		/* Noise sample standard deviation (dB) */
} ;

/* Task identification information describing the meaning of the data
 * that are being collected.
 */
struct rvp8TaskID {
  UINT2 iSweep ;		/* Sweep number within a task */
  UINT2 iAuxNum ;		/* Auxiliary sequence number */
  char sTaskName[1+DSPTASKNAMELEN] ; /* Name of the task (NULL terminated) */
  UINT1 iScanType ;		/* Scan geometry, one of SCAN_xxx */
  char pad22x2[2] ;
} ;
struct rvp8TaskID_IO {		/* I/O Version encoded as UINT2's */
  UINT2 iSweep, iAuxNum ;
  UINT2 sTaskName[DSPTASKNAMELEN/2] ;
  UINT2 iScanType, pad22x3[3] ;
} ;

/* Information about the active range mask that is loaded into the
 * RVP8/Rx receiver card.
 */
struct rngMaskInfo {
  SINT4 iDataBins ;		/* Number of data bins (excludes burst bin) */
  UINT4 lDataZero ;		/* Range zero (burst) is also a data bin */
  SINT4 iHwBitTab[RVP8MAXBINS];	/* Hardware bits selected for each range */
  FLT4  fRangesKM[RVP8MAXBINS]; /* Table of defined data bin ranges (km) */
} ;

/* Burst pulse amplitude tracking
 */
struct bpMagAvg {
  FLT4  fMagAvg ;		/* Evolving average of magnitudes */
  SINT4 iGoodMags ;		/* # of successive pulses w/ mag close to avg */
} ;

/* Information about the measured burst phase sequence
 */
struct phseq_sz {		/* Info needed for SZ(8/64) coding */
  /* These are the sequences of eight phase differences (in 1/16's of a
   * revolution) across the code, along with the corresponding unit
   * rotation vectors.
   */
  SINT4 iPhDiffs[8] ; FLT4 fRotVecs[8][2] ;
} ;
struct burstPhseq {	  /* Container for any burst phase analysis */
  UINT4 lError ;	      /* Error in measured phase sequence */
  union {		      /* Info for each type of modulation */
    /* For SZ analysis, the [2] dimension is for spectral octants that
     * are offset by 1 or 3 from each other.
     */
    struct phseq_sz sz[2] ;	
  } u ;
} ;

/* Threshold comparison and control structure for one individual type
 * of data parameter.
 */
struct threshOneParam {
  UINT2 iTCF ;			/* Threshold control flag bit mask */
  char pad2x2[2] ;
  FLT4 fLOG_dB, fLOG_lin  ;	/* LOG (total power) threshold */
  FLT4 fCCR_dB, fCCR_lin ;	/* Clutter Correction threshold */
  FLT4 fSQI ;			/* SQI threshold */
  FLT4 fWSP_dB, fWSP_lin  ;	/* Weather Signal Power threshold */
} ;

/* Major mode information that is relevant to both RVP8/Main and
 * RVP8/Proc.
 */
struct rvp8MajorMode {
  SINT4 iMode ;			/* The current major mode (PMODE_...) */
#define PMODE_NONE   (-1)	/*   Code for no major mode at all */

  UINT4 lMakesSpec ;		/* Spectra are generated as a byproduct */
  UINT4 iNumTripsUsed ;		/* Number of return trips of echo we'll use */
  UINT4 lMoreThanOneRxTS ;      /* Uses data from more than one receiver at a time */
  UINT4 iTriggerOptions ;	/* Trigger setup/load options */
#define MMTRIG_PROCDEPENDENT 0x01 /* Processor parameters affect trigger patterns */
#define MMTRIG_DEFERTILLPROC 0x02 /* Defer trigger loadup until PROC command runs */
#define MMTRIG_NOEXTERNTRIG  0x04 /* Do not allow external trigger to be used */
} ;

/* A customized sequence of PRTs, and an alternate trigger pattern to
 * be used within prescribed angle sectors.
 */
struct prtSequence {		/* A customized sequence of PRTs */
  SINT4 nPRTs ;			/*   Number of PRTs actually in use */
  FLT4  fPRTs[MAXTRIGPERIODS] ; /*   List of PRTs (usec) */
} ;
struct prfSector {		/* Special instructions within a sector */
  BIN2 iAzLo, iAzHi ;		/*   AZ angle limits */
  BIN2 iElLo, iElHi ;		/*   EL angle limits */
  FLT4 fPRF ;			/*   Alternate PRF to use */
  UINT1 lInUse ;		/*   This sector is being used */
  char  pad13x3[3] ;
} ;
#define TBANK_PRFSECT( LOWPRF, SECTOR ) \
  ( TBANK_CUSTOM + ( 2 * (SECTOR) ) + ((LOWPRF) ? 1 : 0) )

/* Trigger definition parameters that are required by the RVP8/Rx PCI
 * driver.  This is common information that is shared among all of the
 * trigger banks and waveforms.
 */
struct rvp8TgInfo {		/* Trigger parameters required by the driver */
  UINT4 lextrig ;		/*   Use external trigger input */
  UINT4 lextrig_rising ;	/*     based on rising or falling edge, */
  UINT4 lextrig_synch ;		/*     and whether sync'd to aqclk, */
  FLT4  fextdelay ;		/*     and specified pretrigger delay. */
  UINT4 lAbsTrigs ;		/*   Align triggers to absolute time */
  SINT4 iPrtQuantMpy ;		/*   Multiplier and Offset for */
  SINT4 iPrtQuantOff ;		/*     PRT quantization. */
  UINT4 iPolVHighBits ;		/*   Bits indicating polarization line polarity */
  SINT4 nPolars ;		/*   Number of user trigs allocated for polarization */
  SINT4 iFrameOpts ;		/*   Timeframe options for waveform Begin/End */
#define TGFRAME_DLYBEG  0x1	/*     Place the time delay to achieve the requested */
#define TGFRAME_DLYEND  0x2	/*       PRT at begin/end/both sides of the waveform. */
  volatile const		/*   Bit masks of other triggers to merge */
    UINT4 *pTrigMerges ;	/*     into, or NULL if none. */
  UINT4 iBlankableTrigs ;	/*   Bit mask of blankable triggers */
} ;

/* ------------------------------
 * The RVP8ALLPARAMS macro provides a maintainable way of performing
 * operations on the entire set of parameters.  Note that the order of
 * these statements may be important depending on the specific macro
 * operations being performed (e.g., the ordering of multiple output
 * parameters is determined here).
 */
#define RVP8ALLPARAMS( MACRO ) \
  MACRO(    dbz, DBZ   )  MACRO(    dbt, DBT   )  MACRO(    vel, VEL   ) \
  MACRO(    wid, WID   )  MACRO(    zdr, ZDR   )  MACRO(    kdp, KDP   ) \
  MACRO(  phidp, PHIDP )  MACRO(  rhohv, RHOHV )  MACRO(    sqi, SQI   ) \
  MACRO(   ldrh, LDRH  )  MACRO(   rhoh, RHOH  )  MACRO(   phih, PHIH  ) \
  MACRO(   ldrv, LDRV  )  MACRO(   rhov, RHOV  )  MACRO(   phiv, PHIV  ) \
  MACRO(  flags, FLAGS )

#define PPRMS_N_DBZ      0	/* Possible bits in iPPrms. */
#define PPRMS_N_DBT      1	/* Can't use RVP8ALLPARAMS, */
#define PPRMS_N_VEL      2	/*   though we'd like to.   */
#define PPRMS_N_WID      3
#define PPRMS_N_ZDR      4
#define PPRMS_N_KDP      5
#define PPRMS_N_PHIDP    6
#define PPRMS_N_RHOHV    7
#define PPRMS_N_SQI      8
#define PPRMS_N_LDRH     9
#define PPRMS_N_RHOH    10
#define PPRMS_N_PHIH    11
#define PPRMS_N_LDRV    12
#define PPRMS_N_RHOV    13
#define PPRMS_N_PHIV    14
#define PPRMS_N_FLAGS   15
#define PPRMS_N_COUNT     16	/* Number of defined parameter types */

#define PPRMS_DBZ    BIT( PPRMS_N_DBZ   )
#define PPRMS_DBT    BIT( PPRMS_N_DBT   )
#define PPRMS_VEL    BIT( PPRMS_N_VEL   )
#define PPRMS_WID    BIT( PPRMS_N_WID   )
#define PPRMS_ZDR    BIT( PPRMS_N_ZDR   )
#define PPRMS_KDP    BIT( PPRMS_N_KDP   )
#define PPRMS_PHIDP  BIT( PPRMS_N_PHIDP )
#define PPRMS_RHOHV  BIT( PPRMS_N_RHOHV )
#define PPRMS_SQI    BIT( PPRMS_N_SQI   )
#define PPRMS_LDRH   BIT( PPRMS_N_LDRH  )
#define PPRMS_RHOH   BIT( PPRMS_N_RHOH  )
#define PPRMS_PHIH   BIT( PPRMS_N_PHIH  )
#define PPRMS_LDRV   BIT( PPRMS_N_LDRV  )
#define PPRMS_RHOV   BIT( PPRMS_N_RHOV  )
#define PPRMS_PHIV   BIT( PPRMS_N_PHIV  )
#define PPRMS_FLAGS  BIT( PPRMS_N_FLAGS )

#define PPSET_ZDR   ( PPRMS_ZDR   | PPRMS_KDP   | PPRMS_PHIDP | PPRMS_RHOHV )
#define PPSET_LDRH  ( PPRMS_LDRH  | PPRMS_RHOH  | PPRMS_PHIH                )
#define PPSET_LDRV  ( PPRMS_LDRV  | PPRMS_RHOV  | PPRMS_PHIV                )

#define PPSET_POLAR ( PPSET_ZDR   | PPSET_LDRH  | PPSET_LDRV )

/* Some additional DBFLG_xxx bits that are only used internally to the
 * RVP8.  These must occupy the upper 16-bits, since the lower sixteen
 * are actual output bits.
 */
#define DBFLG_VALIDREFL  0x00010000 /* Similar to the public 'obscured' flags, */
#define DBFLG_VALIDVEL   0x00020000 /*   but only used internally within these */
#define DBFLG_VALIDWID   0x00040000 /*   BATCH routines. */
#define DBFLG_PTCLTALL   0x00080000 /* All bins affected by point clutter censoring */

/* ===============================================
 * ========== The Global Section Itself ==========
 * ===============================================
 * Shared structure for configuration and control.  The data that
 * reside here are maintained by the RVP8 master threads, but can be
 * viewed by any other processes that need information about the
 * current processor state.  The memory is writable only by the RVP8
 * master.
 */
struct rvp8Global {
  /* ------------------------------
   * Burst pulse amplitude tracking and phase analysis
   */
  FLT8 fBPMagExpMul ;		/* Multiplier for exponential averaging */
  struct bpMagAvg bpMagAvgs[MAXVIQPERBIN] ; /* Burst mag info for each Rx */

  struct burstPhseq bpPhseq ;	/* Burst phase analysis results */

  /* ------------------------------
   * RVP8 command line options and startup flags
   */
#define NOCMDARG 0x80000000
  UINT4 lVerbose ;		/* Add more details to requested printouts */
  UINT4 lNoDiags ;		/* Skip running initial diagnostics */
  UINT4 lForceVer ;		/* Attempt to use mismatched hardware */
  UINT4 lRxSwap ;		/* Swap Rx0/Rx1 functions */
  UINT4 lShowAQ ;		/* Show pulses acquired from receiver card(s) */
  UINT4 lNoFork ;		/* Do not fork any compute processes */
  SINT4 nProcs ;		/* Number of compute processes to use */
  UINT4 lExposeIO ;		/* Show I/O with host computer */
  UINT4 lShowCPIs ;		/* Show Coherent Processing Intervals */
  SINT4 iTxCardForce ;		/* Force a particular Tx or Io card to */
  SINT4 iIoCardForce ;		/*   be used, including -1 for none. */
  SINT4 iRxModeForce ;		/* Select fundamental RVP8/Receiver mode */
  UINT4 lShowRxMode ;		/* Show operations for present receiver mode */
  UINT4 lShowRTCtrl ;		/* Show realtime callback timer activity */
  UINT4 lRunAsDaemon ;		/* Run as background daemon process */
  UINT4 lCoreDump ;		/* Try to dump core on abnormal exits */
  UINT4 lLogFile ;		/* Log to rvp8.log rather than to stderr */

  /* ------------------------------
   * Fundamental operating mode of the RVP8 and RVP8/Rx card.  This
   * location is set from NVRAM just once during powerup and is never
   * altered again.  The macros should be used both by RVP8MAIN and
   * RVP8PROC for testing various derived conditions.
   */
  SINT4 iRxMode ;		/* One of RXM_xxx */

#define LRVP8_DUALPOL   LRXM_DUALPOL  ( GM->iRxMode )
#define LRVP8_DUALCARDS LRXM_DUALCARDS( GM->iRxMode )
#define LRVP8_DUALFILT  LRXM_DUALFILT ( GM->iRxMode )
#define LRVP8_HALFBAND  LRXM_HALFBAND ( GM->iRxMode )
#define LRVP8_CARD2IQ   LRXM_CARD2IQ  ( GM->iRxMode )
#define LRVP8_CARD2TS   LRXM_CARD2TS  ( GM->iRxMode )
#define LRVP8_DUALATOD  LRXM_DUALATOD ( GM->iRxMode )
#define LRVP8_VIEW2IFS  LRXM_VIEW2IFS ( GM->iRxMode )

  /* ------------------------------
   * The "non-volatile" setup information.
   */
  struct rvp8NV nv ;		/* Internal working copy */
  struct rvp8NV nvSaved ;	/* Version presently saved on disk */
  struct rvp8NV nvMIN ;		/* Minimum setup values */
  struct rvp8NV nvMAX ;		/* Maximum setup values */

  /* ------------------------------
   * IFD and Clutter Filter configurations
   */
  SINT4 azelSectFiltLimits[2] ;      /* Low/High limits of valid table entries */
  struct rvp8SectorFilters	     /* Clutter filter selection versus range */
    azelFilters[ RVP8ASTABSIZE+1 ] ; /*   for many AZ/EL sectors, plus one NULL. */

  FLT4 fsdbmburst ;		/* Burst A/D full scale power (dBm) */
  FLT4 fsdbmlevel ;		/* Receiver A/D full scale power (dBm) */
  SINT4 iSatPowerCode ;		/* 4-bit code conveying saturation power */

  /* Noise levels for each available pulsewidth, and from all possible
   * receivers.
   */
  struct rvp8Noise noises[ RVP8NPWIDS ][ MAXVIQPERBIN ] ;
  BIN2 iNoiseAZ, iNoiseEL ;	/* Mean AZ/EL of last noise sample */

  /* ------------------------------
   * Normal Doppler processing variables.
   */
  UINT4 iPPrms ;     /* Individual processed parameters (PPRMS_xxx) */

  SINT4 iSpecTS ;		/* Spectra/Timeseries (SPEC_xxx & TSOUT_xxx) */
#define TSOUT_ALLMASKS (BIT(TSOUT_SPEC) | BIT(TSOUT_TS8) | BIT(TSOUT_TS16))

  SINT4 iUmode ;		/* 0:No unfolding 1:2/3  2:3/4  3:4/5 */
  UINT4 lSimulateTS ;		/* Using simulated time series samples */
  UINT4 lSimulateLowPRF ;	/* Lo/Hi PRF flag for next incoming pulse */
  UINT4 lUseTargSim ;		/* Use internal target simulator */

  struct rvp8MajorMode MMode ;	/* Generic major mode info (Main & Proc) */

  struct threshOneParam		/* Individual threshold criteria for each */
    allThresh[PPRMS_N_COUNT] ;  /*   separate data parameter. */

  /* ------------------------------
   * Range mask information
   */
#define USERMASKLEN 512		/* Number of 16-bit range mask words */
  UINT2 iUserRangeMask[ USERMASKLEN ] ;
  SINT4 iBinCount ;		/* # bins total in range mask */
  SINT4 iAvgBins ;		/* # bins after range averaging */
  SINT4 iRangeAvg ;		/* # bins to average in range */

  struct rngMaskInfo rngMaskInfo ; /* RVP8/Rx range mask details */

  /* The custom range normalization lookup table spans five decades
   * from 0.01 km to 1000 km with 50 steps within each range.  Values
   * are in dB, thus this is a log power versus log range table, and
   * will generally be quite linear.
   */
#define CUSTOMRNVSIZE 251
  FLT4 fcustom_rnvtab[ CUSTOMRNVSIZE ] ;

  /* ------------------------------
   * Trigger Generation
   */
  struct prtSequence custTrig ;	/* Optional custom sequence of trigger PRTs */

  FLT4  fprfgen ;		/* Nominal trigger generator rate (Hz) */
  UINT4 iTrigAltered ;		/* Triggers altered (from RXTGALT_xxx) */
  struct rvp8TgInfo tgInfo ;	/* Params used to create the current triggers */

  UINT4 iTrigFeatures ;		/* Attributes of the present suite of triggers */
#define TGFEAT_PRFSECT  0x0001	/*   Can perform variable PRF sectors */

  BIN2  iPhseqTab[RVP8MAXPULSES] ; /* Custom table of binary angle Tx phases */
  SINT4 iPhseqLen ;		/* Length of table */

  struct prfSector		/* Custom triggers within sectors */
    sectTrig[ PRFSECT_MAXSECTS ] ;

  /* ------------------------------
   * Angle synchronization for ray boundaries
   */
  BIN2 astab[ RVP8ASTABSIZE ] ; /*   Antenna sync table binary angles */
  SINT4 assize ;		/*   Actual loaded size */

  /* ------------------------------
   * Results for a GPARM command
   */
  struct gparm gparm ;
				/* Diagnostic results "A" register bits */
#define RVP8DGA_RXCARD1  0x0001	/*   Error in first/second */
#define RVP8DGA_RXCARD2  0x0002	/*     RVP8/Rx card. */
#define RVP8DGA_TXCARD1  0x0004	/*   Error in first/second */
#define RVP8DGA_TXCARD2  0x0008	/*     RVP8/Tx card. */
#define RVP8DGA_IOCARD1  0x0010	/*   Error in first/second */
#define RVP8DGA_IOCARD2  0x0020	/*     IO62 card  */
#define RVP8DGA_LDSETUP  0x0040	/*   Error loading setup files */
#define RVP8DGA_ANTLIB   0x0080	/*   Could not access the antenna library */
#define RVP8DGA_FORK     0x0100	/*   Problem creating compute processes */
#define RVP8DGA_SPLCONF  0x0200	/*   Error(s) in softplane configuration */
#define RVP8DGA_SIGNALS  0x0400	/*   Messages signaled during startup */
#define RVP8DGA_NOTROOT  0x0800	/*   RVP8 running without 'root' privileges */
#define RVP8DGA_DAEMON   0x1000	/*   Problem creating daemon process */
#define RVP8DGA_CONSIST  0x2000	/*   Inconsistent setup values detected */
} ;

/* ***********************************************
 * *                                             *
 * *  RVP8 Live Time Series Shared Data Segment  *
 * *                                             *
 * ***********************************************
 */
/* Shared structures for live (I,Q) pulse headers and time series data
 * that are being acquired by the RVP8 master threads.  These data are
 * accessed by any number of readers in an eavesdropping manner via
 * the RVP8TS API.  The memory is writable only by the RVP8 master.
 */

/* ------------------------------
 * The RVP8 pulse header contains all of the housekeeping information
 * that might change from pulse to pulse.  The information that will
 * be different for each receiver within a given pulse appears in a
 * substructure dimensioned by the maximum number of receivers.
 */
struct rvp8PulseHdrRx {
  SINT4 iDataOff ;		/* Offset of the start of this pulse in fIQ[] */
  FLT4  fBurstMag ;             /* Burst pulse magnitude (amplitude, not power) */
  BIN2  iBurstArg ;             /* Burst phase changes (PrevPulse - ThisPulse) */
  UINT1 iWrapIQ ;		/* Data wraparound count for validity check */
  char  pad11x9[9] ;
} ;

struct rvp8PulseHdr {
  UINT1 iVersion ;		/* Version of this public structure */
				/*   0: Initial public element layout */
#define PHDRVERSION    1	/*   1: Added iNanoUTC precise time field */

  UINT1 iFlags ;		/* Control flags */
#define PHDRFLG_VALID     0x01  /*   Header plus associated data are all valid */
#define PHDRFLG_DATAGAP   0x02  /*   One or more pulses are missing prior to this one */
#define PHDRFLG_BNKFIRST  0x04  /*   First pulse within the present trigger bank */
#define PHDRFLG_BNKLAST   0x08  /*   Last pulse within the present trigger bank */
#define PHDRFLG_BNKBEGIN  0x10  /*   Trig bank (possibly unchanged) is just beginning */
#define PHDRFLG_BLANKED   0x20  /*   Triggers were blanked on this pulse */

  UINT2 iMSecUTC ;		/* MiliSeconds absolute time \ See also */
  UINT4 iTimeUTC ;		/* Seconds absolute time     / iNanoUTC */

  UINT4 iBtimeAPI ;		/* Local time (ms) when pulse arrived in API */
  UINT4 iSysTime ;		/* IFD system clock time (see rvp8PulseInfo.fSyClkMHz) */
  UINT4 iPrevPRT, iNextPRT ;	/* SysTime ticks to previous/next pulse */

  UINT4 iSeqNum ;		/* Sequence number by which pulses are referenced */
  UINT1 iAqMode ;		/* Sequence numbers for acquisition mode */

  UINT1 iPolarBits ;		/* State of polarization control bits */
  BIN2  iTxPhase ;		/* Phase angle of transmit data */

  UINT4 iNanoUTC ;		/* Nanoseconds absolute time */

  char pad36x12[12] ;

  BIN2  iAz, iEl ;		/* Antenna azimuth and elevation */

  SINT2 iNumVecs ;		/* Actual (I,Q) vectors (burst+data) for each Rx, */
  SINT2 iMaxVecs ;		/*   and maximum number (which sets data stride). */
  UINT1 iVIQPerBin ;		/* (I,Q) vectors/bin, i.e., # of Rx channels */

  UINT1 iTgBank ;		/* Trigger bank number (one of TBANK_xxx) */
  UINT2 iTgWave ;		/* Trigger waveform sequence number within a bank */

  struct uiqbits uiqPerm ;	/* User specified bits (Permanent) */
  struct uiqbits uiqOnce ;	/* User specified bits (One-Shot) */

  struct rvp8PulseHdrRx		/* Header information that is different for */
    Rx[ MAXVIQPERBIN ] ;	/*   each receive channel. */

  char pad116x56[56] ;
} ;

/* ------------------------------
 * The auxiliary information structure holds data that remain constant
 * within each block of pulses that are acquired in a consistent
 * manner, i.e., within each "ProcSection" interval.
 */
struct rvp8PulseInfo {
  UINT1 iVersion ;		/* Version of this public structure */
                                /*  0: Initial public element layout */
                        	/*  1: Added fDBzCalib, iSampleSize, iMeanAngleSync, 
                                 *     iFlags, iPlaybackVersion */
#define PINFOVERSION   2	/*  2: taskID.iScanType */

  UINT1 iMajorMode ;		/* RVP8 major mode, one of PMODE_xxx */  
  UINT1 iPolarization ;		/* Polarization selection, one of POL_xxx */
  UINT1 iPhaseModSeq ;		/* Tx phase modulation, one of PHSEQ_xxx */

  struct rvp8TaskID taskID ;	/* Task identification info */

  char sSiteName                /* Data are from this site */
    [1+DSPSITENAMELEN] ; 	/*   (NULL terminated) */

  UINT1 iAqMode ;		/* Acquisition mode (filled in by local API) */
  UINT1 iUnfoldMode ;		/* Dual-PRF unfolding  0:None, 1:2/3, 2:3/4, 3:4/5 */

  UINT1 iPWidthCode ;		/* Pulse width selection (0 to RVP8NPWIDS-1), */
  FLT4  fPWidthUSec ;		/*   and actual width in microseconds */

  FLT4  fDBzCalib ;		/* Calibration reflectivity (dBZ at 1 km) */
  SINT2 iSampleSize ;		/* Number of pulses per ray */
  BIN2  iMeanAngleSync ;	/* Mean angle sync ray spacing */

  UINT4 iFlags ;		/* Various bit flags */
#define RPIF_ANGLESYNCD   0x00000001 /* Angle synchronization was being used */

  SINT2 iPlaybackVersion ;	/* Allows playback tagging, zeroed initially */

  char pad66x46[46] ;

  FLT4 fSyClkMHz ;		/* IFD system (XTAL) clock frequency (MHz) */
  FLT4 fWavelengthCM ;		/* Radar wavelength (cm) */
  FLT4 fSaturationDBM ;         /* Power (dBm) corresponding to MAG(I,Q) of 1.0 */

  FLT4 fRangeMaskRes ;		/* Spacing between range bins (meters) */
  UINT2				/* Bit mask of bins that have actually been */
    iRangeMask[ USERMASKLEN ] ;	/*   selected at the above spacing. */

  FLT4 fNoiseDBm   [ MAXVIQPERBIN ] ; /* Noise level in dBm, and standard */
  FLT4 fNoiseStdvDB[ MAXVIQPERBIN ] ; /*   deviation of measurement in dB. */
  FLT4 fNoiseRangeKM ;		/* Range (km) and PRF (Hz) at which the */
  FLT4 fNoisePRFHz ;		/*   last noise sample was taken. */

  UINT2 iGparmLatchSts[2] ;	/* Copies of latched and immediate status */
  UINT2 iGparmImmedSts[6] ;	/*   words from the GPARM structure. */
  UINT2 iGparmDiagBits[4] ;	/* Copies of GPARM diagnostic bits */

  char sVersionString[12] ;	/* IRIS/RDA version (full Major/Minor string) */
				/*   that created the data. */

  char pad1212x1188[1188] ;
} ;

/* ======================================================
 * ========== The IQCtrl/IQData Segment Itself ==========
 * ======================================================
 */
/* Memory is sized according to the number of shared (I,Q) vectors
 * that that can be held at once, and the number of pulse headers that
 * can be held at once.  The former is sized at runtime, so only the
 * default value is given here.
 */
struct rvp8AqModeNow {		/* Transient AqMode info for this API only */
  UINT4 iTopSeqNum ;		/*   AqMode ends just before this sequence number */
  UINT1 lValidTSM ;		/*   Above slot holds a valid sequence number */
  char pad5x3[3] ;
} ;
#define RVP8IQDVECS_DFLT   2400000 /* 2.0 sec @ 125-meter bins */
#define RVP8IQDHDRS          40000 /* 2.0 sec @ 20KHz PRF */

struct rvp8IQCtrl {		/* ===== Control portion ===== */
  /* The following indicies manage the pulse headers and data storage
   * areas.  IHDRWRITEOFF is the index of the next header to be
   * written.  The previous header, therefore, always contains the
   * most recent valid entry.  The LVALID, IAQMODE, and ISEQNUM header
   * flags should be used to decide which headers can be grabbed.
   */
  SINT4 iHdrWriteOff ;		/* Offset in hdrs[] of next header to write */

  UINT4 iSeqNumReference ;	/* For assigning header sequence numbers, */
  UINT1 iAqModeReference ;	/*   and acquisition mode serial numbers. */
  char  pad9x3[3] ;

  /* The actual (I,Q) data for each receiver can reside in any of the
   * data areas for other timeseries APIs.  This provides a powerful
   * mechanism for sharing and re-presenting data from a given source
   * without requiring any expensive memory copies.
   */
  SINT4 iDataUnits[ MAXVIQPERBIN ] ; /* TS unit holding data for each Rx */

  /* The type of writer client that is currently attached to and in
   * control of this API, along with the type of writer client that we
   * really want to be controlling it.
   */
  SINT4 iCurrentWriterClient ;	/* The writer who is active now */
  SINT4 iDesiredWriterClient ;	/* Who we really want */

  /* List of client types that are currently attached to each TS unit
   * within the API.
   */
#define RVP8TSUNITDIM     8	/* Sized here, but cross checked */
#define RVP8TSCLIENTDIM  12	/*   in rdasubs_lib.h */
  UINT1 lUnitClientTab[ RVP8TSUNITDIM ][ RVP8TSCLIENTDIM ] ;

  /* Circular buffer of pulse headers.
   */
  struct rvp8PulseHdr hdrs[ RVP8IQDHDRS ] ;

  /* Auxiliary information structures are indexed by the acquisition
   * mode byte that is associated with each pulse.  These hold fixed
   * information that applies to all pulses that were acquired within
   * a given ProcSection.
   */
  struct rvp8PulseInfo infos[ 256 ] ;

  /* Additional transient information about each acquisition mode is
   * stored here.  These data are only of interest in the current API,
   * and thus should not appear in the pulse info structures.
   */
  struct rvp8AqModeNow aqNows[ 256 ] ;
} ;

struct rvp8IQData {		/* ===== Data portion ===== */
  SINT4 iFIQWriteOff ;		/* Offset in fIQ[] of next data to write */
  UINT1 iWrapIQReference ;	/* For assigning IQ buffer wraparound counts, */
  char  pad5x3[3] ;
  /* Circular buffer of floating (I,Q) data sample pairs.  The first
   * dimension is configured at runtime, generally according to the
   * 'nIQDVecs' field of the 'rvp8tsConfig' structure.  Obviously,
   * this must be the last element in the structure definition.
   */
  FLT4 fIQ[ 1 ][2] ;		/* The (I,Q) data themselves */
} ;

/* ****************************************
 * *                                      *
 * *  Shared Memory Segment Between RVP8  *
 * *      Master & Compute Threads        *
 * *                                      *
 * ****************************************
 */

/* ------------------------------
 * Semaphores to lock the data and control structures that are shared
 * between RVP8/Main and RVP8/Proc, and event flags to wake up those
 * processes.
 */
#define RVP8_CTINFO_SEM       (RVP8_GLOBAL_CLUSTER + 0)
#define RVP8_MEMBARRIER_SEM   (RVP8_GLOBAL_CLUSTER + 1)

#define RVP8_CMD_DONE_EF      (RVP8_GLOBAL_CLUSTER + 0)
#define RVP8_PROC_SLOT0_EF    (RVP8_GLOBAL_CLUSTER + 1) /* \             */
#define RVP8_PROC_SLOT1_EF    (RVP8_GLOBAL_CLUSTER + 2) /*  \  Must be   */
#define RVP8_PROC_SLOT2_EF    (RVP8_GLOBAL_CLUSTER + 3) /*  / sequential */
#define RVP8_PROC_SLOT3_EF    (RVP8_GLOBAL_CLUSTER + 4) /* /             */
#define RVP8_MEMBARRIER0_EF   (RVP8_GLOBAL_CLUSTER + 5) /* \             */
#define RVP8_MEMBARRIER1_EF   (RVP8_GLOBAL_CLUSTER + 6) /*  \  Must be   */
#define RVP8_MEMBARRIER2_EF   (RVP8_GLOBAL_CLUSTER + 7) /*  / sequential */
#define RVP8_MEMBARRIER3_EF   (RVP8_GLOBAL_CLUSTER + 8) /* /             */

#define RVP8_GLOBAL_SEM_NUM   (2) /* Number of semaphores, followed by */
#define RVP8_GLOBAL_EF_NUM    (9) /*   this number of event flags. */

#if ( MAXPROCS != 4 )
#error Please manually maintain the RVP8 Sem and EF counts
#endif

/* ------------------------------
 * Control and data structures for the various processing phases.
 */
struct ctRngInfo {		/* Assignment of range bins to processors */
  SINT4 iStartBin ;		/*   Starting (input) bin to be handled */
  SINT4 nBins ;			/*   Number of contiguous (input) bins */
} ;

struct ctAvailBin {		/* Housekeeping info about available bins */
  UINT1 lValid ;		/*   Data for this range bin are valid */
  UINT1 iWinType ;		/*   Type of window (if any) applied here */
  UINT1 lSaturatedIF ;		/*   Some of the timeseries data were saturated */
  char pad3x3[3] ;
  UINT2 nPulses ;		/*   Number of pulses used to compute this bin */
  UINT4 iFlags ;		/*   Propagated forward, interpreted per major mode*/
  FLT4  fRangeKM ;		/*   Range in KM of this bin */
} ;
#if RVP8MAXPULSES >= 0x10000
#error Please repair nPulses field in struct ctAvailBin
#endif

/* ------------------------------
 * Information that is specific to each parallel compute process.
 */
struct ctInfo {
  /* Process ID of this compute thread.  Set by the compute thread
   * itself on startup, and zeroed by the exit handler on shutdown.
   */
  int iPID ;			/* PID of startup compute thread */
  int iPolicy, iPriority ;	/* Linux scheduling policy & priority */

  /* Unique Version/Build code for making sure that Main and Proc are
   * both compiled with the same version of headers.
   */
  UINT4 iUniqueCore ;		/* Unique build info for the CORE, */
  UINT4 iUniqueOpen ;		/*   OPEN, and SITE portions. */
  UINT4 iUniqueSite ;

  UINT4 lProfiling ;		/* Compiled with profiling */
  UINT4 lHaveRootPrivs ;	/* We can get root privileges if needed */

  /* When each compute thread is awakened by the RVP8/Master, the work
   * that it is supposed to do is coded into the following array.  The
   * compute thread stores the NONE code and wakes up the RVP8/Master
   * when the operation is done.
   */
  SINT4 iCommand ;		/* Command for this compute thread */
#define CTCMD_NONE         0	/*   No operation, or last command done */

#define CTCMD_INITMMODE    1	/*   Initialize for running new major mode */
#define CTCMD_EXITMMODE    2	/*   Exit current major mode, freeing resources */

#define CTCMD_INITPSECT    3	/*   Initialize for running new PROC section */
#define CTCMD_EXITPSECT    4	/*   Exit current PROC section, freeing resources */

#define CTCMD_BINMOMENTS   5	/*   Run ctBinMoments (autocors at each bin) */
#define CTCMD_ALGORPASS    6	/*   Run all subsequent processing phases */

#define CTCMD_NOPROTOCHK 0x100	/* Flag bit to suppress protocol checks */

  /* Memory barrier index.  This is used in conjunction with the set
   * of RVP8_MEMBARRIERn_EF event flags to allow the compute processes
   * to synchronize to each other.
   */
  UINT4 iMemBarrierIndex ;	/* Bumped for each lock/sync */
} ;

/* ------------------------------
 * Coherent Processing Interval definitions
 */
struct limbCPI {		/* One CPI limb (starting or ending edge) */
  struct rvp8PulseHdr PHdr ;	/*   The pulse header for this limb */
} ;
struct procInCPI {		/* Processing interval within all/part of a CPI */
  UINT4 lValid ;		/*   Contents of this structure are valid */
  SINT4 iStart, nPulses ;	/*   Interval of pulses being described */
  SINT4 iMinAqBins ;		/*   Min/Max/Avg number of bins that were acquired */
  SINT4 iMaxAqBins ;		/*     properly within this subset of CPI pulses. */
  FLT4  fAvgAqBins ;
  SINT4 iTripBins ;		/*   Number of bins considered 'first trip' */
  FLT4  fSamplePRF ;		/*   Instantaneous PRF for this pulse interval */
  FLT4  fNominalPRF ;		/*   Nominal PRF (when unfolding) */
} ;
#define MAXCPIPROCS 4		/* Max sections to process in a complex CPI */

struct oneCPI {			/* Coherent Processing Interval spec */
  SINT4 nPulses ;		/*   Number of pulses in whole CPI */
  FLT4  fLateness ;		/*   Lateness (0-1) for pacing purposes */
  SINT4 iNextSyncIndex ;	/*   Sync angle index to apply to next CPI */
  UINT2 iMismatchTS ;		/*   Mismatched TS parmaeters (from MMTS_xxx) */
  UINT1 lEndedTS ;		/*   This CPI resulted from the TS writer ending */
  UINT1 lHasBlankedTrigs ;	/*   Triggers are blanked in one or more pulses */
  UINT1 lDataWereUsed ;		/*   A ray was actually computed from this CPI */
  UINT1 lLowPRF ;		/*   Low-PRF block of pulses (during Dual-PRF) */
  UINT1 lContiguous ;		/*   No discontinuous hop from prior CPI */
  char pad19x1[1] ;
  UINT4 nCPIs ;			/*   Number of CPIs within this PROC section */
  SINT4 iAzElFilterSlot ;	/*   Which clutter filter slot to use */
  SINT4 iFirstBinInTS ;		/*   Offset of first range bin in current TS */
  struct procInCPI procs[ MAXCPIPROCS ] ; /* Individual sections to be processed */
  struct limbCPI start, end ;	/*   Start and end limbs of the CPI */
} ;

/* ===============================================
 * ========== The Main/Proc Area Itself ==========
 * ===============================================
 * This shared memory area is private between the RVP8 Master threads
 * and the RVP8 Compute threads.  The control and data passing needed
 * to implement the PROC command can all be found here.  This memory
 * is writable by both the master and compute threads.
 */
struct rvp8MMProc {
  /* Configuration and control information that is unique to each
   * compute thread.
   */
  struct ctInfo ctInfos[ MAXPROCS ] ;

  /* Build dates (as text strings) for each of the dynamic libraries
   * that we're using.
   */
#define RVP8DATELENGTH 80
  char rvp8ProcCoreDate[ RVP8DATELENGTH ] ;
  char rvp8ProcOpenDate[ RVP8DATELENGTH ] ;
  char rvp8ProcSiteDate[ RVP8DATELENGTH ] ;

  /* Information about the next CPI to be processed.  The CPI itself
   * is accompanied by conversion information for each of the PRFs
   * that might be contained within it.
   */
  struct oneCPI procCPI ;
  struct data_convert convs[ MAXCPIPROCS ] ;

  /* Which algorithm processing pass is currently being executed, and
   * bit mask of processing passes needed by the compute threads for
   * the current major mode.
   */
#define MAXALGORPASSES 12	/* Max number of algorithm passes */
  SINT4 iAlgorPass ;		/* Current pass running */
  UINT4 iAlgorPassMask ;	/* Mask of all defined passes */

  /* Assignment of range bin intervals to each of the available PROC
   * threads.  Note that the special BINMOMENTS phase runs before any
   * of the sequential processing passes and distributes the bins to
   * each processing thread based on how the (I,Q) data can be most
   * efficiently extracted from the timeseries API.
   */
  struct ctRngInfo rayRngInfo[ MAXPROCS ] ;

  /* The following two arrays are filled in by the compute threads as
   * they process their assigned range bins.  The RAW items are set
   * for each input range bin that was available during processing.
   * The RAW items should be only be addressed by input bin number.
   * Likewise, the AVG items are set to indicate that range-averaged
   * bin data were available, on the assumption that the table is
   * addressed by averaged bin number.
   *
   * Note that the raw items are usualy fixed according to the range
   * mask, but the averaged items might vary slightly due to data
   * dependent decisions about which raw bins get included in those
   * averages.
   */
  struct ctAvailBin ctAvailRaw[ RVP8MAXBINS ] ; /* Available raw bins, and */
  struct ctAvailBin ctAvailAvg[ RVP8MAXBINS ] ; /*   range averaged bins. */

  /* Formatted output parameters from the PROC threads are stored in
   * the following arrays.  They are sized for 2-byte data, but 1-byte
   * results would simply be packed into the low bytes.
   */
#define RVP8PARAMALLOC( LOWERCASENAME, UPPERCASENAME ) \
  UINT2 LOWERCASENAME[ RVP8MAXBINS ] ;

  RVP8ALLPARAMS( RVP8PARAMALLOC )

  /* ------------------------------
   * NOTE: The following two arrays are only used when timeseries or
   *       spectra need to be viewed by the RVP8/Main threads.  There
   *       is a cache performance penalty if this memory is used all
   *       the time.
   */

  /* Dynamic dimensions for the following arrays of timeseries and
   * spectra.  These should be written using the MMVIQSETDIMS macro.
   */
  SINT4 _nPulses ;		/* Number of pulses in this CPI, and */
  SINT4 _iVIQPerBin ;		/*   number of receive channels. */

#define MMVIQSETDIMS( PTR, VIQPERBIN, NPULSES ) \
  do { PTR->_iVIQPerBin = (VIQPERBIN) ; PTR->_nPulses = (NPULSES) ; } while(0) 

  /* intermediate storage for timeseries that are generated during the
   * processing of bins in the current major mode.  The timeseries
   * array is the actual working storage that is used by the compute
   * processes, and holds the data that will be output whenever the
   * PROC command requests them.  Thus, the FIQ[] data are available
   * in all major modes.
   *
   * The data area is dynamically dimensioned according to the sample
   * size and number of receivers being used.  It should be accessed
   * only through the MMFIQ macro:
   *
   *      [ BinNumber ][ ReceiveChan ][ PulseNumber ][ I/Q ]
   */
  FLT4 _fIQ[ MAXVIQPERRAY ][ 2 ] ;

#define MMVIQINDEX( PTR, BIN, RX, PULSE ) \
  ( (PULSE) + (PTR->_nPulses * ((RX) + (PTR->_iVIQPerBin * (BIN)))) )

#define MMFIQ( PTR, BIN, RX, PULSE ) \
  ( (FLT4 *)&PTR->_fIQ[ MMVIQINDEX( PTR, BIN, RX, PULSE ) ][0] )

  /* Intermediate storage for power spectra that are generated during
   * the processing of bins in the current major mode.  Not all modes
   * will fill in FSPEC[]; but for those that do, it is these data
   * that will be output when the PROC opcode requests them.  Indexed
   * dynamically similar to the IQ data area:
   *
   *      [ BinNumber ][ ReceiveChan ][ SpectralTerm ]
   */
  FLT4 _fSpec[ MAXVIQPERRAY ] ;

#define MMFSPEC( PTR, BIN, RX ) \
  ( (FLT4 *)&PTR->_fSpec[ MMVIQINDEX( PTR, BIN, RX, 0 ) ] )
} ;

#endif /* #ifndef SIGMET_RVP8_H */
