#ifndef XP_HWP_H
#define XP_HWP_H

#include "x_basic_types.h"
#include "xp_cds_status_bus.h"
#include "xp_id_plate_info.h"
			
							  
#define MODE_HWP_SPEED_NORMAL	0 // 0 - îáû÷íàß âåðñèß øèíû HWP (äëß ñòàðûõ ïëàò)
#define MODE_HWP_SPEED_SLOW		1 // 1 - ìåäëåííàß âåðñèß øèíû HWP (äëß íîâûõ ïëàò)
#define MODE_HWP_SPEED_AUTO		16 // 16 - ïðîáóåì ïåðåáðàòü â àâòîìàòå îáà âàðèàíòà: 0 and 1


enum {HWP_AUTOSPEED_NOTDETECTED=0,
      HWP_AUTOSPEED_DETECTED,
      HWP_AUTOSPEED_FIALED,
      HWP_AUTOSPEED_OFF
};

#define HWP_SPEED_VERSION_DEFINE	MODE_HWP_SPEED_AUTO // MODE_HWP_SPEED_NORMAL

#define UrefDAC 				4000.0  // 4V Uref DAC - ïèòàíèå ÖÀÏà
#define HWP_U_OPORA_DEFINE 		2000 	// mV çíà÷åíèå îïîðû = 2 - âñå êàíàëû ïîäíèìàþòñß íà ýòîò óðîâåíü
#define HWP_U_TEST_DEFINE 		0 	 	// mV êàíàë äëß ïîäà÷è òåñòîâîãî ñèãíàëà = 0

#define HWP_ENABLE_ALL_MASK 	0x0 	// 0 = ìàñêà íàëîæåíà = êàíàë îòêëþ÷åí
#define HWP_DISABLE_ALL_MASK 	0xffff 	// 1 = ìàñêà ñíßòà = êàíàë âêëþ÷åí â ðàáîòó

#define MAX_WAIT_TRANSMIT_TO_HWP	1000	// âðåìß îæèäàíèß çàâåðøåíèß êîíöà ïåðåäà÷è â HWP
#define MAX_WAIT_TEST_ERROR_HWP		50000   // âðåìß îæèäàíèß çàâåðøåíèß ñðàáàòûâàíèß òåñòîâîãî ñèãíàëà, èçìåðåíèå DELAY 
#define HWP_U_LEVEL_COMP_FOR_TEST_DEFINE	1000 	// mV - óñòàâêà êîìïàðàòîðà ïðè ëîâëå òåñòîâîãî ñèãíàëà
#define HWP_MAX_ERROR_DELAY_DEFINE		1000 // ýòî ìàêñ. ÷èñëî çàãðóçèòñß â ìàññèâ îïðåäåëåíèß çàäåðæåê êàíàëîâ ïðè îøèáêå â êàíàëå

#define HWP_U_TEST_LEVEL_FOR_DO_PLUS_TEST 	1100 //mV - óðîâåíü ïîäà÷è U_TEST ïðè òåñòå ïëþñîâûõ êàíàëîâ
#define HWP_U_TEST_LEVEL_FOR_DO_MINUS_TEST 	0 //mV- óðîâåíü ïîäà÷è U_TEST ïðè òåñòå ìèíóñîâûõ êàíàëîâ

#define HWP_U_TEST_LEVEL_FOR_PREPARE_MINUS_TEST 	1500 //mV - íà÷àëüíûé óðîâåíü U_TEST äî ïîäà÷è òåñòà äëß ìèíóñîâûõ êàíàëîâ
#define HWP_U_OPORA_LEVEL_FOR_PREPARE_MINUS_TEST 	3500 //mV- íà÷àëüíûé óðîâåíü U_OPORA äî ïîäà÷è òåñòà äëß ìèíóñîâûõ êàíàëîâ
#define HWP_U_TEST_LEVEL_FOR_PREPARE_PLUS_TEST 		0 //mV - íà÷àëüíûé óðîâåíü U_TEST äî ïîäà÷è òåñòà äëß ïëþñîâûõ êàíàëîâ
#define HWP_U_OPORA_LEVEL_FOR_PREPARE_PLUS_TEST 	2000 //mV -  íà÷àëüíûé óðîâåíü U_OPORA äî ïîäà÷è òåñòà äëß ïëþñîâûõ êàíàëîâ


