/**C*
 *
 * Vaisala software source code file
 *
 * Copyright (c) Vaisala Oyj 2002, 2004, 2005, 2007, 2008, 2009, 2010, 2013.
 * All rights reserved.
 *
 **C*/

/** @file
 *
 * Common Memory Definitions for RCP8 Threads
 *
 * $URL: https://subversion.vaisala.com/svn/repos/sigmet/wr_iris_rda/branches/release8.13.5/rda/rcp8/open/rcp8main.h $
 *
 * $Id: rcp8main.h 30247 2014-09-23 15:37:04Z rke $
 *
 */

/* Include requirements: sigtypes.h rcp8.h softplane_lib.h */

/* *******************************
 * *                             *
 * * Message Catalog Definitions *
 * *                             *
 * *******************************
 */
#define RCP8_CHAT_CLOSED       (RCP8_FACILITY + 1)
#define RCP8_INTERR            (RCP8_FACILITY + 2)
#define RCP8_EXITREQUEST       (RCP8_FACILITY + 3)
#define RCP8_EXITFORCE         (RCP8_FACILITY + 4)
#define RCP8_INU_INVALID       (RCP8_FACILITY + 5)
#define RCP8_AZ_ANGLE_SKIPPED  (RCP8_FACILITY + 6)
#define RCP8_EL_ANGLE_SKIPPED  (RCP8_FACILITY + 7)
#define RCP8_AZ_ANGLE_VALID    (RCP8_FACILITY + 8)
#define RCP8_EL_ANGLE_VALID    (RCP8_FACILITY + 9)
#define RCP8_SHAFT_CAL_FAILED  (RCP8_FACILITY + 10)
#define RCP8_AZ_CAL_JUMP       (RCP8_FACILITY + 11)
#define RCP8_EL_CAL_JUMP       (RCP8_FACILITY + 12)
#define RCP8_HPIB_OPEN         (RCP8_FACILITY + 13)

/* ***********************
 * *                     *
 * * 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 DT12PERDT 20.48         /* D12/T12 units per D/T unit */
#define  MAKE12( FVAL ) ( NINT( DT12PERDT * (FVAL) ) )
#define  SEXT12( TD12 ) ( ( ((int32_t)(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) ((uint32_t) (((uint16_t)(ARG1)) * ((uint16_t)(ARG2))))
#define  MULS(ARG1, ARG2) ((int32_t)  (((int16_t)(ARG1))  * ((int16_t) (ARG2))))
#define LMULU(ARG1, ARG2) ((uint32_t) (((uint32_t)(ARG1)) * ((uint32_t)(ARG2))))
#define LMULS(ARG1, ARG2) ((int32_t)  (((int32_t)(ARG1))  * ((int32_t) (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_PERIOD 0.0025000 /* Period of control/status tick (sec ) */

#define SERVO_PERIOD_USEC 1600  /* Period of primary servo tick (usec) */
#define SERVO_PERIOD   0.0016000 /* Period of primary servo tick (sec) */

#define BMON_PERIOD      0.0500000 /* Background monitor period (sec) */
#define BMON_PERIOD_USEC    50000  /* Background monitor period (usec) */
#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 BGMTCUSEC 1000000     /* Data duration for tach cal check [usec] */
#define BGMUASEC 2.5          /* Data duration for unresponsive ant check */
#define BGMUAUSEC 2500000     /* Data duration for unresponsive ant check [usec]*/

#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)/(SERVOPERIOD))) )
#define BGMTCSIZ ((int)((BGMTCUSEC + BMON_PERIOD_USEC) / (2 * BMON_PERIOD_USEC)))
#define BGMUASIZ ((int)((BGMUAUSEC + BMON_PERIOD_USEC) / (2 * BMON_PERIOD_USEC)))

/* 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 {
    uint8_t 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.
     */
    int16_t itach12 ;             /* Desired measured pedestal velocity (T12-Units) */
    int16_t ivel ;                /* Desired earth velocity (binang/sec) */
    uint16_t ipos ;               /* Desired earth angle (binary angle) */
    int16_t 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.
     */
    uint16_t ih_vel ;             /* Desired earth velocity (binang/sec) */
    uint16_t 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 {
    uint16_t irawpos ;            /* Raw incoming angle position */
    uint16_t imespos ;            /* Measured pedestal angle (binary angle), */
    uint16_t ipedpos ;            /*  and pedestal angle of selected antenna. */
    uint32_t ipedposTick ;        /* Time of trusted pedestal position */

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

    int16_t ipedvel ;             /* Pedestal velocity (binang/sec) */
    int16_t itach ;               /* Tachometer measurement (T12-Units) */
    int16_t idrive ;              /* Internal drive level (D12-Units) and */
    int16_t iDriveFinalOut ;      /*   final value being sent to motors. */

    uint16_t ipos ;               /* Earth angle (binary angle) */
    int16_t ivel ;                /* Earth velocity (binang/sec) */
    int32_t ivel64x ;             /* For Earth velocity smoothing */

    int32_t intverr ;             /* Integral of velocity error */

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

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

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

    /* Variables used when the angle source is ANG_SOURCE_CANBUS to
     * allow the canbus RCP8 thread to supply the position and velocity
     * from some external source.
     */
    BIN2  iCanbusPos ;            /* Custom measured position */
    int16_t iCanbusTach ;         /* Custom measured tachometer */

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

    uint16_t ilastpos ;           /* Last position servo request */
    uint8_t lNewPosRequest ;      /* Flag that request has changed */

    uint8_t lhysteresis ;         /* Position servo outside of zone */
    uint8_t 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 * SERVO_PERIOD ) ) ) */ /* illegal */
#define QTABSIZE ( (int)( 5000000 / (3 * SERVO_PERIOD_USEC ) ) )

    int16_t imestachQtab[QTABSIZE]; /* Measured tach history list (T12-Units) */
    int16_t    itachQtab[QTABSIZE]; /* Filtered tach history list (T12-Units) */
    int16_t   idriveQtab[QTABSIZE]; /* Drive history list (D12-Units) */
    int16_t  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.
     */
    int16_t ibgm_index ;          /* Index of last tach/drive/pos sample */
    int16_t ibgm_hold ;           /* Hold-off counter before running checks */

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

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

    int16_t   itachlist[BGMHSIZE]; /* Tach history list (T12-Units) */
    int16_t  idrivelist[BGMHSIZE]; /* Drive history list (D12-Units) */
    uint16_t 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))
    int16_t ivtach_mespos[VTACHSIZE] ;
    int16_t ivtach_drives[VTACHSIZE] ;
    int16_t ivtach_hold ;         /* Hold-off till valid history */

    /* Variables related to Feed Forward Position Servo
     */
    uint32_t iP0Time ; int16_t iP0Drive ;  /* Binary times of 4-point drive */
    uint32_t iP1Time ; int16_t iP12Drive ; /*   trajectory that conveys two */
    uint32_t iP2Time ;            /*   sloped regions, an intermediate */
    uint32_t iP3Time ;            /*   flat region, and ending at zero. */
    /* Feed Forward Servo uses various drive constants for depending on 
     * the distance to travel. These can be defined in steps.
     */
