#ifndef XP_INCREMENTAL_SENSORS_H
#define XP_INCREMENTAL_SENSORS_H

#include "IQmathLib.h"
#include "x_basic_types.h"
#include "xp_cds_in.h"
#include "xp_id_plate_info.h"

#define INCREMENTAL_SENSOR_SAMPLING_TIME_PM67_MS		0	
#define INCREMENTAL_SENSOR_SAMPLING_TIME_PM67_NS		1

#define LEVEL_SWITCH_TUNE_TIME_PM67_MICROSEC		40000
#define LEVEL_SWITCH_TUNE_TIME_PM67_NANOSEC			300

//Äèñêðåòèçàöèþ, ïðè êîòîðîé ðàñ÷èòûâàåòñß äëèòåëüíîñòü èìïóëüñîâ
#define SAMPLING_TIME_PM67_NS                       1  // 16,666667ns
#define SAMPLING_TIME_PM67_MS                       0  // 1,666667us

#define MODE_OFF_SPEED_TUNE_PM67		0 
#define MODE_AUTO_SPEED_TUNE_PM67		1 
#define MODE_LOW_SPEED_TUNE_PM67		2 
#define MODE_FAST_SPEED_TUNE_PM67		3


/////////////////////////////////////////////////////////////
// IN plane
/////////////////////////////////////////////////////////////
// Registers with data for incremental sensor
/////////////////////////////////////////////////////////////
typedef union {
	unsigned int all;
	struct {
		unsigned int filter_sensitivity:12;
		unsigned int set_sampling_time:1;	//(1)-16,666667ns (0)-1,666667us
		unsigned int sampling_time2:1;	//(1)-16,666667ns (0)-1,666667us
		unsigned int sampling_time1:1;
		unsigned int update_registers:1; //0 - updated
	}bit;
}T_inc_sensor_comand_pm67;

#define T_INC_COMAND_DEFAULT 0
////////////////////////////////////////////////////////////
typedef struct {
	unsigned int time_line1;
    unsigned int n_impulses_line1;
    unsigned int time_line2;
    unsigned int n_impulses_line2;

    unsigned int zero_time_line1;
    unsigned int one_time_line1;
    unsigned int zero_time_line2;
    unsigned int one_time_line2;

} T_inc_sensor_data_pm67;

#define T_INC_SENSOR_DATA_PM67	{0,0,0,0,0,0,0,0}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////




