/* **********************************************************************
 * *                                                                    *
 * *             Common Memory Definitions for RCP8 Threads             *
 * *                                                                    *
 * **********************************************************************
 * File: include/rcp8main.h
 *
 *                  COPYRIGHT (c) 2002, 2004, 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.
 */
/* Include requirements: sigtypes.h rcp8.h softplane_lib.h */

/* *******************************
 * *                             *
 * * Message Catalog Definitions *
 * *                             *
 * *******************************
 */
#define      CHAT_CLOSED        1
#define RCP8_CHAT_CLOSED       (RCP8_FACILITY + CHAT_CLOSED)
#define      INTERR             2
#define RCP8_INTERR            (RCP8_FACILITY + INTERR)
#define      EXITREQUEST        3
#define RCP8_EXITREQUEST       (RCP8_FACILITY + EXITREQUEST)
#define      EXITFORCE          4
#define RCP8_EXITFORCE         (RCP8_FACILITY + EXITFORCE)
#define      INU_INVALID        5
#define RCP8_INU_INVALID       (RCP8_FACILITY + INU_INVALID)
#define      AZ_ANGLE_SKIPPED   6
#define RCP8_AZ_ANGLE_SKIPPED  (RCP8_FACILITY + AZ_ANGLE_SKIPPED)
#define      EL_ANGLE_SKIPPED   7
#define RCP8_EL_ANGLE_SKIPPED  (RCP8_FACILITY + EL_ANGLE_SKIPPED)
#define      AZ_ANGLE_VALID     8
#define RCP8_AZ_ANGLE_VALID    (RCP8_FACILITY + AZ_ANGLE_VALID)
#define      EL_ANGLE_VALID     9
#define RCP8_EL_ANGLE_VALID    (RCP8_FACILITY + EL_ANGLE_VALID)
#define      SHAFT_CAL_FAILED   10
#define RCP8_SHAFT_CAL_FAILED  (RCP8_FACILITY + SHAFT_CAL_FAILED)
#define      AZ_CAL_JUMP        11
#define RCP8_AZ_CAL_JUMP       (RCP8_FACILITY + AZ_CAL_JUMP)
#define      EL_CAL_JUMP        12
#define RCP8_EL_CAL_JUMP       (RCP8_FACILITY + EL_CAL_JUMP)

#ifndef MESSAGE_ONLY                      

/* ***********************
 * *                     *
 * * Compilation Support *
 * *                     *
 * ***********************
 */

/* Debug and development flags
 */
#define STDIO_SETUP_TTY          0 /* Put setup TTY on STDIO for debugging */
#define EXIT_HANDLER_MESSAGES    0 /* Exit handler diagnostic messages */
#define SIGNAL_HANDLER_MESSAGES  0 /* Signal handler diagnostic messages */

#define ORDAPROTOTYPE            0 /* ORDA prototype RxNet7 w/custom lines */

/* Check compilation flags
 */
#ifndef _REENTRANT
#error Missing _REENTRANT symbol required by pthreads
#endif

#ifdef __PROFILING		/* See rda/rdasubs/threads.c */
#define pthread_create gprof_pthread_create
#define LPROFILING TRUE
#else
#define LPROFILING FALSE
#endif

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Explaination of various units:
 *   T-Units      Tach units,   -100 to  +100, generally floating
 *   T12-Units    Tach units,  -2047 to +2047, generally integer
 *   D-Units      Drive units,  -100 to  +100, generally floating
 *   D12-Units    Drive units, -2047 to +2047, generally integer
 */
/* Conversions to and from D12/T12 integer units.
 */
#define  MAKE12( FVAL ) ( NINT( 20.48 * (FVAL) ) )
#define  SEXT12( TD12 ) ( ( ((SINT4)(TD12)) << 20 ) >> 20 )
#define MAKE100( TD12 ) ( (MULS( (TD12), 625 ) + 64) >> 7 )
#define MAXV12 (2047)

/* Macros used in the original RCP02.  Not really necessary in the
 * embedded Linux version , but included to simplify porting of code.
 */
#define  MULU( ARG1, ARG2 ) ( (UINT4) ( ((UINT2)(ARG1)) * ((UINT2)(ARG2)) ) )
#define  MULS( ARG1, ARG2 ) ( (SINT4) ( ((SINT2)(ARG1)) * ((SINT2)(ARG2)) ) )
#define LMULU( ARG1, ARG2 ) ( (UINT4) ( ((UINT4)(ARG1)) * ((UINT4)(ARG2)) ) )
#define LMULS( ARG1, ARG2 ) ( (SINT4) ( ((SINT4)(ARG1)) * ((SINT4)(ARG2)) ) )

#define BIN2DEG  ( 360.0 / 65536.0 )
#define DEG2BIN  ( 65536.0 / 360.0 )

/* *****************************************
 * *                                       *
 * * Private RCP8 Structures and Constants *
 * *   (i.e., inappropriate for rcp8.h)    *
 * *                                       *
 * *****************************************
 */

/* Timing parameters
 */
#define RCP8POLLMICROSEC  40000	/* Default polling rate (microseconds) */

#define CSTICK_SY_PERIOD 0.0200000 /* Period of control/status tick (sec ) */
#define CSTICK_IO_PERIOD 0.0025000 /*   for system/IO62 scheduling */

#define SERVO_SY_PERIOD  0.0200000 /* Period of primary servo tick (sec) */
#define SERVO_IO_PERIOD  0.0016000 /*   for system/IO62 scheduling */

#define BMON_PERIOD      0.0500000 /* Background monitor period (sec) */

#define IO62_TIMER_SHARED    0	/* IO62 timer fixed allocations */
#define IO62_TIMER_CSTICK    1
#define IO62_TIMER_SERVO     2

/* BGMSAMPS is the number of tach and drive samples that the servo
 * loop could acquire in two periods of the background monitor.
 * BGMHSIZE is the number of tach and drive history points that the
 * background monitor will store for performance analysis purposes.
 * It must be a power of two to permit efficient circular ring
 * calculations.
 */
#define BGMTCSEC 1.0		/* Data duration for tach cal check */
#define BGMUASEC 2.5		/* Data duration for unresponsive ant check */

#define BGMHSIZE 32		/* Sized for maximum time sample that will */
				/*  be required at 2*BMON_PERIOD spacing.  */
#define BGMINDEX(IVAL) ((IVAL) & (BGMHSIZE-1))

#define BGMSAMPS(SERVOPERIOD) ( (int)(0.5 + ((2.0 * BMON_PERIOD)/(3.0 * (SERVOPERIOD)))) )
#define BGMTCSIZ ( (int)(0.5 + (BGMTCSEC / (2.0 * BMON_PERIOD))) )
#define BGMUASIZ ( (int)(0.5 + (BGMUASEC / (2.0 * BMON_PERIOD))) )

/* Run the unresponsive antenna checks only if this expression computes
 * to TRUE.
 */
#define RUN_UANT_CHECKS ( ldrcp_sio_servos_c )

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * AZ and EL axis servo control structure.
 */
struct rcp8_aeservo {
  UINT1 imode ;			/* Servo mode for each axis */
#define SRVMODE_DISABLED 0
#define SRVMODE_TACHRATE 1
#define SRVMODE_VELOCITY 2
#define SRVMODE_POSITION 3
#define SRVMODE_MOTORDRV 4

  char pad1x1[1] ;

  /* Only one of the following variables will be actively used at any
   * given time (depending on imode).  A union is not used, however,
   * so that all values can be retained independntly.
   */
  SINT2 itach12 ;		/* Desired measured pedestal velocity (T12-Units) */
  SINT2 ivel ;			/* Desired earth velocity (binang/sec) */
  UINT2 ipos ;			/* Desired earth angle (binary angle) */
  SINT2 idrive ;		/* Desired motor drive (D12-Units) */

  /* The following variables are internal requests that are computed
   * by the servos themselves.  They should not be altered externally.
   */
  UINT2 ih_vel ;		/* Desired earth velocity (binang/sec) */
  UINT2 ih_pedvel ;		/* Desired pedestal velocity (binang/sec) */

  char pad14x2[2] ;
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * AZ and EL axis status structure.
 */
#define AESIGN( STATUS ) ( ((STATUS)->lAuxAntReverse) ? -1 : 1 )

struct rcp8_aestatus {
  UINT2 imespos ;		/* Measured pedestal angle (binary angle), */
  UINT2 ipedpos ;		/*   and pedestal angle of selected antenna. */
  UINT4 ipedposTick ;		/* Time of trusted pedestal position */

  UINT2 iAuxAntOffset ;		/* Offsets from measured-->real angles */
  UINT1 lAuxAntReverse ;	/* Reverse sign of measured angles */
  UINT1 lAuxAntAdd180 ;	        /* Add 180-degrees to measured angles */

  SINT2 ipedvel ;		/* Pedestal velocity (binang/sec) */
  SINT2 itach ;			/* Tachometer measurement (T12-Units) */
  SINT2 idrive ;		/* Present drive output level (D12-Units) */
  char pad18x2[2] ;

  UINT2 ipos ;			/* Earth angle (binary angle) */
  SINT2 ivel ;			/* Earth velocity (binang/sec) */
  SINT4 ivel64x ;		/* For Earth velocity smoothing */

  SINT4 intverr ;		/* Integral of velocity error */

  UINT2 iStepperPhase ;		/* Optional stepper motor phase (binang) */

  SINT2 ivel_shdn_time ;	/* Time out counter for velocity overshoots */

  UINT2 isoftlimits[2] ;	/* Lower and upper soft limits (binang)*/
  UINT2 ishutlimits[2] ;	/* Lower and upper shutdown limits (binang)*/

  /* List of most recent sixteen earth angle positions.  Used only when
   * stabilization is running, for the purpose of estimating the earth
   * angular velocity.
   */
  UINT2 iearth_pos_list[16] ;	/* Earth angle history list */

  UINT2 ilastpos ;		/* Last position servo request */
  UINT1 lhysteresis ;		/* Position servo outside of zone */
  UINT1 lLastSkipped;           /* Last position insert was skipped */

  /* The "xxxQtab[]" tables are filled in with instantaneous samples
   * from the servo thread.  This preserves the recent history of
   * these measurements.  The tables are sized to hold 5 seconds of
   * data in the worst case.
   */
#define QTABSIZE ( (int)( 5.0 / (3 * MIN( SERVO_SY_PERIOD, SERVO_IO_PERIOD )) ) )

  SINT2 imestachQtab[QTABSIZE] ; /* Measured tach history list (T12-Units) */
  SINT2    itachQtab[QTABSIZE] ; /* Filtered tach history list (T12-Units) */
  SINT2   idriveQtab[QTABSIZE] ; /* Drive history list (D12-Units) */
  SINT2  imesposQtab[QTABSIZE] ; /* Measured angle list (binang) */

