#ifndef XP_CDS_TK_23550_H
#define XP_CDS_TK_23550_H


#include <project_setup.h>

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



/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////  23550
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//#define Cds_Tk_Xilinx_SP6	0

//#if Cds_Tk_Xilinx_SP6 == 1
#define T_CDS_TK_COUNT_ADR_PBUS_23550			6	// count max elements in parallel bus 
//#else
//	#define T_CDS_TK_COUNT_ADR_PBUS_23550		0	// count max elements in parallel bus 
//#endif //Cds_Tk_Xilinx_SP6

#define T_CDS_TK_SETUP_USE_ADR_PBUS_23550		0xffff // по умолчанию - настройка какие регистры использовать длЯ PBUS, 0xffff - все возможные

/*-----------------------------------------------------------------------------
Define the types
-----------------------------------------------------------------------------*/
/////////////////////////////////////////////////////////////
//  write serial bus reg
/////////////////////////////////////////////////////////////
typedef struct {
//0
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0 :1;
		 UInt16 tk1 :1;
		 UInt16 tk2 :1;
		 UInt16 tk3 :1;
		 UInt16 tk4 :1;
		 UInt16 tk5 :1;
		 UInt16 tk6 :1;
		 UInt16 tk7 :1;
		 UInt16 reserv :8;
		} bit;	
	} mask_tk_out_40pin;
//1
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 mintime  :8; // N=mintime  * fclk   fclk=5000kHz
		   UInt16 deadtime :8; // N=deadtime * fclk   fclk=5000kHz
		} bit;	
	} dead_min_time;
//2
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 time :8;
		   UInt16 reserv :8;				      	    
		} bit;	
	} ack_time;
//3
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0_ack :1;
		 UInt16 tk1_ack :1;
		 UInt16 tk2_ack :1;
		 UInt16 tk3_ack :1;
		 UInt16 tk4_ack :1;
		 UInt16 tk5_ack :1;
		 UInt16 tk6_ack :1;
		 UInt16 tk7_ack :1;	    		      	    
		 UInt16 tk0_current :1;
		 UInt16 tk1_current :1;
		 UInt16 tk2_current :1;
		 UInt16 tk3_current :1;
		 UInt16 tk4_current :1;
		 UInt16 tk5_current :1;
		 UInt16 tk6_current :1;
		 UInt16 tk7_current :1;
		} bit;	
	} mask_protect_tk;
//4
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 reserv :8;
           UInt16 detect_soft_disconnect :1;
		   UInt16 enable_soft_disconnect :1;
		   UInt16 enable_line_err :1;
		   UInt16 disable_err_mintime :1;
		   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;

//10
	UInt16  time_after_err; //time_after_err = 4000<-DEC * 0.02 = 80mc

} T_cds_tk_write_sbus_23550;

#define T_CDS_TK_WRITE_SBUS_DEFAULTS_23550			{0x0000,0x5f5f,0x0909,0x0000,0x0000,0x0105}


////////////////////////////////////    /////////////////////////
/////////////////////////////////////////////////////////////
// read reg serial bus
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
typedef struct {
//0
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0 :1;
		 UInt16 tk1 :1;
		 UInt16 tk2 :1;
		 UInt16 tk3 :1;
		 UInt16 tk4 :1;
		 UInt16 tk5 :1;
		 UInt16 tk6 :1;
		 UInt16 tk7 :1;
		 UInt16 reserv :8;
		} bit;	
	} mask_tk_out_40pin;

//1
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 mintime  :8; // N=mintime  * fclk   fclk=5000kHz
		   UInt16 deadtime :8; // N=deadtime * fclk   fclk=5000kHz
		} bit;	
	} dead_min_time;

//2
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 time :8;
		   UInt16 reserv :8;				      	    
		} bit;	
	} ack_time;

//3
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0_ack :1;
		 UInt16 tk1_ack :1;
		 UInt16 tk2_ack :1;
		 UInt16 tk3_ack :1;
		 UInt16 tk4_ack :1;
		 UInt16 tk5_ack :1;
		 UInt16 tk6_ack :1;
		 UInt16 tk7_ack :1;	    		      	    
		 UInt16 tk0_current :1;
		 UInt16 tk1_current :1;
		 UInt16 tk2_current :1;
		 UInt16 tk3_current :1;
		 UInt16 tk4_current :1;
		 UInt16 tk5_current :1;
		 UInt16 tk6_current :1;
		 UInt16 tk7_current :1;
		} bit;	
	} mask_protect_tk;

