/************************************************/
/*                                              */
/* File        : calbhard.h                     */
/* Description : Calorimeter Boards             */
/*                    hardware base access      */
/*                                              */
/* Authors: G.Cabibbo, A.Passeri                 */
/*                                              */
/* Created      : 07.02.1997                    */
/* Last modified: 02.05.1997                    */
/*                                              */
/************************************************/

#ifndef CALBHARD_H
#define CALBHARD_H


/************************************************/
/*                                              */
/*   The result should be CALBH_ERROR_OK,       */
/*   else there have been an error              */
/*   (see CALBH_ERROR_.. constants)             */
/*   if not stated otherwise                    */
/*                                              */
/************************************************/

#define CALBH_ERROR_OK            0     /* MUST be 0 */
#define CALBH_ERROR_TEST          -1
#define CALBH_ERROR_UNKNOWN       -10
#define CALBH_ERROR_OUTRANGE      -9
#define CALBH_WARNING_ZSUP        -2

/********************************************************************/
/*                      Register offsets                            */
/*                DO NOT USE DIRECTLY IF NOT REALLY NECESSARY       */
/********************************************************************/

/* internal registers (16 bit)*/
#define CALBH_CREG_ofs	        0x3c         /*  R/W  */
#define CALBH_SREG_ofs          0x3e         /*   R   */
#define CALBH_RDTRG_ofs         0x4a         /*   R   */
#define CALBH_RESET_ofs         0x4c         /*   W   */
#define CALBH_CLRTRG_ofs        0x4e         /*   W   */
#define CALBH_SWTRG_ofs         0x50         /*   W   */


/* FIFO registers I/O  (32 bit)*/
#define CALBH_HFIFO_ofs   	0x40	
#define CALBH_DFIFO_ofs   	0x44	

/********************************************************************/
/*                          Page offsets                            */
/*                DO NOT USE DIRECTLY IF NOT REALLY NECESSARY       */
/********************************************************************/

#define CALBH_PAGE_LATCH_ofs	0x0000       /*   R   */
#define CALBH_PAGE_CSR_ofs	0x003c       /*   R   */
#define CALBH_PAGE_PED_A_ofs	0x4000       /*  R/W  */
#define CALBH_PAGE_PED_B_ofs	0x4040       /*  R/W  */
#define CALBH_PAGE_ZSUP1_A_ofs	0x8000       /*  R/W  */
#define CALBH_PAGE_ZSUP1_B_ofs	0xA000       /*  R/W  */
#define CALBH_PAGE_ZSUP2_A_ofs	0xC000       /*  R/W  */
#define CALBH_PAGE_ZSUP2_B_ofs	0xE000       /*  R/W  */

/*********************************************************************/
/*                          CALB hard id type                        */
/*********************************************************************/

typedef struct 
         {
	   int cid;                    /* VME channel id  */
	   unsigned int vme_addr;      /* VME address     */
	   unsigned int vme_am;        /* VME am          */
	   unsigned int offs;          /* CALB offs       */
	   void *map_ptr;              /* VME map pointer */
	 } CALBH_id_base;

typedef CALBH_id_base *CALBH_id;

/*********************************************************************/
/*                             readpage types                        */
/*********************************************************************/

typedef struct
         {
	   unsigned short creg;
	   unsigned short sreg; /*************warning************/
         } CALBH_CSR_regs;

/*********************************************************************/
/*                             array  types                          */
/*********************************************************************/

typedef unsigned int CHANNELS[30]; 
typedef unsigned int CHALF[15]; 

/*********************************************************************/
/*                             pedestal struct type                  */
/*********************************************************************/

typedef struct
        {
           CHANNELS ped_a; 
           CHANNELS ped_b; 
        } CALBH_PEDS_val;

/*********************************************************************/
/*                          zero suppression struct type             */
/*********************************************************************/

typedef struct
        {
           CHALF zlow1_a; 
           CHALF zlow1_b; 
           CHALF zhig1_a; 
           CHALF zhig1_b; 
           CHALF zlow2_a; 
           CHALF zlow2_b; 
           CHALF zhig2_a; 
           CHALF zhig2_b; 
        } CALBH_ZSUP_val;