  /* The following variables are used by the background antenna
   * monitor checks.  Groups of "xxxQtab[]" values are summed by the
   * background monitor thread to form the "xxxlist[]" tables.  The
   * reason for performing the two-tier sum of the tach and drive
   * levels is to insure that monitor_ih() gets an accurate
   * representation of the mean value.
   */
  SINT2 ibgm_index ;		/* Index of last tach/drive/pos sample */
  SINT2 ibgm_hold ;		/* Hold-off counter before running checks */

  SINT2 itcal_tavg ;		/* Averaged tach level over TCALSEC interval */
  SINT2 itcal_dpdt ;		/* Estimated velocity over same interval */

  SINT2 iuant_terror ;		/* Unresponsive ant check tach error */
  SINT2 iuant_shdn_time ;	/* Timer for shutdown */

  SINT2   itachlist[BGMHSIZE] ;	/* Tach history list (T12-Units) */
  SINT2  idrivelist[BGMHSIZE] ;	/* Drive history list (D12-Units) */
  UINT2 imesposlist[BGMHSIZE] ;	/* Measured angle list (binang) */

  /* The following pedestal position history table is used to estimate
   * pedestal velocity when tachometers are not available.  The drive
   * history is used to extrapolate the tach estimate forward to the
   * current time.
   */
#define VTACHSIZE 128		/* Must be power of two */
#define VTACHINDEX( IVAL ) ((IVAL) & (VTACHSIZE-1))
  SINT2 ivtach_mespos[VTACHSIZE] ;
  SINT2 ivtach_drives[VTACHSIZE] ;
  SINT2 ivtach_hold ;		/* Hold-off till valid history */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Working copies of parameters that define the Azimuth and Elevation
 * axes.  These are often merely converted versions of a corresponding
 * item in the user-interface setup structures.  This structure exists
 * so that real time operations can be performed efficiently using
 * precomputed constants.
 */
struct rcp8_aework {
  SINT2 ibps_to_t12 ;		/* Convert  binang/sec --> 12-bit Tach */
  SINT2 it12_to_bps ;		/* Convert  12-bit Tach --> binang/sec */

  FLT4 ftach_speed_level ;	/* Floating speed/level (for monitor only) */

  SINT2 iantsim_accel ;		/* Max simulated acceleration */

  char  pad10x2[2] ;
  SINT4 idrive_slew ;		/* Max 64x slew rate / tick */

  UINT2 iangle_mask ;		/* Bit mask for incoming angles */
  UINT2 iangle_offset ;		/* Angle offset that must be added */

  SINT2 imotor_psustain ;	/* Motor sustain drives in positive and */
  SINT2 imotor_nsustain ;	/*  negative directions (D12-Units) */

  SINT2 idrive_pslope ;		/* Nominal drive slopes in positive and */
  SINT2 idrive_nslope ;		/*  negative directions (D/T-Units) */

  SINT2 ivel_max ;		/* Maximum servo velocity (T12-Units) */
  SINT2 ivel_deadzone ;		/* Velocity feedback deadzone (T12-Units) */
  SINT2 ivel_slope ;		/* Velocity feedback slope (D/dT-Units) */

  SINT2 intverr_scl ;		/* Integrator gain (D/dT-Units) */
  SINT4 intverr_max ;		/* Max integrated velocity error (T12-Units) */

  SINT2 ivel_shdn ;		/* Shutdown velocity (T12-Units) */
  SINT2 ivel_shdn_time ;	/* Maximum # ticks of excess velocity */

  SINT2 itcal_shdn_pslope ;	/* High and low slopes for tachometer cal */
  SINT2 itcal_shdn_nslope ;	/*  consistency check (dimensionless). */
  SINT2 itcal_shdn_offset ;	/* Fixed offset tolerance (binang/sec) */

  SINT2 iuant_shdn_terr ;	/* Max tach prediction error (T12-Units) */
  SINT2 iuant_shdn_time ;	/* Max # ticks with such error */

  UINT2 ipservo_hyst[2] ;	/* Pos servo hysteresis (binang) */
  UINT2 ipservo_pos[2] ;	/* Pos servo break angles (binang) */
  UINT2 ipservo_vel[2] ;	/* Pos servo break velocities (T12-Units) */
  UINT2 ipservo_slope[3] ;	/* Pos servo slopes (T12 / deg) */

  SINT2 idrive_offset ;		/* Drive offset value (D12-units) */
  SINT2 itach_offset ;		/* Tachometer offset value (T12-units) */

  SINT2 iaccelim_drive ;	/* Model-based drive window (D12-units) */
  SINT2 iaccelim_zreach_mpy ;	/* Multiplier for reach toward zero drive */

  SINT2 it0decay ;		/* Expected decay of initial tach */
  SINT2 idrivexp[BGMUASIZ] ;	/* Exponential decay of drive */

  char  pad132x2[2] ;
  SINT2 ivtach_npairs ;		/* Number of position pairs to difference */
  SINT4 ivtach_normsum ;	/* Normalizing sum */
  SINT4 ivtach_mintravel ;	/* Minimum travel in integration window */
  SINT2 ivtach_t0decay ;	/* Decay of oldest tach point */
  SINT2 ivtach_drivexp[VTACHSIZE/2] ;	/* Exponential decay of drive */

  char  pad278x2[2] ;
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Unified Radar/Antenna control structure.  All control operations and
 * output changes that the RCP performs are requested via the contents
 * of this structure.
 */
struct rcp8_bit_control {
  UINT1 auxcnt[NSPL_CNTBYTES] ;	/* Auxiliary unnamed control lines */
  UINT1 lnoisegen_on ;		/* Noise source Off/On */
  UINT1 lsiggen_on ;		/* Signal generator Off/On */
  UINT1 lsiggen_cw ;		/* Signal generator Pulse/CW output */
  UINT1 lShaftForceCal ;        /* Force calibration of the shaft encoders */
  SINT2 isiggen_level ;		/* Signal generator level (dBm) */
  UINT1 lpwidth0 ;		/* Pulse-Width bit 0 */
  UINT1 lpwidth1 ;		/* Pulse-Width bit 1 */
  UINT1 lradiate ;		/* Radiate */
  UINT1 lservopwr ;		/* Servo Power */
  UINT1 ltrpower ;		/* Transmitter/Receiver Power */
  UINT1 lreset ;		/* External reset */
  UINT1 lirismode0 ;		/* IRIS mode bit 0 */
  UINT1 lirismode1 ;		/* IRIS mode bit 1 */
  UINT1 lirismode2 ;		/* IRIS mode bit 2 */
  UINT1 lnstokay0 ;		/* Network status for site 0 */
  UINT1 lnstokay1 ;		/* Network status for site 1 */
  UINT1 lnstokay2 ;		/* Network status for site 2 */
  UINT1 lnstokay3 ;		/* Network status for site 3 */
  UINT1 lcabrelay ;		/* External cabinet relay control */
  UINT1 lshut1 ;		/* User-Shutdown #1 */
  UINT1 lshut2 ;		/* User-Shutdown #2 */
  UINT1 lTrigBlank ;		/* Trigger blank control line */
  UINT1 lSblnkEnabs[NSBLNKS] ;	/* Selectively enable each sector */
				/* Dual-RCP02 info about 'This' system */
  UINT1 ldrcp_disabled ;	/*   Disabled by 'kill' switch */
  UINT1 ldrcp_active ;		/*   Unit is in control */
  UINT1 ldrcp_activeOut ;	/*   Delayed and cleaned version */
  UINT1 ldrcp_okay ;		/*   Health checks all pass */
  UINT1 ldrcp_relinquish ;	/*   Okay/Offer to relinquish control */
  UINT1 ldrcp_wouldUse ;	/*   Unit would be used if it became active */
  UINT1 ldrcp_driveOut ;	/*   Output drive relays are energized */
  UINT1 ldrcp_maintMode ;	/*   The systems are in maintenance mode */
                                /* Transmit polarization request */
  UINT1 lXmtPolHoriz ;		/*   Horizontal fixed */
  UINT1 lXmtPolVert ;		/*   Vertical fixed */
  UINT1 lXmtPolAlter ;		/*   Alternating */
  UINT1 lXmtPolSimul ;		/*   Simultaneous */
  UINT1 lXmtPolChanged ;	/*   Polarization just changed */
  char  pad54x2[2] ;
} ;

struct rcp8_control {
  struct rcp8_aeservo azservo ;	/* Servo requests */
  struct rcp8_aeservo elservo ;

  struct rcp8_bit_control req ;	/* Individual control bit requests */
  struct rcp8_bit_control tmp ;	/* Temporary array to prevent glitches */
  struct rcp8_bit_control bit ;	/* Actual usable control bit values */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Unified Radar/Antenna status structure.  All status queries should
 * be done by reading the contents of this structure.  The elements
 * themselves may be filled in from different sources depending on the
 * user's configuration.
 */
struct rcp8_bit_status {
  UINT1 auxsts[NSPL_STSBYTES] ;	/* Auxiliary unnamed status lines */
  UINT1 lnoisegen_on ;		/* Noise source Off/On */
  UINT1 lsiggen_on ;		/* Signal generator Off/On */
  UINT1 lsiggen_cw ;		/* Signal generator Pulse/CW output */
  UINT1 lsiggen_fault ;		/* Signal generator fault */
  SINT2 isiggen_level ;		/* Signal generator level (dBm) */
  UINT1 lpwidth0 ;		/* Pulse-Width bit 0 */
  UINT1 lpwidth1 ;		/* Pulse-Width bit 1 */
  UINT1 lradiate ;		/* Radiate */
  UINT1 lservopwr ;		/* Servo Power */
  UINT1 ltrlocal ;		/* TxRx may be controlled remotely */
  UINT1 ltrpower ;		/* Transmitter/Receiver Power */
  UINT1 llocal ;		/* User local mode */
  UINT1 lstandby ;		/* Standby */
  UINT1 linterlock ;		/* Interlock is open */
  UINT1 lmagcurrent ;		/* Magnetron current */
  UINT1 lairflow ;		/* Airflow */
  UINT1 lwavegp ;		/* WaveGuide pressure */
  UINT1 lelimlo ;		/* Lower limit switch encountered */
  UINT1 lelimhi ;		/* Upper limit switch encountered */
  UINT1 lreset ;		/* External reset */
  UINT1 lirismode0 ;		/* IRIS mode bit 0 */
  UINT1 lirismode1 ;		/* IRIS mode bit 1 */
  UINT1 lirismode2 ;		/* IRIS mode bit 2 */
  UINT1 lantstopped ;		/* Antenna appears to be stopped */
  UINT1 lshutdown ;		/* RCP02 is shutdown */
  UINT1 lunsafe ;		/* Shutdown's are inhibited now */
  UINT1 lovel_az ;		/* Velocity is beyond maximum limits */
  UINT1 lovel_el ;
  UINT1 lBlankedSector ;	/* Antenna is within a blanking sector */
  UINT1 lAuxAnt ;		/* Secondary antenna is being used */