typedef struct
{
////////////////////////
////////////////////////
// data_from_pm67	  //
////////////////////////
	struct {

		struct {
			_iq time_s1;
			_iq time_s2;
		} raw_solo;

		struct {
			_iq before_time_s1;
			_iq before_time_s2;

			_iq time_s1;
			_iq time_s2;
		} filter_solo;

		struct {
			_iq TimeCalcS1;
			_iq TimeCalcS2;

		} raw_pulses;

		struct {
			_iq before_ch0_s1;
			_iq before_ch1_s1;

			_iq before_ch0_s2;
			_iq before_ch1_s2;

			_iq ch0_s1;
			_iq ch1_s1;

			_iq ch0_s2;
			_iq ch1_s2;

		} filter_pulses;


//		_iq solo_time_s1;
//		_iq solo_time_s2;

//		_iq pulses_time_s1;
//		_iq pulses_time_s2;

		T_inc_sensor_data_pm67 data_from_xilinx;

	} data_from_pm67;	

////////////////////////
////////////////////////
////////////////////////
// data_from_in	      //
////////////////////////

	struct {

		struct {
			_iq speed_s1;
			_iq speed_90_s1;

			_iq speed_s2;
			_iq speed_90_s2;

			_iq zero_point_s1;
			_iq zero_point_rising_s1;
			_iq zero_point_falling_s1;
		
			_iq zero_point_s2;
			_iq zero_point_rising_s2;
			_iq zero_point_falling_s2;

			unsigned int dir_s1;
			unsigned int dir_s2;

			_iq angle_f_s1;
			_iq angle_r_s1;

			_iq angle_f_s2;
			_iq angle_r_s2;

			int status_s1;
			int status_s2;

		} raw;

		struct {

			_iq speed_s1;
			_iq speed_90_s1;

			_iq speed_s2;
			_iq speed_90_s2;

			_iq zero_point_s1;
			_iq zero_point_rising_s1;
			_iq zero_point_falling_s1;
		
			_iq zero_point_s2;
			_iq zero_point_rising_s2;
			_iq zero_point_falling_s2;


			unsigned int dir_s1;
			unsigned int dir_s2;

		} filter;


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

	} data_from_in;	

////////////////////////
////////////////////////
/// config //
////////////////////////
	struct {

	 struct {
		_iq KoefNormMS;
		_iq KoefNormNS;
		_iq koefW;
		long long KoefNormImpulses;
		unsigned int use;
		unsigned int use_s1;
		unsigned int use_s2;
		unsigned int ModeAutoDiscret;// 1 -auto, 2-low speed, 3- fast speed
		unsigned int  time_level_discret_1to0;
		unsigned int  time_level_discret_0to1;

	 } for_pm67;
////////////////////////

	 struct {

		unsigned int use_it;
		unsigned int use_sp6;
	 	struct {
			unsigned int ModeAutoDiscret;// 1 -auto, 2-low speed, 3- fast speed
			unsigned int use_s1;
			unsigned int use_s2;
			unsigned int decoder_zero_level;
			unsigned int decoder_max_level;
			unsigned int max_count_overfull_discret;
			unsigned int max_count_zero_discret;
			unsigned int time_level_discret_1to0;
			unsigned int time_level_discret_0to1;
			long long KoefNorm_discret0;
			long long KoefNorm_discret1;
		} incremental_sensors;

	 	struct {
			long long KoefNorm_angle;
			unsigned int use_z1;
			unsigned int use_z2;
		} zero_sensors;
	 } for_in;

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

	 struct {
	 	unsigned int count_impulses; // one oborots
	 } inc_sensor;

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

	struct {

	 struct {
		unsigned int alarm_s1;
		unsigned int alarm_s2;
		unsigned int error_s1_s2;
		unsigned int error_update_registers;
	 } for_pm67;

	 struct {

	 	struct {
			unsigned int alarm_s1;
			unsigned int alarm_s2;
			unsigned int alarm_dir1;
			unsigned int alarm_dir2;
			unsigned int error_s1_s2;
			unsigned int error_dir1_dir2;
		} incremental_sensors;
	 	
	 	struct {
			unsigned int alarm_z1;
			unsigned int alarm_z2;
			unsigned int error_z1_z2;
		} zero_sensors;
	 } for_in;

	} error_alarms_timeouts;	

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

	struct {

	 struct {
		unsigned int alarm_s1;
		unsigned int alarm_s2;
		unsigned int error_s1_s2;
	 } for_pm67;

	 struct {

	 	struct {
			unsigned int alarm_s1;
			unsigned int alarm_s2;
			unsigned int alarm_dir1;
			unsigned int alarm_dir2;
			unsigned int error_s1_s2;
			unsigned int error_dir1_dir2;
		} incremental_sensors;
	 	
	 	struct {
			unsigned int alarm_z1;
			unsigned int alarm_z2;
			unsigned int error_z1_z2;
		} zero_sensors;
	 } for_in;

	} error_alarms_on_off;	

	} config;	
////////////////////////
// error_alarms_stat
////////////////////////	

	struct {

	 struct {
		unsigned int error_update_registers;
		unsigned int alarm_s1;
		unsigned int alarm_s2;
		unsigned int error_s1_s2;
	 } for_pm67;

	 struct {

	 	struct {
			unsigned int alarm_s1;
			unsigned int alarm_s2;
			unsigned int alarm_dir1;
			unsigned int alarm_dir2;
			unsigned int error_s1_s2;
			unsigned int error_dir1_dir2;
		} incremental_sensors;
	 	
	 	struct {
			unsigned int alarm_z1;
			unsigned int alarm_z2;
			unsigned int error_z1_z2;
		} zero_sensors;
	 } for_in;

	} error_alarms_stat;	
////////////////////////
// error_alarms_status
////////////////////////
	struct {

	 struct {
		unsigned int error_update_registers;
		unsigned int alarm_s1;
		unsigned int alarm_s2;
		unsigned int error_s1_s2;
	 } for_pm67;

	 struct {

	 	struct {
			unsigned int alarm_s1;
			unsigned int alarm_s2;
			unsigned int alarm_dir1;
			unsigned int alarm_dir2;
			unsigned int error_s1_s2;
			unsigned int error_dir1_dir2;
		} incremental_sensors;
	 	
	 	struct {
			unsigned int alarm_z1;
			unsigned int alarm_z2;
			unsigned int error_z1_z2;
		} zero_sensors;
	 } for_in;

	} error_alarms_status;	
////////////////////////
////////////////////////	
// error_alarms_counters
////////////////////////
	struct {

	 struct {
		unsigned int alarm_s1;
		unsigned int alarm_s2;
		unsigned int error_s1_s2;
		unsigned int error_update_registers;
	 } for_pm67;

	 struct {

	 	struct {
			unsigned int alarm_s1;
			unsigned int alarm_s2;
			unsigned int alarm_dir1;
			unsigned int alarm_dir2;
			unsigned int error_s1_s2;
			unsigned int error_dir1_dir2;
		} incremental_sensors;
	 	
	 	struct {
			unsigned int alarm_z1;
			unsigned int alarm_z2;
			unsigned int error_z1_z2;
		} zero_sensors;
	 } for_in;

	} error_alarms_counters;	
	
////////////////////////
	T_inc_sensor_comand_pm67 	write_comand_reg_pm67;
	T_inc_sensor_comand_pm67 	read_comand_reg_pm67;

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

////////////////////////
////////////////////////
	
//	int RotorDirection1;
//	int RotorDirection2;

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

//	void (*request_data_from_sensors_pm67)();
	void (*read_sensors_pm67)();
	void (*read_sensors_in)();
	void (*update_regs_sensors_pm67)();
//	void (*update_regs_sensors_in)();

} T_Incremental_sensors;

