/* **********************************************************************
 * *                                                                    *
 * *        RDA System PCI Board-Level Driver Library Definitions       *
 * *                                                                    *
 * **********************************************************************
 * File: include/pcicards_lib.h
 *
 *                  COPYRIGHT (c) 2001, 2002, 2003  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#ifndef SIGMET_PCICARDS_LIB_H
#define SIGMET_PCICARDS_LIB_H 1

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 * The PCI driver library entry points fundamentally deal with
 * only one PCI board at a time.  All of the board support for
 *   each individual card should be placed in this library.
 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 */

/* *******************************
 * *                             *
 * * Message Catalog Definitions *
 * *                             *
 * *******************************
 */
#define     OPENERR            1
#define PCI_OPENERR          (PCI_FACILITY + OPENERR)
#define     OPENEXCLERR        2
#define PCI_OPENEXCLERR      (PCI_FACILITY + OPENEXCLERR)
#define     PCIBARNULL         3
#define PCI_PCIBARNULL       (PCI_FACILITY + PCIBARNULL)
#define     TGENRESET          4
#define PCI_TGENRESET        (PCI_FACILITY + TGENRESET)
#define     UPTOSSNOTG         5
#define PCI_UPTOSSNOTG       (PCI_FACILITY + UPTOSSNOTG)
#define     RNGMSKBADRNG       6
#define PCI_RNGMSKBADRNG     (PCI_FACILITY + RNGMSKBADRNG)
#define     RNGMSKDUPRNG       7
#define PCI_RNGMSKDUPRNG     (PCI_FACILITY + RNGMSKDUPRNG)
#define     FIRTOOLONG         8
#define PCI_FIRTOOLONG       (PCI_FACILITY + FIRTOOLONG)
#define     DECITOOSMALL       9
#define PCI_DECITOOSMALL     (PCI_FACILITY + DECITOOSMALL)
#define     NORVP8RXDATA      10
#define PCI_NORVP8RXDATA     (PCI_FACILITY + NORVP8RXDATA)
#define     SYSTIMESLEW       11
#define PCI_SYSTIMESLEW      (PCI_FACILITY + SYSTIMESLEW)
#define     GPIOCONFIG        12
#define PCI_GPIOCONFIG       (PCI_FACILITY + GPIOCONFIG)
#define     GPIOBADPDEF       13
#define PCI_GPIOBADPDEF      (PCI_FACILITY + GPIOBADPDEF)
#define     PANELMISSING      14
#define PCI_PANELMISSING     (PCI_FACILITY + PANELMISSING)
#define     MISMATCHVER       15
#define PCI_MISMATCHVER      (PCI_FACILITY + MISMATCHVER)
#define     KMODNOVER         16
#define PCI_KMODNOVER        (PCI_FACILITY + KMODNOVER)
#define     KMODBADVER        17
#define PCI_KMODBADVER       (PCI_FACILITY + KMODBADVER)
#define     DISPLAYDEAD       18
#define PCI_DISPLAYDEAD      (PCI_FACILITY + DISPLAYDEAD)
#define     CPSERIALSANE      19
#define PCI_CPSERIALSANE     (PCI_FACILITY + CPSERIALSANE)
#define     TXBADFREQ         20
#define PCI_TXBADFREQ        (PCI_FACILITY + TXBADFREQ)
#define     TXBANDWIDTH       21
#define PCI_TXBANDWIDTH      (PCI_FACILITY + TXBANDWIDTH)
#define     AQCLKCHANGED      22
#define PCI_AQCLKCHANGED     (PCI_FACILITY + AQCLKCHANGED)

#ifndef MESSAGE_ONLY

/* ***********************************
 * *                                 *
 * *  Miscellaneous PCI Definitions  *
 * *                                 *
 * ***********************************
 */

/* Parameters defining the optional interface to an internal Matrix
 * Orbital serial display unit.  The same code is used in all cards
 * since the display might be physically cabled to any of them.
 */
#define MATORB_FIFOSIZE    64	/* Number of words in outgoing FIFO */
#define MATORB_FIFOUSED( CSR ) ( (CSR) & ((MATORB_FIFOSIZE)-1) )
#define MATORB_DATAVAIL     8	/* Received char available */
#define MATORB_NOHELLO      9	/* Skip welcome messages after reset */
#define MATORB_TXBUSY      10	/* Still sending chars to the display */

#define MATORB_LINES        2	/* Height (number of lines) and */
#define MATORB_WIDTH       20	/*   width of the display. */

#define MATORB_BSLSH   0x07	/* Have to make backslash ourself! */
#define MATORB_LBETA   0xE2	/* Lower case Beta */
#define MATORB_DEGREE  0xDF	/* Degree symbol */

#ifdef INCLUDE_PTHREAD_PROTOTYPES
struct matorbInfo {
  pthread_mutex_t PCIMutex ;	/* Lockes access to PCI registers */
  volatile UINT4 *pCSR ;	/* ==> Front panel display CSR */
  volatile UINT4 *pData ;	/* ==> Front panel data read/write */
  const char *pDevName ;	/* ==> Device name of board */
  UINT1 lDisabled ;		/* Kill display if it's not working */
  UINT1 lNeedInits ;		/* Display initializations need to be done */
  char padEndx2[2] ;
} ;
#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

/* The following characters read back from the Matrix Orbital display
 * front panel buttons.
 */
#define MATORB_PB_UP       'I'	/* Cursor up */
#define MATORB_PB_DOWN     'J'	/* Cursor down */
#define MATORB_PB_LEFT     'O'	/* Cursor left */
#define MATORB_PB_RIGHT    'E'	/* Cursor right */
#define MATORB_PB_ENTER    'H'	/* "Enter" button */
#define MATORB_PB_F2       'M'	/* "F2" button */
#define MATORB_PB_F1       'N'	/* "F1" button */

/* The general purpose PCI Clock/Timer module has the following fixed
 * bit definitions in its CSR.  In addition to these bits, the counter
 * value can be read in the low bits of the word, and the interrupt-on
 * value is written in same.
 */ 
#define GPTIMER_TRIGLD     26	/* Load trigger level from low bits */
#define GPTIMER_CLKSRCLD   27	/* Load clock source bits */
#define GPTIMER_CLKSRC0    28	/* Two bits select one of four input */
#define GPTIMER_CLKSRC1    29	/*   clock sources for the counter. */
#define GPTIMER_INTCLR     30	/* Clear/Set the interrupt request */
#define GPTIMER_INTREQ     31	/*   bit (Only INTREQ reads back) */

#define MAXGPTIMERS 4
struct gpTimerInfo {		/* Driver info required to use a GPTimer */
  volatile UINT4 *pCSRs[MAXGPTIMERS] ; /* ==> hardware CSRs for several timers */
  SINT4       iIntUnits[MAXGPTIMERS] ; /* Interrupt channel for this timer */
  UINT4          iMasks[MAXGPTIMERS] ; /* Mask of counter/timer bits in the CSR */
  UINT1      lFireTimer[MAXGPTIMERS] ; /* External requests to fire a timer */
  SINT4 iFD ;			       /* File descriptor for IOCTL interrupts */
  SINT4 nTimers ;		       /* Number of available timers */
} ;
struct gpTimerWait {		/* User args for waiting on timers */
  SINT4 nWaitTimers ;		  /* Number of timer events to OR together */
  SINT4   iTimers[MAXGPTIMERS] ;  /* Which timers we're choosing */
  SINT4 iFireVals[MAXGPTIMERS] ;  /* Values at which to fire */
} ;

/* Generic software-driven serial decoder/encoder module to produce an
 * output bit stream and receive an input bit stream, making both
 * available to a PCI driver that carries out the actual encoding and
 * decoding functions.  In this model, exotic serial protocols can be
 * implemented without requiring any changes to the FPGA code.
 */
#define IOSCSR_HOOKUP0      0	/*  How to enable/attach serial */
#define IOSCSR_HOOKUP1      1	/*    functions to external lines. */
#define IOSCSR_BAUDLO       4	/* (Divisor-1) of IOSERIAL_MAXBAUD baud */
#define IOSCSR_BAUDHI       7

#define IOSERIAL_DEPTH     32	/* Depth of FIFO buffered octets */
#define IOSERIAL_MAXBAUD 19200	/* Maximum baud rate */

struct ioSerialInfo {		/* Driver info required for generic serializer */
  UINT4 iHookupCSR ;		/*   Hookup bits from CSR (since we can't read 'em) */
  volatile UINT4 *pCSR ;	/*   ==> hardware CSR of serializer */
  volatile UINT4 *pData ;	/*   ==> hardware Data port of serializer */
  UINT4 offCSR, offData ;	/*   Byte offsets of the above ports */
  SINT4 iIntUnit ;		/*   Interrupt unit number */
  SINT4 iFD ;			/*   File descriptor for IOCTLs */
} ;

/* Basic softplane flexCircuit test/termination functions are provided
 * by a common module with the following CSR bit definitions.
 */