				/* Dual-RCP02 info about 'Other' system */
  UINT1 ldrcp_alive ;		/*   Vaild records are being received */
  UINT1 ldrcp_disabled ;	/*   Disabled by 'kill' switch */
  UINT1 ldrcp_active ;		/*   Unit is in control */
  UINT1 ldrcp_activeOut ;	/*   Delayed and cleaned version */
  UINT1 ldrcp_okay ;		/*   Health checks all pass */
  UINT1 ldrcp_relinquish ;	/*   Okay/Offer to relinquish control */
  UINT1 ldrcp_wouldUse ;	/*   Unit would be used if it became active */
                                /* Transmit polarization request */
  UINT1 lXmtPolHoriz ;		/*   Horizontal fixed */
  UINT1 lXmtPolVert ;		/*   Vertical fixed */
  UINT1 lXmtPolAlter ;		/*   Alternating */
  UINT1 lXmtPolSimul ;		/*   Simultaneous */
  UINT1 lXmtPolOkay ;		/*   The polarization state is okay */

  /* Variables related to Quadrature shaft encoders
   */
  UINT1 lShaftAzIndexCal;       /* The AZ index pulse is calibrated */
  UINT1 lShaftAzCal;            /* The AZ angle entirely calibrated */
  UINT1 lShaftAzCalFailed;      /* The AZ angle auto calibration failed */
  UINT1 lShaftElIndexCal;       /* The EL index pulse is calibrated */
  UINT1 lShaftElCal;            /* The EL angle entirely calibrated */
  UINT1 lShaftElCalFailed;      /* The EL angle auto calibration failed */
  UINT1 lShaftAutoCal;          /* The auto calibration is in progress */

  UINT1 lProxSwAZ ;		/* Generic proximity switch */
  UINT1 lProxSwEL ;		/*   contacts for each axis. */
} ;

struct rcp8_adcstatus {		/* Analog-to-Digital converter status */
  FLT4 fVolts[ ADCHAN_NUM ] ;   /*   Samples of each user channel (volts) */
} ;

/* Information reported from the INU
 */
struct rcp8_inu_status
{
  struct ymds_time PacketYmds;  /* Time of last packet */
  struct ymds_time ValidYmds;   /* Time of last packet with valid angle */
  struct ymds_time InuYmds;     /* Time reported by the INU */
  UINT1 lTimeOut;               /* No data from the INU, replaces rcp02 linu_alive() */
  UINT1 invred ;		/* Invalid and Reduced status bits */

#define INVRED_REDHORZ 0x01	/* Reduced horizontal pos/vel */
#define INVRED_INVHORZ 0x02	/* Invalid horizontal pos/vel */
#define INVRED_REDVERT 0x04	/* Reduced vertical pos/vel */
#define INVRED_INVVERT 0x08	/* Invalid vertical pos/vel */
#define INVRED_REDROLL 0x10	/* Reduced roll/pitch angle/vel */
#define INVRED_INVROLL 0x20	/* Invalid roll/pitch angle/vel */
#define INVRED_REDHEAD 0x40	/* Reduced heading angle/vel */
#define INVRED_INVHEAD 0x80	/* Invalid heading angle/vel */

				/* Invalid attitude angles */
#define INV_ATTITUDE (INVRED_INVROLL | INVRED_INVHEAD)

  UINT2 status ;		/* Status bits */
  SINT4 iReadCount;             /* Total number of bytes read */
  SINT4 iErrorCount;            /* Total number of error bytes read */
  SINT4 iChecksumPacketCount;   /* Total number of packets failing CRC check */
  SINT4 iValidPacketCount;      /* Total number of good packets */

  BIN2  roll  ;			/* Roll, Pitch, Heading as binary */
  BIN2  pitch ;			/*   angles */
  BIN2  head ;
  SINT2 rdot ;			/* Rates of change of Roll, Pitch, */
  SINT2 pdot ;			/*   and heading as binary angles  */
  SINT2 hdot ;			/*   per second */
  BIN4  iLat;			/* Latitude  binary angle */
  BIN4  iLon;    		/* Longitute, binary angle */
  SINT4 iAltitude ;		/* Height in cm */
  SINT2 eastvel ;		/* East, North, and UP velocities */
  SINT2 northvel ;		/*   in 0.01 m/sec units */
  SINT2 upvel ;
  char  ipad_end[2];
} ;

/* INU related precomputed parameters
 */
struct rcp8_inu_params
{
  /* Information precomputed from each INU record to allow fast
   * coordinate transformations.  This is filled in by the
   * inu_params() function.
   */
  FLT4 fAD11;    /* Velocity matrix terms... */
  FLT4 fAD12;
  FLT4 fAD13;
  FLT4 fAD21;
  FLT4 fAD22;
  FLT4 fAD23;
  FLT4 fAD31;
  FLT4 fAD32;
  FLT4 fAD33;

  FLT4 fA11;	/* =  fCPCT    Rotation matrix terms... */
  FLT4 fA12;	/* = -fCPST */
  FLT4 fA13;	/* = -fSinP */
  FLT4 fA21;
  FLT4 fA22;
  FLT4 fA23;	/* = -fSRCP */
  FLT4 fA31;
  FLT4 fA32;
  FLT4 fA33;    /* =  fCRCP */
  
  /* This section contains further information computable only after
   * the pedestal position information has arrived.  This is all
   * filled in by the inu_ped_to_earth() function.
   */
  FLT4   fPedX,   fPedY,   fPedZ;      /* Pedestal vector */
  
  FLT4 fEarthX, fEarthY, fEarthZ;      /* Earth vector */
  /* Note that fEarthZ is sine(fEarthEl) */
  
  FLT4 fEarthAz, fEarthEl;             /* Earth Az/El */

  /* sin/cos of pedestal AZ/EL
   */
  FLT4 fSinPAz;
  FLT4 fCosPAz;
  FLT4 fSinPEl;
  FLT4 fCosPEl;
} ;

struct rcp8_status {
  UINT4 iTickAngles ;	        /* Time that angles were last updated */
  struct rcp8_aestatus azstatus ; /* Antenna axis status */
  struct rcp8_aestatus elstatus ;

  struct rcp8_adcstatus adc ;	/* A/D input channel measurements */