//4
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 reserv :8;
           UInt16 detect_soft_disconnect :1;
           UInt16 enable_soft_disconnect :1;
		   UInt16 enable_line_err :1;
		   UInt16 disable_err_mintime :1;
		   UInt16 disable_err_hwp :1;
		   UInt16 disable_err0_in :1;
		   UInt16 enable_err_switch :1;
		   UInt16 enable_err_power :1;
		} bit;	
	} protect_error;

//5
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0_ack :1;
		 UInt16 tk1_ack :1;
		 UInt16 tk2_ack :1;
		 UInt16 tk3_ack :1;
		 UInt16 tk4_ack :1;
		 UInt16 tk5_ack :1;
		 UInt16 tk6_ack :1;
		 UInt16 tk7_ack :1;
		 UInt16 tk0 :1;
		 UInt16 tk1 :1;
		 UInt16 tk2 :1;
		 UInt16 tk3 :1;
		 UInt16 tk4 :1;
		 UInt16 tk5 :1;
		 UInt16 tk6 :1;
		 UInt16 tk7 :1;	    		      	    
		} bit;	
	} status_tk_40pin;

//6
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0_a4 :1;
		 UInt16 tk1_b4 :1;
		 UInt16 tk2_c4 :1;
		 UInt16 tk3_a5 :1;
		 UInt16 tk4_b5 :1;
		 UInt16 tk5_c5 :1;
		 UInt16 tk6_a6 :1;
		 UInt16 tk7_b6 :1;
		 UInt16 tk8_c6 :1;
		 UInt16 tk9_a7 :1;
		 UInt16 tk10_b7 :1;
		 UInt16 tk11_c7 :1;
		 UInt16 tk12_a8 :1;
		 UInt16 tk13_b8 :1;
		 UInt16 tk14_a9 :1;
		 UInt16 tk15_b9 :1;	    		      	    
		} bit;	
	} status_tk_96pin;

//7
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 reserv     :5;
		   UInt16 ErrorSoftShutdownForbidComb     :1;
		   UInt16 ErrorSoftShutdownFromErr0    :1;
		   UInt16 line_err_keys_3210 :1;
		   UInt16 line_err_keys_7654 :1;
		   UInt16 mintime_err_keys_3210 :1;
		   UInt16 mintime_err_keys_7654 :1;
		   UInt16 err0_local :1;
		   UInt16 err_hwp    :1;		      	    
		   UInt16 err0_in    :1;
		   UInt16 err_switch :1;
		   UInt16 err_power  :1;
		} bit;	
	} lock_status_error;

//8
	union
	{
		UInt16 all;
		struct 
		{
		 UInt16 tk0_ack :1;
		 UInt16 tk1_ack :1;
		 UInt16 tk2_ack :1;
		 UInt16 tk3_ack :1;
		 UInt16 tk4_ack :1;
		 UInt16 tk5_ack :1;
		 UInt16 tk6_ack :1;
		 UInt16 tk7_ack :1;	    		      	    
		 UInt16 tk0_current :1;
		 UInt16 tk1_current :1;
		 UInt16 tk2_current :1;
		 UInt16 tk3_current :1;
		 UInt16 tk4_current :1;
		 UInt16 tk5_current :1;
		 UInt16 tk6_current :1;
		 UInt16 tk7_current :1;
		} bit;	
	} status_protect_current_ack;

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

//10

    UInt16 time_after_err;


//11
	union
	{
		UInt16 all;
		struct 
		{
		   UInt16 tk_3210     :8;
		   UInt16 tk_7654     :8;
		} bit;	
	} time_err_tk_all;

//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_tk_read_sbus_23550;


#define T_CDS_TK_READ_SBUS_DEFAULTS_23550  		{0,0,0,0,0,0,0,0,0,0,0}



/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// read reg parallel bus
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

typedef union {
    UInt16 all;
    struct {
        UInt16 id:4;                    // -Идентификатор отправки(целостности по параллельной шине). До прочтения
                                        // (должен совпасть с идентификатором после)
        UInt16 id_sbus:4;               // Счетчик принимаемых посылок, увелич.на +1 при каждой новой посылке

        UInt16 count_receiver_error:4;  // число ошибок при получении данных (приемник на текущей плате ТК)
        UInt16 trans_busy:1;            // busy 1-приемник в процессе получения данных, 0- в ожидании (приемник на плате ТК в другой корзине)
        UInt16 trans_error:1;           // ошибка при получении данных (приемник на плате ТК в другой корзине)
        UInt16 receiver_busy :1;        // busy 1-приемник в процессе получения данных, 0- в ожидании (приемник на текущей плате ТК)
        UInt16 receiver_error:1;        // ошибка при получении данных (приемник на текущей плате ТК)
    } bit;
} STATUS_OPT_BUS;

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

