#ifndef XP_ROT_SENS_H
#define XP_ROT_SENS_H

#include "x_basic_types.h"
#include "xp_cds_in.h"
#include "xp_cds_rs.h"


//RS speed of angle sensor
#define TS400   0
#define TS350   1
#define TS300   2
#define TS250   3
#define TS200   4

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

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

/////////////////////////////////////////////////////////////
// IN plane
/////////////////////////////////////////////////////////////

// Registers with data for rotation 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_cds_in_comand;

#define R_CDS_IN_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_cds_in_comand comand_reg;

} T_cds_in_rotation_sensor_read_regs;

#define T_CDS_IN_ROTATION_SENSOR_READ_REGS_DEFAULTS {0,0,0,0, 0,0,0,0, R_CDS_IN_COMAND_DEFAULT}

typedef struct {
	T_cds_in_comand comand_reg;

} T_cds_in_rotation_sensor_write_regs;

#define T_CDS_IN_ROTATION_SENSOR_WRITE_REGS_DEFAULTS {R_CDS_IN_COMAND_DEFAULT}

/////////////////////////////////////////////////////////////
//read reg parallel bus
/////////////////////////////////////////////////////////////
typedef struct {
    union {
		unsigned int all;
		struct {
			int sensor1:4;
			int sensor2:4;
			unsigned int sens_err1:1;
			unsigned int sens_err2:1;
			unsigned int reserved:6;
		} bit;
	} direction;

} T_cds_in_rotation_sensor_read_pbus;

#define T_CDS_IN_ROTATION_SENSOR_READ_PBUS_DEFAULTS {0}

/////////////////////////////////////////////////////////////
//  write serial bus reg
/////////////////////////////////////////////////////////////
typedef struct {
	//0
	union
	{
		UInt16 all;
		struct{
			UInt16 discret : 8;
			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_inputs;

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

} T_cds_in_rotation_sensor_write_sbus;

#define T_CDS_IN_ROTATION_SENSOR_WRITE_SBUS_DEFAULTS {0, 0, 0}

////////////////////////////////////////////////////////
typedef struct {
	T_cds_in_rotation_sensor_read_pbus pbus;
	T_cds_in_rotation_sensor_read_regs regs;
}T_cds_in_rotation_sensor_read;

#define T_CDS_IN_ROTATION_SENSOR_READ_DEFAULTS \
		{T_CDS_IN_ROTATION_SENSOR_READ_PBUS_DEFAULTS, \
		T_CDS_IN_ROTATION_SENSOR_READ_REGS_DEFAULTS}

typedef struct {
	T_cds_in_rotation_sensor_write_sbus sbus;
	T_cds_in_rotation_sensor_read_regs regs;
}T_cds_in_rotation_sensor_write;

#define T_CDS_IN_ROTATION_SENSOR_WRITE_DEFAULTS \
			{T_CDS_IN_ROTATION_SENSOR_WRITE_SBUS_DEFAULTS, \
			T_CDS_IN_ROTATION_SENSOR_WRITE_REGS_DEFAULTS}


////// Rotation sensor with IN plane
typedef struct {
	//UInt16 plane_address;
	unsigned int count_wait_for_update_registers;
	unsigned int error_update;

	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
		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
		int direction2;	// 1 - direct; 0 - reverse
	} out;

	T_cds_in *cds_in;

	T_cds_in_rotation_sensor_write write;
	T_cds_in_rotation_sensor_read read;

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

	void (*read_sensor1)();

	void (*read_sensor2)();

} T_cds_in_rotation_sensor;

#define T_CDS_IN_ROTATION_SENSOR_DEFAULT 	\
			{0, 0,	\
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
			NULL, \
			T_CDS_IN_ROTATION_SENSOR_WRITE_DEFAULTS, \
			T_CDS_IN_ROTATION_SENSOR_READ_DEFAULTS, \
			in_plane_set, \
			in_sensor_read1, \
			in_sensor_read2}


///////////////////////////////////////////////////////////////////////////
///// Rotation Plane
///////////////////////////////////////////////////////////////////////////
typedef union {
	unsigned int all;
	struct {
		unsigned int survey_time:8;	//Ïåðèîä îïðîñà ïî 10ìêñ (0==10, 1==20,...)
		unsigned int channel4_enable:1;
		unsigned int channel3_enable:1;
		unsigned int channel2_enable:1;
		unsigned int channel1_enable:1;
		unsigned int transmition_speed:3;
		unsigned int plane_is_master:1;
	}bit;
} T_cds_rotation_plane_config;

#define T_CDS_ROTATION_PLANE_CONFIG_DEFAULT 0xA031	//{49, 1, 0, 0, 0, 2, 1}

typedef struct {
	T_cds_rotation_plane_config config;
} T_cds_rotation_plane_write_sbus;

#define T_CDS_ROTATION_PLANE_WRITE_SBUS_DEFAULT \
			{T_CDS_ROTATION_PLANE_CONFIG_DEFAULT}

typedef struct {
	int direction;
	unsigned int turned_angle;
	unsigned int angle;
} RsSensor;

#define SENSOR_DEFAULT {0, 0, 0}

typedef struct {
	RsSensor sensor[4];
} T_cds_rotation_plane_read_pbus;

#define T_CDS_ROTATION_PLANE_READ_PBUS_DEFAULT { \
			{SENSOR_DEFAULT, SENSOR_DEFAULT, SENSOR_DEFAULT, SENSOR_DEFAULT}}