  struct rcp8_bit_status req ;	/* Individual status bit requests */
  struct rcp8_bit_status tmp ;	/* Temporary array to prevent glitches */
  struct rcp8_bit_status bit ;	/* Actual usable status bit values */
  struct rcp8_inu_status InuStatus ;
  struct rcp8_inu_params InuParams ;
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Hardware control output.  These are the desired states of the hardware
 * outputs themselves.  Lines may be redefined from their normal function
 * by the user's setup.
 */
struct rcp8_hw_control {
  UINT1 auxcnt[NSPL_CNTBYTES] ;	/* Auxiliary unnamed control lines */
  UINT1 lnoisegen_on ;		/* Noise source Off/On */
  UINT1 lsiggen_on ;		/* Signal generator Off/On */
  UINT1 lsiggen_cw ;		/* Signal generator Pulse/CW output */
  char  pad13x1[1] ;
  SINT2 isiggen_level ;		/* Signal generator level (dBm) */
  UINT1 lpwidth0 ;		/* Pulse-Width bit 0 */
  UINT1 lpwidth1 ;		/* Pulse-Width bit 1 */
  UINT1 lradiate_on ;		/* Radiate ON */
  UINT1 lradiate_off ;		/* Radiate OFF */
  UINT1 lservopwr ;		/* Servo Power */
  UINT1 ltrpower ;		/* Transmitter/Receiver Power */
  UINT1 lcabrelay ;		/* Servo cabinet relay */
  UINT1 lreset ;		/* External reset */
  UINT1 lTrigBlank ;		/* Trigger blank control line */
  UINT1 lirismode0 ;		/* IRIS mode bit 0 */
  UINT1 lirismode1 ;		/* IRIS mode bit 1 */
  UINT1 lirismode2 ;		/* IRIS mode bit 2 */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Hardware status inputs.  These are direct readings from the hardware
 * inputs themselves.  Lines may be redefined from their normal function
 * by the user's setup.
 */
struct rcp8_hw_status {
  UINT1 auxsts[NSPL_STSBYTES] ;	/* Auxiliary unnamed status lines */
  UINT1 lnoisegen_on ;		/* Noise source Off/On */
  UINT1 lsiggen_on ;		/* Signal generator Off/On */
  UINT1 lsiggen_cw ;		/* Signal generator Pulse/CW output */
  UINT1 lsiggen_fault ;		/* Signal generator fault */
  SINT2 isiggen_level ;		/* Signal generator level (dBm) */
  UINT1 lpwidth0 ;		/* Pulse-Width bit 0 */
  UINT1 lpwidth1 ;		/* Pulse-Width bit 1 */
  UINT1 lradiate ;		/* Radiate */
  UINT1 lservopwr ;		/* Servo Power */
  UINT1 ltrlocal ;		/* TxRx may be controlled remotely */
  UINT1 ltrpower ;		/* Transmitter/Receiver Power */
  UINT1 llocal ;		/* User local mode */
  UINT1 lstandby ;		/* Standby */
  UINT1 linterlock ;		/* Interlock is open */
  UINT1 lmagcurrent ;		/* Magnetron current */
  UINT1 lairflow ;		/* Airflow */
  UINT1 lwavegp ;		/* WaveGuide pressure */
  UINT1 lelimlo ;		/* Lower limit switch encountered */
  UINT1 lelimhi ;		/* Upper limit switch encountered */
  UINT1 lreset ;		/* External reset */
  UINT1 lirismode0 ;		/* IRIS mode bit 0 */
  UINT1 lirismode1 ;		/* IRIS mode bit 1 */
  UINT1 lirismode2 ;		/* IRIS mode bit 2 */
  UINT1 lProxSwAZ ;		/* Generic proximity switch */
  UINT1 lProxSwEL ;		/*   contacts for each axis. */
  char pad66x2[2] ;
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Sector blanking definitions
 */
struct rcp8_sblnk_work {	/* Working definitions */
  UINT1 linuse ;		/*   Include this sector in overall test */
  UINT1 lped_angle ;		/*   Use pedestal angle (else earth angle) */  
  SINT2 ielx, iely ;		/*   Elevation boundaries (binang) */
  UINT2 iazx, iazy ;		/*   Azimuth boundaries (binang) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Internal antenna simulator state.  The simulated values are stored in
 * 32-bit binary representations so that there are adaquate lower bits
 * for smooth simulation.
 */
struct rcp8_antsim {
  UINT4 ipedpos ;		/* Pedestal angle (binary angle) */
  SINT4 ipedvel ;		/* Pedestal velocity (binang/sec) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Boolean Equation definitions
 */
#define BOOLVARS  4		/* Maximum # right-hand-side variables */
#define VARUNUSED 0xFFFF	/* Unused variable flag */

struct rcp8_boolean_control {	/* One Boolean control constraint */
  UINT2 iequation ;		/*   Bit encoding of the equation */
  UINT2 ilhs_var ;		/*   Left-hand-side output variable */
  UINT2 irhs_vars[BOOLVARS] ;	/*   Actual variables being referenced */
  char  comment[BOOLCOMLEN] ;	/*   Null terminated comment string */
  UINT1 iflags ;		/*   Additional flags */
  char  pad89x3[3] ;
#define BOOL_DISABLED    0x01	/*     Equation disabled */
} ;

/* *************************************************
 * *                                               *
 * *  I/O Definitions Used Internally by the RCP8  *
 * *                                               *
 * *************************************************
 */
struct QBite32 { UINT1 iCh[5] ; } ; /* Various Q-BITE elements */
struct QBite28 { UINT1 iCh[4] ; } ;
struct QBite21 { UINT1 iCh[3] ; } ;
struct QBite14 { UINT1 iCh[2] ; } ;
struct QBite07 { UINT1 iCh[1] ; } ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structure of serial records transmitted by the RCP.  Note that the
 * direction is relative to the host computer, hence the RCP transmits
 * the RCVxx formats, and receives the XMTxx formats.
 */
struct rcv01_rec {
  UINT1 sync ;			/* Initial sync byte (0x80) */
  UINT1 az_lo ;			/* Low,Hi 7-bits of AZ */
  UINT1 az_hi ;
  UINT1 el_lo ;			/* Low,Hi 7-bits of EL */
  UINT1 el_hi ;
  UINT1 stat1 ;
  UINT1 stat2 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct rcv02_04_rec {
  UINT1 sync ;			/* Initial sync byte (0x80) */
  UINT1 az_lo ;			/* Low,Hi 7-bits of AZ */
  UINT1 az_hi ;
  UINT1 el_lo ;			/* Low,Hi 7-bits of EL */
  UINT1 el_hi ;
  UINT1 azvel_lo ;		/* Low,Hi 7-bits of AZ velocity */
  UINT1 azvel_hi ;
  UINT1 elvel_lo ;		/* Low,Hi 7-bits of EL velocity */
  UINT1 elvel_hi ;
  UINT1 stat1 ;
  UINT1 stat2 ;
  UINT1 stat3 ;
  UINT1 siggen_code ;
  UINT1 time_lo ;		/* Low,Hi 7-bits of 1ms time stamp */
  UINT1 time_hi ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct rcv03_rec {
  UINT1 sync ;			/* Initial sync byte (0x80) */
  UINT1 id ;			/* Identification */
  UINT1 az_lo ;			/* Low,Hi 7-bits of Earth AZ */
  UINT1 az_hi ;
  UINT1 el_lo ;			/* Low,Hi 7-bits of Earth EL */
  UINT1 el_hi ;
  UINT1 paz_lo ;		/* Low,Hi 7-bits of Pedestal AZ */
  UINT1 paz_hi ;
  UINT1 pel_lo ;		/* Low,Hi 7-bits of Pedestal EL */
  UINT1 pel_hi ;
  UINT1 pitch_lo ;		/* Low,Hi 7-bits of Pitch */
  UINT1 pitch_hi ;
  UINT1 roll_lo ;		/* Low,Hi 7-bits of Roll */
  UINT1 roll_hi ;
  UINT1 head_lo ;		/* Low,Hi 7-bits of Heading */
  UINT1 head_hi ;
  UINT1 azvel_lo ;		/* Low,Hi 7-bits of AZ velocity */
  UINT1 azvel_hi ;
  UINT1 elvel_lo ;		/* Low,Hi 7-bits of EL velocity */
  UINT1 elvel_hi ;
  UINT1 pdot_lo ;		/* Low,Hi 7-bits of Pitch velocity */
  UINT1 pdot_hi ;
  UINT1 rdot_lo ;		/* Low,Hi 7-bits of Roll velocity */
  UINT1 rdot_hi ;
  UINT1 hdot_lo ;		/* Low,Hi 7-bits of Heading velocity */
  UINT1 hdot_hi ;
  UINT1 stat1 ;
  UINT1 stat2 ;
  UINT1 stat3 ;
  UINT1 siggen_code ;
  UINT1 time_lo ;		/* Low,Hi 7-bits of 1ms time stamp */
  UINT1 time_hi ;
  UINT1 lat_lo ;		/* Low,Med,Hi 7-bits of Latitude */
  UINT1 lat_med ;
  UINT1 lat_hi ;
  UINT1 lon_lo ;		/* Low,Med,Hi 7-bits of Longitude */
  UINT1 lon_med ;
  UINT1 lon_hi ;
  UINT1 altitude_lo ;		/* Low,Hi 7-bits of Altitude */
  UINT1 altitude_hi ;
  UINT1 eastvel_lo ;		/* Low,Hi 7-bits of Velocity East */
  UINT1 eastvel_hi ;
  UINT1 northvel_lo ;		/* Low,Hi 7-bits of Velocity North */
  UINT1 northvel_hi ;
  UINT1 upvel_lo ;		/* Low,Hi 7-bits of Velocity Up */
  UINT1 upvel_hi ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct rcv05_rec {
  UINT1 sync ;			/* Initial sync byte (0x80) */
  UINT1 az_lo ;			/* Low,Hi 7-bits of AZ */
  UINT1 az_hi ;
  UINT1 el_lo ;			/* Low,Hi 7-bits of EL */
  UINT1 el_hi ;
  UINT1 azvel_lo ;		/* Low,Hi 7-bits of AZ velocity */
  UINT1 azvel_hi ;
  UINT1 elvel_lo ;		/* Low,Hi 7-bits of EL velocity */
  UINT1 elvel_hi ;
  UINT1 stat1 ;
  UINT1 stat2 ;
  UINT1 stat3 ;
  UINT1 siggen_code ;
  UINT1 time_lo ;		/* Low,Hi 7-bits of 1ms time stamp */
  UINT1 time_hi ;
  UINT1 stat4 ;
  UINT1 stat5 ;
  UINT1 stat6 ;
  UINT1 stat7 ;
  UINT1 stat8 ;
  UINT1 stat9 ;
  UINT1 stat10 ;
  UINT1 stat11 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

union rcvnn {
  struct rcv01_rec rcv01 ;
  struct rcv03_rec rcv03 ;
  struct rcv05_rec rcv05 ;
  struct rcv02_04_rec rcv02_04 ;
} ;

struct time_rec {
  UINT1 sync ;			/* Initial sync byte (0xB0) */
  UINT1 year_lo ;
  UINT1 year_hi ;
  UINT1 month ;			/* Origin 1 */
  UINT1 day ;			/* Origin 1 */
  UINT1 hour ;			/* Origin zero */
  UINT1 minute ;		/* Origin zero */
  UINT1 second ;		/* Origin zero */
  UINT1 sec100 ;		/* Origin zero */
  UINT1 status ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct bite_interrogate {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification (BITEID_INTERROGATE) */
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct bite_internal {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 shut_06_00 ;		/* Shutdown bits 06:00 */
  UINT1 shut_13_07 ;		/* Shutdown bits 13:07 */
  UINT1 shut_20_14 ;		/* Shutdown bits 20:14 */
  UINT1 shut_27_21 ;		/* Shutdown bits 27:21 */
  UINT1 shut_31_28 ;		/* Shutdown bits 31:28 */
  UINT1 byte8 ;
  UINT1 byte9 ;
  UINT1 byte10 ;
  UINT1 lvar_06_00 ;		/* Local variables 06:00 */
  UINT1 lvar_13_07 ;		/* Local variables 13"07 */
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct bite_adc_Q {
  UINT1 sync ;			/* Initial sync byte (0xAF) */
  UINT1 id ;			/* Identification */
  struct QBite21 QMVolts[10] ;	/* Signed 21-bit milivolts */
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct bite_auxsts {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 status[10] ;		/* Up to 70 bits of status */
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct bite_auxcnt {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 control[10] ;		/* Up to 70 bits of control */
  UINT1 end ;			/* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structure of serial records received by RCP8
 */
struct xmt01_rec {
  UINT1 sync ;			/* Initial sync byte (0x80) */
  UINT1 az_lo ;			/* Low,Hi 7-bits of AZ */
  UINT1 az_hi ;
  UINT1 el_lo ;			/* Low,Hi 7-bits of EL */
  UINT1 el_hi ;
  UINT1 cnt1 ;
  UINT1 cnt2 ;
  UINT1 cnt3 ;
  UINT1 siggen_code ;
  UINT1 speed ;			/* AZ/EL antenna speed, 0.55 deg/sec units */
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct xmt02_04_rec {
  UINT1 sync ;			/* Initial sync byte (0x80) */
  UINT1 az_lo ;			/* Low,Hi 7-bits of AZ */
  UINT1 az_hi ;
  UINT1 el_lo ;			/* Low,Hi 7-bits of EL */
  UINT1 el_hi ;
  UINT1 cnt1 ;
  UINT1 cnt2 ;
  UINT1 cnt3 ;
  UINT1 siggen_code ;
  UINT1 azvel_lo ;		/* Low,Hi 7-bits of AZ velocity */
  UINT1 azvel_hi ;
  UINT1 elvel_lo ;		/* Low,Hi 7-bits of EL velocity */
  UINT1 elvel_hi ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct xmt05_rec {
  UINT1 xmt02_04[13] ;		/* The first 13 bytes match with XMT02/04 */
  UINT1 cnt4 ;			/*  (i.e., everything but the "end" byte) */
  UINT1 cnt5 ;
  UINT1 cnt6 ;
  UINT1 cnt7 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structure of bidirectional remote chat record.  The buffer holds up
 * to six 7-bit characters, and is NULL padded if fewer characters are
 * being sent.  The ideas behind this format are: 1) it permits
 * transmitting at up to 75% of the available serial line baud rate,
 * 2) the packets are short enough that they will not interrupt the
 * normal data stream.
 */
struct chat_rec {
  UINT1 sync ;			/* Initial sync byte (0xF1) */
  UINT1 buf[6] ;		/* Character buffer */
  UINT1 end ;			/* End of message (0xFF) */  
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structure of SDLC data stream received from the Honeywell Inertial
 * Navigation Unit.  The first INU_PREPAD bytes contain data that are
 * not part of the actual SDLC data stream, but which are filled in by
 * other means upon reception.
 */
#if 0
#define INU_PREPAD 4
#define INU_FIRST ( 1 + INU_PREPAD) /* Offsets of first actual valid data */
#define INU_END   (38 + INU_PREPAD) /*  byte, and first invalid byte. */
#define INU_ENDPAD 4
#endif

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with WSR-88D DCU (Antenna/Pedestal)
 */
struct dcu_ratepos_cmd { UINT1 one, two ; } ;
struct dcu_bitreq_cmd  { UINT1 one, two ; } ;

struct dcu_txrec {		/* Serial data sent from RCP8->DCU */
  struct dcu_ratepos_cmd az ;
  struct dcu_ratepos_cmd el ;
  struct dcu_bitreq_cmd  bit ;
} ;

struct bite_dcu {		/* Standard BIT data from the DCU */
  UINT1 sync ;			/*   Initial sync byte (0xC0) */
  UINT1 id ;			/*   Identification */
  UINT1 byte03, byte04, byte05, byte06, byte07 ;
  UINT1 byte08, byte09, byte10 ;
  UINT1 end ;			/*   End of message (0xFF) */
} ;
struct bite_dcu_st1 {		/* Self-Test-1 */
  UINT1 sync, id ;
  UINT1 byte03, byte04, byte05, byte06, byte07 ;
  UINT1 end ;
} ;
struct bite_dcu_st2 {		/* Self-Test-2 */
  UINT1 sync, id ;
  UINT1 byte03, byte04, byte05 ;
  UINT1 end ;
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with WSR-88D DAU (BITE/Status)
 */
struct dau_data_cmd {		/* MultiByte data command to DAU */
  UINT1 cmd, byte0, byte1, byte2, byte3 ;
} ;

#define NUMDAUBITS   14
#define NUMDAUVALS   48
struct dau_rxrec {		/* Received record from the DAU */
  UINT1 iBits[NUMDAUBITS] ;	/*   Single-bit status */
  UINT1 iVals[NUMDAUVALS] ;	/*   8-Bit data values */
} ;

struct bite_dau {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 byte03, byte04, byte05, byte06, byte07 ;
  UINT1 byte08, byte09, byte10, byte11, byte12 ;
  UINT1 byte13, byte14, byte15, byte16, byte17 ;
  UINT1 byte18, byte19, byte20 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

struct bite_dau_Q {
  UINT1 sync ;			/* Initial sync byte (0xAF) */
  UINT1 id ;			/* Identification */
  struct QBite14 QVals[30] ;	/* All values are 14-bits */
  UINT1 end ;			/* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with Kavouras TCU (Radiate/BITE)
 */
struct kavtcu_cmd {		/* Single byte command to KAVTCU */
  UINT1 cmd ;
} ;
struct kavtcu_stsrec {		/* Received status record from KAVTCU */
  UINT1 iMode ;			/*   Current mode */
  UINT1 iMaxFlts, iCurFlts ;	/*   Maximum and current strike faults*/
  UINT1 iVals[8] ;		/*   8-Bit data values */
} ;
struct kavtcu_tmprec {		/* Received temperature record from KAVTCU */
  UINT1 iVals[8] ;		/*   8-Bit data values */
} ;
struct bite_kavtcu {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 byte03, byte04, byte05, byte06, byte07 ;
  UINT1 byte08, byte09, byte10, byte11, byte12 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;
struct bite_kavtcu_Q {
  UINT1 sync ;			/* Initial sync byte (0xAF) */
  UINT1 id ;			/* Identification */
  struct QBite14 QVals[12] ;	/* All values are 14-bits */
  UINT1 end ;			/* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the Andrew-Canada pedestal.
 */
struct andrew_cmd {		/* Andrew control record (to ACU) */
  UINT1 sync ;			/*   Initial sync byte (0xAA) */
#define ANDREW_SYNC 0xAA

  UINT1 cmdtype ;		/*   Command type */
#define ANDREW_CMD_STSREQ 0x00	/*     Status request */
#define ANDREW_CMD_PRMREQ 0x02	/*     Parameter request */
#define ANDREW_CMD_MONREQ 0x04	/*     Monitor request */
#define ANDREW_CMD_ANTCMD 0x06	/*     Antenna command */
#define ANDREW_CMD_OFFSET 0x0A	/*     Resolver offset request */

  UINT1 antcmd ;		/*   Antenna command */
#define ANDREW_ANT_LOCAL  0x80	/*     Local (else Host), status only */
#define ANDREW_ANT_ACTIVE 0x40	/*     Active (else Standby) pedestal mode */
#define ANDREW_ANT_AZSCAN 0x20	/*     Scan (else Position) on AZ axis */
#define ANDREW_ANT_ELSCAN 0x10	/*     Scan (else Position) on EL axis */
#define ANDREW_ANT_ELRETN 0x08	/*     Elevation return mode */
#define ANDREW_ANT_SELDIR 0x04	/*     AZ selected direction (else shortest) */
#define ANDREW_ANT_CCWDIR 0x02	/*     AZ selected direction is CCW */
#define ANDREW_ANT_ANTMON 0x01	/*     Antenna monitor is ON */

  UINT1 free3x1[1] ;

  UINT1 azhi, azlo ;		/*   AZ 16-bit position or velocity */
  UINT1 elhi, ello ;		/*   EL 16-bit position or velocity */

  UINT1 azmaxvhi, azmaxvlo ;	/*   AZ maximum velocity */
  UINT1 elmaxvhi, elmaxvlo ;	/*   EL maximum velocity */
  UINT1 free12x4[4] ;

  UINT1 csumhi, csumlo ;	/*   16-bit checksum */
} ;

struct andrew_antsts {		/* Possible element of receive record */
  UINT1 antcmd ;		/*   Copy of antenna command */
  UINT1 free1x1[1] ;

  UINT1 azposhi, azposlo ;	/*   AZ 16-bit position */
  UINT1 elposhi, elposlo ;	/*   EL 16-bit position */

  UINT1 azvelhi, azvello ;	/*   AZ 16-bit velocity */
  UINT1 elvelhi, elvello ;	/*   EL 16-bit velocity */

  UINT1 status1 ;		/*   Status bytes */
  UINT1 status2 ;

  UINT1 fault1 ;		/*   Fault bytes */
  UINT1 fault2 ;
} ;

struct andrew_offsts {		/* Possible element of receive record */
  UINT1 azoffhi, azofflo ;	/*   AZ 16-bit offset */
  UINT1 eloffhi, elofflo ;	/*   EL 16-bit offset */

  UINT1 free4x10[10] ;
} ;

struct andrew_sts {		/* Andrew status record (from ACU) */
  UINT1 sync ;			/*   Initial sync byte (0xAA) */
  UINT1 ststype ;		/*   Status type */
#define ANDREW_STS_ANTSTS 0x00	/*     Antenna status */
#define ANDREW_STS_OFFSET 0x0A	/*     Resolver offsets */

  union {			/* Internal structure depends on the */
    struct andrew_antsts ant ;	/*   type of status record that we */
    struct andrew_offsts off ;	/*   actually have. */
  } u ;

  UINT1 csumhi, csumlo ;	/*   16-bit checksum */
} ;

struct bite_andrew {		/* BITE packet w/pedestal status */
  UINT1 sync ;			/*   Initial sync byte (0xC0) */
  UINT1 id ;			/*   Identification */
  UINT1 byte3 ;			/*   Packed info into data bytes */
  UINT1 byte4 ;
  UINT1 byte5 ;
  UINT1 byte6 ;
  UINT1 byte7 ;
  UINT1 end ;			/*   End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with Applied Systems Transmitter
 */
struct appsys_cmd {		/* Command to APPSYS */
  UINT1 stx, cmd, etx, sum ;	/*   Start, Command, End, Checksum */
} ;
struct appsys_sts {		/* Received status record from APPSYS */
  UINT1 stx ;			/*   Start */
  UINT1 bits[4] ;		/*   Discrete status bits */
  UINT1 values[3][4] ;		/*   Analog text numerical values */
  UINT1 etx, sum ;		/*   End, Checksum */
} ;
struct bite_appsys {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 byte03, byte04, byte05, byte06, byte07 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;
struct bite_appsys_Q {
  UINT1 sync ;			/* Initial sync byte (0xAF) */
  UINT1 id ;			/* Identification */
  struct QBite14 QVals[3] ;	/* All values are 14-bits */
  UINT1 end ;			/* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with Orbit antenna controller
 */
struct bite_orbit {
  UINT1 sync ;			/* Initial sync byte (0xC0) */
  UINT1 id ;			/* Identification */
  UINT1 byte03, byte04, byte05, byte06, byte07 ;
  UINT1 end ;			/* End of message (0xFF) */
} ;

/* ******************************************
 * *                                        *
 * *  Default Macro Support for BITE Units  *
 * *                                        *
 * ******************************************
 *
 * These are the standard I/O interfaces for BITE units that simply
 * report their status whenever anything changes, and which respond to
 * INTERROGATE commands with an immediate retransmission of whatever
 * bits they have at the time (i.e., no side effects).  See notes in
 * hostio.c
 */

/* ------------------------------
 * If NAME BITE packets are enabled, then format another one for
 * transmission whenever its contents change; but do not send them
 * faster than a given maximum rate.
 */
#define BITE_XMTREC_DEFAULT( NAME, ENABLED, MINPERIOD ) \
  UINT1 bite_xmtrec_##NAME \
  ( volatile struct bite_##NAME *biterec_a, UINT4 iTickNow_a ) \
  { \
    UINT1 lMadePacket = FALSE ; \
    if( ENABLED ) { \
      static UINT4 iTickLast=0 ;  \
      if( ( lRequest_bite_##NAME##_c                                  ) || \
          ( btimeGrace( iTickNow_a - iTickLast ) > (UINT4)(MINPERIOD) ) ) { \
	struct bite_##NAME xRec ; make_bite_##NAME( &xRec ) ; \
	if( lRequest_bite_##NAME##_c || \
	    memcmp( (void *)biterec_a, &xRec, sizeof(xRec) ) ) { \
	  lRequest_bite_##NAME##_c = FALSE ; \
	  *biterec_a = xRec ; lMadePacket = TRUE ; \
	} \
	iTickLast = iTickNow_a ; \
      } \
    } \
    return( lMadePacket ) ; \
  }

/* ------------------------------
 * Handle both the targeted and system-wide BITE commands.  There is
 * not much to do here, other than handling the INTERROGATE requests.
 */
#define BITE_CMDOPS_DEFAULT( NAME, ENABLED, BITEID, QSUFFIX ) \
  void bite_cmdops_##NAME( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) \
  { \
    if( (ENABLED) && ( (iID_a == -1) || (iID_a == (BITEID)) ) ) { \
      switch( iCmdOp_a ) { \
      case CMDOPS_ONE_INTERROGATE : \
      case CMDOPS_ALL_INTERROGATE##QSUFFIX : \
	lRequest_bite_##NAME##_c = TRUE ; break ; \
      } \
    } \
  }

/* Define our own commands internally -- the legacy serial BITE
 * definitions have gone through so much evolution that they're
 * unusably confused.
 */
#define CMDOPS_NONE               0 /* Nothing to do */

#define CMDOPS_ONE_INTERROGATE    1 /* Targeted request to resend BITE packet */
#define CMDOPS_ALL_INTERROGATE    2 /* Global request to resend BITE packets */
#define CMDOPS_ALL_INTERROGATE_Q  3 /*   (either standard or Q-BITE) */

#define CMDOPS_ONE_TAKE_SAMPLE    4 /* Targeted and global requests to carry out */
#define CMDOPS_ALL_TAKE_SAMPLE    5 /*   side effects to get fresh data. */

#define CMDOPS_ONE_RESET          6 /* Targeted and global requests to reset */
#define CMDOPS_ALL_RESET          7 /*   the underlying BITE hardware. */

#define CMDOPS_ONE_SET_VALUES     8 /* Targeted and global requests to propagate */
#define CMDOPS_ALL_SET_VALUES     9 /*   commands out to external units. */

/* ******************************************
 * *                                        *
 * * Shared Memory Available to All Threads *
 * *                                        *
 * ******************************************
 */

/* ---------------------------- NOTE ----------------------------
 * All of the variables defined below are put here because they are
 * referenced by more than one thread.  Therefore, the 'volatile'
 * qualifier is the appropriate default in almost all cases.  The only
 * exceptions are variables that are known to be initialized only
 * once, and for which LIBC problems arise with the 'volatile' cast
 * (e.g. FILE*).
 */
#ifdef RCPCOMMON_ALLOCATE
  #define XM
  #define VM volatile
#else
  #define XM extern
  #define VM extern volatile
#endif

/* ------------------------------
 * Command line options and args
 */
#define NOCMDARG 0x80000000
XM UINT1 lNoDiags_c ;		/* Skip diagnostics entirely */
XM UINT1 lForceVer_c ;		/* Attempt to use mismatched hardware */
XM SINT4 iIoCardForce_c ;	/* Force a particular I/O-62 card (or none) */
XM UINT1 lInterruptible_c ;	/* Allow ^C from startup session */
XM UINT1 lUseLocalTTY_c ;	     /* Use a console device */
XM char sLocalTTY_c[PATHNAME_SIZE] ; /* Device to use as local console */

/* ------------------------------
 * The IRIS portion of the antenna setups that are stored here are
 * from the initial startup of the RCP8, and only a few of its
 * elements pertaining to toplevel config should ever be referenced.
 */
#ifdef SIGMET_SETUP_H
VM struct ant_manual_setup irisAnt_c ;
#endif

VM UINT4 mtimeIRIS_c ;		/* Last modification times of IRIS and */
VM UINT4 mtimeRCP8_c ;		/*   RCP8 configuration files. */

XM struct rcp8_nv nv_c ;	/* Internal working copy */
XM struct rcp8_nv nvMIN_c ;	/* Minimum setup values */
XM struct rcp8_nv nvMAX_c ;	/* Minimum setup values */

XM struct rcp8_nv nvNEW_c ;	/* New values from user */

/* ------------------------------
 * SIGMET PCI Cards and other hardware
 */
#ifdef SIGMET_PCICARDS_LIB_H
XM Io62        *Io_c[RCP8MAXIO] ; /* ==> Optional I/O-62 card */
XM UINT1 lHasPanel_c[RCP8MAXIO] ; /* Optional backpanel is present */
XM SINT4 iIo62Card_c[RCP8MAXIO] ; /* Unit number of card being used */

#ifdef SIGMET_SOFTPLANE_LIB_H
XM SPL *SPL_c ;			/* ==> Softplane driver layer */
XM struct splLogicCnt splCntUsage_c ; /* Usage mask of output bits */
#endif /* #ifdef SIGMET_SOFTPLANE_LIB_H */

#ifdef SIGMET_RDA_H
XM struct rda_boardinfo IoInfo_c[RCP8MAXIO] ;
#endif /* #ifdef SIGMET_RDA_H */

#endif /* #ifdef SIGMET_PCICARDS_LIB_H */

VM UINT4 iSharedTimerUsers_c ;	/* Allocator for IO62 shared timer */

VM UINT1 lPowerUpError_c ;	/* Some powerup error(s) were noted */

/* ------------------------------
 * Boolean variable shared info
 */
XM struct rcp8_boolean_control boolist_c[NEQUATIONS] ;

XM char  stimer_var_names_c[NTIMER_VARS][40] ;
VM UINT1 itimer_bits_c     [NTIMER_VARS][2] ; /* timer variable bits/prevs */
VM UINT4 itimer_counts_c   [NTIMER_VARS] ;    /* timer variable counts */
XM UINT4 itimer_periods_c  [NTIMER_VARS] ;    /* timer periods */
XM UINT4 itimer_htimes_c   [NTIMER_VARS] ;    /* timer HI times */

XM char  sadcvar_var_names_c[ADCVAR_NUM][4 + ADCVAR_NAMELEN + 1] ;
VM UINT1 iadcvar_bits_c     [ADCVAR_NUM] ;    /* Analog input test bits */

XM char  santvar_var_names_c[ANTVAR_NUM][40] ;
VM UINT1 iantvar_bits_c     [ANTVAR_NUM] ;    /* Antenna Pos/Vel test bits */

VM UINT1 local_vars_c[NLOC_BYTES] ;           /* Local variable bits */

XM UINT2 iantstop_ticks_c ;	/* Timeout count for stopped antenna status */

/* ------------------------------
 * Control/Status structure allocations.
 */
#ifdef INCLUDE_PTHREAD_PROTOTYPES
XM pthread_mutex_t rcpStatusMutex_c ;   /* Lock on (parts of) rcp_status_c, */
XM pthread_cond_t  rcpStatusCond_c ;    /*   along with a conditional and */
VM UINT4           rcpStatusSerial_c ;  /*   serial change number. */
#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

VM struct rcp8_control rcp_control_c ;  /* Current control information */
VM struct rcp8_status  rcp_status_c ;   /* Current status information */

VM struct rcp8_hw_control hw_control_c ; /* Actual hardware control outputs */
VM struct rcp8_hw_status  hw_status_c ;  /* Actual hardware status inputs */

VM UINT1 lreset_req_c ;		/* Reset request */
VM SINT2 ireset_pulse_c ;	/* Timer for external reset pulse */

VM SINT4 iQtabIndex_c ;	        /* Sequential access to xxxQtab[] arrays */

VM SINT2 iXmtPolChangedTimer_c ; /* Short lockout timer for polarization */

XM struct full_time_spec TimeBoot_c ; /* Full time and BTIME at which the */
XM UINT4 iBtimeBoot_c ;		 /*   RCP8 was booted */

/* ------------------------------
 * Precomputed "working" copies of setup information to reduce the
 * overhead in real-time code.
 */
XM struct rcp8_aework azwork_c ; /* AZ servo parameters */
XM struct rcp8_aework elwork_c ; /* EL servo parameters */

XM struct rcp8_sblnk_work sblnk_work_c[NSBLNKS] ; /* Sector blanking info */

/* ------------------------------
 * Background monitor, IRIS antenna, and top level servo variables.
 */
XM FLT4 fServoPeriod_c ;	/* Servo loop period (seconds) */
XM FLT4 fCSTickPeriod_c ;	/* Control/Status tick period (seconds) */

XM UINT1 lServoPosSamps_c ;	/* Servo process samples and provides */
XM UINT1 lServoVelSamps_c ;	/*   positions and velocities. */

#ifdef SIGMET_PCICARDS_LIB_H
XM struct synchro *syAZ_c ;	/* ==> Synchro conversion states */
XM struct synchro *syEL_c ;	/* ==>   for each axis. */

XM struct shaftEncoderSts shaftEncAZ_c ; /* Internal status for optional */
XM struct shaftEncoderSts shaftEncEL_c ; /*   A/B/Index shaft encoders. */
#endif /* #ifdef SIGMET_PCICARDS_LIB_H */

XM SINT4 iBGMSamps_c ;		/* Value of BGMSAMPS() for current servo period */

VM struct rcp8_antsim antsim_az_c ; /* Simulated antenna information */
VM struct rcp8_antsim antsim_el_c ;

#ifdef INCLUDE_PTHREAD_PROTOTYPES
XM pthread_mutex_t ant_mutex_c ; /* Lock for accessing the driver */
#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

/* ------------------------------
 * Chatting and Setup variables
 */
VM UINT1 lChatLocal_c ;		/* Chatting locally, else via chat packets */
#ifdef INCLUDE_TERMIOS_PROTOTYPES
XM struct ttydev localTTY_c ;	/* ==> startup TTY for local chatting */
#endif /* #ifdef INCLUDE_TERMIOS_PROTOTYPES */

XM FILE *wChat_c, *rChat_c ;	/* ==> Internal serial chat packet streams */
XM int wChatFD_c, rChatFD_c ;	/* File descriptors of "other side" */

#if STDIO_SETUP_TTY
#define WCHAT ( stdout )
#define RCHAT ( stdin  )
#else
#define WCHATLOCSIO(LOCAL) ( (LOCAL) ? localTTY_c.Tx : wChat_c )
#define RCHATLOCSIO(LOCAL) ( (LOCAL) ? localTTY_c.Rx : rChat_c )
#define WCHAT WCHATLOCSIO( lChatLocal_c )
#define RCHAT RCHATLOCSIO( lChatLocal_c )
#endif

/* The TTY input line is sized to maximum length Boolean equation,
 * since this is likely to be the longest input we will ever
 * encounter.
 */
VM char ttyline_c[BOOLEQNLEN] ;	/* TTY input command line */
VM char *pttych_c ;		/* Shared pointer into command line */

/* We allow the characters "_-./" to be treated as part of a name,
 * i.e., not a real punctuation mark.
 */
#define ISPUNCT(CH) ( ispunct((CH)) && \
  ((CH) != '_') && ((CH) != '-') && ((CH) != '.') && ((CH) != '/') )

/* If the following variable is TRUE then the setup dialog macros will
 * print their output text but will not pause for any user input.  This
 * is how the overall setup printouts are made.
 */
VM UINT1 lprintonly_c ;

/* ------------------------------
 * Host computer serial I/O variables
 */
VM UINT4 isio_tickms_c ;	/* Time of last valid SIO received record */

VM UINT2 isio_char_outcnt_c ;	/* SIO character output count */
VM UINT2 isio_rec_outcnt_c ;	/* SIO record output count */

VM UINT2 isio_char_incnt_c ;	/* SIO character input count */
VM UINT2 isio_rec_incnt_c ;	/* SIO record input count */
VM UINT2 isio_rec_inerrcnt_c ;	/* SIO record error count */

/* Flags indicating that incoming antenna packets from the host
 * computer serial line will be processed, and finer control over
 * whether servo requests in particular will be honored.
 */
#define LSIO_ALIVE \
  ( (nv_c.isio_rcvfmt != ANTFMT_XMTVOID) && \
    ((iBtimeMS() - isio_tickms_c) < nv_c.isio_deadtime) )

#define LSIO_CONTROL_OKAY						\
  ( nv_c.lsio_control_okay && (nv_c.isio_rcvfmt != ANTFMT_XMTVOID) &&	\
    lmon_sio_control_c ) 

#define LSIO_SERVOS_OKAY  ( ldrcp_sio_servos_c && (!rcp_status_c.bit.lShaftAutoCal))

VM struct rcp8_aeservo sioAzServoReq_c ; /* Servo requests from the host */
VM struct rcp8_aeservo sioElServoReq_c ; /*   computer. */

VM UINT1 lmon_sio_control_c ;	/* Monitor says okay for SIO control */

/* ------------------------------
 * System-wide serial line monitoring facility.  More than one thread
 * can be writing into this at once.
 */
#ifdef INCLUDE_PTHREAD_PROTOTYPES
VM BFIFO(250) SIOMonFIFO_c ;	   /* Buffered stream data to be watched */
XM pthread_mutex_t SIOMonMutex_c ; /*  and lock for multiple writers */

VM UINT4 iSIOMonSelect_c ;	/* Which stream to watch */
#define SIOMON_HOSTRCV       0x00000001 /* Host computer */
#define SIOMON_HOSTXMT       0x00000002
#define SIOMON_DCURCV        0x00000004 /* WSR-88D DCU (antenna/pedestal) */
#define SIOMON_DCUXMT        0x00000008
#define SIOMON_DCUSIMRCV     0x00000010 /* WSR-88D DCU Simulator */
#define SIOMON_DCUSIMXMT     0x00000020
#define SIOMON_DAURCV        0x00000040 /* WSR-88D DAU (BITE/Status) */
#define SIOMON_DAUXMT        0x00000080
#define SIOMON_DAUSIMRCV     0x00000100 /* WSR-88D DAU Simulator */
#define SIOMON_DAUSIMXMT     0x00000200
#define SIOMON_KAVTCURCV     0x00000400 /* Kavouras TCU (Radiate/BITE) */
#define SIOMON_KAVTCUXMT     0x00000800
#define SIOMON_KAVTCUSIMRCV  0x00001000 /* Kavouras TCU Simulator */
#define SIOMON_KAVTCUSIMXMT  0x00002000
#define SIOMON_ANDREWRCV     0x00004000 /* Andrew ACU (Antenna/Pedestal) */
#define SIOMON_ANDREWXMT     0x00008000
#define SIOMON_ANDREWSIMRCV  0x00010000 /* Andrew ACU Simulator */
#define SIOMON_ANDREWSIMXMT  0x00020000
#define SIOMON_APPSYSRCV     0x00040000 /* Applied Systems Transmitter */
#define SIOMON_APPSYSXMT     0x00080000
#define SIOMON_ORBITRCV      0x00100000 /* Orbit serial pedestal */
#define SIOMON_ORBITXMT      0x00200000
#define SIOMON_INURCV        0x00400000 /* Seapath INU */
#define SIOMON_INUSIMXMT     0x00800000

#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

/* ------------------------------
 * Variables related to optional HPIB bus.
 */
XM UINT1 lhpib_inuse_c ;	/* HPIB requested and usable */

VM  char sgen_identity_c[80] ;	/* SIGGEN identity string */
VM SINT2 isgen_level_c ;	/* SIGGEN level in dBm */
VM UINT1 lsgen_on_c ;		/* SIGGEN RF output is enabled */
VM UINT1 lsgen_cw_c ;		/* SIGGEN is in CW mode */
VM UINT1 lsgen_okay_c ;		/* SIGGEN appears to be okay */

/* ------------------------------
 * Dual/Redundant RCP8 System Variables
 */
#define DRCP_MODE_VOID    0	/* In a dual system, the host computer will */
#define DRCP_MODE_A       1	/*   select one of these modes to either    */
#define DRCP_MODE_B       2	/*   force the A or B channel active, or to */
#define DRCP_MODE_AUTO    3	/*   allow them to swap on failures.        */
#define DRCP_MODE_NAMES  "None", "A", "B", "Auto"

VM UINT2 iDrcpMode_c ;		/* Current operational mode */
VM UINT1 lDrcpModeTrusted_c ;	/* Mode has been freshly updated */

VM UINT1 iDrcpIrisModeReq_c ;	/* Requested IRIS mode */

XM struct rcp8_drcpIrisModeStrategy /* Mode switching strategy to use when the */
  drcp_MntInactive_c,		    /*   pair of RCPs are in maintenence mode */
  drcp_MntActive_c ;		    /*   and we are active or inactive. */

#define DRCP_ACT_INACTIVE 0	/* Activity codes */
#define DRCP_ACT_WARMUP   1
#define DRCP_ACT_ACTIVE   2

VM UINT2 iDrcpAct_c ;		/* Cleaned up activity codes for */
VM UINT2 iDrcpActOther_c ;	/*   display of system activity. */

XM UINT2 iDrcpOffTime_c ;	/* Minimum off time, in ticks */
XM UINT2 iDrcpCoolTime_c ;	/* Coast-down time when becoming inactive */

VM UINT1 ldrcp_sio_servos_c ;	/* Okay for SIO to control AZ & EL */

/* ------------------------------
 * Thread control and housekeeping
 */
#define MAX_RCP_THREADS 16
VM SINT4 nThreads_c ;		/* Number of running threads */
VM UINT1 lQuitFlag_c ;		/* Request for RCP8 complete exit */

#ifdef INCLUDE_PTHREAD_PROTOTYPES
struct oneThread {		/* Description of one background thread */
  SINT4 iPID ;			/*   Actual process ID of this thread */
  UINT1 lQuitRequest ;		/*   Request for thread to exit */
  char pad5x3[3] ;
  pthread_t id ;		/*   Thread ID from pthread_create() */
  char sName[40] ;		/*   Name of this thread */
  pthread_mutex_t runlock ;	/*   Mutex to block running */
} ;
struct threadSet {		/* Entire collection of RCP8 threads */
  pthread_key_t pSelf ;		/*   ==> this thread in threads[] */
  pthread_mutex_t lock ;	/*   Lock for accessing the set */
  pthread_cond_t  cond ;	/*   Condition for wakeup initializations */
  struct oneThread threads[MAX_RCP_THREADS] ;
} ;
XM struct threadSet threadSet_c ;

XM pthread_mutex_t cstick_mutex_c ;
#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

XM UINT1 lHaveRootPrivs_c ;	/* We can get root privileges if needed */

#undef VM /* End of shared variables */
#undef XM

/* ******************************
 * *                            *
 * *  Core Function Prototypes  *
 * *                            *
 * ******************************
 */

/* ------------------- rcp8_main.c -------------------
 */
int rcp8_main( int argc_a, char *argv_a[] ) ;

/* ------------------- bmon_main.c -------------------
 */
void *bmon_main( void *arg_a ) ;

/* ------------------- cstick_main.c -------------------
 */
void *cstick_main( void *arg_a ) ;

/* ------------------- hostio_main.c -------------------
 */
void *hostio_rcv_main( void *arg_a ) ;
void *hostio_xmt_main( void *arg_a ) ;
void *hostio_net_main( void *arg_a ) ;

UINT1 bite_xmtrec_internal
( volatile struct bite_internal *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_internal( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_adc_Q
( volatile struct bite_adc_Q *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_adc_Q( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_auxsts
( volatile struct bite_auxsts *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_auxsts( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

/* ------------------- servos_main.c -------------------
 */
void *servos_main( void *arg_a ) ;

/* ------------------- stag_main.c -------------------
 */
void *stag_main( void *arg_a ) ;

/* ------------------- subs_boolean.c -------------------
 */
UINT1 lparse_boolean
( struct rcp8_boolean_control *bool_a, volatile char *sEqn_a, char *sPre_a  ) ;

void print_boolean( struct rcp8_boolean_control *bool_a ) ;

void format_boolean
( struct rcp8_boolean_control *bool_a, char sEqn_a[BOOLEQNLEN] ) ;

void compile_equations
( struct rcp8_boolean_control boolist_a[], UINT1 lenab_a ) ;

void run_boolean_equations( void ) ;
void update_timers( void ) ;
void update_adcvar_tests( void ) ;
void update_antvar_tests( void ) ;

void initBooleanNames( void ) ;
void makeBooleanNames( volatile const struct rcp8_nv *pnv_a ) ;

void boolinit( struct rcp8_boolean_control *bool_a ) ;
UINT1 boolused( struct rcp8_boolean_control *bool_a ) ;
const char *boolvarname( UINT2 ivar_a ) ;
char *adc_sum_terms_text( struct rcp8_adcvar *adcvar_a ) ;

void logic_help( UINT1 imask_a ) ;
void check_multiple_assignments( struct rcp8_boolean_control *pbool_a ) ;

/* ------------------- subs_display.c -------------------
 */
UINT1 lHaveLocalDisplay( void ) ;

void rcp8DispPrint
( SINT4 iLine_a, UINT1 lWait_a, const char *text_a ) ;

void fpd_update( void ) ;

char *ubin_to_ch( UINT2 iangle_a, char *buf_a, UINT1 lhndths_a ) ;
char *sbin_to_ch( SINT2 iangle_a, char *buf_a, UINT1 lhndths_a ) ;
char *ebin_to_ch( SINT2 iangle_a, char *buf_a, UINT1 lhndths_a ) ;

UINT1 iHexFromChar( UINT1 char_a ) ;

/* ------------------- subs_init.c -------------------
 */
void init_common( void ) ;

void init_status_and_work( void ) ;

void init_aestatus
( volatile struct rcp8_aestatus *status_a,
  const struct rcp8_aework   *work_a,
  const struct rcp8_aesetup  *setup_a ) ;

FLT4 ftach_speed_level( const struct rcp8_aesetup *aesetup_a ) ;

void createRCPThreads( void ) ;
void killRCPThreads( void ) ;
void waitThreadInits( void ) ;

void rcp8_run_as_root( void ) ;
void rcp8_run_as_operator( void ) ;

/* ------------------- subs_inu.c -------------------
 */
void inu_params
( volatile const struct rcp8_inu_status *pInuStatus_a,
  volatile struct rcp8_inu_params *pInuParams_a );

void inu_params_ped
( BIN2 iAz_a,   /* Pedestal azimuth */
  BIN2 iEl_a,   /* Pedestal elevation */
  volatile struct rcp8_inu_params *pPrm_a);

void inu_earthv_to_pedv
( BIN2 iEarthAzVel_a,
  BIN2 iEarthELVel_a,
  const volatile struct rcp8_inu_params *pPrm_a,
  volatile BIN2 *pPedAzVel_a,
  volatile BIN2 *pPedElVel_a );

/* ------------------- subs_misc.c -------------------
 */
#define CMD_NOMATCH   (-3)
#define CMD_BLANK     (-2)
#define CMD_AMBIGUOUS (-1)

SINT4 icmd_lookup( const char *slist_a[], const char *sword_a ) ;
SINT4 icmd_lookup_many( const char **smany_a[], const char *sword_a ) ;

UINT4 iBtimeMS( void ) ;

UINT4 ishutdown( void ) ;
UINT4 ishutdown_locktime( void ) ;
void Rcp8Shutdown( UINT4 ibits_a ) ;
void reset_shutdown( UINT4 iLockMS_a ) ;
void shutdown_text( SINT4 ibit_a, char text_a[20] ) ;

SINT2 inominal_drive
( SINT2 itach_a, volatile const struct rcp8_aework *work_a ) ;

SINT4 imoment_of_inertia
( volatile struct rcp8_aestatus *aests_a,
  volatile struct   rcp8_aework *work_a,
  SINT4 *itdot_a) ;

void shdn_poslimit_check
( volatile struct rcp8_aesetup *setup_a, volatile struct rcp8_aework *work_a,
  volatile struct rcp8_aestatus *status_a, UINT4 locode_a, UINT4 hicode_a ) ;

UINT2 iApplySoftPosLimits
( UINT2 ipos_a, volatile struct rcp8_aesetup *setup_a,
  volatile struct rcp8_aestatus *status_a ) ;

void conditionalAntStatus( void ) ;

#define RCP8_AXIS_AZ (0)
#define RCP8_AXIS_EL (1)
void pedposFilterAndSet
( UINT1 iAxis_a,    /* Which axis we are checking */
  BIN2  iMesPos_a,
  UINT4 iTickAngle_a,
  FLT4  fMaxAngVel_a,
  BIN2  iPosQuant_a,
  BIN2  iShaftJump_a ); /* How much the shaft calibration jumped */

/* ------------------- subs_monitor.c -------------------
 */
void launch_monitor( void ) ;
void crlf( void ) ;
void drainChat( void ) ;
void get_ttyline( void ) ;
void get_ttyline_nlch( const char *nlch_a ) ;
UINT1 live_get_ttyline( void ) ;
FLT8 fgetnum( FLT8 fdefault_a, UINT1 *lfound_a ) ;
SINT4 get_word_lcase( char stext_a[], SINT4 len_a ) ;
SINT4 get_word_casefold( char stext_a[], SINT4 len_a, SINT4 ifold_a ) ;

/* ------------------- subs_nv.c -------------------
 */
void factory_nv( volatile struct rcp8_nv *pnv_a ) ;
void restore_nv( volatile struct rcp8_nv *pnv_a, FILE *stream_a ) ;
void save_nv( volatile struct rcp8_nv *pnv_a ) ;

void factory_drcpstrat
( volatile struct rcp8_drcpIrisModeStrategy *pStrat_a,
  UINT1 iStrategy_a, UINT1 iMode_a, UINT1 lAllowSwitch_a ) ;

void save_command( void ) ;
void restore_command( void ) ;

void parse_saved_equations
( struct rcp8_boolean_save *pSave_a, UINT1 lPrintBanner_a ) ;

void format_saved_equations( struct rcp8_boolean_save *pSave_a ) ;

/* ------------------- subs_sio.c -------------------
 */
void writeSIOMonitor
( UINT4 iSelect_a, volatile void *data_a, SINT4 iCount_a ) ;

void encodeQBite07( volatile struct QBite07 *qb_a, SINT4 iVal_a ) ;
void encodeQBite14( volatile struct QBite14 *qb_a, SINT4 iVal_a ) ;
void encodeQBite21( volatile struct QBite21 *qb_a, SINT4 iVal_a ) ;
void encodeQBite28( volatile struct QBite28 *qb_a, SINT4 iVal_a ) ;
void encodeQBite32( volatile struct QBite32 *qb_a, SINT4 iVal_a ) ;

#define SYNC_BYTES( SYNC ) { rec->sync = (SYNC) ; rec->end  = 0xFF ; }

SINT4 new_antstat_rec
( SINT4 iFormat_a, union rcvnn *rcvnn_a, char *sAntPktType_a ) ;

/* ------------------- subs_setup.c -------------------
 */
void setup_axis( const char *stext_a ) ;
void setup_vservo( const char *stext_a ) ;
void setup_pservo( const char *stext_a ) ;
void setup_status( void ) ;
void setup_control( const char *stext_a ) ;
void setup_site( const char *stext_a ) ;
void setup_inu( void ) ;

void titletext( const char *title_a, const char *cmd_a ) ;

/* ******************************
 * *                            *
 * *  Open Function Prototypes  *
 * *                            *
 * ******************************
 */

/* ------------------- rcp8_open.c -------------------
 */
UINT1 lOpenProfiling( void ) ;
UINT4 iOpenUnique( void ) ;

/* ------------------- dau_main.c -------------------
 */
void *dau_main( void *arg_a ) ;
void *dauSim_main( void *arg_a ) ;

UINT1 bite_xmtrec_dau
( volatile struct bite_dau *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_dau( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_dau_Q
( volatile struct bite_dau_Q *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_dau_Q( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

void dau_rcp_status( volatile struct rcp8_bit_status  *bit_a ) ;

void dau_mappings( volatile struct rcp8_bit_control *req_a ) ;

#if ORDAPROTOTYPE
void init_ordaproto( void ) ;
void get_ordaproto_hw_status( volatile struct rcp8_hw_status *sts_a ) ;
void put_ordaproto_hw_control( volatile struct rcp8_hw_control *cnt_a ) ;
#endif /* #if ORDAPROTOTYPE */

/* ------------------- dcu_main.c -------------------
 */
void *dcu_main( void *arg_a ) ;
void *dcuSim_main( void *arg_a ) ;

UINT1 bite_xmtrec_dcu
( volatile struct bite_dcu *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_dcu( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_dcu_st1
( volatile struct bite_dcu_st1 *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_dcu_st1( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_dcu_st2
( volatile struct bite_dcu_st2 *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_dcu_st2( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

void dcu_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- kavouras_tcu_main.c -------------------
 */
void *kavtcu_main( void *arg_a ) ;
void *kavtcuSim_main( void *arg_a ) ;

UINT1 bite_xmtrec_kavtcu
( volatile struct bite_kavtcu *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_kavtcu( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_kavtcu_Q
( volatile struct bite_kavtcu_Q *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_kavtcu_Q( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

void kavtcu_rcp_status( volatile struct rcp8_bit_status  *bit_a ) ;
void kavtcu_rcp_control( void ) ;

/* ------------------- andrew_acu_main.c -------------------
 */
void *andrew_main( void *arg_a ) ;
void *andrewSim_main( void *arg_a ) ;

UINT1 bite_xmtrec_andrew
( volatile struct bite_andrew *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_andrew( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

void andrew_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- appsys_main.c -------------------
 */
void *appsys_main( void *arg_a ) ;
void *appsysSim_main( void *arg_a ) ;

UINT1 bite_xmtrec_appsys
( volatile struct bite_appsys *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_appsys( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

UINT1 bite_xmtrec_appsys_Q
( volatile struct bite_appsys_Q *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_appsys_Q( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iTickNow_a ) ;

void appsys_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- orbit_main.c -------------------
 */
void *orbit_main( void *arg_a ) ;

UINT1 bite_xmtrec_orbit
( volatile struct bite_orbit *biterec_a, UINT4 iTickNow_a ) ;
void bite_cmdops_orbit( UINT1 iCmdOp_a, SINT4 iID_a, UINT4 iBtimeNow_a ) ;

void orbit_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- rcp_limits.c ------------------- */
MESSAGE rcp8_load_conf
( const char *sRemoteHostname_a, volatile struct rcp8_nv *pRcp8NV_a ) ;
MESSAGE rcp8_save_conf
( const char *sRemoteHostname_a, volatile const struct rcp8_nv *pRcp8NV_a ) ;

/* ------------------- seapath_main.c ------------------- */
void *SeapathInuMain( void *arg_a );
void *SeapathInuSimMain( void *arg_a );

/* -------------------- shaft_sim.c --------------------- */
void ShaftEncoderSim( volatile struct rcp8_bit_control *pReq_a );

/* -------------------- ShaftAutoCal.c --------------------- */
void ShaftEncoderAutoCal( void );

/* ******************************
 * *                            *
 * *  Site Function Prototypes  *
 * *                            *
 * ******************************
 */

/* ------------------- rcp8_site.c -------------------
 */
UINT1 lSiteProfiling( void ) ;
UINT4 iSiteUnique( void ) ;

/* ------------------- dau_hooks.c -------------------
 */
void dau_initHook( void ) ;
void dau_exitHook( void ) ;
void dau_rxRecHook( const struct dau_rxrec *rxrec_a ) ;
void dau_txRecHook( struct dau_data_cmd *txrec_a ) ;
void dau_txResetHook( void ) ;
void dau_biteHook( volatile struct bite_dau *biterec_a ) ;
void dau_qbiteHook( volatile struct bite_dau_Q *biterec_a ) ;

void dausim_initHook( void ) ;
void dausim_exitHook( void ) ;
void dausim_rxRecHook( volatile const UINT1 rxData_a[4] ) ;
void dausim_rxResetHook( void ) ;
void dausim_txRecHook( volatile struct dau_rxrec *simTxRec_a ) ;

/* ------------------- dcu_hooks.c -------------------
 */
void dcu_initHook( void ) ;
void dcu_exitHook( void ) ;
void dcu_rxAntRecHook( const UINT1 antBuf_a[], UINT4 iBtimeData_a ) ;
void dcu_rxBitRecHook( const UINT1 bitBuf_a[], UINT4 iBtimeData_a ) ;
void dcu_rxTstRecHook( const UINT1 tstBuf_a[], UINT4 iBtimeData_a, SINT4 iTest_a ) ;
void dcu_txRecHook( struct dcu_txrec *txrec_a ) ;
void dcu_biteHook( volatile struct bite_dcu *biterec_a ) ;

void dcusim_initHook( void ) ;
void dcusim_exitHook( void ) ;
void dcusim_rxRecHook( const struct dcu_txrec *rxCmd_a ) ;
void dcusim_txAntHook( UINT1 simAntRec[8] ) ;
void dcusim_txBitHook( UINT1 simAntRec[6] ) ;
void dcusim_txST2Hook( UINT1 simAntRec[4] ) ;

#endif  /* #ifndef MESSAGE_ONLY */