typedef struct {
	//0
    STATUS_OPT_BUS status1;
	//1
	union {
		UInt16 all;
	} DataReg0;
	//2
	union {
		UInt16 all;
	} DataReg1;
	//3
	union {
		UInt16 all;
	} DataReg2;
	//4
	union {
		UInt16 all;
	} DataReg3;
	//5
	STATUS_OPT_BUS status2;

} T_cds_tk_read_pbus_23550;
//в общем 15, 14, 11-8 это статусы приема, 13, 12 - статусы отправки, являющиеся статусами приема у платы во второй корзине
//ну в общем ключевой бит - 15, значит мы от платы в другой корзине получили данные, у которых не совпал ЦРЦ, и 13, значит что в другую корзину данные не ушли.
//busy чисто на всякий случай, проверить перед отправкой.
//Ну и после, если бизи ноль(12), еррор(13) ноль, значит данные ушли и все супер.
//если бизи 1, значит в процессе, либо что-то залипло, но вроде не должно
//Ну а при чтении данных полученных из другой корзины мы смотрим 15 и 14, если 15 и 14 = 0, значит все хорошо, если 15 = 1, бизи 0, значит передача была, но не удачно
//идентификатор отправки обновляется каждый раз, как данные были изменены.
//соответственно если пока мы что-то слали по параллельной шине, по оптике пришли новые данные, и идентификатор обновился, данные могли смешаться, это плохо, значит надо прочитать параллельную шину еще раз
//Регистр #0 должен быть равен #5 если передача не была нарушена или перезаписана на этапе ее трансляции в PBUS
//id инкрементируется по кругу при каждой передачи


#define T_CDS_TK_READ_PBUS_DEFAULTS_23550  		{0,0,0,0,0,0}


/////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//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 res		: 10;
		}bit;
	} use_reg_in_pbus;	

} T_cds_tk_setup_pbus_23550;

#define T_CDS_TK_SETUP_PBUS_DEFAULTS_23550  	{T_CDS_TK_COUNT_ADR_PBUS_23550,T_CDS_TK_SETUP_USE_ADR_PBUS_23550}
//////////////////////////////////////////////////////////////




typedef struct{
	T_cds_tk_write_sbus_23550			sbus;
} T_cds_tk_write_23550;

typedef struct{
	T_cds_tk_read_sbus_23550			sbus;
	T_cds_tk_read_pbus_23550			pbus;
	Int16								type_cds_xilinx;
} T_cds_tk_read_23550;

#define T_CDS_TK_READ_DEFAULTS_23550			{T_CDS_TK_READ_SBUS_DEFAULTS_23550,T_CDS_TK_READ_PBUS_DEFAULTS_23550,TYPE_CDS_XILINX_DEFAULTS}

typedef struct {
		UInt16 adr_table[T_CDS_TK_COUNT_ADR_PBUS_23550];
} T_cds_tk_adr_pbus_23550;

#define T_CDS_TK_ADR_PBUS_DEFAULTS_23550  		{0,0,0,0,0,0}


//////////////////////////////////////////////////////////////
typedef struct {
        UInt16 setup_count_error;
        UInt16 full_count_error;
        UInt16 local_count_error;
        UInt16 count_send;
        UInt16 ready;
        UInt16 error_not_ready_count;
        UInt16 raw_local_error;
        UInt16 buf[4];
} T_cds_optical_bus_data_out;

#define T_CDS_OPTICAL_BUS_DATA_OUT_DEFAULTS         {15,0,0,0,0,0,0,{0,0,0,0}}

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

typedef union {
    UInt16 all;
    struct {
        UInt16 new_data_ready:1;      // есть новые данные
        UInt16 overfull_new_data:1;   // данные новые затерли старые
        UInt16 old_data:1;              // старые данные
        UInt16 lost_data:1;             // были потери при чтении, слишком медленно читаем парал.шину
        UInt16 bad_status12:1;          // при чтении была напушена целостность данных, надо повторить чтение
        UInt16 receiver_busy:1;         //busy 1-приемник в процессе получения данных, 0- в ожидании (приемник на текущей плате ТК)
        UInt16 receiver_error:1;        // ошибка при получении данных (приемник на текущей плате ТК)

    } bit;
} STATUS_DATA_READ_OPT_BUS;

