#ifndef XP_CDS_IN_H
#define XP_CDS_IN_H

#include "x_basic_types.h"
#include "xp_cds_status_bus.h"
#include "xp_id_plate_info.h"

// Òèï ïëàòû IN1 èëè IN2
typedef enum {
    cds_in_type_in_1           = 0x0,  // òèï ïëàòû IN1 ñ âíåøíèì ïèòàíèå
    cds_in_type_in_2           = 0x1, // òèï ïëàòû IN2 ñ âíóòðåííèì ïèòàíèåì
    cds_in_type_not_inited     = -1 // íå îïðåäåëåí
} T_cds_in_type_plate;

#define	C_cds_in_dout_range	4
// xSENS - number sensors
// FIRST_x_x_SECOND_x_x - number sens pairs
// 0 pair = in0+in1
// 1 pair = in2+in3
// 2 pair = in4+in5
// 3 pair = in6+in7

#define T_CDS_IN_COUNT_ADR_PBUS			14	// count max elements in parallel bus 

#define T_CDS_IN_COUNT_ADR_PBUS_SP2		8	// òóò 8 øòóê, ò.ê. äëß SP2 íåò èçìåðèòåëß äëß ìåòêè ÍÓËß.
#define T_CDS_IN_COUNT_ADR_PBUS_SP6		T_CDS_IN_COUNT_ADR_PBUS


#define T_CDS_IN_SETUP_USE_ADR_PBUS 0xffff // ïî óìîë÷àíèþ - íàñòðîéêà êàêèå ðåãèñòðû èñïîëüçîâàòü äëß PBUS, 0xffff - âñå âîçìîæíûå, 0x0000 - íèêàêèå

#define SENSOR_COMBO_2SENS_FIRST_0_1_SECOND_2_3		1
#define SENSOR_COMBO_2SENS_FIRST_0_3_SECOND_1_2		2
#define SENSOR_COMBO_2SENS_FIRST_0_2_SECOND_1_3		3
#define SENSOR_COMBO_1SENS_FIRST_0_1				4
#define SENSOR_COMBO_1SENS_FIRST_1_2				5
#define SENSOR_COMBO_1SENS_FIRST_2_3				6
#define SENSOR_COMBO_1SENS_FIRST_0_2				7
#define SENSOR_COMBO_1SENS_FIRST_0_3				8
#define SENSOR_COMBO_1SENS_FIRST_1_3				9

/*-----------------------------------------------------------------------------
Define the types
-----------------------------------------------------------------------------*/
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//  write serial bus reg
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
typedef struct {

//0
	union
	{
		UInt16 all;
		struct{
			UInt16 discret : 1;
			UInt16 reserv : 7;
			UInt16 sens_2_inv_ch_90deg : 1;
			UInt16 sens_2_direct_ch_90deg : 1;
			UInt16 sens_2_inv_ch : 1;
			UInt16 sens_2_direct_ch : 1;
			UInt16 sens_1_inv_ch_90deg : 1;
			UInt16 sens_1_direct_ch_90deg : 1;
			UInt16 sens_1_inv_ch : 1;
			UInt16 sens_1_direct_ch : 1;
		}bit;
	}enabled_channels;

//1
	union
	{
		UInt16 all;
		struct{
			UInt16 inv_ch_90deg : 4;
			UInt16 direct_ch_90deg : 4;
			UInt16 inv_ch : 4;
			UInt16 direct_ch : 4;		
		}bit;
	}first_sensor;

//2 
	union
	{
		UInt16 all;
		struct{	
			UInt16 inv_ch_90deg : 4;
			UInt16 direct_ch_90deg : 4;
			UInt16 inv_ch : 4;
			UInt16 direct_ch : 4;			
		}bit;
	}second_sensor;

//3 // for SP6 only
	union
	{
		UInt16 all;
		struct{	
			UInt16 enable_sensor2 : 1; // 0 - disable, 1 - enable
			UInt16 enable_sensor1 : 1; // 0 - disable, 1 - enable
			UInt16 reserv : 6;
			UInt16 for_sensor2 : 4;
			UInt16 for_sensor1 : 4;
		}bit;
	}zero_sensors;

	//UInt16 sensor_combo;
//6
	union
	{
		UInt16 all;
		struct 
		{
	       UInt16 reserv :12;
		   UInt16 disable_err_hwp :1;
	       UInt16 disable_err0_in :1;				      	    
		   UInt16 enable_err_switch :1;
		   UInt16 enable_err_power :1;
		} bit;	
	} protect_error;

//7
    UInt16 cmd_reset_error;

} T_cds_in_write_sbus;