#define SPLCOM_USEFRONT     0	/* Use front/rear flexcircuit, else */
#define SPLCOM_USEREAR      1	/*   pull unused inputs low. */
#define SPLCOM_SECUNIT      2	/* This board is the secondary unit */
#define SPLCOM_OWNTEST      3	/* This own board's test bit */
#define SPLCOM_RX0TEST      4	/* Readback test bits for all boards */
#define SPLCOM_RX1TEST      5
#define SPLCOM_TX0TEST      6
#define SPLCOM_TX1TEST      7
#define SPLCOM_IO0TEST      8
#define SPLCOM_IO1TEST      9

#define FLEXMAXCARDS 6		/* Max card count: Pri/Sec of Rx/Tx/Io */
#define FLEXSERIALMICROSEC  10	/* Max serial time any-board-to-any-board */

/* Macros to help with opening and identifying boards.
 */
#define RDAOPEN_EXCLUSIVE  0x01 /* Error if device is in use already */
#define RDAOPEN_SECUNIT    0x02 /* Open as secondary unit of two boards */

#define FOUNDBOARD( NAME, INFO, STREAM )				\
  fprintf( STREAM, "  Found PCI Card " NAME				\
                   " - Rev.%c  Serial:%-4d  Code:%-2d (%s/%s)\r\n",	\
	   RDA_REV_LETTER(INFO.iBoardRev), INFO.iSerialNum,		\
	   INFO.iCodeRev, RDA_DEV_TOPPATH, INFO.sName )

#define FOUNDPANEL( IO62, STREAM )							\
  fprintf( STREAM, "   \\--> IO62CP Backpanel - Rev.%c  Serial:%-4d  Code:%-2d\r\n",	\
           RDA_REV_LETTER( iIo62CpBoardRev( IO62 ) ), iIo62CpSerialNum( IO62 ),		\
	   iIo62CpCodeRev( IO62 ) )

#define PANELCURRENTS( IO62, STREAM )							\
  if( iIo62CpBoardRev( IO62 ) >= 2 )							\
    fprintf( STREAM, "       ( Supply Currents - Panel: %d mA,  Relays: %d mA )\r\n",	\
             NINT( 1E3 * fIo62CpAMUXPanelAmps( IO62 ) ),				\
             NINT( 1E3 * fIo62CpAMUXRelayAmps( IO62 ) ) )

#define FOUNDIFD( RX, STREAM ) {							\
  if( lRvp8RxStyleCAT5E(RX) ) {								\
    const struct ifd_status *_STS = Rvp8RxIFDStatus( RX ) ;				\
    fprintf( STREAM, "   \\--> Remote IFD Assy  - Rev.%c  Serial:%-4d  Code:%-2d\r\n",	\
	     RDA_REV_LETTER( _STS->iBoardRev ), _STS->iSerialNum, _STS->iCodeRev ) ;	\
  }											\
}

/* Macros to help with card diagnostic routines.
 */
#ifdef PCICARDIAG
#define  PMSG( STR )         if( st_a ) { fprintf( st_a, STR         ) ; fflush(st_a) ; }
#define PMSG1( STR, A1 )     if( st_a ) { fprintf( st_a, STR, A1     ) ; fflush(st_a) ; }
#define PMSG2( STR, A1, A2 ) if( st_a ) { fprintf( st_a, STR, A1, A2 ) ; fflush(st_a) ; }

#define REPEAT_LOOP(ITERS) for( _iter=0 ; _iter < ITERS ; _iter++ )
#endif /* #ifdef PCICARDIAG */

/* ========================================
 * ============== cardsubs.c ==============
 * ========================================
 */
MESSAGE rdaReconfigPCI( void ) ;

MESSAGE rdaOpenAndMap
( const char *sDevice_a, SINT4 iDwordSize_a,
  void **addr_a, SINT4 *size_a, SINT4 *chan_a ) ;

MESSAGE rdaClose( void *addr_a, SINT4 size_a, SINT4 chan_a ) ;

#ifdef SIGMET_RDA_H
MESSAGE rdaGetBoardInfo( SINT4 iFD_a, struct rda_boardinfo *pInfo_a ) ;
MESSAGE rdaVersionCheck( struct rda_boardinfo *pInfo_a, SINT4 iExpected_a ) ;
#endif /* #ifdef SIGMET_RDA_H */

MESSAGE rdaVersionCheckSignal
( const char *pName_a, SINT4 iHave_a, SINT4 iNeed_a ) ;

MESSAGE rdaKModVersionCheck( void ) ;

#ifdef INCLUDE_PTHREAD_PROTOTYPES
void rdaEnableSpl
( pthread_mutex_t *pMutex_a, volatile UINT4 *pSPLCom_a,
  UINT1 lFront_a, UINT1 lRear_a ) ;
void rdaSplSetUnit
( pthread_mutex_t *pMutex_a, volatile UINT4 *pSPLCom_a, UINT1 lSecUnit_a ) ;
void rdaSetSplTest
( pthread_mutex_t *pMutex_a, volatile UINT4 *pSPLCom_a, UINT1 lTest_a ) ;

void rdaDispPrint
( struct matorbInfo *fpd_a, SINT4 iLine_a, UINT1 lWait_a, const char *text_a ) ;

SINT4 rdaDispSpaceUsed( struct matorbInfo *fpd_a ) ;
SINT4 rdaDispSpaceFree( struct matorbInfo *fpd_a ) ;
#endif /* #ifdef INCLUDE_PTHREAD_PROTOTYPES */

void printableFromMatorb( char *pText_a, SINT4 nChars_a ) ;

UINT1 lDwordMirrorFail( volatile UINT4 *pIO_a, volatile UINT4 iFailMasks_a[2] ) ;

UINT4 iDwordMemFail( void *addr_a, SINT4 iDwords_a ) ;
void   DwordMemFill( void *addr_a, UINT4 iFirst_a, UINT4 iInc_a, SINT4 iDwords_a ) ;

UINT4 iRdaGetTimerVal ( volatile struct gpTimerInfo *gpt_a, SINT4 iTimer_a ) ;
UINT4 iRdaGetTimerMask( volatile struct gpTimerInfo *gpt_a, SINT4 iTimer_a ) ;

void RdaSetTimerClkSrc
( volatile struct gpTimerInfo *gpt_a, SINT4 iTimer_a, SINT4 iClkSrc_a ) ;

void RdaWaitTimer
( volatile struct gpTimerInfo *gpt_a, SINT4 iTimer_a, UINT4 iFireVal_a ) ;

void RdaWaitTimerGroup
( volatile struct gpTimerInfo *gpt_a, const struct gpTimerWait *gpWait_a,
  void( *prepFunc_a )( void *prepArgs_a ), void *prepArgs_a ) ;

void RdaFireTimer( volatile struct gpTimerInfo *gpt_a, SINT4 iTimer_a ) ;
UINT1 lRdaTimerHasFired( UINT4 iDiff_a, UINT4 iMask_a ) ;

#ifdef SIGMET_USER_LIB_H
MESSAGE iRdaSerializerConfig
( struct ioSerialInfo *pInfo_a, const struct ttyspec *pSpec_a ) ;
#endif /* #ifdef SIGMET_USER_LIB_H */

void RdaSerializerWrite
( const struct ioSerialInfo *pInfo_a, volatile const void *pBuf_a, SINT4 nChars_a ) ;
SINT4 iRdaSerializerRead
( const struct ioSerialInfo *pInfo_a, volatile void *pBuf_a, SINT4 iMaxChars_a ) ;
SINT4 iRdaSerializerQueued
( const struct ioSerialInfo *pInfo_a, SINT4 iIosQueued_a ) ;

/* =======================================
 * ============== lmx3206.c ==============
 * =======================================
 */
struct lmx2306Regs {		/* Control registers for LMX2306 */
  SINT4 iRegIO, iBitIO ;	/*   State of serialization */
  SINT4 iR, iN ;		/*   Numerical values for R&N counters */
  UINT4 iFBits21 ;		/*   These are the 21-bit words which, when */
  UINT4 iRBits21 ;		/*     shifted into the chip, will load up */
  UINT4 iNBits21 ;		/*     the Function, N-Count and R-Count. */
} ;

void lmx2306DesignPLL
( struct lmx2306Regs *pRegs_a,	/* Output structure holding PLL design */
  SINT4 iNumer_a,		/* Numerator and denominator ratio */
  SINT4 iDenom_a, 		/*   of frequencies (OSC/VCXO). */
  SINT4 iPhCmpFreqRatio_a,      /* Ratio (VCXO / PhaseCompFrequency) */
  UINT1 lPllPosFreqDev_a ) ;	/* Positive frequency deviation */

void  lmx2306InitForIO( struct lmx2306Regs *pRegs_a ) ;
SINT4 lmx2306CycleIO  ( struct lmx2306Regs *pRegs_a ) ;

