/*
 *  Header file for Allen-Bradley #6008-SV VMEbus I/O Scanner
 *	based on an example given in the Allen-Bradley users manual
 *
 */

/*
 *      Author: Bill Brown
 *      Date:   as noted in change history
 *
 *      Copyright 1992, 1993, the Regents of the University of California.
 *
 *      This software was produced under  U.S. Government contract:
 *      (DE-AC03-76SF00098) at the Lawrence Berkeley Laboratory.
 *
 *
 */

/*
    @(#) $Header: vmeIOScannerLib.h,v 3.5 93/05/06 13:06:15 wbrown Exp $ (LBL)
 */

/*
    @(#) $Log:	vmeIOScannerLib.h,v $
 * Revision 3.5  93/05/06  13:06:15  wbrown
 * added copyright notice
 * 
 * Revision 3.4  92/04/07  14:23:20  wbrown
 * added adc support, digital I/O
 *  getAbPlcbit() setAbPlcBit() plcIrqDaemon() plcQueueBTMsg()
 *  createAb1771_IFE_dev() initAb1771_IFE_dev() readAb1771Ife()
 *  adcReader() addAdcToReadList()
 * 
 * Revision 3.3  92/03/04  13:56:50  wbrown
 * routine checkin during developement
 *   everything up to "block transfers" (startup, echoBits, etc)
 *   seems to be working.
 * 
 * Revision 3.2  92/02/24  11:07:02  wbrown
 * routine checkin during development
 * 
 * Revision 3.1  92/02/03  13:32:37  wbrown
 * preliminary testing of #1771-IFE adc module,
 *   misc. clean-up.
 * 
 * Revision 3.0  91/12/19  16:44:04  bordua
 * Baseline for new aip project.
 * 
 * Revision 1.3  91/12/12  10:42:39  wbrown
 * added features to deal with SYSFAIL asserted
 * at "power-on" time.
 * 
 * 
 * Revision 1.2  91/10/15  09:02:06  wbrown
 * first cut at "beta" version
 * 
 * Revision 1.1  91/10/11  11:14:20  wbrown
 * Initial revision
 * 
 * 
 */

#ifndef VME_IO_SCANNEDdfn
#define VME_IO_SCANNEDdfn 1

/*
 *
 *	Scanner Management Commands & other constants
 */
#define SET_UP (u_char)0x13
#define AUTOCONFIGURE (u_char)0x10
#define SCAN LIST (u_char)0x11
#define FAULT_DEPENDENT_GROUP (u_char)0x12
#define SET_MODE (u_char)0x20
#define LINK_STATUS (u_char)0x21

#define HI_BAUD_RATE (u_short)0x02
#define LO_BAUD_RATE (u_short)0x01

#define DEF_IRQ_LVL (u_short)0x01
#define PLC_DBG_ON  (u_short)0x01

#define MODE_PROG_RESET (u_short)0x01
#define MODE_TEST_RESET 0(u_short)x02
#define MODE_RUN 0x04

#define SCAN_STAT_SCANNER_OP_OK 0
#define SCAN_STAT_SCANNER_PWR_UP (u_short)0x90
#define NO_CHANGE (u_short)0xff

#define BLOCK_WT (u_short)2
#define BLOCK_RD (u_short)1
#define IGNORE_SYSFAIL (u_short)0x0100
#define RESET_PREP (u_short)0x0080
#define RESET_PREP_ADRS (u_short)1870
#define RESET_XEQ (u_short)0xa0a0
#define RESET_XEQ_ADRS (u_short)1871

#define MAX_NR_PLC_SCANNERS 4

#define MAX_PLC_SCANNER_BUSY_WAIT 10

/*  operation codes = (int)commands.			*/
typedef enum
    {
    SETUP_PLC = 0x13,
    AUTOCONFIG_PLC = 0x10,
    SCAN_LIST_PLC = 0x11,
    FAULT_DEP_GROUP = 0x12,
    SET_MODE_PLC = 0x20,
    LINK_STATUS_PLC = 0x21,
    BT_WRITE_PLC = 0x02,
    BT_READ_PLC = 0x01
    } PLC_COMMAND ;

/*  "Confirmation Status codes"		*/
#define CONF_STATUS_OK 0
#define CONF_STATUS_UNKNOWN_CMND 0x10
#define CONF_STATUS_ILLEGAL_CMND 0x11
#define CONF_STATUS_MNGMT_CMND_PENDING 0x12
#define CONF_STATUS_QUEUE_FULL 0x14
#define CONF_STATUS_XFER_TIMEOUT 0x23
#define CONF_STATUS_BLOCK_XFER_QUEUED 0x2f

typedef enum
    {
    PLC_OK,
    PLC_LINK_CREATE_ERROR,
    PLC_BUS_ADRS_ERROR,
    PLC_SEMCREATE_FAIL,
    PLC_IVECALLOC_FAIL,
    PLC_INTERFACE_BUSY,
    PLC_RESET_FAIL,
    PLC_NO_REPLY,
    PLC_OPR_QUEUE,
    PLC_ERROR,
    PCL_INIT_COMPLETE,
    PLC_SET_MODE_FAIL,
    PLC_LINK_STATUS_ERROR,
    PLC_COMMAND_QUEUED,
    } PLC_STATUS ;

typedef enum
    {
    PLC_STATE_UNINIT,
    PLC_STATE_LINK_CREATED,
    PLC_STATE_CONFIG,
    PLC_STATE_PROG_MODE,
    PLC_STATE_TEST_MODE,
    PLC_LINK_STATUS_REQ,
    PLC_STATE_RUN_MODE,
    } PLC_STATE ; 