typedef struct {
	T_cds_rotation_plane_config config;
} T_cds_rotation_plane_read_sbus;

#define T_CDS_ROTATION_PLANE_READ_SBUS_DEFAULT {T_CDS_ROTATION_PLANE_CONFIG_DEFAULT}

typedef struct {
	T_cds_rotation_plane_write_sbus sbus;
} T_cds_rotation_plane_write;

#define T_CDS_ROTATION_PLANE_WRITE_DEFAULT \
			{T_CDS_ROTATION_PLANE_WRITE_SBUS_DEFAULT}

typedef struct {
	T_cds_rotation_plane_read_pbus pbus;
	T_cds_rotation_plane_read_sbus sbus;
} T_cds_rotation_plane_read;

#define T_CDS_ROTATION_PLANE_READ_DEFAULT \
			{T_CDS_ROTATION_PLANE_READ_PBUS_DEFAULT, T_CDS_ROTATION_PLANE_READ_SBUS_DEFAULT}

typedef struct {
    
	struct {
		unsigned long Delta_angle1;
		unsigned long Delta_angle2;
		unsigned long Delta_angle3;
		unsigned long Delta_angle4;
		unsigned long Current_angle1;
		unsigned long Current_angle2;
		unsigned long Current_angle3;
		unsigned long Current_angle4;
		unsigned int survey_time_mks;	//Âðåìß îïðîñà äàò÷èêà â ìêñ
		unsigned int direction;
	} out;

	unsigned int error;

	T_cds_rs *cds_rs;

	T_cds_rotation_plane_read read;
	T_cds_rotation_plane_write write;

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

	void (*read_sensor)();

} T_cds_angle_sensor;

#define T_CDS_ANGLE_SENSOR_DEFAULT {	\
			{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
			0, NULL, \
			T_CDS_ROTATION_PLANE_READ_DEFAULT, \
			T_CDS_ROTATION_PLANE_WRITE_DEFAULT, \
			angle_plane_set, angle_sensor_read}


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

typedef struct {
	UInt16 use_sensor1;
	UInt16 use_sensor2;
	UInt16 use_angle_plane;

	T_cds_in_rotation_sensor in_plane;
	T_cds_angle_sensor rotation_plane;

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

} T_rotation_sensor;

#define T_CDS_ROTATION_SENSOR_DEFAULTS {0, 0, 0,  \
				T_CDS_IN_ROTATION_SENSOR_DEFAULT, \
				T_CDS_ANGLE_SENSOR_DEFAULT, \
				rot_sensor_set, \
				sensor_read, \
				update_sensors_data_r}

//Public functions
void rot_sensor_set(T_rotation_sensor *rs);
void sensor_read(T_rotation_sensor *rs);
void update_sensors_data_r(T_rotation_sensor *rs);
void angle_plane_set(T_cds_angle_sensor *rs);
void angle_sensor_read(T_cds_angle_sensor *as);
void in_plane_set(T_cds_in_rotation_sensor* rs);
void in_sensor_read1(T_cds_in_rotation_sensor *rs);
void in_sensor_read2(T_cds_in_rotation_sensor *rs);


extern T_rotation_sensor rotation_sensor;

#endif //XP_ROT_SENS_H