/************************************************/
/*                                              */
/* File        : rockfifo.h                     */
/* Description : ROCK FIFO specific library     */
/*                                              */
/* Author: Sfiligoi Igor                        */
/*                                              */
/* Comment: If this module is used,             */
/*          nobody else should access the FIFO  */
/*                                              */
/* Created      : 14.02.1997                    */
/* Last modified: 20.03.1997                    */
/*                                              */
/************************************************/

#ifndef ROCKFIFO_H
#define ROCKFIFO_H

#include "rock.h"

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

/**********************************************************************/
/*                                                                    */
/*                          error constants                           */
/*                                                                    */
/**********************************************************************/

#define ROCK_ERROR_FIFO_EMPTY		-101	/* try to read an empty fifo */
						/* should not be considered as an error */
#define ROCK_ERROR_FIFO_FRAME_HEADER	-111	/* invalid header, frame is not read */
#define ROCK_ERROR_FIFO_FRAME_SLAVE	-112	/* invalid slave , frame is not read */
#define ROCK_ERROR_FIFO_FRAME_FOOTER	-113	/* footer immediatly after header, frame is not read */
#define ROCK_ERROR_FIFO_FRAME_PARITY	-121	/* parity wrong  , frame is read */
#define ROCK_ERROR_FIFO_FRAME_OVERFLOW	-131	/* frame too large, frame is not read */


/**********************************************************************/
/*                                                                    */
/*                          cache constants                           */
/*                                                                    */
/**********************************************************************/

#define ROCK_FIFO_CACHE_OFF		0	/* disable read-ahead caching */
#define ROCK_FIFO_CACHE_MINIMAL		1	/* read more only if half full */
#define ROCK_FIFO_CACHE_ADVANCED	2	/* read while not empty */
#define ROCK_FIFO_CACHE_BLOCK		3	/* force block transfer */
#define ROCK_FIFO_CACHE_BLOCK_ADVANCED	4	/* force block transfer and read while not empty */

#define ROCK_FIFO_CACHE_DEFAULT		ROCK_FIFO_CACHE_MINIMAL

/**********************************************************************/
/*                                                                    */
/*                        FIFO selector constants                     */
/*                                                                    */
/**********************************************************************/

#define ROCK_FIFO_EFIFO		0
#define ROCK_FIFO_DFIFO		1

/**********************************************************************/
/*                                                                    */
/*                          other constants                           */
/*                                                                    */
/**********************************************************************/

	/* the size of the FIFO */
#define ROCK_FIFO_FIFO_SIZE_HALF	(8*1024)
#define ROCK_FIFO_FIFO_SIZE		(2*ROCK_FIFO_FIFO_SIZE_HALF)

	/* max frame size */
#define ROCK_FIFO_FRAME_SIZE		(16*1024)

	/* cache size should be the size of the FIFO + FRAME + 1*/
#define ROCK_FIFO_CACHE_SIZE		(ROCK_FIFO_FIFO_SIZE+ROCK_FIFO_FRAME_SIZE+1)

/**********************************************************************/
/*                                                                    */
/*                       Frame related types                          */
/*                                                                    */
/**********************************************************************/

typedef struct
        {
	  unsigned char  sy;         /* Is low for Syncrd frame */
	  unsigned char  last;       /* last bit */
	  unsigned char  cradd;      /* crate address */
	  unsigned short trigger;    /* trigger number */
        } ROCK_FIFO_HEADER; 

typedef struct
        {
	  unsigned char  channel;
	  unsigned char  reserved;
	  unsigned short data;
        } ROCK_FIFO_SLV_data;

typedef struct
        {
	  unsigned int        nrels;   /* number of elements */
          ROCK_FIFO_SLV_data *els;     /* array of elements  */
        } ROCK_FIFO_SLV;

typedef struct
        {
	  unsigned char last;          /* last bit, should be the same as in header */
	  unsigned int  softparity;    /* calculated parity */
	  unsigned int  hardparity;    /* hardware reported parity */
	                               /* the two parities should be equal */
        } ROCK_FIFO_FOOTER;

typedef struct
        {
	  ROCK_FIFO_HEADER header;

	  ROCK_FIFO_SLV slv[16];

	  ROCK_FIFO_FOOTER footer;
        } ROCK_FIFO_FRAME;