#define T_CDS_IN_WRITE_SBUS_DEFAULTS  {0,0,0,0,0xc000,0}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//read reg parallel bus
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
typedef struct {
//0 PB
	union
	{
		UInt16 all;
		struct{
			UInt16 in0		: 1;
			UInt16 in1		: 1;
			UInt16 in2		: 1;
			UInt16 in3		: 1;
			UInt16 in4		: 1;
			UInt16 in5		: 1;
			UInt16 in6		: 1;
			UInt16 in7		: 1;
			UInt16 in8		: 1;
			UInt16 in9		: 1;
			UInt16 in10		: 1;
			UInt16 in11		: 1;
			UInt16 in12		: 1;
			UInt16 in13		: 1;
			UInt16 in14		: 1;
			UInt16 in15		: 1;
		}bit;
	} data_in;
//1 PB
	union
	{
		UInt16 all;
		struct{
			UInt16 in0		: 1;
			UInt16 in1		: 1;
			UInt16 in2		: 1;
			UInt16 in3		: 1;
			UInt16 in4		: 1;
			UInt16 in5		: 1;
			UInt16 in6		: 1;
			UInt16 in7		: 1;
			UInt16 in8		: 1;
			UInt16 in9		: 1;
			UInt16 in10	: 1;
			UInt16 in11	: 1;
			UInt16 in12	: 1;
			UInt16 in13	: 1;
			UInt16 in14	: 1;
			UInt16 in15	: 1;
		}bit;
	} ready_in;
//2 PB
	union
	{
		UInt16 all;
		struct{
			UInt16 dir_sens_1			: 2; // 00 - stop, 10-"+" 01-"-" 11-error
			UInt16 dir_sens_2			: 2; // 00 - stop, 10-"+" 01-"-" 11-error
			UInt16 reserv				: 4;
			UInt16 mode_sensor2_90		: 1; //ðåæèì äèñêðåòèçàöèè, ïðè êîòîðîì áûëà ðàñ÷èòàíà äëèòåëüíîñòü èñïóëüñà  1 - 20ns 0 - 2us. 
			UInt16 mode_sensor2_direct	: 1; //ðåæèì äèñêðåòèçàöèè, ïðè êîòîðîì áûëà ðàñ÷èòàíà äëèòåëüíîñòü èñïóëüñà  1 - 20ns 0 - 2us. 
			UInt16 mode_sensor1_90		: 1; //ðåæèì äèñêðåòèçàöèè, ïðè êîòîðîì áûëà ðàñ÷èòàíà äëèòåëüíîñòü èñïóëüñà  1 - 20ns 0 - 2us. 
			UInt16 mode_sensor1_direct	: 1; //ðåæèì äèñêðåòèçàöèè, ïðè êîòîðîì áûëà ðàñ÷èòàíà äëèòåëüíîñòü èñïóëüñà  1 - 20ns 0 - 2us. 
			UInt16 value_vaild_sensor2_90    : 1;//1- íå áûëî ñìåíû äèñêðåòèçàöèè â ïðîöåññå ðàñ÷åòà 0 - ñìåíà áûëà, çíà÷åíèå èñïîëüçîâàòü íåëüçß
			UInt16 value_vaild_sensor2_direct: 1;
			UInt16 value_vaild_sensor1_90	 : 1;
			UInt16 value_vaild_sensor1_direct: 1;
		}bit;
	} direction_in;


//3 PB
    UInt16 SpeedS1_cnt;
//4 PB
	UInt16 SpeedS1_cnt90;
//5 PB
	UInt16 SpeedS2_cnt;
//6 PB
	UInt16 SpeedS2_cnt90;
//7 PB
	UInt16 Time_since_zero_point_S1;
//8 PB
	UInt16 Impulses_since_zero_point_Rising_S1;
//9 PB
	UInt16 Impulses_since_zero_point_Falling_S1;
//10 PB
	UInt16 Time_since_zero_point_S2;
//11 PB
	UInt16 Impulses_since_zero_point_Rising_S2;
//12 PB
	UInt16 Impulses_since_zero_point_Falling_S2;
//13 PB
	union
	{
		UInt16 all;
		struct{
			UInt16 reserv : 8;
			UInt16 sens_2_inv_ch_90deg : 1;
			UInt16 sens_2_direct_ch_90deg : 1;
			UInt16 sens_2_inv_ch : 1;
			UInt16 sens_2_direct_ch : 1;
			UInt16 sens_1_inv_ch_90deg : 1;
			UInt16 sens_1_direct_ch_90deg : 1;
			UInt16 sens_1_inv_ch : 1;
			UInt16 sens_1_direct_ch : 1;
		}bit;
	} channel_alive;

} T_cds_in_read_pbus;