#define NUMDRIVECONSTS (5)
#define DRIVECONSTALLOWEDDIFF (10.0)  /* Allowed difference in percentage from setup value for const to be saved */
    float  fFFS_driveConst[NUMDRIVECONSTS]; /* Drive Constant (deg/sec)/D12-Unit */
    float  fFFS_driveSteps[NUMDRIVECONSTS]; /* Steps for drive constants */
    float  fFFS_integral ;        /* Intergral used in current drive */
    float  fFFS_startAngle ;      /* Angle when the drive was started */
    uint32_t iDCUsed ;            /* Drive constant used in current drive */
    uint32_t lDriveInterrupted ;  /* Flag to indicate if drive was interrupted */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * 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 {
    int16_t ibps_to_t12 ;         /* Convert  binang/sec --> 12-bit Tach */
    int16_t it12_to_bps ;         /* Convert  12-bit Tach --> binang/sec */

    float ftach_speed_level ;     /* Tachometer calibration (deg/sec)/T-Unit */

    int32_t iantsim_accel ;       /* Max simulated acceleration (BIN4/tick) */

    int32_t idrive_slew ;         /* Max 64x slew rate / tick */

    uint16_t iangle_mask ;        /* Bit mask for incoming angles */
    uint16_t iangle_offset ;      /* Angle offset that must be added, */
    uint16_t iangle_offpre ;      /*   and optional prescale offset. */

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

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

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

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

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

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

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

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

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

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

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

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

    char  pad278x2[2] ;

    /* Variables related to Feed Forward Position Servo
     */
    float fFFS_maxDrive ;         /* Maximum drive (D12-Units) */
    float fFFS_maxAccel ;         /* Max rate of change of drive (D12-Units / sec) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * 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 {
    float fPulseWidth;            /* Pulse width in microseconds */
    float fPRF;                   /* PRF in Hertz */
    uint8_t auxcnt[NSPL_CNTBYTES]; /* Auxiliary unnamed control lines */
    uint8_t lnoisegen_on ;        /* Noise source Off/On */
    uint8_t lsiggen_on ;          /* Signal generator Off/On */
    uint8_t lsiggen_cw ;          /* Signal generator Pulse/CW output */
    uint8_t lShaftForceCal ;      /* Force calibration of the shaft encoders */
    int16_t isiggen_level ;       /* Signal generator level (dBm) */
    uint8_t lpwidth0 ;            /* Pulse-Width bit 0 */
    uint8_t lpwidth1 ;            /* Pulse-Width bit 1 */
    uint8_t lradiate ;            /* Radiate */
    uint8_t lservopwr ;           /* Servo Power */
    uint8_t ltrpower ;            /* Transmitter/Receiver Power */
    uint8_t lreset ;              /* External reset */
    uint8_t lirismode0 ;          /* IRIS mode bit 0 */
    uint8_t lirismode1 ;          /* IRIS mode bit 1 */
    uint8_t lirismode2 ;          /* IRIS mode bit 2 */
    uint8_t lnstokay0 ;           /* Network status for site 0 */
    uint8_t lnstokay1 ;           /* Network status for site 1 */
    uint8_t lnstokay2 ;           /* Network status for site 2 */
    uint8_t lnstokay3 ;           /* Network status for site 3 */
    uint8_t lcabrelay ;           /* External cabinet relay control */
    uint8_t lshut1 ;              /* User-Shutdown #1 */
    uint8_t lshut2 ;              /* User-Shutdown #2 */
    uint8_t lTrigBlank ;          /* Trigger blank control line */
    uint8_t lSblnkEnabs[NSBLNKS]; /* Selectively enable each sector */
    /* Dual-RCP02 info about 'This' system */
    uint8_t lDrcpDisabled ;       /*   Disabled by 'kill' switch */
    uint8_t lDrcpActive ;         /*   Unit is in control */
    uint8_t lDrcpActiveOut ;      /*   Delayed and cleaned version */
    uint8_t lDrcpOkay ;           /*   Health checks all pass */
    uint8_t lDrcpRelinquish ;     /*   Okay/Offer to relinquish control */
    uint8_t lDrcpWouldUse ;       /*   Unit would be used if it became active */
    uint8_t lDrcpDriveOut ;       /*   Output drive relays are energized */
    uint8_t lDrcpMaintMode ;      /*   The systems are in maintenance mode */
    /* Transmit polarization request */
    uint8_t lXmtPolHoriz ;        /*   Horizontal fixed */
    uint8_t lXmtPolVert ;         /*   Vertical fixed */
    uint8_t lXmtPolAlter ;        /*   Alternating */
    uint8_t lXmtPolSimul ;        /*   Simultaneous */
    uint8_t 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 {
    uint8_t auxsts[NSPL_STSBYTES]; /* Auxiliary unnamed status lines */
    uint8_t lnoisegen_on ;        /* Noise source Off/On */
    uint8_t lsiggen_on ;          /* Signal generator Off/On */
    uint8_t lsiggen_cw ;          /* Signal generator Pulse/CW output */
    uint8_t lsiggen_fault ;       /* Signal generator fault */
    int16_t isiggen_level ;       /* Signal generator level (dBm) */
    uint8_t lpwidth0 ;            /* Pulse-Width bit 0 */
    uint8_t lpwidth1 ;            /* Pulse-Width bit 1 */
    uint8_t lradiate ;            /* Radiate */
    uint8_t lservopwr ;           /* Servo Power */
    uint8_t ltrlocal ;            /* TxRx may be controlled remotely */
    uint8_t ltrpower ;            /* Transmitter/Receiver Power */
    uint8_t llocal ;              /* User local mode */
    uint8_t lstandby ;            /* Standby */
    uint8_t linterlock ;          /* Interlock is open */
    uint8_t lmagcurrent ;         /* Magnetron current */
    uint8_t lairflow ;            /* Airflow */
    uint8_t lwavegp ;             /* WaveGuide pressure */
    uint8_t lelimlo ;             /* Lower limit switch encountered */
    uint8_t lelimhi ;             /* Upper limit switch encountered */
    uint8_t lreset ;              /* External reset */
    uint8_t lirismode0 ;          /* IRIS mode bit 0 */
    uint8_t lirismode1 ;          /* IRIS mode bit 1 */
    uint8_t lirismode2 ;          /* IRIS mode bit 2 */
    uint8_t lantstopped ;         /* Antenna appears to be stopped */
    uint8_t lshutdown ;           /* RCP02 is shutdown */
    uint8_t lunsafe ;             /* Shutdown's are inhibited now */
    uint8_t lovel_az ;            /* Velocity is beyond maximum limits */
    uint8_t lovel_el ;
    uint8_t lBlankedSector ;      /* Antenna is within a blanking sector */
    uint8_t lAuxAnt ;             /* Secondary antenna is being used */
    uint8_t lHostAlive ;          /* XMT_xxx packets are arriving from host computer */
    uint8_t lHostControl ;        /* Host computer is controlling the antenna */
    uint8_t lPosDriveAZ ;         /* A positive drive level is being requested*/
    uint8_t lPosDriveEL ;         /*   by the antenna servos on either axis. */

    /* Dual-RCP02 info about 'Other' system */
    uint8_t lOtherDrcpAlive;      /*   Valid records are being received */
    uint8_t lOtherDrcpDisabled;   /*   Disabled by 'kill' switch */
    uint8_t lOtherDrcpActive;     /*   Unit is in control */
    uint8_t lOtherDrcpActiveOut;  /*   Delayed and cleaned version */
    uint8_t lOtherDrcpOkay;       /*   Health checks all pass */
    uint8_t lOtherDrcpRelinquish; /*   Okay/Offer to relinquish control */
    uint8_t lOtherDrcpWouldUse;   /*   Unit would be used if it became active */

    /* Transmit polarization request */
    uint8_t lXmtPolHoriz ;        /*   Horizontal fixed */
    uint8_t lXmtPolVert ;         /*   Vertical fixed */
    uint8_t lXmtPolAlter ;        /*   Alternating */
    uint8_t lXmtPolSimul ;        /*   Simultaneous */
    uint8_t lXmtPolOkay ;         /*   The polarization state is okay */

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

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

struct rcp8_adcstatus {         /* Analog-to-Digital converter status */
    float 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 */
    uint8_t lTimeOut;             /* No data from the INU, replaces rcp02 linu_alive() */
    uint8_t 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)

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

    BIN2  roll  ;                 /* Roll, Pitch, Heading as binary */
    BIN2  pitch ;                 /*   angles */
    BIN2  head ;
    int16_t rdot ;                /* Rates of change of Roll, Pitch, */
    int16_t pdot ;                /*   and heading as binary angles  */
    int16_t hdot ;                /*   per second */
    BIN4  iLat;                   /* Latitude  binary angle */
    BIN4  iLon;                   /* Longitute, binary angle */
    int32_t iAltitude ;           /* Height in cm */
    int16_t eastvel ;             /* East, North, and UP velocities */
    int16_t northvel ;            /*   in 0.01 m/sec units */
    int16_t 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.
     */
    float fAD11;    /* Velocity matrix terms... */
    float fAD12;
    float fAD13;
    float fAD21;
    float fAD22;
    float fAD23;
    float fAD31;
    float fAD32;
    float fAD33;

    float fA11;    /* =  fCPCT    Rotation matrix terms... */
    float fA12;    /* = -fCPST */
    float fA13;    /* = -fSinP */
    float fA21;
    float fA22;
    float fA23;    /* = -fSRCP */
    float fA31;
    float fA32;
    float 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.
     */
    float   fPedX,   fPedY,   fPedZ;      /* Pedestal vector */
  
    float fEarthX, fEarthY, fEarthZ;      /* Earth vector */
    /* Note that fEarthZ is sine(fEarthEl) */
  
    float fEarthAz, fEarthEl;             /* Earth Az/El */

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

struct rcp8_status {
    uint32_t 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 {
    uint8_t auxcnt[NSPL_CNTBYTES]; /* Auxiliary unnamed control lines */
    uint8_t lnoisegen_on ;        /* Noise source Off/On */
    uint8_t lsiggen_on ;          /* Signal generator Off/On */
    uint8_t lsiggen_cw ;          /* Signal generator Pulse/CW output */
    char  pad13x1[1] ;
    int16_t isiggen_level ;       /* Signal generator level (dBm) */
    uint8_t lpwidth0 ;            /* Pulse-Width bit 0 */
    uint8_t lpwidth1 ;            /* Pulse-Width bit 1 */
    uint8_t lradiate_on ;         /* Radiate ON */
    uint8_t lradiate_off ;        /* Radiate OFF */
    uint8_t lservopwr ;           /* Servo Power */
    uint8_t ltrpower ;            /* Transmitter/Receiver Power */
    uint8_t lcabrelay ;           /* Servo cabinet relay */
    uint8_t lreset ;              /* External reset */
    uint8_t lTrigBlank ;          /* Trigger blank control line */
    uint8_t lirismode0 ;          /* IRIS mode bit 0 */
    uint8_t lirismode1 ;          /* IRIS mode bit 1 */
    uint8_t lirismode2 ;          /* IRIS mode bit 2 */
    uint8_t iDrcpComm;            /* Dual-RCP comm output bits */
    uint8_t lDrcpActive;          /* Dual-RCP I-am-active signal */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * 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 {
    uint8_t auxsts[NSPL_STSBYTES]; /* Auxiliary unnamed status lines */
    uint8_t lnoisegen_on ;        /* Noise source Off/On */
    uint8_t lsiggen_on ;          /* Signal generator Off/On */
    uint8_t lsiggen_cw ;          /* Signal generator Pulse/CW output */
    uint8_t lsiggen_fault ;       /* Signal generator fault */
    int16_t isiggen_level ;       /* Signal generator level (dBm) */
    uint8_t lpwidth0 ;            /* Pulse-Width bit 0 */
    uint8_t lpwidth1 ;            /* Pulse-Width bit 1 */
    uint8_t lradiate ;            /* Radiate */
    uint8_t lservopwr ;           /* Servo Power */
    uint8_t ltrlocal ;            /* TxRx may be controlled remotely */
    uint8_t ltrpower ;            /* Transmitter/Receiver Power */
    uint8_t llocal ;              /* User local mode */
    uint8_t lstandby ;            /* Standby */
    uint8_t linterlock ;          /* Interlock is open */
    uint8_t lmagcurrent ;         /* Magnetron current */
    uint8_t lairflow ;            /* Airflow */
    uint8_t lwavegp ;             /* WaveGuide pressure */
    uint8_t lelimlo ;             /* Lower limit switch encountered */
    uint8_t lelimhi ;             /* Upper limit switch encountered */
    uint8_t lreset ;              /* External reset */
    uint8_t lirismode0 ;          /* IRIS mode bit 0 */
    uint8_t lirismode1 ;          /* IRIS mode bit 1 */
    uint8_t lirismode2 ;          /* IRIS mode bit 2 */
    uint8_t iDrcpComm;            /* Dual-RCP comm input bits */
    uint8_t lDrcpEnable;          /* Dual-RCP disable switch input */
    uint8_t lProxSwAZ ;           /* Generic proximity switch */
    uint8_t lProxSwEL ;           /*   contacts for each axis. */
    char pad66x2[2] ;
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Sector blanking definitions
 */
struct rcp8_sblnk_work {        /* Working definitions */
    uint8_t linuse ;              /*   Include this sector in overall test */
    uint8_t lped_angle ;          /*   Use pedestal angle (else earth angle) */
    BIN2 ielx, iely ;             /*   Elevation boundaries (binang) */
    BIN2 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 {
    uint32_t ipedpos ;            /* Pedestal angle (binary angle) */
    int32_t 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 */
    uint16_t iequation ;          /*   Bit encoding of the equation */
    uint16_t ilhs_var ;           /*   Left-hand-side output variable */
    uint16_t irhs_vars[BOOLVARS]; /*   Actual variables being referenced */
    char  comment[BOOLCOMLEN] ;   /*   Null terminated comment string */
    uint8_t iflags ;              /*   Additional flags */
    char  pad89x3[3] ;
#define BOOL_DISABLED    0x01   /*     Equation disabled */
} ;

/* *************************************************
 * *                                               *
 * *  I/O Definitions Used Internally by the RCP8  *
 * *                                               *
 * *************************************************
 */
struct QBite32 { uint8_t iCh[5] ; } ; /* Various Q-BITE elements */
struct QBite28 { uint8_t iCh[4] ; } ;
struct QBite21 { uint8_t iCh[3] ; } ;
struct QBite14 { uint8_t iCh[2] ; } ;
struct QBite07 { uint8_t 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 {
    uint8_t sync ;                /* Initial sync byte (0x80) */
    uint8_t az_lo ;               /* Low,Hi 7-bits of AZ */
    uint8_t az_hi ;
    uint8_t el_lo ;               /* Low,Hi 7-bits of EL */
    uint8_t el_hi ;
    uint8_t stat1 ;
    uint8_t stat2 ;
    uint8_t end ;                 /* End of message (0xFF) */
} ;

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

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

struct rcv05_rec {
    uint8_t sync ;                /* Initial sync byte (0x80) */
    uint8_t az_lo ;               /* Low,Hi 7-bits of AZ */
    uint8_t az_hi ;
    uint8_t el_lo ;               /* Low,Hi 7-bits of EL */
    uint8_t el_hi ;
    uint8_t azvel_lo ;            /* Low,Hi 7-bits of AZ velocity */
    uint8_t azvel_hi ;
    uint8_t elvel_lo ;            /* Low,Hi 7-bits of EL velocity */
    uint8_t elvel_hi ;
    uint8_t stat1 ;
    uint8_t stat2 ;
    uint8_t stat3 ;
    uint8_t siggen_code ;
    uint8_t time_lo ;             /* Low,Hi 7-bits of 1ms time stamp */
    uint8_t time_hi ;
    uint8_t stat4 ;
    uint8_t stat5 ;
    uint8_t stat6 ;
    uint8_t stat7 ;
    uint8_t stat8 ;
    uint8_t stat9 ;
    uint8_t stat10 ;
    uint8_t stat11 ;
    uint8_t 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 {
    uint8_t sync ;                /* Initial sync byte (0xB0) */
    uint8_t year_lo ;
    uint8_t year_hi ;
    uint8_t month ;               /* Origin 1 */
    uint8_t day ;                 /* Origin 1 */
    uint8_t hour ;                /* Origin zero */
    uint8_t minute ;              /* Origin zero */
    uint8_t second ;              /* Origin zero */
    uint8_t sec100 ;              /* Origin zero */
    uint8_t status ;
    uint8_t end ;                 /* End of message (0xFF) */
} ;

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

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

struct bite_adc_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite21                /* Signed 21-bit millivolts */
    QMVolts[ ADCHAN_NUM ] ;       /*   for each A/D input channel. */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

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

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

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

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

struct xmt05_rec {
    uint8_t xmt02_04[13] ;        /* The first 13 bytes match with XMT02/04 */
    uint8_t cnt4 ;                /*  (i.e., everything but the "end" byte) */
    uint8_t cnt5 ;
    uint8_t cnt6 ;
    uint8_t cnt7 ;
    uint8_t 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 {
    uint8_t sync ;                /* Initial sync byte (0xF1) */
    uint8_t buf[6] ;              /* Character buffer */
    uint8_t 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 { uint8_t one, two ; } ;
struct dcu_bitreq_cmd  { uint8_t 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 */
    uint8_t sync ;                /*   Initial sync byte (0xC0) */
    uint8_t id ;                  /*   Identification */
    uint8_t byte03, byte04, byte05, byte06, byte07 ;
    uint8_t byte08, byte09, byte10 ;
    uint8_t end ;                 /*   End of message (0xFF) */
} ;
struct bite_dcu_st1 {           /* Self-Test-1 */
    uint8_t sync, id ;
    uint8_t byte03, byte04, byte05, byte06, byte07 ;
    uint8_t end ;
} ;
struct bite_dcu_st2 {           /* Self-Test-2 */
    uint8_t sync, id ;
    uint8_t byte03, byte04, byte05 ;
    uint8_t end ;
} ;

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

#define NUMDAUBITS_SERIAL   14
#define NUMDAUBITS_EXTRA     2 
#define NUMDAUVALS          48
struct dau_rxrec {              /* Received record from the DAU */
    uint8_t  iBits[NUMDAUBITS_SERIAL + NUMDAUBITS_EXTRA] ;   /*   Single-bit status */
    uint8_t  iVals[NUMDAUVALS] ;   /*   8-Bit data values */
    uint16_t iVals2[NUMDAUVALS] ;  /*  16-Bit data values */
} ;

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

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

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

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

    uint8_t 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 */

    uint8_t 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 */

    uint8_t free3x1[1] ;

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

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

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

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

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

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

    uint8_t status1 ;             /*   Status bytes */
    uint8_t status2 ;

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

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

    uint8_t free4x10[10] ;
} ;

struct andrew_sts {             /* Andrew status record (from ACU) */
    uint8_t sync ;                /*   Initial sync byte (0xAA) */
    uint8_t 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 ;

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

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

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with Applied Systems Transmitter
 */
struct appsys_cmd {             /* Command to APPSYS */
    uint8_t stx, cmd, etx, sum ;  /*   Start, Command, End, Checksum */
} ;

struct appsys_sts_177 {         /* Received status record from APPSYS Model 177 */
    uint8_t stx ;                 /*   Start */
    uint8_t bits[4] ;             /*   Discrete status bits */
    char  values[3][4] ;          /*   Analog text numerical values */
    uint8_t etx, sum ;            /*   End, Checksum */
} ;
struct appsys_sts_337 {         /* Received status record from APPSYS Model 337 */
    uint8_t stx ;                 /*   Start */
    uint8_t bits[4] ;             /*   Discrete status bits */
    char  values[5][4] ;          /*   Analog text numerical values */
    uint8_t etx, sum ;            /*   End, Checksum */
} ;
struct appsys_sts_377 {         /* Received status record from APPSYS Model 377 */
    uint8_t stx ;                 /*   Start */
    uint8_t bits[4] ;             /*   Discrete status bits */
    char  values[4][4] ;          /*   Analog text numerical values */
    uint8_t etx, sum ;            /*   End, Checksum */
} ;
union appsys_sts {              /* Union of possible status records */
    struct appsys_sts_177 m177 ;  /*   Status for Model 177 */
    struct appsys_sts_337 m337 ;  /*   Status for Model 377 */
    struct appsys_sts_377 m377 ;  /*   Status for Model 377 */
} ;

struct bite_appsys {            /* BITE for all models */
    uint8_t sync ;                /*   Initial sync byte (0xC0) */
    uint8_t id ;                  /*   Identification */
    uint8_t byte03, byte04, byte05, byte06, byte07 ;
    uint8_t end ;                 /*   End of message (0xFF) */
} ;
struct bite_appsys_Q177 {       /* Q-BITE for Model 177 */
    uint8_t sync ;                /*   Initial sync byte (0xAF) */
    uint8_t id ;                  /*   Identification */
    struct QBite14 QVals[3] ;     /*   All values are 14-bits */
    uint8_t end ;                 /*   End of message (0xFF) */
} ;
struct bite_appsys_Q337 {       /* Q-BITE for Model 337 */
    uint8_t sync ;                /*   Initial sync byte (0xAF) */
    uint8_t id ;                  /*   Identification */
    struct QBite14 QVals[5] ;     /*   All values are 14-bits */
    uint8_t end ;                 /*   End of message (0xFF) */
} ;
struct bite_appsys_Q377 {       /* Q-BITE for Model 377 */
    uint8_t sync ;                /*   Initial sync byte (0xAF) */
    uint8_t id ;                  /*   Identification */
    struct QBite14 QVals[4] ;     /*   All values are 14-bits */
    uint8_t end ;                 /*   End of message (0xFF) */
} ;
  
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with Orbit antenna controller
 */
struct bite_orbit {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t byte03, byte04, byte05, byte06, byte07 ;
    uint8_t end ;                 /* End of message (0xFF) */
} ;


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the GigaCom interface
 */
struct bite_gigatx_A {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t bytes[6] ;            /*  */
    uint8_t end ;                 /* End of message (0xFF) */
};

struct bite_gigatx_B {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t bytes[6] ;            /*  */
    uint8_t end ;                 /* End of message (0xFF) */
};

struct bite_gigatx_A_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 QVals[10] ;    /* */
    uint8_t end ;                 /* End of message (0xFF) */
};

struct bite_gigatx_B_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 QVals[10] ;    /* */
    uint8_t end ;                 /* End of message (0xFF) */
};

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the CAN-Bus interface
 */
struct bite_canbus {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t bytes[6] ;            /* JOK: define these */
    uint8_t end ;                 /* End of message (0xFF) */
} ;
struct bite_canbus_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 QVals[8] ;     /* JOK: define these */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the ADH-2A COM dehydrator
 */
struct bite_dehydrator {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t bytes[5] ;            /* Data from dehydrator */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

struct bite_dehydrator_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 QVals[4] ;     
    uint8_t end ;                 /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the klystron transmitter
 */
struct bite_klystron {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t bytes[4] ;            /* Data from klystron */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

struct bite_klystron_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 QVals[9] ;     
    uint8_t end ;                 /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the Power Monitor
 */
struct bite_powermon {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t bytes[1] ;            /* Status and alarm bits */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

struct bite_powermon_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 QVals[12] ;    /* Data from power sensors */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures related to the MELCO Turkey-01 serial interface
 */
struct melco_tky01_rrec {       /* Received record */
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    uint8_t qval[4] ;             /* Status bytes */
    uint8_t end ;                 /* End of message (0xFF) */
} ;

struct bite_melco_tky01_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
#define MELCO_TKY01_SYNC 0xAF
    uint8_t id ;                  /* Identification */
    uint8_t genhrs[4] ;           /* Generator running hours */
    uint8_t genfuel[2] ;          /* Generator fuel level */
    uint8_t genv1[2] ;            /* Generator V1/V2/V3 voltage */
    uint8_t genv2[2] ;
    uint8_t genv3[2] ;
    uint8_t end ;                 /* End of message (0xFF) */
#define MELCO_TKY01_END 0xFF
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with Pulse Systems TR-1163 
 * transmitter, ethernet interface
 */
struct bite_ps_tr1163 {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t byte03, byte04, byte05;// byte06 ;
    uint8_t end ;                 /* End of message (0xFF) */
};

struct bite_ps_tr1163_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite21 TrSystemHours ;
    struct QBite21 TrRadiateHours ;
    struct QBite14 TrHeaterVoltage ;
    struct QBite14 TrMagAvgCurrent ;
    struct QBite14 TrPSVoltage ;
    struct QBite14 TrPSCurrent ;
    uint8_t end ;                 /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with ARA ACU-3 (Antenna Controller)
 */

struct bite_ara_acu {
    uint8_t sync ;                /*   Initial sync byte (0xC0) */
    uint8_t id ;                  /*   Identification */
    uint8_t byte03, byte04, byte05, byte06 ;
    uint8_t end ;                 /*   End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with TSC TWT (Transmitter)
 */

struct bite_tsc_twt {
    uint8_t sync ;                /* Initial sync byte (0xC0) */
    uint8_t id ;                  /* Identification */
    uint8_t byte03, byte04, byte05, byte06, byte07 ;
    uint8_t end ;                 /* End of message (0xFF) */
};

struct bite_tsc_twt_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 TrFrequencyCode;
    struct QBite14 TrRcvProtectLeakage;
    struct QBite14 TrTransmitterPower;
    struct QBite14 TrReflectedPower;
    struct QBite14 TrWaveGuidePres1 ;
    struct QBite14 TrWaveGuidePres2 ;
    struct QBite14 TrRecoveryTime ;
    uint8_t end ;                 /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with EEC DDC (Transmitter)
 */

struct bite_eec_ddc {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    uint8_t byte03, byte04, byte05, byte06, byte07 ;
    uint8_t end ;                 /* End of message (0xFF) */
};

struct bite_eec_ddc_Q {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    struct QBite14 eec_qb_0 ;     /* DdcTxWarmupCount */
    struct QBite14 eec_qb_1 ;     /* DdcDppmFwdPwr */
    struct QBite14 eec_qb_2 ;     /* DdcDppmRefPwr */
    struct QBite14 eec_qb_3 ;     /* DdcDppmPRF*/
    struct QBite14 eec_qb_4 ;     /* DdcTxReportAge */
    struct QBite14 eec_qb_5 ;     /* DdcTxCapTemp */
    struct QBite14 eec_qb_6 ;     /* DdcHotBoxTemp */
    struct QBite14 eec_qb_7 ;     /* DdcHvPsVoltage */
    struct QBite14 eec_qb_8 ;     /* DdcHvPsCurrent */
    struct QBite14 eec_qb_9 ;     /* DdcMagCurrent */
    struct QBite14 eec_qb_10 ;    /* DdcAfcVoltage */
    struct QBite14 eec_qb_11 ;    /* spare qbite records */
    struct QBite14 eec_qb_12 ;
    struct QBite14 eec_qb_13 ;
    struct QBite14 eec_qb_14 ;
    struct QBite14 eec_qb_15 ;
    struct QBite14 eec_qb_16 ;
    struct QBite14 eec_qb_17 ;
    struct QBite14 eec_qb_18 ;
    struct QBite14 eec_qb_19 ;
    struct QBite14 eec_qb_20 ;
    struct QBite14 eec_qb_21 ;
    struct QBite14 eec_qb_22 ;
    struct QBite14 eec_qb_23 ;

    uint8_t end ;                   /* End of message (0xFF) */
} ;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * Structures for communication with RPM PED
 */

struct bite_rpm_ped {
    uint8_t sync ;                /* Initial sync byte (0xAF) */
    uint8_t id ;                  /* Identification */
    uint8_t byte03, byte04 ;
    uint8_t 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 )                 \
    uint8_t bite_xmtrec_##NAME                                          \
    ( volatile struct bite_##NAME *biterec_a, uint32_t iTickNow_a )     \
    {                                                                   \
        uint8_t lMadePacket = FALSE ;                                   \
        if( ENABLED ) {                                                 \
            static uint32_t iTickLast=0 ;                               \
            if( ( lRequest_bite_##NAME##_c                         ) || \
                ( btimeGrace(iTickNow_a-iTickLast) > (uint32_t)(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( uint8_t iCmdOp_a, int32_t iID_a, uint32_t 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 uint8_t lNoDiags_c ;           /* Skip diagnostics entirely */
XM uint8_t lForceVer_c ;          /* Attempt to use mismatched hardware */
XM int32_t iIoCardForce_c ;       /* Force a particular I/O-62 card (or none) */
XM uint8_t lInterruptible_c ;     /* Allow ^C from startup session */
XM uint32_t lCoreDump_c ;         /* Try to dump core on abnormal exits */
XM uint8_t 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_ANTENNA_LIB_H
/* Must be defined when we are allocating */
VM struct ant_manual_setup irisAnt_c ;
#endif

VM uint32_t mtimeIRIS_c ;         /* Last modification times of IRIS and */
VM uint32_t 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 uint8_t lHasPanel_c[ RCP8MAXIO ]; /* Optional backpanel is present */
XM int32_t iIo62Card_c[ RCP8MAXIO ]; /* Unit number of card being used */
#endif /* #ifdef SIGMET_PCICARDS_LIB_H */

#ifdef SIGMET_NETCARDS_LIB_H
#ifdef RVP9WR_LWRPC_EXPANDFUNCS
XM Rvp9WR *Rvp9_c[ RVP9MAXUNITS ]; /* ==> Optional RVP9/IFD */
#endif /* #ifdef RVP9WR_LWRPC_EXPANDFUNCS */
#ifdef RCP9ORDA_LWRPC_EXPANDFUNCS
XM Rcp9ORDA *Rcp9ORDA_c[ RCP9MAXUNITS  ]; /* ==> Optional Networked Panel */
#endif /* #ifdef RCP9ORDA_LWRPC_EXPANDFUNCS */
#endif /* #ifdef SIGMET_NETCARDS_LIB_H */

#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 */

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

VM uint8_t 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 uint8_t itimer_bits_c    [NTIMER_VARS][2] ; /* timer variable bits/prevs */
VM uint32_t itimer_counts_c   [NTIMER_VARS] ;  /* timer variable counts */
XM uint32_t itimer_periods_c  [NTIMER_VARS] ;  /* timer periods */
XM uint32_t itimer_htimes_c   [NTIMER_VARS] ;  /* timer HI times */

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

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

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

XM uint16_t 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 uint32_t        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 uint8_t lreset_req_c ;         /* Reset request */
VM int16_t ireset_pulse_c ;       /* Timer for external reset pulse */

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

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

XM struct full_time_spec TimeBoot_c; /* Full time and BTIME at which the */
XM uint32_t 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 float fSrvIntPeriod_c ;        /* Servo process interrupt period and */
XM float fSrvAntPeriod_c ;        /*   antenna update period (seconds) */
XM float fCSTickPeriod_c ;        /* Control/Status tick period (seconds) */

#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 int32_t 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 uint8_t 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 uint8_t lprintonly_c ;

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

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

VM uint16_t isio_char_incnt_c ;   /* SIO character input count */
VM uint16_t isio_rec_incnt_c ;    /* SIO record input count */
VM uint16_t 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 uint8_t 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(2000) SIOMonFIFO_c ;      /* Buffered stream data to be watched */
XM pthread_mutex_t SIOMonMutex_c; /*  and lock for multiple writers */

VM uint64_t 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
#define SIOMON_ARA_ACU_RCV   0x01000000 /* ARA ACU-3 */
#define SIOMON_ARA_ACU_XMT   0x02000000
#define SIOMON_MELTKYRCV     0x04000000 /* Melco Turkey-01 BITE stream */
#define SIOMON_TSC_TWT_TR_RCV   0x08000000 /* TSC TWT T/R */
#define SIOMON_TSC_TWT_TR_XMT   0x10000000
#define SIOMON_TSC_TWT_MOD_RCV  0x20000000 /* TSC TWT Modulator*/
#define SIOMON_TSC_TWT_MOD_XMT  0x40000000
#define SIOMON_EEC_DDC_RCV      0x0000000080000000 /* EEC DDC */
#define SIOMON_EEC_DDC_XMT      0x0000000100000000
#define SIOMON_GIGATXRCV        0x0000000200000000 /* GigaCom */
#define SIOMON_GIGATXXMT        0x0000000400000000
#define SIOMON_GIGATXSIMRCV     0x0000000800000000 /* GigaCom simulator */
#define SIOMON_GIGATXSIMXMT     0x0000001000000000
#define SIOMON_SERVORCV		0x0000002000000000 /* Network Servo */
#define SIOMON_SERVOXMT		0x0000004000000000 /* Network Servo */
#define SIOMON_RPM_CMD_RCV      0x0000020000000000 /* RPM PED */
#define SIOMON_RPM_CMD_XMT      0x0000040000000000
#define SIOMON_RPM_DATA_XMT     0x0000080000000000
#define SIOMON_TR1163RCV        0x0000100000000000 /* Pulse Systems TR-1163 */
#define SIOMON_TR1163XMT        0x0000200000000000
#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

/* ------------------------------
 * Variables related to optional signal generator
 */
VM int16_t isgen_level_c ;        /* SIGGEN level in dBm */
VM uint8_t lsgen_on_c ;           /* SIGGEN RF output is enabled */
VM uint8_t lsgen_cw_c ;           /* SIGGEN is in CW mode */
VM uint8_t 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 uint16_t iDrcpMode_c ;         /* Current operational mode */
VM uint8_t lDrcpModeTrusted_c ;   /* Mode has been freshly updated */

VM uint8_t 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 uint16_t iDrcpAct_c ;          /* Cleaned up activity codes for */
VM uint16_t iDrcpActOther_c ;     /*   display of system activity. */

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

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


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

#ifdef INCLUDE_PTHREAD_PROTOTYPES
struct oneThread {              /* Description of one background thread */
    int32_t iPID ;                /*   Actual process ID of this thread */
    uint8_t 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 uint8_t lHaveRootPrivs_c ;     /* We can get root privileges if needed */
VM uint16_t lDaurcverror;

#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 ) ;

uint8_t bite_xmtrec_internal
( volatile struct bite_internal *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_internal( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_adc_Q
( volatile struct bite_adc_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_adc_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_auxsts
( volatile struct bite_auxsts *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_auxsts( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

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

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

/* ------------------- subs_boolean.c -------------------
 */
uint8_t 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[], uint8_t 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 ) ;
uint8_t boolused( struct rcp8_boolean_control *bool_a ) ;
const char *boolvarname( uint16_t ivar_a ) ;
char *adc_sum_terms_text( struct rcp8_adcvar *adcvar_a ) ;

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

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

void rcp8DispPrint
( int32_t iLine_a, uint8_t lWait_a, const char *text_a ) ;

void fpd_update( void ) ;

char *ubin_to_ch( uint16_t iangle_a, char *buf_a, uint8_t lhndths_a ) ;
char *sbin_to_ch( int16_t iangle_a, char *buf_a, uint8_t lhndths_a ) ;
char *ebin_to_ch( int16_t iangle_a, char *buf_a, uint8_t lhndths_a ) ;

uint8_t iHexFromChar( uint8_t 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 ) ;

float 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)

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

uint32_t iBtimeMS( void ) ;

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

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

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

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

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

void conditionalAntStatus( void ) ;

#define RCP8_AXIS_AZ (0)
#define RCP8_AXIS_EL (1)
void pedposFilterAndSet
( uint8_t iAxis_a,                /* Which axis we are checking */
  BIN2  iMesPos_a,
  uint32_t iTickAngle_a,
  float  fMaxAngVel_a,            /* Maximum speed in degrees/second */
  BIN2  iPosQuant_a,
  BIN2  iShaftJump_a );           /* How much the shaft calibration jumped */

/* Convenience function for open interface programs. */
void pedpos_insert_in_rvp8 
( BIN2 iPedAz_a,
  BIN2 iPedEl_a,
  uint32_t iBtimeData_a,          /* Time of the angle position */
  float fMaxAngVel_a,             /* Maximum speed in degrees/second */
  BIN2 iPosQuant_a );

/* ------------------- 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 ) ;
uint8_t live_get_ttyline( void ) ;
double fgetnum( double fdefault_a, uint8_t *lfound_a ) ;
int32_t get_word_lcase( char stext_a[], int32_t len_a ) ;
int32_t get_word_casefold( char stext_a[], int32_t len_a, int32_t 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,
  uint8_t iStrategy_a, uint8_t iMode_a, uint8_t lAllowSwitch_a ) ;

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

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

void format_saved_equations( struct rcp8_boolean_save *pSave_a ) ;

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

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

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

int32_t new_antstat_rec
( int32_t 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.c -------------------
 */
uint8_t lOpenProfiling( void ) ;
uint32_t iOpenUnique( void ) ;

/* ------------------- rcp8_lib_nls_init.c -------------------
 */
void rcp8_lib_nls_init(void);
#define RCP8_LIB_INIT rcp8_lib_nls_init()

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

uint8_t bite_xmtrec_dau
( volatile struct bite_dau *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dau( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_dau_Q
( volatile struct bite_dau_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dau_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t 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 ) ;

uint8_t bite_xmtrec_dcu
( volatile struct bite_dcu *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dcu( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_dcu_st1
( volatile struct bite_dcu_st1 *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dcu_st1( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_dcu_st2
( volatile struct bite_dcu_st2 *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dcu_st2( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void dcu_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- dualsys.c --------------------------- */
void drcp_states(volatile struct rcp8_bit_control *req_a);
void drcp_control(void);
void drcp_status(volatile struct rcp8_bit_status *bit_a);

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

uint8_t bite_xmtrec_kavtcu
( volatile struct bite_kavtcu *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_kavtcu( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_kavtcu_Q
( volatile struct bite_kavtcu_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_kavtcu_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t 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 ) ;

uint8_t bite_xmtrec_andrew
( volatile struct bite_andrew *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_andrew( uint8_t iCmdOp_a, int32_t iID_a, uint32_t 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 ) ;

uint8_t bite_xmtrec_appsys
( volatile struct bite_appsys *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_appsys( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_appsys_Q177
( volatile struct bite_appsys_Q177 *biterec_a, uint32_t iTickNow_a ) ;
uint8_t bite_xmtrec_appsys_Q337
( volatile struct bite_appsys_Q337 *biterec_a, uint32_t iTickNow_a ) ;
uint8_t bite_xmtrec_appsys_Q377
( volatile struct bite_appsys_Q377 *biterec_a, uint32_t iTickNow_a ) ;

void bite_cmdops_appsys_Q177( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;
void bite_cmdops_appsys_Q337( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;
void bite_cmdops_appsys_Q377( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void appsys_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

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

uint8_t bite_xmtrec_orbit
( volatile struct bite_orbit *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_orbit( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

void orbit_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- gigacom_main.c -------------------
 */
void *gigatx_main( void *arg_a ) ;

uint8_t bite_xmtrec_gigatx_A
( volatile struct bite_gigatx_A *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_gigatx_A( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

uint8_t bite_xmtrec_gigatx_B
( volatile struct bite_gigatx_B *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_gigatx_B( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

uint8_t bite_xmtrec_gigatx_A_Q
( volatile struct bite_gigatx_A_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_gigatx_A_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_gigatx_B_Q
( volatile struct bite_gigatx_B_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_gigatx_B_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void gigatx_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

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

uint8_t bite_xmtrec_canbus
( volatile struct bite_canbus *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_canbus( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

uint8_t bite_xmtrec_canbus_Q
( volatile struct bite_canbus_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_canbus_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void canbus_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- dehydrator.c -------------------
 */
void *dehydrator_main( void *arg_a ) ;

uint8_t bite_xmtrec_dehydrator
( volatile struct bite_dehydrator *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dehydrator( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

uint8_t bite_xmtrec_dehydrator_Q
( volatile struct bite_dehydrator_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_dehydrator_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void dehydrator_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

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

uint8_t bite_xmtrec_klystron
( volatile struct bite_klystron *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_klystron( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

uint8_t bite_xmtrec_klystron_Q
( volatile struct bite_klystron_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_klystron_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void klystron_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- power_monitor.c -------------------
 */
void *powermon_main( void *arg_a ) ;

uint8_t bite_xmtrec_powermon
( volatile struct bite_powermon *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_powermon( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iBtimeNow_a ) ;

uint8_t bite_xmtrec_powermon_Q
( volatile struct bite_powermon_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_powermon_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void powermon_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- melco_tky01.c -------------------
 */
void *melco_tky01_main( void *arg_a ) ;
void *melco_tky01Sim_main( void *arg_a ) ;

uint8_t bite_xmtrec_melco_tky01_Q
( volatile struct bite_melco_tky01_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_melco_tky01_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void melco_tky01_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- ps_tr1163.c -------------------
 */
void *ps_tr1163_main(void *arg_a) ;

uint8_t bite_xmtrec_ps_tr1163
( volatile struct bite_ps_tr1163 *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_ps_tr1163( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_ps_tr1163_Q
( volatile struct bite_ps_tr1163_Q *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_ps_tr1163_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void ps_tr1163_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;


/* ------------------- ara_acu3_main.c -------------------
 */
void *ara_acu_main( void *arg_a ) ;
void *ara_acu_sim_main( void *arg_a ) ;

uint8_t bite_xmtrec_ara_acu
( volatile struct bite_ara_acu *biterec_a, uint32_t iTickNow_a ) ;
void bite_cmdops_ara_acu( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void ara_acu_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

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

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

uint8_t bite_xmtrec_tsc_twt
( volatile struct bite_tsc_twt *biterec_a, uint32_t iTickNow_a ) ;

void bite_cmdops_tsc_twt( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_tsc_twt_Q
( volatile struct bite_tsc_twt_Q *biterec_a, uint32_t iTickNow_a ) ;

void bite_cmdops_tsc_twt_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

void tsc_twt_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

void *tsc_twt_sim_tr_main( void *arg_a ) ;
void *tsc_twt_sim_mod_main( void *arg_a ) ;

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

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

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

uint8_t bite_xmtrec_eec_ddc
( volatile struct bite_eec_ddc *biterec_a, uint32_t iTickNow_a ) ;

void bite_cmdops_eec_ddc( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;

uint8_t bite_xmtrec_eec_ddc_Q
( volatile struct bite_eec_ddc_Q *biterec_a, uint32_t iTickNow_a ) ;

void bite_cmdops_eec_ddc_Q( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;
void eec_ddc_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

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

uint8_t bite_xmtrec_rpm_ped
( volatile struct bite_rpm_ped *biterec_a, uint32_t iTickNow_a ) ;

void bite_cmdops_rpm_ped( uint8_t iCmdOp_a, int32_t iID_a, uint32_t iTickNow_a ) ;
void rpm_ped_rcp_status( volatile struct rcp8_bit_status *bit_a ) ;

/* ------------------- rcp_limits.c -------------------
 */
MESSAGE rcp8_load_conf
( volatile struct rcp8_nv *pRcp8NV_a ) ;
MESSAGE rcp8_save_conf
( 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 -------------------
 */
uint8_t lSiteProfiling( void ) ;
uint32_t 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 uint8_t 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 uint8_t antBuf_a[], uint32_t iBtimeData_a ) ;
void dcu_rxBitRecHook( const uint8_t bitBuf_a[], uint32_t iBtimeData_a ) ;
void dcu_rxTstRecHook( const uint8_t tstBuf_a[], uint32_t iBtimeData_a, int32_t 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( uint8_t simAntRec[8] ) ;
void dcusim_txBitHook( uint8_t simAntRec[6] ) ;
void dcusim_txST2Hook( uint8_t simAntRec[4] ) ;