#define T_Incremental_sensors_DEFAULT	{}

void incremental_sensors_init(T_Incremental_sensors *inc_s);
void incremental_sensors_read_pm67(T_Incremental_sensors *inc_s);
void incremental_sensors_update_sensors_data_pm67(T_Incremental_sensors *inc_s);

/*






//Àâòîìàòè÷åñêè ïåðåêëþ÷àåò ñ÷¸ò÷èê, êîãäà êîëè÷åñòâî îòñ÷¸òîâ
// íà 1 èìïóëüñ ñòàíîâèòñß ñëèøêîì áîëüøèì èëè ìàëåíüêèì.
#define AUTO_CHANGE_SAMPLING_TIME	1
//
//	×òî áû ïðî÷èòàòü äàííûå èç äàò÷èêà, íóæíî âûçâàòü
//	rotation_sensor.read_sensors(&rotation_sensor);
//	Ðåçóëüòàò ïëàòû IN áóäåò â 
//	rotation_sensor.in_plane.out....
//

/////////////////////////////////////////////////////////////
// IN plane
/////////////////////////////////////////////////////////////
// Registers with data for incremental sensor
/////////////////////////////////////////////////////////////
typedef union {
	unsigned int all;
	struct {
		unsigned int filter_sensitivity:12;
		unsigned int set_sampling_time:1;	//(1)-16,666667ns (0)-1,666667us
		unsigned int sampling_time2:1;	//(1)-16,666667ns (0)-1,666667us
		unsigned int sampling_time1:1;
		unsigned int update_registers:1; //0 - updated
	}bit;
}T_inc_sensor_comand;

#define T_INC_COMAND_DEFAULT 0
////////////////////////////////////////////////////////////
typedef struct {
	unsigned int time_line1;
    unsigned int n_impulses_line1;
    unsigned int time_line2;
    unsigned int n_impulses_line2;

    unsigned int zero_time_line1;
    unsigned int one_time_line1;
    unsigned int zero_time_line2;
    unsigned int one_time_line2;

	T_inc_sensor_comand 	write_comand_reg;
	T_inc_sensor_comand 	read_comand_reg;

} T_inc_sensor_regs;

#define T_INC_SENSOR_REGS_DEFAULTS {0,0,0,0, 0,0,0,0, T_INC_COMAND_DEFAULT, T_INC_COMAND_DEFAULT}


////////////////////////////////////////////////
////// incremental sensors with IN plane
///////////////////////////////////////////////
typedef struct {
	//UInt16 plane_address;
	unsigned int count_wait_for_update_registers;
	unsigned int error_update;
	unsigned int use_sensor1;
	unsigned int use_sensor2;

	struct {

		unsigned int Time1;			// Sensor's survey time in mksec
		unsigned int Impulses1;		// Quantity of full impulses during survey time
		unsigned int CountZero1; 	// Value of the zero-half-period counter 
		unsigned int CountOne1;		// Value of the one-half-period counter
		unsigned int counter_freq1;	// 1 - 60MHz; 0 - 600KHz
		unsigned long TimeCalcFromImpulses1; // Ïåðåñ÷åò âðåìåíè èìïóëüñà èç êîëè÷åñòâà Impulses1 è âðåìåíè Time1
		int direction1;	// 1 - direct; 0 - reverse

		unsigned int Time2;			// Sensor's survey time in mksec
		unsigned int Impulses2;		// Quantity of full impulses during survey time
		unsigned int CountZero2;		// Value of the zero-half-period counter 
		unsigned int CountOne2;		// Value of the one-half-period counter
		unsigned int counter_freq2;	// 1 - 60MHz; 0 - 600KHz
		unsigned long TimeCalcFromImpulses2; // Ïåðåñ÷åò âðåìåíè èìïóëüñà èç êîëè÷åñòâà Impulses1 è âðåìåíè Time1
		int direction2;	// 1 - direct; 0 - reverse
	} data;

	T_inc_sensor_regs pm67regs;

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

	void (*update_sensors)();
	void (*read_sensors)();
	void (*read_sensor1)();
	void (*read_sensor2)();

} T_inc_sensor;

#define T_INC_SENSOR_DEFAULT {0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, T_INC_SENSOR_REGS_DEFAULTS, inc_sensor_set, update_sensors_data, inc_sensor_read, inc_sensor_read1, inc_sensor_read2}

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

//Public functions

void inc_sensor_set(T_inc_sensor *inc_s);
void inc_sensor_read1(T_inc_sensor *inc_s);
void inc_sensor_read2(T_inc_sensor *inc_s);
void inc_sensor_read(T_inc_sensor *inc_s);
void update_sensors_data(T_inc_sensor *inc_s);


extern T_inc_sensor inc_sensor;
*/


#endif //XP_INCREMENTAL_SENSORS_H