typedef struct
	{
	 unsigned int nrframes;		/* number of frawes */
	 ROCK_FIFO_FRAME *frames;	/* array of frames */
	} ROCK_FIFO_FRAMEs;

/**********************************************************************/
/*                                                                    */
/*                              raw data type                         */
/*                                                                    */
/**********************************************************************/

typedef struct
	{
	  unsigned int  nrels;		/* nr. of elements */
	  unsigned int *els;		/* elements */
	} ROCK_FIFO_RAW;

/**********************************************************************/
/*                                                                    */
/*                      complete raw data type                        */
/*                                                                    */
/**********************************************************************/

typedef struct
	{
	  unsigned int  nrels;		/* nr. of elements */
	  ROCK_EDFIFO_bits *els;	/* elements */
	} ROCK_FIFO_RAW_bits;

/**********************************************************************/
/*                                                                    */
/*                               FIFO_id                              */
/*                                                                    */
/**********************************************************************/

typedef struct
	{
	  ROCK_id rock_id;				/* rock id */
	  unsigned char fifotype;			/* ROCK_FIFO_EFIFO or ROCK_FIFO_DFIFO */
	  unsigned char cancache;			/* see ROCK_FIFO_CACHE_... */
		/* cache structures */
	  unsigned int head,		/* first element */
		       tail;		/* one after the last element */
	  unsigned int cache[ROCK_FIFO_CACHE_SIZE];
	} ROCK_FIFO_id_base;

typedef ROCK_FIFO_id_base *ROCK_FIFO_id;

/**********************************************************************/
/*                                                                    */
/*                       Initialisation routines                      */
/*                                                                    */
/**********************************************************************/

/*********************************/
/* internal, do not use directly */
/*********************************/

int rock_fifo_open(ROCK_id       rock_id,   /* IN : standard rock id */
		   unsigned char fifotype,  /* IN : ROCK_FIFO_EFIFO or ROCK_FIFO_DFIFO */
		   unsigned char cancache,  /* IN : see ROCK_FIFO_CACHE_... constants */
                   ROCK_FIFO_id *fifo_id);  /* OUT: fifo id related to the rock */

/************/
/* use this */
/************/

#define rock_fifo_open_efifo(/*ROCK_id        */ rock_id,   /* IN : standard rock id */			  \
		   	     /*unsigned char  */ cancache,  /* IN : see ROCK_FIFO_CACHE_... constants */  \
                   	     /*ROCK_FIFO_id * */ fifo_id)   /* OUT: fifo id related to the rock */	  \
	rock_fifo_open(rock_id,ROCK_FIFO_EFIFO,cancache,fifo_id)

#define rock_fifo_open_dfifo(/*ROCK_id        */ rock_id,   /* IN : standard rock id */			  \
		   	     /*unsigned char  */ cancache,  /* IN : see ROCK_FIFO_CACHE_... constants */  \
                   	     /*ROCK_FIFO_id * */ fifo_id)   /* OUT: fifo id related to the rock */	  \
	rock_fifo_open(rock_id,ROCK_FIFO_DFIFO,cancache,fifo_id)

int rock_fifo_close(ROCK_FIFO_id   fifo_id,      /* IN : fifo id */
                    ROCK_FIFO_RAW_bits *cache);  /* OUT: the unused cache */
					         /*      should be disposed by caller */ 
		    
/**********************************************************************/
/*                                                                    */
/*                          Settings routines                         */
/*                                                                    */
/**********************************************************************/

int rock_fifo_set_cancache(ROCK_FIFO_id  fifo_id,	/* IN : fifo id */
			   unsigned char cancache);	/* IN : new cancache value */

/**********************************************************************/
/*                                                                    */
/*                          Cache routines                            */
/*                                                                    */
/**********************************************************************/

int rock_fifo_cache_flush(ROCK_FIFO_id   fifo_id,	/* IN : fifo id */
			  ROCK_FIFO_RAW_bits *cache);  	/* OUT: the unused cache */
							/*      should be disposed by caller */ 

    /* Very dangerous!!!! */
int rock_fifo_cache_refill_bits(ROCK_FIFO_id  fifo_id,     /* IN : fifo_id */
                                ROCK_FIFO_RAW_bits data);  /* IN : data to be filled to the cache */