#define HWP_DEF_LEVEL_ERROR		1900 // mV - óñòàâêà êîìïàðàòîðîâ ïî óìîë÷àíèþ

///////////////////////////////
#define MINIMAL_TEST_TIME_ERROR_HWP	15 // mks*10 ìèíèìàëüíîå îæèäàåìîå âðåìß ñðàáàòûâàíèß êîìïàðàòîðîâ, åñëè ïîëó÷èì ìåíüøå - îøèáêà êàíàëà
#define MAXIMAL_TEST_TIME_ERROR_HWP	200 //mks*10 ìàêñèìàëüíîå îæèäàåìîå âðåìß ñðàáàòûâàíèß êîìïàðàòîðîâ, åñëè ïîëó÷èì áîëüøå - îøèáêà êàíàëà

#define HWP_DEFAULT_USE_CHANNEL_PLUS 0xffff 	// ïî óìîë÷àíèþ èñïîëüçîâàòü âñå êàíàëû â ïëþñàõ
#define HWP_DEFAULT_USE_CHANNEL_MINUS 0xfffc 	// ïî óìîë÷àíèþ èñïîëüçîâàòü âñå êàíàëû â ìèíóñàõ, íî êðîìå äâóõ ïåðâûõ 0 è 1. ýòè îòñóòñòâóþò.


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

typedef union{
	unsigned int all;
	struct{
		unsigned int DACValue:12;
		unsigned int DACChannelNumb:4;
	}bit;
}DAC_Channals;

typedef union{
	unsigned int all;
	struct{
		unsigned int transfer_finished:1;
		unsigned int transmitErr:1;
		unsigned int Reserv:7;
		unsigned int HWP_Speed:1;
		unsigned int DACNumber:2;	
		unsigned int ErrReset:1;
		unsigned int DACOrMask:1;
		unsigned int R_W_Direction:1;
		unsigned int HWPAddress:1;
	}bit;
}HWPDACConfig;

typedef union{
	unsigned int all;
	struct{
		unsigned int DACCh14:1;	
		unsigned int DACCh15:1;
		unsigned int DACCh16:1;
		unsigned int DACCh17:1;
		unsigned int DACCh18:1;
		unsigned int DACCh19:1;
		unsigned int DACCh20:1;
		unsigned int DACCh21:1;
		unsigned int DACCh22:1;
		unsigned int DACCh23:1;
		unsigned int DACCh24:1;
		unsigned int DACCh25:1;
		unsigned int DACCh26:1;
		unsigned int DACCh27:1;
		unsigned int DACCh28:1;
		unsigned int DACCh29:1;
	}bit;
}MaskDACs_29to14;

typedef union{
	unsigned int all;
	struct{
		unsigned int Reserve:2;
		unsigned int DACCh0:1;
		unsigned int DACCh1:1;
		unsigned int DACCh2:1;
		unsigned int DACCh3:1;
		unsigned int DACCh4:1;
		unsigned int DACCh5:1;
		unsigned int DACCh6:1;
		unsigned int DACCh7:1;
		unsigned int DACCh8:1;
		unsigned int DACCh9:1;
		unsigned int DACCh10:1;
		unsigned int DACCh11:1;
		unsigned int DACCh12:1;
		unsigned int DACCh13:1;
	}bit;
}MaskDACs_13to0;