/*********************************************************************/
/*                       Initialization routines                     */
/*********************************************************************/

int calbh_open(int chain,                   /* IN  */
	       int crate,                   /* IN  */
	       int slot,                    /* IN  */
	       CALBH_id *calb_id);           /* OUT */

int calbh_close(int chain,                 /*  IN  */
                int crate,                 /*  IN  */
                int slot,                  /*  IN  */
                CALBH_id calb_id);          /* IN  */

/*********************************************************************/
/*                       read routines                               */
/*                       return the read value                       */
/*********************************************************************/

/***********************/
/*        generic      */
/* Do not use directly */
/***********************/


unsigned short calbh_read_reg16(CALBH_id calb_id,     /* IN  */
				unsigned int offset); /* IN  */

unsigned int   calbh_read_reg32(CALBH_id calb_id,     /* IN  */
				unsigned int offset); /* IN  */

/***********************/
/*      Use this       */
/***********************/

/*  internal registers */

#define calbh_read_creg(/*CALBH_id*/ calb_id)  /* IN  */ \
	calbh_read_reg16(calb_id,CALBH_CREG_ofs)

#define calbh_read_sreg(/*CALBH_id*/ calb_id)  /* IN  */ \
	calbh_read_reg16(calb_id,CALBH_SREG_ofs)

#define calbh_read_rdtrg(/*CALBH_id*/ calb_id)  /* IN  */ \
	calbh_read_reg16(calb_id,CALBH_RDTRG_ofs)

/*  FIFO  */

#define calbh_read_hfifo(/*CALBH_id*/ calb_id)  /* IN  */ \
	calbh_read_reg32(calb_id,CALBH_HFIFO_ofs)

#define calbh_read_dfifo(/*CALBH_id*/ calb_id)  /* IN  */ \
	calbh_read_reg32(calb_id,CALBH_DFIFO_ofs)

/* Zero Suppression */

#define calbh_read_zsup_a(/*CALBH_id       */ calb_id,    /* IN  */  \
			  /*unsigned short */ bit_nr)     /* IN  */  \
        ((unsigned int) (calbh_read_reg16(calb_id,CALBH_PAGE_ZSUP1_A_ofs+((bit_nr)*2)) & 0x7fff) | \
	 (((unsigned int) (calbh_read_reg16(calb_id,CALBH_PAGE_ZSUP2_A_ofs+((bit_nr)*2))) & 0x7fff)<<15))

#define calbh_read_zsup_b(/*CALBH_id       */ calb_id,    /* IN  */  \
			  /*unsigned short */ bit_nr)     /* IN  */  \
        ((unsigned int) (calbh_read_reg16(calb_id,CALBH_PAGE_ZSUP1_B_ofs+((bit_nr)*2)) & 0x7fff) | \
	 (((unsigned int) (calbh_read_reg16(calb_id,CALBH_PAGE_ZSUP2_B_ofs+((bit_nr)*2)) & 0x7fff))<<15))


/*********************************************************************/
/*                       write routines                              */
/*********************************************************************/

/***********************/
/*        generic      */
/* Do not use directly */
/***********************/

int calbh_write_reg16(CALBH_id calb_id,         /* IN */
		      unsigned int offset,      /* IN */
		      unsigned short reg,       /* IN */
		      unsigned short testmask); /* IN, test if >0 */

/***********************/
/*      Use this       */
/***********************/

/* internal regs */

#define calbh_write_creg(/*CALBH_id      */ calb_id,  /* IN  */        \
			  /*unsigned char */ creg,    /* IN  */        \
			  /*char          */ test)     /* IN, bool  */  \
	calbh_write_reg16(calb_id,CALBH_CREG_ofs,creg,test*0xff)
        /*  only 8 significant bits in CREG  */

#define calbh_write_reset(/*CALBH_id      */ calb_id)  /* IN  */        \
	calbh_write_reg16(calb_id,CALBH_RESET_ofs,0,0)