/**********************************************************************/
/*                                                                    */
/*                          Raw read routines                         */
/*                                                                    */
/**********************************************************************/

int rock_fifo_raw_read(ROCK_FIFO_id  fifo_id,		/* IN : fifo id */
		       unsigned int *data);		/* OUT: one FIFO value */

int rock_fifo_raw_blockread(ROCK_FIFO_id   fifo_id,	/* IN : fifo id */
			    unsigned int   nrels,	/* IN : max number of elements */
			    ROCK_FIFO_RAW *data);	/* OUT: FIFO data */
					    		/*      should be disposed by caller */ 

/**********************************************************************/
/*                                                                    */
/*                    Complete raw read routines                      */
/*                                                                    */
/**********************************************************************/

int rock_fifo_raw_read_bits(ROCK_FIFO_id  fifo_id,		/* IN : fifo id */
			    ROCK_EDFIFO_bits *data);		/* OUT: one FIFO value */

int rock_fifo_raw_blockread_bits(ROCK_FIFO_id   fifo_id,	/* IN : fifo id */
				 unsigned int   nrels,		/* IN : max number of elements */
				 ROCK_FIFO_RAW_bits *data);	/* OUT: FIFO data */
					    			/*      should be disposed by caller */ 

/**********************************************************************/
/*                                                                    */
/*                          Frame read routines                       */
/*                                                                    */
/**********************************************************************/

int rock_fifo_frame_read(ROCK_FIFO_id     fifo_id,	/* IN : fifo id */
		   	 ROCK_FIFO_FRAME *data);	/* OUT: one FIFO frame */
					    		/*      should be disposed by caller */ 

	/* parity errors are not reported */
int rock_fifo_frame_blockread(ROCK_FIFO_id      fifo_id,/* IN : fifo id */
			      unsigned int      nrels,	/* IN : max number of raw elements */
			      ROCK_FIFO_FRAMEs *data);	/* OUT: FIFO data */
					    		/*      should be disposed by caller */ 

int rock_fifo_frame_rawread(ROCK_FIFO_id     fifo_id,	/* IN : fifo id */
			    ROCK_FIFO_RAW *data);	/* OUT: one FIFO frame */
					       		/*      should be disposed by caller */ 

int rock_fifo_frame_rawread_bits(ROCK_FIFO_id     fifo_id,	/* IN : fifo id */
				 ROCK_FIFO_RAW_bits *data);    	/* OUT: one FIFO frame */
					    			/*      should be disposed by caller */ 


	/* Synch the FIFO to the start of the frame */
int rock_fifo_frame_synch(ROCK_FIFO_id   fifo_id,	/* IN : fifo id */
			  ROCK_FIFO_RAW *data);		/* OUT: FIFO data */
					    		/*      should be disposed by caller */ 

	/* Synch the FIFO to the start of the frame */
int rock_fifo_frame_synch_bits(ROCK_FIFO_id   fifo_id,		/* IN : fifo id */
			       ROCK_FIFO_RAW_bits *data);	/* OUT: FIFO data */
					    			/*      should be disposed by caller */ 

/**********************************************************************/
/*                                                                    */
/*                       Frame conversion routines                    */
/*                                                                    */
/**********************************************************************/

int rock_fifo_conv_frame2raw(ROCK_FIFO_FRAME indata,	/* IN : formatted data */
			     ROCK_FIFO_RAW *outdata);	/* OUT: raw data */

int rock_fifo_conv_raw2frame(ROCK_FIFO_RAW     indata,	/* IN : raw data */
			     ROCK_FIFO_FRAME *outdata);	/* OUT: formated data */

int rock_fifo_conv_raw_bits2frame(ROCK_FIFO_RAW_bits indata,	/* IN : raw data */
			          ROCK_FIFO_FRAME   *outdata);	/* OUT: formated data */

/**********************************************************************/
/*                                                                    */
/*                          FIFO test routines                        */
/*                                                                    */
/**********************************************************************/

	/* returns ROCK_ERROR_OK 	 if not empty */
	/*	   ROCK_ERROR_FIFO_EMPTY if empty */
int rock_fifo_isnotempty(ROCK_FIFO_id fifo_id);	/* IN : fifo id */

#endif /* ROCKFIFO_H */