#define LMX2306_ENABLE   0x1	/* The three serial loadup pins on */
#define LMX2306_DATA     0x2	/*   the PLL chip. */
#define LMX2306_CLOCK    0x4

/* ************************************
 * *                                  *
 * * RVP8/Rx Board Driver Definitions *
 * *                                  *
 * ************************************
 */

/* The RVP8/Rx information structure's actual contents are hidden from
 * the outside world at this point.  Only access should be through the
 * driver.
 */
struct rvp8rx_info ;
typedef struct rvp8rx_info Rvp8Rx ;

/* Fixup versions of the receiver card that accidently had an
 * electrically inverted external trigger input line.
 */ 
#define RX_INVERTEDTRIGGER( DEV ) ( (DEV)->openInfo.iBoardRev <= 2 )

/* ------------------------------
 * Parameters defining FIR capabilities are radically different for
 * the Rev.A/B boards which used dedicated chips, versus the Rev.C+
 * boards that do all computations in the FPGA.
 */

/*               ----- Rev.A and Rev.B Boards -----
 * The maximum number of FIR stages is based on six chips having 16
 * multipliers per chip, and using both the forward and reverse shift
 * paths.  We need to subtract one less than the maximum number of
 * (I,Q) vector components to account for worst case data shift loss
 * when all Rx channels are needed at each bin.
 */
#define MAXFIRCHIPS_AB    6	/* Max number of chips (2, 4, or 6) */
#define MAXFIRSTAGES_AB ( (2 * 16 * MAXFIRCHIPS_AB) - ((2 * MAXVIQPERBIN)-1) )

#define MINDECIMATE_AB    2	/* Bounds on decimation factor for the */
#define MAXDECIMATE_AB   16	/*   FIR chips and external logic. */

#define MAXIMPLENGTH_AB ( MAXDECIMATE_AB * MAXFIRSTAGES_AB )

/*              ----- Rev.C and Higher Boards -----
 * The maximum number of FIR stages is based on four multipliers per
 * DSP block, each of which is clocked at 2x the IF sample rate.
 */
#define NUMDSPBLOCKS_C    4	/* Number of DSP blocks for FIRs */
#define MAXFIRSTAGES_C ( (2 * 4 * NUMDSPBLOCKS_C) - ((2 * MAXVIQPERBIN)-1) )

#define MINDECIMATE_C     4	/* Limits imposed by iqpacker module, */
#define MAXDECIMATE_C    64	/*   and by RAM shift/decimate chain. */

#define MAXIMPLENGTH_C ( MAXDECIMATE_C * MAXFIRSTAGES_C )

/*               ----- Unified Parameters -----
 * The following parameters can be used to dimension arrays that will
 * hold the worst case sizes for all receiver board types.
 */
#define DIMIMPLENGTH  MAX( MAXIMPLENGTH_AB, MAXIMPLENGTH_C )
#define DIMDECIMATE   MAX( MAXDECIMATE_AB , MAXDECIMATE_C  )

#define MINIMPLENGTH      6	/* Same for all boards */

/* ========================================
 * =============== rvp8rx.c ===============
 * ========================================
 */
#define RX8MAXUNITS 2		/* Max number of RVP8/Rx boards */
Rvp8Rx *Rvp8RxOpen( SINT4 iUnit_a, UINT4 iFlags_a, MESSAGE *pStatus_a ) ;
MESSAGE Rvp8RxClose( Rvp8Rx *pDev_a ) ;

UINT1 lRvp8RxStyleCAT5E( Rvp8Rx *pDev_a ) ;

#ifdef SIGMET_RVP8_H
MESSAGE iRvp8RxSetBoardParams
( Rvp8Rx *pDev_a, FLT4 fAqClk_a, FLT4 fifreqs_a[MAXFREQSPERRX],
  UINT1 lifsign_a ) ;
#endif /* #ifdef SIGMET_RVP8_H */

MESSAGE iRvp8RxVersionCheck( Rvp8Rx *pDev_a ) ;

SINT4 iRvp8RxMasterMemWords( Rvp8Rx *pDev_a ) ;
SINT4 iRvp8RxFilterMemWords( Rvp8Rx *pDev_a ) ;

SINT4 iRvp8RxAqToTgRatio( Rvp8Rx *pDev_a ) ;

FLT4 fRvp8RxAqClkMHz( Rvp8Rx *pDev_a ) ;
FLT4 fRvp8RxTgClkMHz( Rvp8Rx *pDev_a ) ;

void Rvp8RxReset( Rvp8Rx *pDev_a, UINT1 lShowBoot_a ) ;

#ifdef SIGMET_RDA_H
MESSAGE Rvp8RxGetBoardInfo( Rvp8Rx *pDev_a, struct rda_boardinfo *pInfo_a ) ;
#endif /* #ifdef SIGMET_RDA_H */

UINT1 lRvp8RxMirrorFail( Rvp8Rx *pDev_a, volatile UINT4 iFailMasks_a[2] ) ;

UINT4 iRvp8RxMemFail( Rvp8Rx *pDev_a, SINT4 iMem_a ) ;
void   Rvp8RxMemFill( Rvp8Rx *pDev_a, SINT4 iMem_a, UINT4 iFirst_a, UINT4 iInc_a ) ;

void Rvp8RxRedLED( Rvp8Rx *pDev_a, SINT4 ledcode_a ) ;
void Rvp8RxGrnLED( Rvp8Rx *pDev_a, SINT4 ledcode_a ) ;
void Rvp8RxSigLED( Rvp8Rx *pDev_a, SINT4 ledcode_a ) ;

void Rvp8RxDispPrint
( Rvp8Rx *pDev_a, SINT4 iLine_a, UINT1 lWait_a, const char *text_a ) ;

SINT4 Rvp8RxDispSpaceFree( Rvp8Rx *pDev_a ) ;

UINT4 iRvp8RxGetTimerVal ( Rvp8Rx *pDev_a, SINT4 iTimer_a ) ;
UINT4 iRvp8RxGetTimerMask( Rvp8Rx *pDev_a, SINT4 iTimer_a ) ;

void Rvp8RxSetTimerClkSrc( Rvp8Rx *pDev_a, SINT4 iTimer_a, SINT4 iClkSrc_a ) ;
#define RX8TIMER_CLK1MHZ    0 /* Clock = 1MHz (Timer #0 only) */
#define RX8TIMER_CLK1KHZ    0 /* Clock = 1KHz (Timers #1 and #2 only) */
#define RX8TIMER_CLKTRIG    1 /* Clock = Trigger pulses */
#define RX8TIMER_CLKIOSHR   2 /* Clock = I/O-62 shared (Line #N -> Timer #N) */

void Rvp8RxWaitTimer( Rvp8Rx *pDev_a, SINT4 iTimer_a, UINT4 iFireVal_a ) ;
void Rvp8RxWaitTimerGroup
( Rvp8Rx *pDev_a, const struct gpTimerWait *gpWait_a,
  void( *prepFunc_a )( void *prepArgs_a ), void *prepArgs_a ) ;

void Rvp8RxFireTimer( Rvp8Rx *pDev_a, SINT4 iTimer_a ) ;

/* Softplane Test/Terminate
 */
void    Rvp8RxEnableSpl( Rvp8Rx *pDev_a, UINT1 lFront_a, UINT1 lRear_a ) ;
UINT1    lRvp8RxSecUnit( Rvp8Rx *pDev_a ) ;
void   Rvp8RxSplSetUnit( Rvp8Rx *pDev_a, UINT1 lSecUnit_a ) ;
UINT4 iRvp8RxGetSplTest( Rvp8Rx *pDev_a ) ;
void   Rvp8RxSetSplTest( Rvp8Rx *pDev_a, UINT1 lTest_a ) ;

/* Association between the card's acquisition clock time, and the
 * Linux Btime in milliseconds.
 */
#ifdef SIGMET_RVP8_H
struct rvp8AssocBtime {		/* BTime <==> SysTime association */
  UINT4 iSysTimeMes, iBtimeMes ;  /* Simultaneous pair of measured values */
  UINT4 iSysTimeAdj ;		  /* Slew rate limited adjusted Rx time */
  UINT4 tval_sec, tval_usec ;	  /* Absolute time that pairing was made */
  SINT4 iPhaseAQIF[MAXFREQSPERRX] ; /* Long term phase of each IF relative to AQ */
} ;
#endif /* #ifdef SIGMET_RVP8_H */

UINT4       iRvp8RxSysTimeNow( Rvp8Rx *pDev_a ) ;

void      Rvp8RxAssociateBtime( Rvp8Rx *pDev_a, UINT1 lSetNow_a  ) ;
UINT4  iRvp8RxBtimeFromSysTime( Rvp8Rx *pDev_a, UINT4 iSysTime_a ) ;
UINT4  iRvp8RxSysTimeFromBtime( Rvp8Rx *pDev_a, UINT4 iBtime_a   ) ;
FLT8       fRvp8RxUTCFromBtime( Rvp8Rx *pDev_a, UINT4 iBtime_a   ) ;
BIN2 iRvp8RxIFPhaseFromSysTime( Rvp8Rx *pDev_a, UINT4 iSysTime_a, SINT4 iFreq_a ) ;

