#include "x_serial_bus.h"
#include "xp_cds_out.h"

#include "x_serial_bus.h"
#include "xp_tools.h"


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

void cds_out_init(T_cds_out *v)
{
    if (v->useit == 0) 
	{
	  clear_adr_sync_table(v->plane_address);
	  return ;
	}
	set_adr_sync_table(v->plane_address);

}

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


int cds_out_read_all(T_cds_out *v)
{
 int err = 0;

  if (v->useit == 0) 
	  return 0;

  err = cds_out_read_sbus(v); 
  err |= cds_out_read_pbus(v);

  return err;
}

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


int cds_out_write_all(T_cds_out *v)
{
 int err = 0;

  if (v->useit == 0) 
	  return 0;

  err = cds_out_write_sbus(v); 
  err |= cds_out_write_pbus(v);

  return err;

}

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

int cds_out_write_sbus(T_cds_out *v)
{
	unsigned int old_err, err = 0, err_ready = 0;
	static unsigned int e;
	static unsigned int c_ok=0;
  
    if (v->useit == 0) 
	  return 0;

	e = 0;
	old_err = v->status_serial_bus.count_write_error;
	x_serial_bus_project.slave_addr = v->plane_address; // number plate

//0 data_out
    x_serial_bus_project.reg_addr 	= 0;   				 			// adr memory in plate
	x_serial_bus_project.write_data = v->write.sbus.data_out.all;   // write data

    if  (x_serial_bus_project.write(&x_serial_bus_project))              // make write
	{
		v->status_serial_bus.count_write_error++;
		e |= 1;
	}

//1 enable_protect_out
    x_serial_bus_project.reg_addr 	= 1;   				 			// adr memory in plate
	x_serial_bus_project.write_data = v->write.sbus.enable_protect_out.all;   // write data

    if  (x_serial_bus_project.write(&x_serial_bus_project))              // make write
	{
		v->status_serial_bus.count_write_error++;
		e |= 2;
	}

//6 protect_error
//    if (v->read.type_cds_xilinx == TYPE_CDS_XILINX_SP6)
//        v->write.sbus.protect_error.bit.enable_err_switch = 0; // ��� SP6 ��������� ������ �� �������, �.�. �� ��� ����

    x_serial_bus_project.reg_addr 	= 6;   				 			// adr memory in plate
	x_serial_bus_project.write_data = v->write.sbus.protect_error.all;   // write data

    if  (x_serial_bus_project.write(&x_serial_bus_project))              // make write
	{
		v->status_serial_bus.count_write_error++;
		e |= 4;
	}


//7 cmd_reset_error
/*
    x_serial_bus_project.reg_addr 	= 7;   				 			// adr memory in plate
	x_serial_bus_project.write_data = v->write.sbus.cmd_reset_error;   // write data

    if  (x_serial_bus_project.write(&x_serial_bus_project))              // make write
		v->status_serial_bus.count_error++;
*/

	if (old_err == v->status_serial_bus.count_write_error)// no errors
	{
	  v->status_serial_bus.count_write_ok++;
	  c_ok++;
	  err = 0; // no errors
	}
	else
	{
	  err = 1; // !errors!
	  c_ok = 0;
	}

    err_ready = check_cds_ready_sbus( err, ITS_WRITE_BUS, &v->status_serial_bus);
	set_status_cds(err_ready, &v->status);

	return err_ready;
}

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

int cds_out_write_pbus(T_cds_out *v)
{

  if (v->useit == 0) 
	  return 0;

  return 0;
}

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

