/* ********************************
 * *                              *
 * *    Low-Level I/O API for     *
 * * Radar Interface Module (RIM) *
 * *        (rimioapi.h)          *
 * *                              *
 * ********************************
 */
#ifndef RIMIOAPI_H
#define RIMIOAPI_H

#ifdef __cplusplus
extern "C" 
{
#endif

/* See notes in rimiodef.h regarding the MUTEX thread lock that is
 * required around virtually all of these routines.
 */

/* ------------------------------
 * Mutex definitions for optional threaded code.  Use
 * rim_mutex_define() to setup the user-defined LOCK and UNLOCK
 * routines.  These should be functions of no arguments, that return a
 * status word in which zero indicates success.
 */
typedef int (*RIM_USER_MUTEX_ROUTINE)( void ) ;

void rim_mutex_define		/* Define routine, called externally */
( RIM_USER_MUTEX_ROUTINE user_mutex_lock_a,
  RIM_USER_MUTEX_ROUTINE user_mutex_unlock_a
  ) ;

int rim_mutex_lock		/* Lock routine, only used from */
( void ) ;			/*   within the rimio API. */

int rim_mutex_unlock		/* UnLock routine, only used from */
( void ) ;			/*   within the rimio API. */

/* ------------------------------
 * Basic ISA Port I/O.
 *
 * The port address is the 6-bit sub address defined by one of the
 * RIMIO_xxxx macros.  RIM_PORT_READ() reads from the specified port
 * and returns a single byte of data.  RIM_PORT_WRITE() writes a data
 * byte to a port, and also returns that same data value.
 */
SINT4 rim_port_init		/* Initialize for port I/O */
( void ) ;			/*   (Return 0 on success) */

UINT1 rim_port_read		/* Read from an I/O port */
( UINT2 portaddr_a		/*   6-bit RIM port number */
  ) ;

UINT1 rim_port_write		/* Write to an I/O port */
( UINT2 portaddr_a,		/*   6-bit RIM port number */
  UINT1 data_a			/*   Data byte to write */
  ) ;

/* ------------------------------
 * Basic RIM Board Functions
 */
UINT1 rim_board_revlevel	/* Returns circuit board revision level */
( void ) ;

UINT1 rim_pld_serial		/* Get serial information from each PLD */
( UINT1 ipld_a,			/*   "U" number of the PLD (1, 2, or 3) */
  UINT1 irequest_a		/*   One of SERIAL_SELECT_XXXX */
  ) ;

void rim_pldreset		/* Equivalent to an ISA reset of the PLDs */
( void ) ;

void rim_board_allowio		/* Connect ISA bus to programmable PLDs */
( UINT1 lallow_a		/*   Connect the bus if TRUE */
  ) ;

/* The JTAG interface to the PLDs is via these two routines.  The GET
 * routine returns the present state of the last TDO pin in the JTAG
 * chain.  The SET routine places the three control lines in a known
 * state.
 */
UINT1 rim_jtag_get		/* Get state of TDO pin */
( void ) ;

void rim_jtag_set		/* Set JTAG lines */
( UINT1 tck_a,			/*   Commanded state of TCK line */
  UINT1 tms_a,			/*   Commanded state of TMS line */
  UINT1 tdi_a			/*   Commanded state of TDI line */
  ) ;

/* The four user programmable LEDs at the front edge of the board are
 * controlled here.  Each LED can be turned On/Off individually, and
 * their overall states are returned.  LED0 is controlled by Bit #0,
 * etc.
 */
UINT1 rim_led_clrset		/* Control/Sense LEDs */
( UINT1 bitclr_a,		/*   LEDs to turn off */
  UINT1 bitset_a		/*   LEDs to turn on */
  ) ;

/* ------------------------------
 * RIM Memory Operations.
 *
 * These routines permit blocks of external RIM memory to be accessed
 * efficiently.
 */
void rim_mem_read		/* Read from RIM memory */
( volatile void * pcaddr_a,	/*   Destination address in PC */
  UINT4 rimaddr_a,		/*   Source address in RIM memory */
  SINT4  icount_a		/*   Byte count */
  ) ;

void rim_mem_write		/* Write into RIM memory */
( UINT4 rimaddr_a,		/*   Destination address in RIM memory */
  volatile void * pcaddr_a,	/*   Source address in PC */
  SINT4  icount_a		/*   Byte count */
  ) ;

void rim_memset			/* Set a block to RIM memory to a value */
( UINT4 rimaddr_a,		/*   Destination address in RIM memory */
  UINT1 data_a,			/*   Data value to set */
  SINT4 icount_a		/*   Byte count */
  ) ;

/* The following routines with a "_nomutex" suffix are identical,
 * except that they assume the mutex is locked on entry.  They should
 * be called only from within this API
 */
void rim_mem_read_nomutex
( volatile void * pcaddr_a, UINT4 rimaddr_a, SINT4  icount_a ) ;

void rim_mem_write_nomutex
( UINT4 rimaddr_a, volatile void * pcaddr_a, SINT4  icount_a ) ;

void rim_memset_nomutex
( UINT4 rimaddr_a, UINT1 data_a, SINT4 icount_a ) ;

/* ------------------------------
 * Serial Data Transmitter.
 *
 * These routines access the onboard serial bit transmitter.
 * RIM_SIO_RESET() should be called first, and serves to reset the SIO
 * hardware.  The clock characteristics should then be set with
 * RIM_SIO_SETCLOCK().
 *
 * Data streams are passed as arrays of bytes, where a zero byte means
 * a "0" bit, and a nonzero byte means a "1" bit.  RIM_SIO_SETIDLE()
 * defines the idle bit sequence (if any) that will be transmitted
 * between runs of data.  RIM_SIO_SENDBUF() transmits an actual data
 * string.  It returns 0 on success, and -1 to indicate that the
 * transmitter queue was full, i.e., that the call should be repeated
 * later.
 */
void rim_sio_reset		/* Reset the entire SIO transmitter */
( UINT1 linestate_a		/*   Default state of output data line */
  ) ;

void rim_sio_setclock		/* Set clock of SIO transmitter */
( FLT4 fbaud_a,			/*   Baud rate (in Hertz) */
  UINT1 iclockphase_a		/*   0-3, location of rising edge  */
  ) ;

void rim_sio_setidle		/* Set IDLE pattern of SIO transmitter */
( void * idlebuffer_a,		/*   ==> IDLE pattern, or NULL for none */
  SINT4  bitcount_a		/*   Length of the IDLE pattern */
  ) ;

SINT4 rim_sio_sendbuf		/* Transmit a buffer of data bits */
( void * databuffer_a,		/*   ==> DATA pattern to transmit */
  SINT4  bitcount_a		/*   Length of the DATA pattern */
  ) ;

void rim_sio_leds		/* Control/Status of the SIO LEDs */
( UINT1 lnormal_a,		/*   Normal function (Sending DATA/IDLE) */
  UINT1 ledstate_a		/*   LED state, if not normal function */
  ) ;

/* ------------------------------
 * Diagnostic Input and Output Signal Monitors
 */
UINT1 rim_get_line_state	/* Return current state of input/output line */
( UINT1 iselect_a		/*   One of DGIN_XXXX or DGOUT_XXXX */
  ) ;

void rim_set_line_state		/* Force an output line to a given state */
( UINT1 iselect_a,		/*   One of DGOUT_XXXX */
  UINT1 ldata_a			/*   Logic level to apply */
  ) ;

UINT1 rim_set_line_state_cmd	/* Readback a forced output line level */
( UINT1 *iselect_a		/*   The selected line is returned here */
  ) ;

/* *******************
 * *                 *
 * * ASR9 Interfaces *
 * *                 *
 * *******************
 */

/* This is the frequency of the ASR9 "10.3" MHz clock, in MegaHertz
 */
#define ASR9_103_FREQMHZ (10.356764)

/* Routines to help with alignment of the 10.3MHz, 2.6MHz, and 1.3MHz
 * clocks from the ASR9.  Clock alignment should be done on initial
 * powerup, and whenever switching between real and simulated clocks.
 */
void rim_asr9_clk_align		/* Align the 10.3MHz clock */
( void ) ;
void rim_asr9_clk_set		/* Set the 10.3MHz clock phase */
( UINT1 iphase_a		/*   Relative phase (0-7) */
  ) ;
UINT1 rim_asr9_clk_get		/* Get the 10.3MHz clock phase (0-7) */
( void ) ;

/* Azimuth position routines.
 */
UINT2 rim_asr9_getaz		/* Get current antenna position (0-4095) */
( UINT2 * arpcount_a		/*   If not NULL, then return 4-bit rotation count */
  ) ;

/* ------------------------------
 * STC Interfaces
 */

/* STC values start prior to xmit - first STC value in each
 * 1024-element array corresponds to range gate -11 (measured)
 */
#define RIMEM_STCMAP_ZEROBIN   (-11)  /* put in rimioapi.h... */ 

/* The selection of one-of-eight STC maps is controlled by a 3-bit
 * address whose bits are defined here.  Each argument should be one
 * of STC_SEL_xxx as defined in rimiodef.h
 */
void rim_asr9_stcsel		/* Control addressing of STC map */
( UINT1 stcsel2_a,		/*   Selection of Bit #2 */
  UINT1 stcsel1_a,		/*   Selection of Bit #1 */
  UINT1 stcsel0_a		/*   Selection of Bit #0 */
  ) ;

void rim_asr9_stcsel_get	/* Readback addressing of STC maps */ 
( UINT1 *stcSel2_a,		/*   Selection of bit #2 */
  UINT1 *stcSel1_a,		/*   Selection of bit #1 */
  UINT1 *stcSel0_a		/*   Selection of bit #0 */
  ) ;

void rim_asr9_stcloadsect	/* Load sector (1024-element array) of STC data */
( UINT1 chan_a,			/*   Channel (0 = A, 1 = B) */
  UINT1 polariz_a,		/*   Polariz (0 = Lin, 1 = Circ) */
  UINT1 beam_a,			/*   Beam (0 = A, 1 = B) */ 
  UINT4 sector_a,		/*   Azimuth (0-255) */
  UINT1 *mapSect_a		/*   ==> Data to be written */
  ) ;

/* The phase of the STC output data and output clock can be stepped in
 * units of the 10.3MHz clock.  This allows the STC to be optimally
 * positioned within a range bin.
 */
UINT1 rim_asr9_stc_datphase_get	/* Get STC data phase (0-7) */
( void ) ;
void rim_asr9_stc_datphase_set	/* Set STC data phase */
( UINT1 iphase_a		/*   Relative phase (0-7) */
  ) ;
UINT1 rim_asr9_stc_clkphase_get	/* Get STC clock phase (0-7) */
( void ) ;
void rim_asr9_stc_clkphase_set	/* Set STC clock phase */
( UINT1 iphase_a		/*   Relative phase (0-7) */
  ) ;

/* ------------------------------
 * ASR9 RF Switch and Status Routines
 */
void rim_asr9_swsts_sim_set	/* Set up simulated status inputs */
( UINT1 iswsts_a,		/*   Bit to simulate - one of SWSTS_XXXX */
  UINT1 lsimulate_a,		/*   NZ -> simulate the selected bit */
  UINT1 ilevel_a		/*   Level to use, if simulating */
  ) ;
void rim_asr9_swsts_sim_get	/* Get info about simulated status inputs */
( UINT1 iswsts_a,		/*   Bit to inquire - one of SWSTS_XXXX */
  UINT1 * lsimulate_a,		/*   NZ -> simulate the selected bit */
  UINT1 * ilevel_a		/*   Level to use, if simulating */
  ) ;

/* ------------------------------
 * RIN-PE Data Stream Control
 */
void  rim_set_rinpe_run		/* Set RIN-PE run state */
( UINT1 lrun_a			/*   Request to run */
  ) ;
UINT1 rim_get_rinpe_run_cmd	/* Get RIN-PE run/stop command */
( void ) ;

UINT1 rim_get_rinpe_run		/* Get actual RIN-PE running status */
( void ) ;

/* ------------------------------
 * Internal Hardware Simulations.
 *
 * These routines control whether internal hardware simulations are
 * used in place of actual external electrical signals.  These
 * simulations are very useful during program development, or when
 * part of the real ASR9/RVP7 is not working.
 */
void rim_asr9_simclocks		/* Control simulation of ASR9 clocks */
( UINT1 lsimulate_a		/*   TRUE to simulate */
  ) ;
UINT1 rim_asr9_simclocks_get	/* Get clock simulation state */
( void ) ;

void rim_asr9_simantenna	/* Control simulation of ASR9 antenna pulses */
( UINT1 lsimulate_a,		/*   TRUE to simulate */
  FLT4  fperiod_a		/*   Period (microseconds) of ACP pulses */
  ) ;
UINT1 rim_asr9_simantenna_get	/* Get antenna simulation state */
( FLT4 * fperiod_a 		/*   Period (microseconds) of ACP pulses */
  ) ;

/* The upper 8-bits of (I,Q) data from both the ASR9 and the RVP7 can
 * be simulated.  The format of the floating input array is signed
 * (I,Q) pairs ranging from -1.0 to +1.0, corresponding to the full
 * range of possible values that might be encountered.  The bin number
 * of the first simulated data element is given by RIM_SIMIQ_ZEROBIN.
 * This starting bin number is negative so that data prior to range
 * zero can also be simulated.
 */
#define RIM_SIMIQ_ZEROBIN (-10)	/* Bin number of first simulated element */

void rim_asr9_simiq		/* Control simulation of ASR9 I/Q data */
( UINT1 lsimulate_a,		/*   TRUE to simulate */
  FLT4 fdata_a[2048][2]		/*   Array of simulated (I,Q) data  */
  ) ;
UINT1 rim_asr9_simiq_get	/* Get ASR9 I/Q data simulation state */
( void ) ;

void rim_rvp7_simiq		/* Control simulation of RVP7 I/Q data */
( UINT1 lsimulate_a,		/*   TRUE to simulate */
  FLT4 fdata_a[2048][2]		/*   Array of simulated (I,Q) data  */
  ) ;
UINT1 rim_rvp7_simiq_get	/* Get RVP7 I/Q data simulation state */
( void ) ;

/* The triggers are simulated using an array of (up to 64) successive
 * time periods, each measured in 14-bit counts of the 1.3MHz clock.
 * This allows fancy trigger patterns (such as are typically used by
 * the ASR9) to be synthesized.
 */
void rim_asr9_simtrigs		/* Control simulation of ASR9 PRETO trigger */
( UINT2 * periods_a,		/*   ==> array of trigger periods */
  UINT1 * endcodes_a,		/*   ==> array of endcodes (PRETO_CODE_XXXX) */
  SINT4 icount_a		/*   Size of above arrays, 0 ==> Dont Simulate */
  ) ;

UINT1 rim_asr9_simtrigs_get	/* Get trigger simulation state */
( UINT2 * periods_a,		/*   ==> array of trigger periods */
  UINT1 * endcodes_a		/*   ==> array of endcodes (PRETO_CODE_XXXX) */
  ) ;

/* The ASR9 RF switch status and control lines can be simulated, i.e.,
 * forced into a known LO/HI state.
 */
void rim_asr9_swsts_sim_set	/* Set up simulated status input */
( UINT1 iswsts_a,		/*   Bit to simulate - one of SWSTS_XXXX */
  UINT1 lsimulate_a,		/*   NZ -> simulate the selected bit */
  UINT1 ilevel_a		/*   Level to use, if simulating */
  ) ;
void rim_asr9_swsts_sim_get	/* Get info about simulated status input */
( UINT1 iswsts_a,		/*   Bit to inquire - one of SWSTS_XXXX */
  UINT1 * lsimulate_a,		/*   NZ -> selected bit is being simulated */
  UINT1 * ilevel_a		/*   Level being used, if simulating */
  ) ;
void rim_asr9_swcnt_sim_set	/* Set up simulated control output */
( UINT1 iswcnt_a,		/*   Bit to simulate - one of SWCNT_XXXX */
  UINT1 lsimulate_a,		/*   NZ -> simulate the selected bit */
  UINT1 ilevel_a		/*   Level to use, if simulating */
  ) ;
void rim_asr9_swcnt_sim_get	/* Get info about simulated control output */
( UINT1 iswcnt_a,		/*   Bit to inquire - one of SWCNT_XXXX */
  UINT1 * lsimulate_a,		/*   NZ -> selected bit is being simulated */
  UINT1 * ilevel_a		/*   Level being used, if simulating */
  ) ;

/* The switch pair 103/104 has only three well defined composite
 * states.  These two routines are merely a remapping cover for the
 * existing switch simulation and readback routines; but they allow
 * the switch pair to be viewed as a single composite entity.  All
 * arguments into and out of these routines are the parameters
 * SW103104_XXXX.
 */
void  rim_asr9_103104sts_sim_set  /* Set up simulation of SW103/104 status */
( SINT4 sw103104_a		  /*   Commanded state, or -1 for "normal" */
  ) ;
SINT4 rim_asr9_103104sts_sim_get  /* Get simulation info for SW103/104 status */
( void ) ;
void  rim_asr9_103104cnt_sim_set  /* Set up simulation of SW103/104 control */
( SINT4 sw103104_a		  /*   Commanded state, or -1 for "normal" */
  ) ;
SINT4 rim_asr9_103104cnt_sim_get  /* Get simulation info for SW103/104 control */
( void ) ;


#ifdef __cplusplus
}
#endif

#endif /* #ifndef RIMIOAPI_H */