UINT4 iRvp8RxDualSystimeOffset( Rvp8Rx *pDevX_a, Rvp8Rx *pDevY_a ) ;

/* =============================================
 * =============== rvp8rx_tgen.c ===============
 * =============================================
 */
#ifdef SIGMET_RVP8_H

volatile const struct rvp8Tgline * Rvp8TglinesElement
( volatile const struct rvp8Tglines *tglines_a, SINT4 index_a ) ;

void Rvp8ClearTglines( struct rvp8Tglines *tglines_a ) ;
void Rvp8ClearTgline( struct rvp8Tgline *tgline_a ) ;

void Rvp8RxTrigInitForWriting
( Rvp8Rx *pDev_a, volatile const struct rvp8TgInfo *tgInfo_a ) ;
void Rvp8RxTrigDoneWriting( Rvp8Rx *pDev_a ) ;

void Rvp8RxTrigWriteBank
( Rvp8Rx *pDev_a, SINT4 iBank_a, SINT4 nPulses_a,
  volatile const struct rvp8TgPulse *pPulses_a,
  volatile const struct rvp8Tglines *tglines_a,
  const FLT4 *fFixedPeriod_a, volatile UINT4 *piTrigAltered_a ) ;

#define RXTGALT_PATTERN   0	/* Bits indicating that the trigger */
#define RXTGALT_PERIOD    1	/*   pattern and/or PRT were altered. */
#define RXTGALT_TRUNC     2	/* Out-of-Memory, triggers truncated */

FLT4 fRvp8RxTrigFreeRAM( Rvp8Rx *pDev_a ) ;

void Rvp8RxTriggerActivityLimits
( FLT4 fLimits_a[2], volatile const struct rvp8Tglines *tglines_a,
  FLT4 fPeriodUSec_a, UINT4 iLineMask_a ) ;

const struct rvp8TgPulse *Rvp8RxGetTgPulse
( Rvp8Rx *pDev_a, SINT4 iBank_a, SINT4 iWave_a ) ;

FLT4 fRvp8RxTgIntervalUSec
( Rvp8Rx *pDev_a, SINT4 iBank_a, SINT4 iStart_a, SINT4 iEnd_a ) ;

void Rvp8RxTrigBlank( Rvp8Rx *pDev_a, UINT1 lBlank_a ) ;

void Rvp8RxTrigRunbankReq
( Rvp8Rx *pDev_a, SINT4 iBank_a, UINT4 iFlags_a ) ;
#define RXRB_STARTGPT0    0	/* Begin running a new trigger bank */
#define RXRB_STARTGPT1    1	/*   as soon as one of the general */
#define RXRB_STARTGPT2    2	/*   purpose timers fires. */
#define RXRB_STARTASAP    3	/* Begin running new bank ASAP */
#define RXRB_NOPREWAIT    4	/* Do not wait for previous requests */
#define RXRB_SETSNAPPED   5	/* Set the 'snapped' detection bit */

void   Rvp8RxTrigRunbankAccept( Rvp8Rx *pDev_a ) ;
UINT1 lRvp8RxTrigRunbankCancel( Rvp8Rx *pDev_a ) ;

UINT1 lRvp8RxTrigBankPending( Rvp8Rx *pDev_a ) ;

SINT4 iRvp8RxGetTgBank( Rvp8Rx *pDev_a ) ;

UINT1 lRvp8RxTrigBlanked( Rvp8Rx *pDev_a, UINT4 *pBtimeMS_a ) ;

void Rvp8RxTrigShutdown( Rvp8Rx *pDev_a ) ;

UINT1 lRvp8RxTimeout( Rvp8Rx *pDev_a ) ;
UINT1 lRvp8RxStuckTOBank( Rvp8Rx *pDev_a ) ;

#endif /* #ifdef SIGMET_RVP8_H */

/* ============================================
 * =============== rvp8rx_ifd.c ===============
 * ============================================
 */
struct ifd_status {
  char pad0x2[2] ;
  UINT1 lSigDet ;		/* Downlink signal detected */
  UINT1 lNormSwitches ;		/* Switches are in normal position */
  UINT1 lPLLError ;		/* PLL is not locked to external clock */
  UINT1 lUplinkOkay ;		/* Uplink is being received properly */
  UINT1 lTripNoSync ;		/* No round trip sync was detected */
  UINT1 lHasIFDOpts ;		/* IFD supports options command */
  FLT4  fTripDelay ;		/* Round trip delay and jitter */
  FLT4  fTripJitter ;
  SINT4 iSerialNum ;		/* Serial number of IFD */
  SINT4 iBoardRev ;		/* IFD board revision level */
  SINT4 iCodeRev ;		/* IFD firmware revision level */
  SINT4 iDiags ;		/* DIAGX/Y bits */
  FLT4  fSatInputdBm ;		/* A/D Saturation input power (dBm) */
  SINT4 iTempOnChipDegC ;	/* Temperature of sensor chip itself, */
  SINT4 iTempRemoteDegC ;	/*   and of sense diode in the FPGA. */
  SINT4 iUpBERR ;		/* Bit-Error-Rate counters for the uplink */
  SINT4 iDnBERR[3] ;		/*   channel and three downlink channels. */
  SINT4 iTimeSecBERR ;		/* Starting time of BERR integration */
} ;

void Rvp8RxUplinkSingle
( Rvp8Rx *pDev_a, UINT2 iData_a, UINT1 lCmd_a, UINT1 lReset_a ) ;

void Rvp8RxUplinkLED
( Rvp8Rx *pDev_a, SINT4 ledcode_a ) ;

void Rvp8RxUplinkSetDiags
( Rvp8Rx *pDev_a, SINT4 iDiags_a ) ;

void Rvp8RxUplinkRun
( Rvp8Rx *pDev_a, UINT1 lRun_a ) ;

void Rvp8RxUplinkSetPinMap
( Rvp8Rx *pDev_a, UINT1 lUse_a, UINT4 iPinMap_a, UINT4 iPinErr_a ) ;

void Rvp8RxUplinkSetOld16
( Rvp8Rx *pDev_a, UINT1 lUse_a, UINT2 iOld16_a ) ;

void Rvp8RxUplinkSetNoise
( Rvp8Rx *pDev_a, UINT1 lUse_a, FLT4 fNoise_a ) ;

void Rvp8RxUplinkSwaps
( Rvp8Rx *pDev_a, UINT1 lUse_a, SINT4 iSwaps_a ) ;
#define UPSWAP_NORMAL     0	/* Normal Inputs */
#define UPSWAP_SWAPBOTH   1	/* Swap Burst/IF */
#define UPSWAP_JUSTBURST  2	/* Send only Burst data */
#define UPSWAP_JUSTIF     3	/* Send only IF data */

void Rvp8RxUplinkAllClear( Rvp8Rx *pDev_a ) ;

SINT4 iRvp8RxIFDNoiseCode( FLT4 *fDitherPower_a ) ;

void Rvp8RxSetPLLCAT5E
( Rvp8Rx *pDev_a, SINT4 iNumer_a, SINT4 iDenom_a, UINT1 lPllPosFreqDev_a ) ;

#define IFDMAXNUMDEN      128	/* Maximum numerator/denominator */

SINT4 Rvp8RxAcquireDIF
( Rvp8Rx *pDev_a, SINT4 iPulses_a, SINT4 iSyncBank_a,
  UINT2 iWords_a[], SINT4 iWordCount_a ) ;

MESSAGE iRvp8RxIFDVersionCheck( Rvp8Rx *pDev_a ) ;
const struct ifd_status *Rvp8RxIFDStatus( Rvp8Rx *pDev_a ) ;

void Rvp8RxIFDGetTemperatures( Rvp8Rx *pDev_a ) ;

const struct ifd_status *Rvp8RxIFDUpdateBERR( Rvp8Rx *pDev_a ) ;
void Rvp8RxIFDClearBERR( Rvp8Rx *pDev_a ) ;

void Rvp8RxGetDIFWords
( Rvp8Rx *pDev_a, SINT4 iDwordAddr_a, UINT2 iWords_a[], SINT4 iWordCount_a ) ;

UINT1 lRvp8RxDIFMagicOkay( UINT2 iCode_a ) ;
SINT4 iRvp8RxDIFBankNum( UINT2 iCode_a ) ;

/* =============================================
 * ============== rvp8rx_iqdata.c ==============
 * =============================================
 */
void Rvp8RxRunRangeMask( Rvp8Rx *pDev_a, UINT1 lRun_a ) ;

#ifdef SIGMET_RVP8_H
void Rvp8RxRangeMaskInit
( Rvp8Rx *pDev_a, SINT4 iDecimate_a, SINT4 viqPerBin_a ) ;