/* Adapter Status Word	 */
typedef struct
    {
    u_short fltDepGrp	: 3 ;	/* Fault Depepndent Group	 */
    u_short inFltDepGrp	: 1 ;	/* in Fault Depepndent Group	 */
    u_short onLine	: 3 ;	/* On Line (any bit set = true)	 */
    u_short grpFaulted	: 1 ;	/* 1 = fault in group		 */
    u_short adptrSize	: 2 ;	/* Adapter Size			 */
				/*	00 = quarter		 */
				/*	01 = half		 */
				/*	10 = three-quarter	 */
				/*	11 = full		 */
    u_short validConfig	: 1 ;	/* 1 = type, size, and adrs ok	 */
    u_short adptrExists : 1 ;	/* 1 = adapter attached		 */
    u_short adptrInList	: 1 ;	/* 1 = in current scan list	 */
    u_short reserved	: 3 ;	/* - reserved - 		 */
    } PLC_ADAP_STAT_WD ;

typedef struct
    {
    PLC_ADAP_STAT_WD adapterStatWds[ 32 ];
    u_char  scanListReply[ 16 ];
    } AUTO_CFIG_SCAN_LIST;

typedef struct
    {
    u_short all[ 1872 ];
    AUTO_CFIG_SCAN_LIST aCfigScanList;
    } DATA_AREA;

typedef struct	/*  physical slot addres of block transfer device	*/
    {
    u_short unused	: 9 ;
    u_short rackAdrs	: 3 ;	/* rack address ( 0 - 7 )		*/
    u_short groupAdrs	: 3 ;	/* group address ( 0 - 7 )		*/
    u_short slotAdrs	: 1 ;	/* slot address (Term 0-7=0, Term 8-15=1)*/
    }		AB_BT_DEV_LOC ;

/*
 *
 *	Two-Port Memory Structures
 */
typedef struct
    {
    u_short conf_stat;		/* confirmation status word	  102-03, */
    u_short command;		/* command			  104-05, */
    AB_BT_DEV_LOC address;	/* module address		  106-07, */
    u_short bt_tag,		/* block transfer tag number	  108-09, */
	    reserved[9],	/* reserved area  10A-0B, 10C-0D, 10E-0F, */
		    /*    110-11, 112-13, 114-15, 116-17, 118-19, 11A-1B, */
	    fl_lock,		/* semaphore word, bit 7 used	  11C-1D, */
	    data_len;		/* "length of data" word	  11E-1F, */
    u_short data_area[1872];	/* data area			  120-21, */

    u_short interruptScanner;	/* write here to interrupt plc	FC0, FC1, */
    } DP_MAILBOX ;

typedef struct
    {
    u_short g_oit[64],		/* global output image table	*/
    	    g_iit[64],		/* global input image table	*/
	    op_stat;		/* operating status word	*/
    DP_MAILBOX mailBox;		/* mail box area		*/
    } PLC_SCANNER_DUAL_PORT;

typedef struct
    {
    u_short cFigBuffer[ 72 ];
    } PLC_CONFIG_BUFFER;

/*
 *  scanner logical connection descriptor
 */
typedef struct
    {
    PLC_SCANNER_DUAL_PORT *plcScanner2Port;
    SEM_ID plcResponse;
    u_short plcConfStatus;
    PLC_STATUS plcScannerStatus;
    PLC_STATE plcScannerState;
    PLC_CONFIG_BUFFER *cFigBufPtr;		
    } PLC_SCANNER_LINK;

/*
 *  it is convienient that (PLC_SCANNER_LINK *) have various 
 *	manifestations.
 */
typedef union
    {
    PLC_SCANNER_LINK *linkIdPtr;
    int linkIdInt;
    char linkIdChar[4];
    } LINK_ID_FORM ;

#define MAX_PLC_MSG_CNT 32
#define PLC_MSG_SIZE 4

typedef enum		/*  block transfer device type			*/
    {
    AB_1771_IFE,	/* 16/8 channel adc				*/
    }	AB_PLC_BT_DEV_TYPE ;

typedef enum
    {
    PLC_BT_OK,
    PLC_BT_UNINIT,
    } OPER_STATUS ;

/*	structure for block transfers		*/
typedef struct
    {
    PLC_SCANNER_LINK *scannerID;    /* identifies scanner		  */
    SEM_ID btCompleteSem;	/* semaphore to give when complete	  */
    u_short confStatWd;		/* current Conf. Status for this transfer */
    u_short commandWd;		/* BLOCK_WT (write) or BLOCK_RD (read)	  */
    AB_BT_DEV_LOC devAdrs;	/* address of device in PLC bus		  */
    u_short wordCount;		/* word count for transfer		  */
    u_short dataBuffer[64];	/* buffer for data			  */
    } BT_REQUEST;

typedef struct		/* generic part of plc device descriptor	*/
    {
    PLC_SCANNER_LINK *scannerID;	/* ID of scanner		*/
    OPER_STATUS operStatus;		/* block transfer status	*/
    AB_PLC_BT_DEV_TYPE btDevType;	/* type of device		*/
    SEM_ID adcBtDone;			/* semaphore for operation done */
    char *devSpecStruc;			/* pointer to device specific	*/
    } PLC_BT_DEV_DESC ;

#ifndef PLC_SCANNER_DRVR

IMPORT PLC_SCANNER_LINK *vmePlcScannerLinkCreate();
IMPORT PLC_SCANNER_LINK *startPLC();
IMPORT STATUS plcAutoConfig();
IMPORT STATUS plcEnableOutput();
IMPORT int setAbPlcBit();
IMPORT int getAbPlcbit();
IMPORT STATUS sndCmnd();
IMPORT STATUS sndCmndAndWait4Done();
IMPORT VOID plcScannerReset();
IMPORT VOID plcIrqDaemon();
IMPORT STATUS plcQueueBTMsg();

#endif

#endif