/***********************************************************/
/*                                                         */
/* File        : rockmfifo.h                               */
/* Description : ROCKM FIFO specific library               */
/*                                                         */
/* Author: Sfiligoi Igor                                   */
/*                                                         */
/* Comment: If this module is used to manipulate a FIFO,   */
/*          nobody else should access that FIFO            */
/*                                                         */
/* Created      : 13.06.1997                               */
/* Last modified: 20.10.1997                               */
/*                                                         */
/***********************************************************/

#ifndef ROCKMFIFO_H
#define ROCKMFIFO_H

#include "RockM.h"

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

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


#define ROCKM_ERROR_FIFO_EMPTY  		-101	/* try to read an empty fifo */
				        		/* should not be considered as an error */
#define ROCKM_ERROR_FIFO_FRAME_SUPER_HEADER	-111	/* invalid super header, frame is not read */
#define ROCKM_ERROR_FIFO_FRAME_SUB_HEADER	-112	/* invalid sub header, frame is not read */
#define ROCKM_ERROR_FIFO_FRAME_SLAVE    	-113	/* invalid slave , frame is not read */
#define ROCKM_ERROR_FIFO_FRAME_SUB_FOOTER	-114	/* sub footer immediatly after sub header,
							   frame is not read */
#define ROCKM_ERROR_FIFO_FRAME_SUPER_FOOTER	-115	/* super footer before after sub footer, frame is not read */
#define ROCKM_ERROR_FIFO_FRAME_PARITY   	-121	/* parity wrong  , frame is read */
#define ROCKM_ERROR_FIFO_FRAME_TRIGGER  	-122	/* trigger nr wrong  , frame is read */
#define ROCKM_ERROR_FIFO_FRAME_LAST     	-123	/* last bit wrong  , frame is read */
#define ROCKM_ERROR_FIFO_FRAME_COUNTER  	-124	/* counter wrong or counter overflow , frame is read */
#define ROCKM_ERROR_FIFO_FRAME_OVERFLOW 	-131	/* frame too large, frame is not read */


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

#define ROCKM_FIFO_CACHE_OFF		0	/* disable read-ahead caching */
#define ROCKM_FIFO_CACHE_MINIMAL       	1	/* read more only if half full */
#define ROCKM_FIFO_CACHE_ADVANCED	2	/* read while not empty */
#define ROCKM_FIFO_CACHE_BLOCK		3	/* force block transfer */
#define ROCKM_FIFO_CACHE_BLOCK_ADVANCED	4	/* force block transfer and read while not empty */

#define ROCKM_FIFO_CACHE_DEFAULT		ROCK_FIFO_CACHE_MINIMAL


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

	/* the size of the FIFO */
#define ROCKM_FIFO_FIFO_SIZE_HALF	(16*1024)
#define ROCKM_FIFO_FIFO_SIZE		(2*ROCKM_FIFO_FIFO_SIZE_HALF)

	/* max frame size */
#define ROCKM_FIFO_FRAME_SIZE		(64*1024)

	/* cache size should be the size of the FIFO + FRAME + 1*/
#define ROCKM_FIFO_CACHE_SIZE		(ROCKM_FIFO_FIFO_SIZE+ROCKM_FIFO_FRAME_SIZE+1)

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

typedef struct
        {
	  unsigned char  ring;       /* ring test bit */
	                             /* if ring on (0), only superheader, superfooter, subframe.ispresent and subheader.last have sense*/
	  unsigned char  chadd;      /* chain address */
	  unsigned short trigger;    /* trigger number */
        } ROCKM_FIFO_SUPER_HEADER;

typedef struct
        {
	  unsigned char  last;       /* last bit */
	  unsigned short trigger;    /* trigger number */
        } ROCKM_FIFO_SUB_HEADER; 

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

typedef struct
        {
	  unsigned int        nrels;   /* number of elements */
          ROCKM_FIFO_SLV_data *els;    /* array of elements  */
        } ROCKM_FIFO_SLV;

typedef struct
        {
	  unsigned int  softparity;    /* calculated parity */
	  unsigned int  hardparity;    /* hardware reported parity */
	                               /* the two parities should be equal */
        } ROCKM_FIFO_SUB_FOOTER;

typedef struct
        {
	  ROCKM_FIFO_SUB_HEADER header;

	  ROCKM_FIFO_SLV slv[16];

	  ROCKM_FIFO_SUB_FOOTER footer;

	  unsigned char ispresent;          /* if 0, the subframe was not present in the superframe */
        } ROCKM_FIFO_SUB_FRAME;