#define T_CDS_IN_READ_PBUS_DEFAULTS  {0,0,0,0,0,0,0,0,0,0,0,0,0,0}
/////////////////////////////////////////////////////////////
// Table for adr parallel bus 
/////////////////////////////////////////////////////////////
typedef struct {
		UInt16 adr_table[T_CDS_IN_COUNT_ADR_PBUS];
} T_cds_in_adr_pbus;

#define T_CDS_IN_ADR_PBUS_DEFAULTS  {0,0,0,0,0,0,0,0,0,0,0,0,0}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//read reg serial bus
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
typedef struct {
//0
	union
	{
		UInt16 all;
		struct{
			UInt16 discret : 1;
			UInt16 reserv : 7;
			UInt16 sens_2_inv_ch_90deg : 1;
			UInt16 sens_2_direct_ch_90deg : 1;
			UInt16 sens_2_inv_ch : 1;
			UInt16 sens_2_direct_ch : 1;
			UInt16 sens_1_inv_ch_90deg : 1;
			UInt16 sens_1_direct_ch_90deg : 1;
			UInt16 sens_1_inv_ch : 1;
			UInt16 sens_1_direct_ch : 1;
		}bit;
	}enabled_channels;

//1
	union
	{
		UInt16 all;
		struct{
			UInt16 inv_ch_90deg : 4;
			UInt16 direct_ch_90deg : 4;
			UInt16 inv_ch : 4;
			UInt16 direct_ch : 4;		
		}bit;
	}first_sensor;

//2 
	union
	{
		UInt16 all;
		struct{	
			UInt16 inv_ch_90deg : 4;
			UInt16 direct_ch_90deg : 4;
			UInt16 inv_ch : 4;
			UInt16 direct_ch : 4;			
		}bit;
	}second_sensor;

//3 // for SP6 only
	union
	{
		UInt16 all;
		struct{	
			UInt16 enable_sensor2 : 1; // 0 - disable, 1 - enable
			UInt16 enable_sensor1 : 1; // 0 - disable, 1 - enable
			UInt16 reserv : 6;
			UInt16 for_sensor1 : 4;
			UInt16 for_sensor2 : 4;
		}bit;
	}zero_sensors;

//6
	union
	{
		UInt16 all;
		struct 
		{
	       UInt16 reserv :12;
		   UInt16 disable_err_hwp :1;
	       UInt16 disable_err0_in :1;				      	    
		   UInt16 enable_err_switch :1;
		   UInt16 enable_err_power :1;
		} bit;	
	} protect_error;
//7
	union
	{
		UInt16 all;
		struct 
		{
	       UInt16 reserv     :11;
		   UInt16 err0_local :1;
	       UInt16 err_hwp    :1;				      	    
		   UInt16 err0_in    :1;
		   UInt16 err_switch :1;
		   UInt16 err_power  :1;
		} bit;	
	} lock_status_error;

//14
	union
	{
		UInt16 all;
		struct 
		{
	       UInt16 revision   :5;
		   UInt16 version    :6;
		   T_plate_type plate_type :5;
		} bit;	
	} id_plate;


//15
	union
	{
		UInt16 all;
		struct 
		{
	       UInt16 reserv :11;
		   UInt16 err0_local :1;
		   UInt16 err_hwp :1;
		   UInt16 err0_in :1;	       				      	    
		   UInt16 err_switch :1;
		   UInt16 err_power :1;
		} bit;	
	} current_status_error;


} T_cds_in_read_sbus;

#define T_CDS_IN_READ_SBUS_DEFAULTS  {0,0,0,0,0}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////


typedef struct{
	T_cds_in_write_sbus			sbus;
} T_cds_in_write;

typedef struct{
    T_cds_in_read_sbus			sbus;
	T_cds_in_read_pbus			pbus;
	Int16						type_cds_xilinx;
} T_cds_in_read;

