/************************************************/
/*                                              */
/* File        : rockframes.h                   */
/* Description : ROCK frame bits interpreter    */
/*                                              */
/* Author: Sfiligoi Igor                        */
/*                                              */
/* Created      : 14.02.1997                    */
/* Last modified: 02.04.1997                    */
/*                                              */
/************************************************/

#ifndef ROCKFRAMES_H
#define ROCKFRAMES_H

#include <bits.h>

#include "rockframes_private.h"

/*********************************************************************/
/**************              constants             *******************/
/*********************************************************************/

#define ROCKF_IS_HEADER		0
#define ROCKF_IS_SLAVE		1
#define ROCKF_IS_FOOTER		2
#define ROCKF_IS_EMPTY		3	/* empty frame */

/*********************************************************************/
/**************                types               *******************/
/*********************************************************************/

typedef struct
        {
	  unsigned char  sy;		/* 0 for SyncR,1 else */
	  unsigned char  l;		/* 0 if last,1 else */
	  unsigned char  ca;		/* 0..7 */
	  unsigned short trigger;	/* 0..0xfff */
	  unsigned int   parity;	/* 0..0xffffff , INPUT ONLY*/
        } ROCKF_HEADER_bits;

typedef ROCKF_HEADER_bits ROCKF_EMPTY_bits;

typedef struct
	{
	  unsigned char  slvadd;	/* 0..15 */
	  unsigned char  channel;	/* 0..128 */
	  unsigned char  reserved;	/* 0/1 */
	  unsigned short data;		/* 0..0xfff */
	  unsigned int   parity;	/* 0..0xffffff , INPUT ONLY*/
	} ROCKF_SLAVE_bits;

typedef struct
	{
	  unsigned char l;		/* 0 if last, 1 else */
	  unsigned int  parity;		/* 0..0xffffff */
	} ROCKF_FOOTER_bits;

/*********************************************************************/
/**************         query routines             *******************/
/*********************************************************************/

	/* return one of ROCKF_IS_... constants */ 
#define rockf_whatis(/*unsigned int*/ nr)		\
	((bits_get_bit(nr,ROCKF_SOF)==0)	?	\
	 ((bits_get_bit(nr,ROCKF_EOF)==0) ?		\
	  ROCKF_IS_EMPTY	:			\
	  ROCKF_IS_HEADER)			:	\
	 ((bits_get_bit(nr,ROCKF_EOF)==0) ?		\
	  ROCKF_IS_FOOTER	:			\
	  ROCKF_IS_SLAVE))


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

/* header */

#define rockf_nr2header(/*unsigned int     */ nr,	/* IN  */	\
			/*ROCKF_HEADER_bits*/ header)	/* OUT */	\
	{								\
	  header.sy = bits_get_bit(nr,ROCKF_HEADER_SY);	 		\
	  header.l = bits_get_bit(nr,ROCKF_HEADER_L);			\
	  header.ca = bits_get_bits_mask(nr,ROCKF_HEADER_CA,ROCKF_HEADER_CA_mask); \
	  header.trigger = bits_get_bits_mask(nr,ROCKF_HEADER_TRIGGER,ROCKF_HEADER_TRIGGER_mask); \
	  header.parity = bits_get_bits_mask(nr,ROCKF_PARITY,ROCKF_PARITY_mask); \
	}

#define rockf_header2nr(/*ROCKF_HEADER_bits*/ header)		\
	(0x5000000 |						\
	 bits_pos_bit(header.sy,ROCKF_HEADER_SY)	|	\
	 bits_pos_bit(header.l,ROCKF_HEADER_L)		|	\
	 bits_pos_bits_mask(header.ca,ROCKF_HEADER_CA,ROCKF_HEADER_CA_mask)	|	\
	 bits_pos_bits_mask(header.trigger,ROCKF_HEADER_TRIGGER,ROCKF_HEADER_TRIGGER_mask))

/* empty */

#define rockf_nr2empty(/*unsigned int    */ nr,		/* IN  */	\
		       /*ROCKF_EMPTY_bits*/ empty)	/* OUT */	\
	{								\
	  empty.sy = bits_get_bit(nr,ROCKF_HEADER_SY); 			\
	  empty.l = bits_get_bit(nr,ROCKF_HEADER_L);			\
	  empty.ca = bits_get_bits_mask(nr,ROCKF_HEADER_CA,ROCKF_HEADER_CA_mask); \
	  empty.trigger = bits_get_bits_mask(nr,ROCKF_HEADER_TRIGGER,ROCKF_HEADER_TRIGGER_mask); \
	  empty.parity = bits_get_bits_mask(nr,ROCKF_PARITY,ROCKF_PARITY_mask); \
	}

#define rockf_empty2nr(/*ROCKF_EMPTY_bits*/ empty)		\
	(bits_pos_bit(empty.sy,ROCKF_HEADER_SY)		|	\
	 bits_pos_bit(empty.l,ROCKF_HEADER_L)		|	\
	 bits_pos_bit(empty.l,ROCKF_CEOF)		|	\
	 bits_pos_bits_mask(empty.ca,ROCKF_HEADER_CA,ROCKF_HEADER_CA_mask)	|	\
	 bits_pos_bits_mask(empty.trigger,ROCKF_HEADER_TRIGGER,ROCKF_HEADER_TRIGGER_mask))

/* slave */

#define rockf_nr2slave(/*unsigned int    */ nr,		/* IN  */	\
		       /*ROCKF_SLAVE_bits*/ slave)	/* OUT */	\
	{								\
	  slave.slvadd = bits_get_bits_mask(nr,ROCKF_SLVADD,ROCKF_SLVADD_mask);	\
	  slave.channel = bits_get_bits_mask(nr,ROCKF_SLAVE_CHANNEL,ROCKF_SLAVE_CHANNEL_mask);	\
	  slave.reserved = bits_get_bit(nr,ROCKF_SLAVE_RESERVED);	\
	  slave.data = bits_get_bits_mask(nr,ROCKF_SLAVE_DATA,ROCKF_SLAVE_DATA_mask);	\
	  slave.parity = bits_get_bits_mask(nr,ROCKF_PARITY,ROCKF_PARITY_mask); \
	}

#define rockf_slave2nr(/*ROCKF_SLAVE_bits*/ slave)	\
	(0x7000000 |					\
	 bits_pos_bits_mask(slave.slvadd,ROCKF_SLVADD,ROCKF_SLVADD_mask)	|	\
	 bits_pos_bits_mask(slave.channel,ROCKF_SLAVE_CHANNEL,ROCKF_SLAVE_CHANNEL_mask)	|	\
	 bits_pos_bit(slave.reserved,ROCKF_SLAVE_RESERVED)	|	\
	 bits_pos_bits_mask(slave.data,ROCKF_SLAVE_DATA,ROCKF_SLAVE_DATA_mask))

/* footer */

#define rockf_nr2footer(/*unsigned int     */ nr,	/* IN  */	\
			/*ROCKF_FOOTER_bits*/ footer)	/* OUT */	\
	{								\
	 footer.l = bits_get_bit(nr,ROCKF_CEOF);			\
	 footer.parity = bits_get_bits_mask(nr,ROCKF_PARITY,ROCKF_PARITY_mask);	\
	}

#define rockf_footer2nr(/*ROCKF_FOOTER_bits*/ footer)	\
	(0x2000000 |					\
	 bits_pos_bit(footer.l,ROCKF_CEOF)	|	\
	 bits_pos_bits_mask(footer.parity,ROCKF_PARITY,ROCKF_PARITY_mask))

#endif /* ROCKFRAMES_H */