#define calbh_write_clrtrg(/*CALBH_id      */ calb_id)  /* IN  */        \
	calbh_write_reg16(calb_id,CALBH_CLRTRG_ofs,0,0)

#define calbh_write_swtrg(/*CALBH_id      */ calb_id)  /* IN  */        \
	calbh_write_reg16(calb_id,CALBH_SWTRG_ofs,0,0)

/* zero suppression */
/* does not return a valid error value */

#define calbh_write_zsup_a(/*CALBH_id       */ calb_id,    /* IN  */  	\
			   /*unsigned short */ bit_nr,     /* IN  */  	\
			   /*unsigned int   */ data)       /* IN  */  	\
        {								\
	  calbh_write_reg16(calb_id,CALBH_PAGE_ZSUP1_A_ofs+((bit_nr)*2),data & 0x7fff,0);	\
	  calbh_write_reg16(calb_id,CALBH_PAGE_ZSUP2_A_ofs+((bit_nr)*2),data>>15,0);	\
        }

#define calbh_write_zsup_b(/*CALBH_id       */ calb_id,    /* IN  */  	\
			   /*unsigned short */ bit_nr,     /* IN  */  	\
			   /*unsigned int   */ data)       /* IN  */  	\
        {								\
	  calbh_write_reg16(calb_id,CALBH_PAGE_ZSUP1_B_ofs+((bit_nr)*2),data & 0x7fff,0);	\
	  calbh_write_reg16(calb_id,CALBH_PAGE_ZSUP2_B_ofs+((bit_nr)*2),data>>15,0);	\
        }


/*********************************************************************/
/*                     readLATCH routines                             */
/*********************************************************************/

/***********************/
/*       internal      */
/* Do not use directly */
/***********************/

int calbh_readlatch_i_chan (CALBH_id calb_id,                /* IN  */
			      unsigned int  chan);  /* IN */

int calbh_readlatch_i_all (CALBH_id calb_id,                /* IN  */
			      CHANNELS   latch);  /* OUT */

/***********************/
/*      Use this       */
/***********************/

#define calbh_readlatch_chan(/*CALBH_id          */ calb_id,    /* IN  */  \
	               	/* unsigned int */ chan)   /* IN  */  \
	calbh_readlatch_i_chan(calb_id,chan)

#define calbh_readlatch_all(/*CALBH_id          */ calb_id,    /* IN  */  \
	               	/* unsigned int */ latch)   /* OUT */  \
	calbh_readlatch_i_all(calb_id,latch)


/*********************************************************************/
/*                     readpage routines                             */
/*********************************************************************/

/***********************/
/*       internal      */
/* Do not use directly */
/***********************/

int calbh_readpage_i_csr (CALBH_id calb_id,                /* IN  */
			      CALBH_CSR_regs *csr);  /* OUT */

int calbh_readpage_i_ped (CALBH_id calb_id,                /* IN  */
			      CALBH_PEDS_val *peds);  /* OUT */

int calbh_readpage_i_zsup (CALBH_id calb_id,                /* IN  */
			      CALBH_ZSUP_val *zsup);  /* OUT */

int calbh_readpage_i_zsup_elem(CALBH_id calb_id /* IN  */,/* IN */ int zofs,
                            /* OUT */ CHALF zlow, /* OUT */ CHALF zhig);

/***********************/
/*      Use this       */
/***********************/

#define calbh_readpage_csr(/*CALBH_id            */ calb_id,    /* IN  */  \
	               	/*CALBH_CSR_regs */ csr)   /* OUT */  \
	calbh_readpage_i_csr(calb_id,&(csr))

#define calbh_readpage_ped(/*CALBH_id            */ calb_id,    /* IN  */  \
	               	/* CALBH_PEDS_val  */ peds)   /* OUT */  \
	calbh_readpage_i_ped(calb_id,&(peds))