typedef struct
        {
	  unsigned char softparity_fail;     /* calculated parity bits, one per crate */
	  unsigned char hardparity_fail;     /* hardware parity bits, one per crate */
	                                     /* the two parities should be equal */
	                                     /* the bit 0 represent crate 0*/
	  unsigned char overflow;            /* overflow in counter */
	  unsigned int  softcounter;         /* calculated counter */
	  unsigned int  hardcounter;         /* hardware reported counter */
	                                     /* the two counters should be equal */
        } ROCKM_FIFO_SUPER_FOOTER;

typedef struct
        {
	  ROCKM_FIFO_SUPER_HEADER header;

	  ROCKM_FIFO_SUB_FRAME subfr[8];

	  ROCKM_FIFO_SUPER_FOOTER footer;
        } ROCKM_FIFO_FRAME;


typedef struct
	{
	 unsigned int nrframes;		/* number of frawes */
	 ROCKM_FIFO_FRAME *frames;	/* array of frames */
	} ROCKM_FIFO_FRAMEs;

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

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

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

typedef struct
	{
	  ROCKM_id rockm_id;				/* rockm id */
	  unsigned char cancache;			/* see ROCKM_FIFO_CACHE_... */
		/* cache structures */
	  unsigned int head,		/* first element */
		       tail;		/* one after the last element */
	  unsigned int cache[ROCKM_FIFO_CACHE_SIZE];
	} ROCKM_FIFO_id_base;

typedef ROCKM_FIFO_id_base *ROCKM_FIFO_id;

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

int rockm_fifo_open(ROCKM_id       rockm_id, /* IN : standard rockm id */
		    unsigned char cancache,  /* IN : see ROCKM_FIFO_CACHE_... constants */
                    ROCKM_FIFO_id *fifo_id); /* OUT: fifo id related to the rockm */

int rockm_fifo_close(ROCKM_FIFO_id   fifo_id,      /* IN : fifo id */
                     ROCKM_FIFO_RAW *cache);       /* OUT: the unused cache */
					           /*      should be disposed by caller */ 
		    
/**********************************************************************/
/*                                                                    */
/*                          Settings routines                         */
/*                                                                    */
/**********************************************************************/

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

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

int rockm_fifo_cache_flush(ROCKM_FIFO_id   fifo_id,	/* IN : fifo id */
			   ROCKM_FIFO_RAW *cache);  	/* OUT: the unused cache */
							/*      should be disposed by caller */ 

    /* Very dangerous!!!! */
int rockm_fifo_cache_refill(ROCKM_FIFO_id  fifo_id,     /* IN : fifo_id */
                            ROCKM_FIFO_RAW data);       /* IN : data to be filled to the cache */

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

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

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

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

int rockm_fifo_frame_read(ROCKM_FIFO_id     fifo_id,	/* IN : fifo id */
		   	  ROCKM_FIFO_FRAME *data);	/* OUT: one FIFO frame */
					    		/*      should be disposed by caller */ 

	/* parity, last, trigger and count errors are not reported */
int rockm_fifo_frame_blockread(ROCKM_FIFO_id      fifo_id,      /* IN : fifo id */
			       unsigned int       nrels,	/* IN : max number of raw elements */
			       ROCKM_FIFO_FRAMEs *data);	/* OUT: FIFO data */
					    		        /*      should be disposed by caller */ 

int rockm_fifo_frame_rawread(ROCKM_FIFO_id   fifo_id,	/* IN : fifo id */
			     ROCKM_FIFO_RAW *data);	/* OUT: one FIFO frame */
					       		/*      should be disposed by caller */ 

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


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

	/* returns ROCKM_ERROR_OK 	  if not empty */
	/*	   ROCKM_ERROR_FIFO_EMPTY if empty */
int rockm_fifo_isnotempty(ROCKM_FIFO_id fifo_id);	/* IN : fifo id */


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

int rockm_fifo_conv_frame2raw(ROCKM_FIFO_FRAME indata,        	/* IN : formatted data */
			      ROCKM_FIFO_RAW  *outdata);	/* OUT: raw data */

int rockm_fifo_conv_raw2frame(ROCKM_FIFO_RAW     indata,	/* IN : raw data */
			      ROCKM_FIFO_FRAME  *outdata);	/* OUT: formated data */

/**********************************************************************/
/*                                                                    */
/*                            query routines                          */
/*                                                                    */
/**********************************************************************/
#define ROCKM_FIFO_IS_ERROR		-1  /* error in type */
#define ROCKM_FIFO_IS_SUPER_HEADER     	0
#define ROCKM_FIFO_IS_SUB_HEADER       	1
#define ROCKM_FIFO_IS_SLAVE 		2
#define ROCKM_FIFO_IS_SUB_FOOTER       	3
#define ROCKM_FIFO_IS_SUPER_FOOTER     	4

 /* return one of the ROCKM_FIFO_IS_... consts */
int rockm_fifo_whatis(unsigned int el);

#endif /* ROCKMFIFO_H */