void Rvp8RxRangeMaskWbit( Rvp8Rx *pDev_a, FLT4 fRangeKM_a ) ;
void Rvp8RxRangeMaskFinish( Rvp8Rx *pDev_a, volatile struct rngMaskInfo *pInfo_a ) ;
#endif /* #ifdef SIGMET_RVP8_H */

SINT4 iRvp8RxRangeMaskLastBit( void ) ;

UINT4 iRvp8RxApproxTrigCount( Rvp8Rx *pDev_a ) ;

void Rvp8RxIQStreamControl( Rvp8Rx *pDev_a, UINT1 lRun_a, UINT1 lPacked_a ) ;

struct rvp8rx_pulseHeader {	/* Header describing each pulse */
  UINT4 iSysTime ;		/*   AQCLK1X time of arrival */
  UINT4 iFlags ;		/*   Miscellaneous flags */
#define PHDR_IQHEAD( FLAGS ) ( (FLAGS)        & 0x7FFFF)
#define PHDR_BLANKD( FLAGS ) (((FLAGS) >> 19) & 0x00001)
#define PHDR_IQWRAP( FLAGS ) (((FLAGS) >> 20) & (RX8IQLWRAPSIZE-1) )
#define PHDR_BNKBEG( FLAGS ) (((FLAGS) >> 24) & 0x00001)
#define PHDR_TGWAVE( FLAGS ) (((FLAGS) >> 25) & 0x00001)
#define PHDR_TGBANK( FLAGS ) (((FLAGS) >> 26) & (BIT(RX8BANKBITS)-1) )
} ;
#define RX8PHDRWORDS     2	/* # words per header entry */
#define RX8IQLWRAPSIZE  16	/* Size of data wrap counter */

SINT4 iRvp8RxIQStreamHeaders
( Rvp8Rx *pDev_a, volatile struct rvp8rx_pulseHeader *pHeaders_a,
  SINT4 nHeaders_a ) ;

SINT4 iRvp8RxCurrentHeaderIndex( Rvp8Rx *pDev_a ) ;

void Rvp8RxGetPulseHeader
( Rvp8Rx *pDev_a, volatile struct rvp8rx_pulseHeader *pHeader_a, SINT4 iIndex_a ) ;

void Rvp8RxGetPulseHeadersDMA
( Rvp8Rx *pDev_a, volatile struct rvp8rx_pulseHeader *pHeaders_a,
  SINT4 iIndex_a, SINT4 nPulses_a ) ;

SINT4 iRvp8RxNPHeaders  ( void ) ;
SINT4 iRvp8RxIndexSize  ( void ) ;
SINT4 iRvp8RxIQLSize    ( void ) ;
SINT4 iRvp8RxIQLWrapSize( void ) ;

MESSAGE Rvp8RxGetIQPulses( Rvp8Rx *pDev_a, SINT4 iPulses_a, UINT1 lPacked_a ) ;

#ifdef SIGMET_RVP8_H
void Rvp8RxUnpackFLT4
( volatile const UINT4 iqPacked_a[], SINT4 iPackInc_a,
  volatile       FLT4   fIQData_a[], SINT4 iDataInc_a,
  FLT4 fScale_a, BIN2 iSubAngle_a,
  volatile const FLT4 fHeadTab_a[HEADTABSIZE], SINT4 iNumVecs_a ) ;
#endif /* #ifdef SIGMET_RVP8_H */

volatile UINT4 * Rvp8RxStartDMA
( Rvp8Rx *pDev_a, UINT4 iDMAOffset_a, UINT4 iStartAddr_a, SINT4 iDWords_a ) ;

void Rvp8RxWaitForDMA( Rvp8Rx *pDev_a ) ;
void Rvp8RxAcquireDMA( Rvp8Rx *pDev_a ) ;
void Rvp8RxReleaseDMA( Rvp8Rx *pDev_a ) ;

UINT1 lRvp8RxBusyNowDMA( Rvp8Rx *pDev_a ) ;

/* =============================================
 * ============== rvp8rx_iqfilt.c ==============
 * =============================================
 */
SINT4 iRvp8RxMinDecimate( Rvp8Rx *pDev_a, SINT4 iLength_a ) ;
SINT4 iRvp8RxMaxDecimate( Rvp8Rx *pDev_a ) ;

SINT4 iRvp8RxMaxFIRStages( Rvp8Rx *pDev_a ) ;

SINT4 iRvp8RxFIRCoefBits( Rvp8Rx *pDev_a ) ;

MESSAGE iRvp8RxConfigureFIR
( Rvp8Rx *pDev_a, SINT4 *ICoefs_a[], SINT4 *QCoefs_a[],
  SINT4 viqPerBin_a, SINT4 iLength_a, SINT4 iDecimate_a ) ;

SINT4 iRvp8RxMinDecimate_ab   /* Needed this way for diagnostics... */
( SINT4 iLength_a, SINT4 iMaxFIRChips_a ) ;

/* =============================================
 * ============== rvp8rx_diag.c  ===============
 * =============================================
 */
UINT4 Rvp8RxRunDiags( Rvp8Rx *pDev_a, FILE *st_a ) ;

/* ************************************
 * *                                  *
 * * RVP8/Tx Board Driver Definitions *
 * *                                  *
 * ************************************
 */

/* The RVP8/Tx information structure's actual contents are hidden from
 * the outside world at this point.  Only access should be through the
 * driver.
 */
struct rvp8tx_info ;
typedef struct rvp8tx_info Rvp8Tx ;

/* The onboard clock PLL feedback was changed from an 'home made'
 * implementation in the FPGA itself to a dedicated LMX2306 chip.
 */ 
#define TX_CLKPLLHOMEMADE( DEV ) ( (DEV)->openInfo.iBoardRev <= 3 )

/* ========================================
 * =============== rvp8tx.c ===============
 * ========================================
 */
#define TX8MAXUNITS 2		/* Max number of RVP8/Tx boards */

/* Some parameters from the RVP8/Tx card itself
 */
#define TX8BANDEDGE     0.420  /* Upper bound of AD9772A halfband filter */
#define TX8MAXPOWDBM   14.8    /* Max (low frequency) terminated power (dBm) */
#define TX8MINPOWDBM  -20.0    /*   and minimum that can be done cleanly. */
#define TX8MAXFREQMHZ  84.0    /* Max TxClk and/or output frequency (MHz) */

#define TXDACPIPES    22	/* Tx clock delays within TxDAC chip itself */
#define TXPHASEPIPES (TXDACPIPES+ 8) /* Tx clock delays for phase change */
#define TXPULSEPIPES (TXDACPIPES+18) /* Tx clock delays for pulse modulation */

Rvp8Tx *Rvp8TxOpen( SINT4 iUnit_a, UINT4 iFlags_a, MESSAGE *pStatus_a ) ;
MESSAGE Rvp8TxClose( Rvp8Tx *pDev_a ) ;

MESSAGE iRvp8TxSetBoardParams
( Rvp8Tx *pDev_a, FLT4 fTxClk_a, FLT4 fTxOpAmpFix_a ) ;

MESSAGE iRvp8TxVersionCheck( Rvp8Tx *pDev_a ) ;

void Rvp8TxRedLED( Rvp8Tx *pDev_a, SINT4 ledcode_a ) ;
void Rvp8TxGrnLED( Rvp8Tx *pDev_a, SINT4 ledcode_a ) ;
void Rvp8TxVisLED( Rvp8Tx *pDev_a, SINT4 ledcode_a ) ;

void Rvp8TxReset( Rvp8Tx *pDev_a ) ;

#ifdef SIGMET_RDA_H
MESSAGE Rvp8TxGetBoardInfo( Rvp8Tx *pDev_a, struct rda_boardinfo *pInfo_a ) ;
#endif /* #ifdef SIGMET_RDA_H */

UINT1 lRvp8TxMirrorFail( Rvp8Tx *pDev_a, volatile UINT4 iFailMasks_a[2] ) ;
UINT4 iRvp8TxMemFail( Rvp8Tx *pDev_a ) ;
void Rvp8TxMemFill( Rvp8Tx *pDev_a, UINT4 iFirst_a, UINT4 iInc_a ) ;

UINT4 iRvp8TxGetTimerVal( Rvp8Tx *pDev_a, SINT4 iTimer_a ) ;
UINT4 iRvp8TxGetTimerMask( Rvp8Tx *pDev_a, SINT4 iTimer_a ) ;

void Rvp8TxSetTimerClkSrc( Rvp8Tx *pDev_a, SINT4 iTimer_a, SINT4 iClkSrc_a ) ;

void Rvp8TxWaitTimer( Rvp8Tx *pDev_a, SINT4 iTimer_a, UINT4 iFireVal_a ) ;
void Rvp8TxWaitTimerGroup
( Rvp8Tx *pDev_a, const struct gpTimerWait *gpWait_a,
  void( *prepFunc_a )( void *prepArgs_a ), void *prepArgs_a ) ;