#define calbh_readpage_zsup(/*CALBH_id            */ calb_id,    /* IN  */  \
	               	/* CALBH_ZSUP_val  */ zsup)   /* OUT */  \
	calbh_readpage_i_zsup(calb_id,&(zsup))

#define calbh_readpage_zsup_elem(/* CALBH_id */ calb_id /* IN  */,    \
                           /* IN */  zofs, /* OUT */  zlow, /* OUT */ zhig)  \
        calbh_readpage_i_zsup_elem(calb_id,zofs,zlow,zhig)

/*********************************************************************/
/*                     writepage routines                            */
/*********************************************************************/

/***********************/
/*       internal      */
/* Do not use directly */
/***********************/

int calbh_writepage_i_ped (CALBH_id calb_id,                /* IN  */
			      CALBH_PEDS_val *peds);  /* OUT */

int calbh_writepage_i_zsup (CALBH_id calb_id,                /* IN  */
			      CALBH_ZSUP_val *zsup);  /* OUT */

int calbh_writepage_i_zsup_elem(CALBH_id calb_id /* IN  */, /* IN */ int zofs,
    			    /* IN */ CHALF zlow, /* IN */ CHALF zhig);

/***********************/
/*      Use this       */
/***********************/

#define calbh_writepage_ped(/*CALBH_id            */ calb_id,    /* IN  */  \
	               	/* CALBH_PEDS_val  */ peds)   /* OUT */  \
	calbh_writepage_i_ped(calb_id,&(peds))

#define calbh_writepage_zsup(/*CALBH_id            */ calb_id,    /* IN  */  \
	               	/* CALBH_ZSUP_val  */ zsup)   /* OUT */  \
	calbh_writepage_i_zsup(calb_id,&(zsup))

#define calbh_writepage_zsup_elem( calb_id /* IN  */, /* IN */ zofs, \
                                       /* IN */ zlow, /* IN */ zhig) \
        calbh_writepage_i_zsup_elem(calb_id,zofs,zlow,zhig)

/*********************************************************************/
/*                     readfifo routines                             */
/*********************************************************************/

/***********************/
/*        generic      */
/* Do not use directly */
/***********************/

int calbh_read_pio_i_hfifo (CALBH_id calb_id,	/* IN  */
			unsigned int nels,	/* IN  */
			unsigned int *buffer,	/* OUT */
			unsigned int *count);	/* OUT, nr of els really read */

int calbh_read_pio_i_dfifo (CALBH_id calb_id,	/* IN  */
			unsigned int nels,	/* IN  */
			unsigned int *buffer,	/* OUT */
			unsigned int *count);	/* OUT, nr of els really read */

int calbh_read_blt_fifo (CALBH_id calb_id,	/* IN  */
			unsigned int offset,	/* IN  */
			unsigned int nrels,	/* IN  */
			unsigned int *buffer,	/* OUT */
			unsigned int *count);	/* OUT, nr of els really read */

/***********************/
/*      Use this       */
/***********************/

#define calbh_read_pio_hfifo(/*CALBH_id       */ calb_id,	/* IN  */    \
			     /*unsigned int   */ count,		/* IN nr els to read, OUT nr els really read */    \
			     /*unsigned int * */ buffer)	/* OUT */ \
	calbh_read_pio_i_hfifo(calb_id,count,buffer,&(count))

#define calbh_read_pio_dfifo(/*CALBH_id       */ calb_id,	/* IN  */    \
			     /*unsigned int   */ count,		/* IN nr els to read, OUT nr els really read */    \
			     /*unsigned int * */ buffer)	/* OUT */ \
	calbh_read_pio_i_dfifo(calb_id,count,buffer,&(count))

#define calbh_read_blt_dfifo(/*CALBH_id       */ calb_id,	/* IN  */    \
			     /*unsigned int   */ count,		/* IN nr els to read, OUT nr els really read */    \
			     /*unsigned int * */ buffer)	/* OUT */ \
	calbh_read_blt_fifo(calb_id,CALBH_DFIFO_ofs,count,buffer,&(count))

#endif /* CALBHARD_H */