/////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
typedef struct {
        UInt16 setup_count_error;           // сколько ждем до падения шины
        UInt16 setup_count_error_between;    // сколько ждем до падения шины при чтении старых значений
        UInt16 full_count_error;            // всего ошибок
        UInt16 local_count_error;           // текущий счетчик ошибок, идет до setup_count_error и снимается ready, при удачном чтении обнуляется
        UInt16 count_ok;                    // сколько удачных чтений
        UInt16 count_lost;                  // сколько потерь данных (по id_sbus)
        UInt16 ready;                       // шина работает, ошибки не превысили setup_count_error
        UInt16 same_id_count;               // сколько всего повторных чтений техже данных, т.е. передатчик в др.ПЧ не прислал ничего нового
        UInt16 same_id_count_between;       // между удачными чтениями, сколько повторных чтений техже данных, т.е. передатчик в др.ПЧ не прислал ничего нового
        UInt16 error_not_ready_count;       // сколько ошибок не готовности шины ready
        UInt16 raw_local_error;             // есть ошибка при чтении, но шина не упала еще
        UInt16 buf[4];                      // данные
        STATUS_OPT_BUS status_1;            // копия status 1
        STATUS_OPT_BUS status_2;            // копия status 2
        UInt16 prev_id_sbus;                // пред. значение id_sbus
        STATUS_DATA_READ_OPT_BUS status_read;// статус после чтения и анализа данных
        STATUS_DATA_READ_OPT_BUS prev_status_read;// статус после чтения и анализа данных
} T_cds_optical_bus_data_in;

#define T_CDS_OPTICAL_BUS_DATA_IN_DEFAULTS         {15,50,0,0,0,0,0,0,0,0,0,{0,0,0,0},0,0,0,0,0}

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

typedef struct  {
	UInt16						plane_address; // 0 to 15
	UInt16						useit;
	Int16						type_cds_xilinx;
	T_cds_tk_setup_pbus_23550	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_tk_write_23550		write;
	T_cds_tk_read_23550			read;
//#if Cds_Tk_Xilinx_SP6 == 1
	T_cds_tk_adr_pbus_23550			adr_pbus;
//#endif
	UInt16						store_protect_error;

	T_cds_optical_bus_data_out      optical_data_out;
    T_cds_optical_bus_data_in       optical_data_in;

	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 (*optical_bus_write_data)();        // 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

    void (*optical_bus_check_error_read)();     // Pointer to calculation function
    void (*optical_bus_check_error_write)();     // Pointer to calculation function

} T_cds_tk_23550;
	


#define T_cds_tk_DEFAULTS_23550	{0,\
							0,\
							TYPE_CDS_XILINX_DEFAULTS,\
							T_CDS_TK_SETUP_PBUS_DEFAULTS_23550,\
							T_cds_status_serial_bus_DEFAULT,\
							T_cds_status_parallel_bus_DEFAULT,\
							component_NotReady,\
							local_status_NotReady,\
							{T_CDS_TK_WRITE_SBUS_DEFAULTS_23550},\
							T_CDS_TK_READ_DEFAULTS_23550,\
							T_CDS_TK_ADR_PBUS_DEFAULTS_23550,\
							0,\
                            T_CDS_OPTICAL_BUS_DATA_OUT_DEFAULTS,\
                            T_CDS_OPTICAL_BUS_DATA_IN_DEFAULTS,\
							(void (*)(Uint32))cds_tk_init,\
							(int (*)(Uint32))cds_tk_read_all,\
							(int (*)(Uint32))cds_tk_write_all,\
							(int (*)(Uint32))cds_tk_read_sbus_23550,\
							(int (*)(Uint32))cds_tk_write_sbus_23550,\
							(int (*)(Uint32))cds_tk_read_pbus_23550,\
							(int (*)(Uint32))cds_tk_write_pbus,\
							(void (*)(Uint32))cds_tk_optical_bus_write_data,\
							(void (*)(Uint32))cds_tk_reset_error,\
							(void (*)(Uint32))cds_tk_store_disable_error,\
							(void (*)(Uint32))cds_tk_restore_enable_error,\
							(void (*)(Uint32))cds_tk_optical_bus_check_error_read,\
							(void (*)(Uint32))cds_tk_optical_bus_check_error_write\
							}






typedef T_cds_tk_23550 *T_cds_tk_handle_23550;

void cds_tk_optical_bus_write_data(T_cds_tk_23550 *v);
void cds_tk_optical_bus_check_error_read(T_cds_tk_23550 *v);
void cds_tk_optical_bus_check_error_write(T_cds_tk_23550 *v);

#endif // XP_CDS_TK_23550_H