void Rvp8TxFireTimer( Rvp8Tx *pDev_a, SINT4 iTimer_a ) ;

/* Softplane Test/Terminate
 */
void    Rvp8TxEnableSpl( Rvp8Tx *pDev_a, UINT1 lFront_a, UINT1 lRear_a ) ;
UINT1    lRvp8TxSecUnit( Rvp8Tx *pDev_a ) ;
void   Rvp8TxSplSetUnit( Rvp8Tx *pDev_a, UINT1 lSecUnit_a ) ;
UINT4 iRvp8TxGetSplTest( Rvp8Tx *pDev_a ) ;
void   Rvp8TxSetSplTest( Rvp8Tx *pDev_a, UINT1 lTest_a ) ;

/* Various clock inputs and outputs
 */
void Rvp8TxConfigClkBNC( Rvp8Tx *pDev_a, SINT4 iMode_a, SINT4 iClkDiv_a ) ;
#define TX8BNCMAXDIV     32	/* Maximum output clock division */

#define TX8BNCMODE_INHIZ  0	/*  BNC serves as a High-Z digital input */
#define TX8BNCMODE_IN50Z  1	/*  BNC serves as a 50-Ohm digital input */
#define TX8BNCMODE_TXOUT  2	/*  BNC outputs divided Tx clock */
#define TX8BNCMODE_RXOUT  3	/*  BNC outputs divided Rx clock */
#define TX8BNCMODE_40OUT  4	/*  BNC outputs divided 40MHz clock */

void Rvp8TxConfigTxClk
( Rvp8Tx *pDev_a, UINT1 lEnablePLL_a, SINT4 iPllSrc_a,
  SINT4 iNumer_a, SINT4 iDenom_a ) ;
#define TX8PLLSRC_BNC       0	/* TxClk PLL locked to external BNC clock */
#define TX8PLLSRC_IFD       1	/* TxClk PLL locked to IFD AQ clock */

#define TX8MAXNUMDEN      512	/* Maximum numerator/denominator */

UINT1 lRvp8TxPLLError( Rvp8Tx *pDev_a ) ;

/* =========================================
 * ============= rvp8tx_wave.c =============
 * =========================================
 */
struct TxDACSpecs {		/* Specifications for a synthesizable frequency */
  FLT8  fNormFreq ;             /*   Normalized output frequency (fOut/TxClk) */
  FLT4  fOutFreq ;		/*   Output frequency in MHz */
  FLT4  fSinXAmpl ;		/*   Amplitude after sin(x)/x losses (0-1) */
  UINT1 lHiPass, lZeroStuff ;   /*   Need HiPass filter and/or Zero stuffing */
  UINT1 lValid ;		/*   Valid results are contained here */
  char  pad19x5[5] ;
} ;

MESSAGE iRvp8TxCreateNCO
( Rvp8Tx *pDev_a, UINT1 lChanB_a, FLT4 fOutFreq_a ) ;
void Rvp8TxSynthesizeCW
( Rvp8Tx *pDev_a, UINT1 lChanB_a, FLT4 fPhaseDeg_a, FLT4 fPowerdBm_a ) ;
void Rvp8TxSetPhaseMod
( Rvp8Tx *pDev_a, UINT1 lChanB_a, UINT1 lPhaseMod_a, UINT1 lAbruptPH_a ) ;

#ifdef SIGMET_INTELIPP_LIB_H
MESSAGE Rvp8TxSynthesizeWave
( Rvp8Tx *pDev_a, UINT1 lChanB_a, const Ipp32fc cTxWave_a[],
  SINT4 nPoints_a, FLT4 fPowerdBm_a ) ;
#endif /* #ifdef SIGMET_INTELIPP_LIB_H */

void Rvp8TxSetRefPot( Rvp8Tx *pDev_a, UINT1 lChanB_a, FLT4 fRef_a ) ;
FLT4 fRvp8TxRefPot( FLT4 fPowerdBm_a ) ;
FLT4 fRvp8TxOpAmpGain( FLT4 fOutFreq_a ) ;
FLT4 fRvp8TxAmplScale( struct TxDACSpecs *pSpecs_a, FLT4 fPowerdBm_a ) ;

void Rvp8TxSyncNCOs( Rvp8Tx *pDev_a ) ;

void Rvp8TxSetTxDAC
( Rvp8Tx *pDev_a, UINT1 lChanB_a, UINT1 lHiPass_a, UINT1 lZeroStuff_a ) ;

void Rvp8TxSetTxWaveIdle( Rvp8Tx *pDev_a, UINT1 lChanB_a ) ;

MESSAGE iRvp8TxSpecDAC( FLT8 fNormFreq_a, struct TxDACSpecs *pSpecs_a ) ;

FLT4 fRvp8TxSinXAmpl( FLT8 fNormFreq_a, const struct TxDACSpecs *pSpecs_a ) ;

FLT4 fRvp8TxMaxOutputPwr( FLT4 fOutFreq_a, FLT4 fTxClk_a ) ;

#define TXCLKDIVTRIGSYNC  1 /* Waveform triggers resync'd to TxClock/N */

/* =========================================
 * ============= rvp8tx_diag.c =============
 * =========================================
 */
UINT4 Rvp8TxRunDiags( Rvp8Tx *pDev_a, FILE *st_a, UINT1 lFlailOkay_a ) ;


/* ***********************************
 * *                                 *
 * *  IO62 Board Driver Definitions  *
 * *                                 *
 * ***********************************
 */

/* The IO62 information structure's actual contents are hidden from
 * the outside world at this point.  Only access should be through the
 * driver.
 */
struct io62_info ;
typedef struct io62_info Io62 ;

/* ========================================
 * ================ io62.c ================
 * ========================================
 */
#define IO62MAXUNITS 4		/* Max number of IO62 boards */
Io62 *Io62Open( SINT4 iUnit_a, UINT4 iFlags_a, MESSAGE *pStatus_a ) ;
MESSAGE Io62Close( Io62 *pDev_a ) ;
MESSAGE iIo62VersionCheck( Io62 *pDev_a ) ;

void Io62RedLED ( Io62 *pDev_a, SINT4 ledcode_a ) ;
void Io62GrnLED ( Io62 *pDev_a, SINT4 ledcode_a ) ;
void Io62VisLED ( Io62 *pDev_a, SINT4 ledcode_a ) ;
void Io62BootLED( Io62 *pDev_a, SINT4 ledcode_a ) ;

void Io62Reset( Io62 *pDev_a, UINT1 lShowBoot_a ) ;

#ifdef SIGMET_RDA_H
MESSAGE Io62GetBoardInfo( Io62 *pDev_a, struct rda_boardinfo *pInfo_a ) ;
#endif /* #ifdef SIGMET_RDA_H */

UINT1 lIo62MirrorFail( Io62 *pDev_a, volatile UINT4 iFailMasks_a[2] ) ;

void Io62DispPrint
( Io62 *pDev_a, SINT4 iLine_a, UINT1 lWait_a, const char *text_a ) ;

SINT4 Io62DispSpaceFree( Io62 *pDev_a ) ;

void Io62SetDAC( Io62 *pDev_a, SINT4 iDAC_a, FLT4 fLevel_a ) ;
#define IO62MAXDACVOLTAGE 10.00	/* Max positive output voltage */

void Io62ADCManualControl( Io62 *pDev_a, UINT1 lEnable_a, SINT4 iAddr_a ) ;

void Io62ADCSampleMinMax( Io62 *pDev_a, UINT1 lMin_a, UINT1 lMax_a ) ;
FLT4 fIo62ADCSample( Io62 *pDev_a ) ;
#define IO62MAXADCVOLTAGE 2.055	/* Max positive input voltage */

UINT4 iIo62GetTimerVal ( Io62 *pDev_a, SINT4 iTimer_a ) ;
UINT4 iIo62GetTimerMask( Io62 *pDev_a, SINT4 iTimer_a ) ;

void Io62SetTimerClkSrc( Io62 *pDev_a, SINT4 iTimer_a, SINT4 iClkSrc_a ) ;
#define IO62TIMER_CLK1MHZ    0	/* Clock = 1MHz */
#define IO62TIMER_CLKIOSHR   1  /* Clock = I/O-62 shared (Line #N -> Timer #N) */

void   Io62SharedLineModel( Io62 *pDev_a, SINT4 iModel_a ) ;
UINT4 iIo62SharedLineBits( Io62 *pDev_a ) ;
#define IO62SHMOD_UNUSED     0	/* All lines are grounded */
#define IO62SHMOD_TDWR_V1    1	/* MIT/Lincoln TDWR ACP/ARP, Ver.1 */

void Io62WaitTimer( Io62 *pDev_a, SINT4 iTimer_a, UINT4 iFireVal_a ) ;
void Io62WaitTimerGroup
( Io62 *pDev_a, const struct gpTimerWait *gpWait_a,
  void( *prepFunc_a )( void *prepArgs_a ), void *prepArgs_a ) ;