int cds_out_read_sbus(T_cds_out *v)
{
	unsigned int old_err, err = 0, err_ready = 0;
  
    if (v->useit == 0) 
	  return 0;

	old_err = v->status_serial_bus.count_read_error;

	x_serial_bus_project.slave_addr = v->plane_address; 			// number plate

//0 data_out
    x_serial_bus_project.reg_addr 	= 0;   				 			// adr memory in plate
	x_serial_bus_project.read(&x_serial_bus_project); 				// read

	if (x_serial_bus_project.flags.bit.read_error == 0) // check error
		v->read.sbus.data_out.all = x_serial_bus_project.read_data;
	else
	 	v->status_serial_bus.count_read_error++;
	  

//1 enable_protect_out
    x_serial_bus_project.reg_addr 	= 1;   				 			// adr memory in plate
	x_serial_bus_project.read(&x_serial_bus_project); 				// read

	if (x_serial_bus_project.flags.bit.read_error == 0) // check error
		v->read.sbus.enable_protect_out.all = x_serial_bus_project.read_data;
	else
	 	v->status_serial_bus.count_read_error++;
	  
//6 protect_error
    x_serial_bus_project.reg_addr 	= 6;   				 			// adr memory in plate
	x_serial_bus_project.read(&x_serial_bus_project); 				// read

	if (x_serial_bus_project.flags.bit.read_error == 0) // check error
		v->read.sbus.protect_error.all = x_serial_bus_project.read_data;
	else
	 	v->status_serial_bus.count_read_error++;
	  
//7 lock_status_error
    x_serial_bus_project.reg_addr 	= 7;   				 			// adr memory in plate
	x_serial_bus_project.read(&x_serial_bus_project); 				// read

	if (x_serial_bus_project.flags.bit.read_error == 0) // check error
		v->read.sbus.lock_status_error.all = x_serial_bus_project.read_data;
	else
	 	v->status_serial_bus.count_read_error++;

//15 current_status_error
    x_serial_bus_project.reg_addr 	= 15;   				 			// adr memory in plate
	x_serial_bus_project.read(&x_serial_bus_project); 				// read

	if (x_serial_bus_project.flags.bit.read_error == 0) // check error
	{
		v->read.type_cds_xilinx	= x_serial_bus_project.read_data & 0x1;
		v->type_cds_xilinx = v->read.type_cds_xilinx;
		v->read.sbus.current_status_error.all = x_serial_bus_project.read_data & 0xfffe;
	}
	else
	 	v->status_serial_bus.count_read_error++;


///////////

	if (old_err == v->status_serial_bus.count_read_error)// no errors
	{
	  v->status_serial_bus.count_read_ok++;
	  err = 0; // no errors
	}
	else
	  err = 1; // !errors!

	err_ready = check_cds_ready_sbus( err, ITS_READ_BUS, &v->status_serial_bus);
	set_status_cds(err_ready, &v->status);

	return err_ready;

}

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

int cds_out_read_pbus(T_cds_out *v)
{
  if (v->useit == 0) 
	  return 0;


  return 0;
}

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

void cds_out_reset_error(T_cds_out *v)
{

    if (v->useit == 0) 
	  return ;

	if (v->status == component_Error || v->status == component_ErrorSBus)
	   v->status = component_Started;
	clear_cur_stat_sbus(&v->status_serial_bus);
	clear_cur_stat_pbus(&v->status_parallel_bus);


	x_serial_bus_project.slave_addr = v->plane_address; // number plate

//7 cmd_reset_error

    x_serial_bus_project.reg_addr 	= 7;   				 			// adr memory in plate
	x_serial_bus_project.write_data = v->write.sbus.cmd_reset_error;   // write data

    if  (x_serial_bus_project.write(&x_serial_bus_project))              // make write
		v->status_serial_bus.count_write_error++;

}

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

void cds_out_store_disable_error(T_cds_out *v)
{
   if (v->useit == 0) 
	  return ;

   v->store_protect_error = v->write.sbus.protect_error.all;
   v->write.sbus.protect_error.all = 0; // disable all error.
   
   cds_out_write_sbus(v);

}

///////////////////////////////////////////////
///////////////////////////////////////////////
void cds_out_restore_enable_error(T_cds_out *v)
{

   if (v->useit == 0) 
	  return ;

   v->write.sbus.protect_error.all = v->store_protect_error; // restore all setup error.   
   cds_out_write_sbus(v);

}

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