typedef struct{
	DAC_Channals dac_ch;
	HWPDACConfig dac_config;
	MaskDACs_29to14 mask_29to14;
	MaskDACs_13to0 mask_13to0;
	MaskDACs_29to14 comp_29to14;
	MaskDACs_13to0 comp_13to0;
	unsigned int transmitErr;
	unsigned int DACValues[32];

	union
	{
		UInt16 all;
		struct 
		{
	     UInt16 counter :15;
	     UInt16 ready :1;
		} bit;	
	} delay;

	union
	{
		UInt16 all;
		struct 
		{
		unsigned int DAC0Ch0:1;
		unsigned int DAC0Ch1:1;
		unsigned int DAC0Ch2:1;
		unsigned int DAC0Ch3:1;
		unsigned int DAC0Ch4:1;
		unsigned int DAC0Ch5:1;
		unsigned int DAC0Ch6:1;
		unsigned int DAC0Ch7:1;

		unsigned int DAC1Ch0:1;
		unsigned int DAC1Ch1:1;
		unsigned int DAC1Ch2:1;
		unsigned int DAC1Ch3:1;
		unsigned int DAC1Ch4:1;
		unsigned int DAC1Ch5:1;
		unsigned int DAC1Ch6:1;
		unsigned int DAC1Ch7:1;
		} bit;	
	} error_transfer_to_dac_0_1;

	union
	{
		UInt16 all;
		struct 
		{
		unsigned int DAC2Ch0:1;
		unsigned int DAC2Ch1:1;
		unsigned int DAC2Ch2:1;
		unsigned int DAC2Ch3:1;
		unsigned int DAC2Ch4:1;
		unsigned int DAC2Ch5:1;
		unsigned int DAC2Ch6:1;
		unsigned int DAC2Ch7:1;

		unsigned int DAC3Ch0:1;
		unsigned int DAC3Ch1:1;
		unsigned int DAC3Ch2:1;
		unsigned int DAC3Ch3:1;
		unsigned int DAC3Ch4:1;
		unsigned int DAC3Ch5:1;
		unsigned int DAC3Ch6:1;
		unsigned int DAC3Ch7:1;
		} bit;	
	} error_transfer_to_dac_2_3;

}HWPstr;


#define HWPstr_DEFAULTS {0,0,0,0,0,0,0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},0,0,0}






unsigned int calcVoltsToDACUop(unsigned int miliVolts);
unsigned int voltsForChanals(int miliVolts, unsigned int miliVoltsUop);
unsigned int calcVoltsToDACUtest(unsigned int miliVolts);


typedef struct{ 
	union
	{
		UInt16 all;
		struct 
		{
	     UInt16 ch0 :1;
	     UInt16 ch1 :1;
	     UInt16 ch2 :1;
	     UInt16 ch3 :1;

	     UInt16 ch4 :1;
	     UInt16 ch5 :1;
	     UInt16 ch6 :1;
	     UInt16 ch7 :1;

	     UInt16 ch8 :1;
	     UInt16 ch9 :1;
	     UInt16 ch10 :1;
	     UInt16 ch11 :1;

	     UInt16 ch12 :1;
	     UInt16 ch13 :1;
	     UInt16 ch14 :1;
	     UInt16 ch15 :1;

		} bit;	
	} minus;

	union
	{
		UInt16 all;
		struct 
		{
	     UInt16 ch0 :1;
	     UInt16 ch1 :1;
	     UInt16 ch2 :1;
	     UInt16 ch3 :1;

	     UInt16 ch4 :1;
	     UInt16 ch5 :1;
	     UInt16 ch6 :1;
	     UInt16 ch7 :1;

	     UInt16 ch8 :1;
	     UInt16 ch9 :1;
	     UInt16 ch10 :1;
	     UInt16 ch11 :1;

	     UInt16 ch12 :1;
	     UInt16 ch13 :1;
	     UInt16 ch14 :1;
	     UInt16 ch15 :1;

		} bit;	
	} plus;
} T_hwp_channels;



typedef struct{
	unsigned int minus;
	unsigned int plus;
} T_hwp_cannel_values;

#define T_HWP_CANNEL_VALUES_DEFAULTS {HWP_DEF_LEVEL_ERROR, HWP_DEF_LEVEL_ERROR}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//write reg hwp bus
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

typedef struct{

    T_hwp_channels mask;
	T_hwp_channels use_channel;

	unsigned int U_test;
	unsigned int U_opora;

	unsigned int HWP_Speed;

    unsigned int flag_detect_HWP_Speed;
    unsigned int test_all_channel; // òåñòèðîâàòü âñå êàíàëû, äàæå ñ ìàñêàìè

	T_hwp_cannel_values values[16];
} T_hwp_write;