void Io62FireTimer( Io62 *pDev_a, SINT4 iTimer_a ) ;

void Io62ForceBits( Io62 *pDev_a, UINT4 iBitsLo_a, UINT4 iBitsHi_a ) ;
UINT4 iIo62MonitorBits( Io62 *pDev_a ) ;
#define IO62_TRIG0   0		/* Trigger drivers */
#define IO62_TRIG1   1
#define IO62_TRIG2   2
#define IO62_TRIG3   3
#define IO62_TTY0X   4		/* RS232 TTY transmitters */
#define IO62_TTY1X   5
#define IO62_TTY0R   6		/* RS232 TTY receivers */
#define IO62_TTY1R   7

void Io62UserTriggers( Io62 *pDev_a, UINT4 iDrivenMask_a, UINT4 iSelectMask_a ) ;

void Io62Relays( Io62 *pDev_a, UINT4 iEnergize_a ) ;

/* The fourty general purpose I/O lines are managed via the following
 * routines, which both configure the electrical I/O standards and
 * also read/write the data values.
 */
struct ioLinePair {		/* Electrical properties of one pair of lines */
  UINT1 iPhysIO ;		/*   What type of physical I/O we're doing */
#define IOLPIO_DONTCARE     0	/*     No constraints imposed */
#define IOLPIO_TTL_IN       1	/*     Single-ended TTL input */
#define IOLPIO_TTL_OUT      2	/*     Single-ended TTL output */
#define IOLPIO_RS422_IN     3	/*     Differential RS422 input */
#define IOLPIO_RS422_OUT    4	/*     Differential RS422 output */

  UINT1 iTerm ;			/*   Termination type */
#define IOLTERM_DONTCARE    0	/*     No constraints imposed */
#define IOLTERM_FLOATING    1	/*     Must not be terminated in any way */
#define IOLTERM_PULLUP      2	/*     Pull-up to +5V */
#define IOLTERM_PULLDOWN    3	/*     Pull-down to GND */
#define IOLTERM_PAIRWISE    4	/*     Differential termination */

  UINT1 lIntData ;		/*   Data source/sink internally, else from PCI */
  char  pad3x1[1] ;
} ;

MESSAGE iIo62GioLinesAlloc
( Io62 *pDev_a, const struct ioLinePair *iolp_a, SINT4 iLine_a, SINT4 nLines_a ) ;

void Io62GioLinesFree
( Io62 *pDev_a, SINT4 iLine_a, SINT4 nLines_a ) ;
void Io62GioLinesFreePreLocked
( Io62 *pDev_a, SINT4 iLine_a, SINT4 nLines_a ) ;

SINT4 iIo62GioLinesInUse( Io62 *pDev_a ) ;

UINT1 lIo62GioLinePairOkay( const struct ioLinePair *iolp_a ) ;

void   Io62GioPutData( Io62 *pDev_a, UINT1 lNeg_a, UINT4 iData_a ) ;
UINT4 iIo62GioGetData( Io62 *pDev_a, UINT1 lNeg_a ) ;

/* Serial data stream support for arbitrary serial protocols
*/
#ifdef SIGMET_USER_LIB_H
MESSAGE iIo62SerializerConfig( Io62 *pDev_a, const struct ttyspec *pSpec_a ) ;
#endif /* #ifdef SIGMET_USER_LIB_H */

void Io62SerializerHookup( Io62 *pDev_a, SINT4 iHookup_a ) ;
#define IO62SER0_UNUSED      0 	/* Serializer is unused */
#define IO62SER0_ENTTY0      1 	/* Hookup to RS232 TTY0 lines */
#define IO62SER0_RX12_TX16   2 	/* Rx/Tx on GPIO lines 12+/16+ */
#define IO62SER0_FREERUN     3	/* Freerunning, hookup done elsewhere */

void   Io62SerializerWrite  ( Io62 *pDev_a, volatile const void *pBuf_a, SINT4 nChars_a ) ;
SINT4 iIo62SerializerRead   ( Io62 *pDev_a, volatile void *pBuf_a, SINT4 iMaxChars_a ) ;
SINT4 iIo62SerializerRdAvail( Io62 *pDev_a ) ;
SINT4 iIo62SerializerWrPend ( Io62 *pDev_a ) ;

/* Board-to-Board serial data bit operations.
 */
#define IO62B2B_NBITS 8 	/* Total number of bits exchanged */
void Io62EnableB2B( Io62 *pDev_a, UINT1 lEnable_a ) ;
void Io62SetB2B( Io62 *pDev_a, UINT4 iBits_a ) ;
UINT4 iIo62GetB2B( Io62 *pDev_a ) ;

/* Softplane Test/Terminate
 */
void    Io62EnableSpl( Io62 *pDev_a, UINT1 lFront_a, UINT1 lRear_a ) ;
UINT1    lIo62SecUnit( Io62 *pDev_a ) ;
void   Io62SplSetUnit( Io62 *pDev_a, UINT1 lSecUnit_a ) ;
UINT4 iIo62GetSplTest( Io62 *pDev_a ) ;
void   Io62SetSplTest( Io62 *pDev_a, UINT1 lTest_a ) ;

/* Custom ORDA backpanel control register.
 */
void Io62ORDACntInit ( Io62 *pDev_a, UINT1 lEnable_a ) ;

UINT1 lIo62ORDACntPRate( Io62 *pDev_a, UINT4 iPRate_a ) ;
UINT1 lIo62ORDACntAMux ( Io62 *pDev_a, UINT4 iAMux_a  ) ;
UINT1 lIo62ORDACntLED  ( Io62 *pDev_a, UINT1 lLedOn_a ) ;

UINT1 lIo62ORDACntTPnts( Io62 *pDev_a, UINT4 iTpA_a, UINT4 iTpB_a ) ;
#define ORDA_TP_RFGATE       1  /* List of available test points */
#define ORDA_TP_RFPLSTART    2
#define ORDA_TP_MODDISCHG    3
#define ORDA_TP_MODCHARGE    4
#define ORDA_TP_FILAMENT     5
#define ORDA_TP_RFDRIVE      6
#define ORDA_TP_POSTCHARGE   7
#define ORDA_TP_TRIGCHARGE   8
#define ORDA_TP_RXPROTCMD    9
#define ORDA_TP_RXPROTRSP   10
#define ORDA_TP_CATHODE     11
#define ORDA_TP_PHZRATEDGE  12
#define ORDA_TP_PHCOHOSEL   13

UINT4 iIo62ORDAGetStatus( Io62 *pDev_a ) ;
#define ORDA_STS_RADIATE     0	/* Radiate ON */
#define ORDA_STS_RFDTEST     1	/* RFD Test Mode */
#define ORDA_STS_CWTEST      2	/* CW Test Mode */
#define ORDA_STS_RXPROTFLT   3	/* Rx protection fault */

/* Custom MIT/LL TDWR backpanel support
 */
void   Io62TdwrV1Enable ( Io62 *pDev_a, UINT1 lEnable_a ) ;
UINT1 lIo62TdwrV1Enabled( Io62 *pDev_a ) ;

void Io62TdwrV1SetMode( Io62 *pDev_a, SINT4 iMode_a ) ;
#define TDWRV1MD_NORMAL      0	/* Normal running mode */
#define TDWRV1MD_MINIMUM     1	/* Remain at minimum attenuation */
#define TDWRV1MD_MAXIMUM     2	/* Remain at maximum attenuation */
#define TDWRV1MD_LOAD        3	/* Load new serial table data */

/* Optional shaft encoder angle inputs
 */
struct shaftEncoderSts {
  SINT4 iTicksPerIndex ;	/* Number of A/B ticks per Index pulse */
  SINT4 iIndxsPerRevol ;	/* Number of Index pulses per revolution */
  SINT4 iTickCount ;		/* Present (full revolution) tick count, */
  BIN2  iTickAngle ;		/*   and equivalent binary angle. */
  UINT1 lCalibrated ;		/* Index pulse seen, & no errors since */
  UINT1 lReverseDir ;		/* Reverse direction of A/B counting */
  UINT4 iLastPCISTS ;		/* Last PCI status read */
} ;
#define MAXTICKSPERINDEX  20480	/* Maximum A/B/ticks per index pulse */
#define MAXINDXSPERREVOL     24	/* Maximum index pulses per revolution */

void Io62UpdateShaftEncoder
( Io62 *pDev_a, struct shaftEncoderSts *pSts_a, UINT1 lElAxis_a,
  const BIN2 *pProxAngle_a ) ;

/* =========================================
 * ============== io62_diag.c ==============
 * =========================================
 */
UINT4 Io62RunDiags( Io62 *pDev_a, FILE *st_a, UINT1 lFlailOkay_a ) ;

/* ==========================================
 * =============== io62cp.c =================
 * ==========================================
 */