//////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//setup parallel bus
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
typedef struct {
	UInt16	count_elements_pbus;
// use_or_not?
	union
	{
		UInt16 all;
		struct{
			UInt16 reg0		: 1;
			UInt16 reg1		: 1;
			UInt16 reg2		: 1;
			UInt16 reg3		: 1;
			UInt16 reg4		: 1;
			UInt16 reg5		: 1;
			UInt16 reg6		: 1;
			UInt16 reg7		: 1;
			UInt16 reg8		: 1;
			UInt16 reg9		: 1;
			UInt16 reg10		: 1;
			UInt16 reg11		: 1;
			UInt16 reg12		: 1;
			UInt16 reg13		: 1;
			UInt16 reg14		: 1;
			UInt16 reg15		: 1;
		}bit;
	} use_reg_in_pbus;	

} T_cds_in_setup_pbus;

#define T_CDS_IN_SETUP_PBUS_DEFAULTS  {T_CDS_IN_COUNT_ADR_PBUS,T_CDS_IN_SETUP_USE_ADR_PBUS}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////


typedef struct TS_cds_in{
	UInt16							plane_address; // 0 to 15
	UInt16							useit;
	Int16							type_cds_xilinx;
	T_cds_in_type_plate             type_plate;

	T_cds_in_setup_pbus				setup_pbus;
	T_cds_status_serial_bus 		status_serial_bus;
	T_cds_status_parallel_bus 		status_parallel_bus;
	T_component_status				status;
    T_local_status                  local_status;

	T_cds_in_write					write;
	T_cds_in_read					read;
	T_cds_in_adr_pbus				adr_pbus;

	UInt16							store_protect_error;

    void (*init)();	    	// Pointer to calculation function

    int (*read_all)();	    // Pointer to calculation function
    int (*write_all)();	    // Pointer to calculation function

    int (*read_sbus)();	        // Pointer to calculation function
    int (*write_sbus)();	    // Pointer to calculation function

    int (*read_pbus)();	        // Pointer to calculation function
    int (*write_pbus)();	    // Pointer to calculation function

    void (*reset_error)();	    		// Pointer to calculation function
    void (*store_disable_error)();    	// Pointer to calculation function
    void (*restore_enable_error)();	  	// Pointer to calculation function

} T_cds_in;


typedef T_cds_in *T_cds_in_handle;

/*-----------------------------------------------------------------------------
Default initalizer for object.
-----------------------------------------------------------------------------*/                     
#define T_cds_in_DEFAULTS { 0,\
							0,\
							TYPE_CDS_XILINX_DEFAULTS,\
							cds_in_type_not_inited,\
							T_CDS_IN_SETUP_PBUS_DEFAULTS,\
							T_cds_status_serial_bus_DEFAULT,\
							T_cds_status_parallel_bus_DEFAULT,\
							component_NotReady,\
                            local_status_NotReady,\
							{T_CDS_IN_WRITE_SBUS_DEFAULTS},\
							{T_CDS_IN_READ_SBUS_DEFAULTS,T_CDS_IN_READ_PBUS_DEFAULTS,TYPE_CDS_XILINX_DEFAULTS},\
							T_CDS_IN_ADR_PBUS_DEFAULTS, \
							0, \
                       		(void (*)(Uint32))cds_in_init, \
                       		(int (*)(Uint32))cds_in_read_all, \
                       		(int (*)(Uint32))cds_in_write_all, \
                       		(int (*)(Uint32))cds_in_read_sbus, \
                       		(int (*)(Uint32))cds_in_write_sbus, \
                       		(int (*)(Uint32))cds_in_read_pbus, \
                       		(int (*)(Uint32))cds_in_write_pbus, \
                       		(void (*)(Uint32))cds_in_reset_error, \
                       		(void (*)(Uint32))cds_in_store_disable_error, \
                       		(void (*)(Uint32))cds_in_restore_enable_error \
							}

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////

void cds_in_init(T_cds_in_handle);

int cds_in_read_all(T_cds_in_handle);
int cds_in_write_all(T_cds_in_handle);

int cds_in_read_sbus(T_cds_in_handle);
int cds_in_write_sbus(T_cds_in_handle);

int cds_in_read_pbus(T_cds_in_handle);
int cds_in_write_pbus(T_cds_in_handle);

void cds_in_reset_error(T_cds_in_handle);
void cds_in_store_disable_error(T_cds_in_handle);
void cds_in_restore_enable_error(T_cds_in_handle);



#endif