#define T_HWP_WRITE_DEFAULTS {\
							   {0xffff,0xffff},\
							   { HWP_DEFAULT_USE_CHANNEL_MINUS, HWP_DEFAULT_USE_CHANNEL_PLUS },\
							     HWP_U_TEST_DEFINE,HWP_U_OPORA_DEFINE,HWP_SPEED_VERSION_DEFINE, HWP_AUTOSPEED_NOTDETECTED, 0,  \
							   { T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, \
							     T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, \
							     T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, \
							     T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS, T_HWP_CANNEL_VALUES_DEFAULTS\
							   }\
							 }


/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
typedef struct{
	union
	{
		UInt16 all;
		struct 
		{
	     UInt16 counter :14;
	     UInt16 ready :1;
		} bit;	
	} timer;
} T_hwp_delay;

//////////////////////////////////////////////////////////////
typedef struct{
	unsigned int er0_HWP;
	unsigned int transmit_data;

} T_hwp_errors;

#define T_HWP_ERRORS_DEFAULTS {0,0}
//////////////////////////////////////////////////////////////
typedef struct{	
	T_hwp_errors   errors;
    T_hwp_channels comp_s;
    T_hwp_channels test_passed;
} T_hwp_read;


#define T_HWP_READ_DEFAULTS {T_HWP_ERRORS_DEFAULTS,{0,0},{0,0}}
//////////////////////////////////////////////////////////////

typedef struct{
	unsigned int plus[16];
	unsigned int minus[16];
} T_hwp_delays;
#define T_HWP_DELAYS_DEFAULTS {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
//////////////////////////////////////////////////////////////


typedef struct TS_hwp{
	UInt16						plane_address; // 0 to 15
	UInt16						useit;
	T_cds_status_hwp_bus 		status_hwp_bus;
	T_component_status			status;
    T_local_status              local_status;
	
	T_hwp_delays				real_delays;

    T_hwp_read					read;
	T_hwp_write					write;

	HWPstr						low_setup;


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

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

    int (*convert_values)();	        // Pointer to calculation function

    int (*reset_error)();	    // Pointer to calculation function
    void (*store_disable_error)();    // Pointer to calculation function
    void (*restore_enable_error)();	    // Pointer to calculation function
    void (*autospeed_detect)();     // Pointer to calculation function
} T_hwp;


typedef T_hwp *T_hwp_handle;

//-----------------------------------------------------------------------------
// Default initalizer for object.
//-----------------------------------------------------------------------------                  
#define T_hwp_DEFAULTS  {   0,\
                            0,\
							T_cds_status_hwp_bus_DEFAULT,\
							component_NotReady,\
                            local_status_NotReady,\
							T_HWP_DELAYS_DEFAULTS,\
							T_HWP_READ_DEFAULTS,\
							T_HWP_WRITE_DEFAULTS,\
							HWPstr_DEFAULTS,\
							(void (*)(Uint32))hwp_init,\
							(int (*)(Uint32))hwp_internal_test,\
							(int (*)(Uint32))hwp_read_all,\
							(int (*)(Uint32))hwp_write_all,\
							(int (*)(Uint32))convert_values,\
							(int (*)(Uint32))hwp_reset_error,\
							(void (*)(Uint32))hwp_store_disable_error,\
							(void (*)(Uint32))hwp_restore_enable_error,\
							(void (*)(Uint32))hwp_autospeed_detect\
}

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void hwp_init(T_hwp_handle);

int run_internal_test(T_hwp_handle);

int hwp_internal_test(T_hwp_handle);
int hwp_read_all(T_hwp_handle);
int hwp_write_all(T_hwp_handle);
void hwp_autospeed_detect(T_hwp_handle);


int convert_values(T_hwp_handle);
int convert_masks(T_hwp_handle);


int hwp_reset_error(T_hwp_handle);
void hwp_store_disable_error(T_hwp_handle);
void hwp_restore_enable_error(T_hwp_handle);

int hwp_write_all_mask(T_hwp_handle);
int hwp_write_all_dacs(T_hwp_handle);

int hwp_read_comparators(T_hwp_handle);
int hwp_read_delay(T_hwp_handle);
void hwp_clear_delay(void);

void hwp_read_error(T_hwp_handle);
int hwp_write_u_test_dacs(T_hwp_handle);

int wait_hwp_transfer(T_hwp_handle);
//------------------------------------------------------------------------------
// Return Type
//------------------------------------------------------------------------------

#endif