MESSAGE iIo62CpOpen( Io62 *pDev_a ) ;
void    Io62CpClose( Io62 *pDev_a ) ;
MESSAGE iIo62CpVersionCheck( Io62 *pDev_a ) ;

SINT4 iIo62CpSerialNum( Io62 *pDev_a ) ;
SINT4  iIo62CpBoardRev( Io62 *pDev_a ) ;
SINT4   iIo62CpBootRev( Io62 *pDev_a ) ;
SINT4   iIo62CpCodeRev( Io62 *pDev_a ) ;

UINT4 iIo62CpGioDrivers( Io62 *pDev_a, UINT4 iSet_a, UINT4 iClr_a ) ;
void   Io62CpGioPutData( Io62 *pDev_a, SINT4 iSlot_a, UINT4 iData_a ) ;
UINT4 iIo62CpGioGetData( Io62 *pDev_a, SINT4 iSlot_a ) ;

void Io62CpDgDrivers( Io62 *pDev_a, UINT4 iDrivers_a ) ;

void Io62CpWaitSerialCycles( Io62 *pDev_a, SINT4 iCycles_a ) ;

void Io62CpCntBits( Io62 *pDev_a, UINT4 iBits_a ) ;
#define IO62CPC_RELAY0   0	/* Onboard relays */
#define IO62CPC_RELAY1   1
#define IO62CPC_RELAY2   2
#define IO62CPC_RCOIL0   3	/* External relay coil drivers */
#define IO62CPC_RCOIL1   4
#define IO62CPC_RCOIL2   5
#define IO62CPC_RCOIL3   6
#define IO62CPC_TMON0H   7	/* Test/Monitor BNC-0 force Hi/Lo */
#define IO62CPC_TMON0L   8
#define IO62CPC_TMON1H   9	/* Test/Monitor BNC-1 force Hi/Lo */
#define IO62CPC_TMON1L  10
#define IO62CPC_DGDATA0 11	/* Data for RS-422 'DG' chips */
#define IO62CPC_DGDATA1 12

UINT4 iIo62CpStsBits( Io62 *pDev_a ) ;
#define IO62CPS_DGDATA0  0	/* Data from RS-422 'DG' chips */
#define IO62CPS_DGDATA1  1

void Io62CpAMUXManualControl( Io62 *pDev_a, UINT1 lEnable_a, SINT4 iAddr_a ) ;
#define IO62CP_AMUX_USER0       0 /* User analog inputs available */
#define IO62CP_AMUX_USER1       1 /*   on the J8 connector. */
#define IO62CP_AMUX_USER2       2
#define IO62CP_AMUX_USER3       3
#define IO62CP_AMUX_USER4       4
#define IO62CP_AMUX_USER5       5
#define IO62CP_AMUX_USER6       6
#define IO62CP_AMUX_USER7       7
#define IO62CP_AMUX_AZTACH      8 /* AZ Tachometer */
#define IO62CP_AMUX_ELTACH      9 /* EL Tachometer */
#define IO62CP_AMUX_USER8      10
#define IO62CP_AMUX_USER9      11
#define IO62CP_AMUX_AZSY_REF   12 /* AZ synchro reference input */
#define IO62CP_AMUX_AZSY_1_2   13 /* AZ synchro S1-S2 sample */
#define IO62CP_AMUX_AZSY_1_3   14 /* AZ synchro S1-S3 sample */
#define IO62CP_AMUX_AZSY_2_3   15 /* AZ synchro S2-S3 sample */
#define IO62CP_AMUX_ELSY_REF   16 /* EL synchro reference input */
#define IO62CP_AMUX_ELSY_1_2   17 /* EL synchro S1-S2 sample */
#define IO62CP_AMUX_ELSY_1_3   18 /* EL synchro S1-S3 sample */
#define IO62CP_AMUX_ELSY_2_3   19 /* EL synchro S2-S3 sample */
#define IO62CP_AMUX_IMON_PAN   20 /* Panel power supply current monitor */
#define IO62CP_AMUX_IMON_RLY   21 /* Relay driver current monitor */
#define IO62CP_AMUX_RESERVE    22 /* <reserved input> */
#define IO62CP_AMUX_GROUND     23 /* Ground reference */

#define IO62CP_AMUX_GROUND_V1     7 /* Old values in Rev.A board */
#define IO62CP_AMUX_AZTACH_V1     8
#define IO62CP_AMUX_AZSY_REF_V1   9
#define IO62CP_AMUX_ELTACH_V1    12
#define IO62CP_AMUX_ELSY_REF_V1  13

#define IO62CP_AMUX_USER_NUM   10 /* Number of 'user' analog inputs */

SINT4 iIo62CpAMUXUserFromNum( SINT4 iNum_a ) ;

struct io62cpAMUXAxis {		/* Analog MUX samples for one axis */
  FLT4 fTach ;			/*   Tachometer input */
  FLT4 fSyRef ;			/*   Synchro reference input */
  FLT4 fSy12, fSy13, fSy23 ;	/*   Three synchro difference pairs */
} ;
struct io62cpAMUXTop {		/* Summary of all voltages on analog MUXs */
  FLT4 fSpanUSec ;		/*   Time span since last AutoScan update */
  FLT4 fMux[ IO62CP_AMUX_USER_NUM ] ; /* MUX'd "user" input lines */
  struct io62cpAMUXAxis AZ,EL ;	/*   Samples for AZ and EL axes */
  FLT4 fMonPanel, fMonRelay ;	/*   Main panel current and relay current */
  FLT4 fGndRef ;		/*   Ground ref (already applied to data) */
} ;
#define IO62CPAMUXVOLTAGE 21.76	/* Max analog MUX positive input voltage */

UINT1 lIo62CpAMUXAutoScan
( Io62 *pDev_a, SINT4 iMinSpanUSec_a,
  UINT1 lNeedSynchros_a, UINT1 lNeedTachs_a ) ;

void Io62CpAMUXAutoScanInit( Io62 *pDev_a ) ;

volatile const struct io62cpAMUXTop *pIo62CpAMUXAutoData( Io62 *pDev_a ) ;

FLT4 fIo62CpAMUXPanelAmps( Io62 *pDev_a ) ;
FLT4 fIo62CpAMUXRelayAmps( Io62 *pDev_a ) ;

/* ==========================================
 * ============= io62cp_diag.c ==============
 * ==========================================
 */
UINT4 iIoCpRunDiags( Io62 *pDev_a, FILE *st_a, int iTypeinFD_a ) ;

/* ==========================================
 * =============== synchro.c ================
 * ==========================================
 */
struct synchro ;		/* Opaque to callers */

struct synchro *synchroInit
( FLT4 fUpdateHz_a, FLT4 fRefHz_a,
  BIN2 iInitialPos_a, FLT4 fInitialVel_a, MESSAGE *iStatus_a ) ;

void synchroFree( struct synchro *pSyn_a ) ;

void synchroUpdate
( struct synchro *pSyn_a, FLT4 fSpanUSec_a, FLT4 fSyRef_a,
  FLT4 fSy12_a, FLT4 fSy13_a, FLT4 fSy23_a ) ;

BIN2 synchroGetPos( struct synchro *pSyn_a ) ;
FLT4 synchroGetVel( struct synchro *pSyn_a ) ;

UINT4 synchroGetStatus
( struct synchro *pSyn_a, FLT4 *pfMagRef_a, FLT4 *pfMagSyn_a,
  UINT4 *pnBadCalls_a ) ;
#define SYSTS_REFLO      0	/* Reference voltage too low */
#define SYSTS_REFHI      1	/* Reference voltage too high */
#define SYSTS_SYNLO      2	/* S1/S2/S3 voltages too low */
#define SYSTS_SYNHI      3	/* S1/S2/S3 voltages too high */

/* ===========================================
 * =============== ttycover.c ================
 * ===========================================
 */
#define RDASERIALNAME  "io62-tty0"

#ifdef SIGMET_USER_LIB_H
#ifdef INCLUDE_TERMIOS_PROTOTYPES

MESSAGE iRdaOpenTTYDev
( Io62 *pDev_a, struct ttydev *tty_a, const struct ttyspec *spec_a ) ;

MESSAGE iRdaCloseTTYDev( Io62 *pDev_a, struct ttydev *tty_a ) ;

SINT4 iRdaWriteTTYDev
( Io62 *pDev_a, struct ttydev *tty_a, volatile const void *pBuf_a, SINT4 nBytes_a ) ;

SINT4 iRdaReadTTYDev
( Io62 *pDev_a, struct ttydev *tty_a, volatile void *pBuf_a, SINT4 iMaxBytes_a ) ;

UINT1 lRdaReadAvailTTYDev( Io62 *pDev_a, struct ttydev *tty_a ) ;

#endif /* #ifdef INCLUDE_TERMIOS_PROTOTYPES */
#endif /* #ifdef SIGMET_USER_LIB_H */

#endif /* #ifndef MESSAGE_ONLY */
#endif /* #ifndef SIGMET_PCICARDS_LIB_H */
