#include <project.h>

#include "DSP281x_Examples.h"   // DSP281x Examples Include File
#include "DSP281x_SWPrioritizedIsrLevels.h"   // DSP281x Examples Include File
#include "DSP281x_Device.h"
#include "MemoryFunctions.h"
#include "Spartan2E_Adr.h"
//#include "xerror.h"

//#include "SpaceVectorPWM.h"
//#include "v_pwm24_v2.h"
//#include "PWMTools.h"



#define SelectLoadXilinx()			WriteOper(0,0,0,1)

//#define TypeAccess_Is_SerialBus 21

#define dat_xilinx_line_do(bitb) \
							     GpioDataRegs.GPEDAT.bit.GPIOE0=bitb

#define setup_xilinx_line_do_on() \
							   GpioMuxRegs.GPEDIR.bit.GPIOE0=1;\
                               GpioDataRegs.GPEDAT.bit.GPIOE0=1

#define reset_xilinx()				WriteOper(1,1,0,1)

#define XSEEPROM_WRITE_REPEAT	3
#define XSEEPROM_READ_REPEAT	3
#define XSEEPROM_MAX_ERROR_CONSECUTIVE_FRAME 20	// threshold
#define XSEEPROM_MIN_LENTH 7 // max 7 => 1 word = 2 byte

#define XSEEPROM_MAX_ERROR_CONSECUTIVE_BREAK   (XSEEPROM_MAX_ERROR_CONSECUTIVE_FRAME + 10)

#define xseeprom_pause  { }

#pragma DATA_SECTION(xeeprom_controll_fast,".fast_vars");
unsigned int xeeprom_controll_fast;

//XSerial_bus XSerial_bus0;
//Xmemory_uni Xmemory_uni0;

//XSerial_bus_stats  XSerial_bus_stats0;

#pragma DATA_SECTION(Controll, ".fast_vars");
XControll_reg Controll;

unsigned int xeeprom_controll_store;

void write_bit_xilinx(unsigned char bitb);
int xseeprom_read_all(unsigned int Mode_is_Verify, XSeeprom_t * Ptr);
int xseeprom_write_all(XSeeprom_t * Ptr);
void xseeprom_adr(unsigned int adr);
//unsigned int xseeprom_case_xilinx (void);
void xseeprom_delay(void);
void xseeprom_init(void);
void xControll_wr();
unsigned int xseeprom_read_byte(unsigned int use_ack);
void xseeprom_set_mode_ON (unsigned int set_mode);
void xseeprom_start(void);
void xseeprom_stop(void);
void xseeprom_undo (void);
unsigned int xseeprom_write_byte(unsigned int byte);
void xseeprom_clk  (unsigned int clk);
unsigned int xseeprom_din (void);
void xseeprom_dout (unsigned int data);
void xseeprom_mode_wr (unsigned int mode);
void ResetPeriphPlane();


unsigned int time = 0;

void write_byte_xilinx(unsigned char bx)
{
  int i;

  for (i=0;i<=7;i++)
    write_bit_xilinx( (bx >> i) & 1);

}

void write_bit_xilinx(unsigned char bitb)
{
	pause_1000(1);
	EALLOW;
	
	GpioDataRegs.GPBDAT.bit.GPIOB8=1;
	dat_xilinx_line_do(bitb);
	
	pause_1000(1);
	GpioDataRegs.GPBDAT.bit.GPIOB8=0;
	
	pause_1000(1);
	GpioDataRegs.GPBDAT.bit.GPIOB8=1;
	EDIS;
}

void setup_xilinx_line()
{
    EALLOW;
	GpioMuxRegs.GPBMUX.bit.CAP4Q1_GPIOB8=0; 
	GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9=0;


    GpioMuxRegs.GPBDIR.bit.GPIOB8=1;
	GpioMuxRegs.GPADIR.bit.GPIOA9=0;
	GpioDataRegs.GPBDAT.bit.GPIOB8=1;

 // init line
    GpioMuxRegs.GPEMUX.bit.XNMI_XINT13_GPIOE2=0; // as io
    GpioMuxRegs.GPEDIR.bit.GPIOE2 = 0;           // as input

	setup_xilinx_line_do_on();

    EDIS;    
}

unsigned int read_init_xilinx()
{
  unsigned int i;
  EALLOW;
    i=GpioDataRegs.GPEDAT.bit.GPIOE2;
  EDIS;
  return (i);
}

unsigned int read_done_xilinx()
{
unsigned int i;
  EALLOW;
    i=GpioDataRegs.GPADAT.bit.GPIOA9;
  EDIS;
  return (i);
}

long xverify_remote_eeprom(unsigned int adr_device, unsigned long adr, 
                         unsigned long adr_eeprom, unsigned long size, unsigned long *ok_write, 
                         unsigned long *write_error, unsigned long *repeat_error )
{
  int i;
  static XSeeprom_t rom;
  unsigned long repeat_er=0;
  unsigned int er_wr=0;
  unsigned int er_rd=0;

  rom.Adr_device=adr_device;
  rom.Adr=adr;
  rom.Adr_seeprom=adr_eeprom;
  rom.size=size;

  if (er_wr)
    return 0;

    for (i=0; i<XSEEPROM_WRITE_REPEAT; i++) {
      er_rd=xseeprom_read_all(1,&rom);
      repeat_er+=rom.repeat_error;
	  if((rom.repeat_error==0) && (er_rd==0))
	    break;
    }
	*ok_write=rom.ok_write;
	*repeat_error=repeat_er;
	*write_error=((unsigned long)(rom.write_error<<8)) | ((unsigned long)(er_wr & 0x000f)) | ((unsigned long)(er_rd<<4 & 0x00f0));

    if (rom.write_error != 0) 
	  xerror(xseeprom_er_ID(3),(void *)0);

    if(er_rd!=0) 
  	  xerror(xseeprom_er_ID(2),(void *)0);

    return 0;
}

long xread_remote_eeprom(unsigned int adr_device, unsigned long adr_eeprom, 
                         unsigned long adr,  unsigned long size, unsigned long *ok_write, 
                         unsigned long *write_error, unsigned long *repeat_error ){
  int i;
  static XSeeprom_t rom;
  unsigned int er_wr=0;
  unsigned int er_rd=0;
  unsigned long repeat_er=0;

  rom.Adr_device=adr_device;
  rom.Adr=adr;
  rom.Adr_seeprom=adr_eeprom;
  rom.size=size;

  
    for (i=0; i<XSEEPROM_WRITE_REPEAT; i++) {
      er_rd=xseeprom_read_all(0,&rom);
      repeat_er+=rom.repeat_error;
	  if((rom.repeat_error==0) && (er_rd==0))
	    break;
    }
	*ok_write=rom.ok_write;
	*repeat_error=repeat_er;
	*write_error=(unsigned long)((er_wr & 0x000f) | (er_rd<<4 & 0x00f0));

    if(er_rd!=0) 
  	  xerror(xseeprom_er_ID(2),(void *)0);
  

    return 0;
}

int xflash_remote_eeprom(unsigned int adr_device, unsigned long adr, 
                         unsigned long adr_eeprom, unsigned long size, unsigned long *ok_write, 
                         unsigned long *write_error, unsigned long *repeat_error )
{
  int i;
  static XSeeprom_t rom;
  unsigned long repeat_er=0;
  unsigned int er_wr=0;
  unsigned int er_rd=0;
  unsigned int old_started=0;

  rom.Adr_device=adr_device;
  rom.Adr=adr;
  rom.Adr_seeprom=adr_eeprom;
  rom.size=size;

  old_started = x_parallel_bus_project.flags.bit.started;
  project_stop_parallel_bus();

  xseeprom_set_mode_ON(1); // on work with Spartan200E
    for (i=0; i<XSEEPROM_WRITE_REPEAT; i++) {
      er_wr=xseeprom_write_all(&rom);
      repeat_er+=rom.repeat_error;
	  if((rom.repeat_error==0) && (er_wr==0))
	    break;
    }
    *ok_write=rom.ok_write;
	*repeat_error=repeat_er;
	*write_error=(unsigned long)((er_wr & 0x000f) | (er_rd<<4 & 0x00f0));

    if(er_wr) 
  	  return xerror(xseeprom_er_ID(1),(void *)0);

//    if (er_wr)
//    return 0;

    for (i=0; i<XSEEPROM_WRITE_REPEAT; i++) {
      er_rd=xseeprom_read_all(1,&rom);
      repeat_er+=rom.repeat_error;
	  if((rom.repeat_error==0) && (er_rd==0))
	    break;
    } 

	xseeprom_set_mode_ON(0); 
	*ok_write=rom.ok_write;
	*repeat_error=repeat_er;
	*write_error=((unsigned long)(rom.write_error<<8)) | ((unsigned long)(er_wr & 0x000f)) | ((unsigned long)(er_rd<<4 & 0x00f0));

    if(er_rd) 
  	  xerror(xseeprom_er_ID(2),(void *)0);

    if (rom.write_error) 
	  xerror(xseeprom_er_ID(3),(void *)0);

	project_reload_all_plates(WITHOUT_RESET_ALL_PLATES_NO_STOP_ERROR);//wait_start_cds + load_cfg

	

	i_WriteMemory(ADR_BUS_ERROR_READ,	0);

	if(i_ReadMemory(ADR_ERRORS_TOTAL_INFO)) //���� �� ������ �������� ������.
	{
//		xerror(main_er_ID(1),(void *)0);
	}
		
	i_WriteMemory(ADR_CONTR_REG_FOR_WRITE, 0xffff);

	if (old_started)
	  project_start_parallel_bus();

    return 0; // no error
}

int load_xilinx_new(unsigned long adr,unsigned long size)
{
  unsigned int wx;
  unsigned long adr_x; 

  unsigned long adr_int;
  unsigned int done_line;
  volatile unsigned int Value;

  setup_xilinx_line();

  reset_xilinx();
  pause_1000(100);

// controll levels on line INIT and DONE

  Value=read_init_xilinx();  // there must be level '0'
  if(Value != 0)
	return xerror(xtools_er_ID(1),(void *)0);

  Value=read_done_xilinx();  // there must be level '0'
  if(Value != 0)
	return xerror(xtools_er_ID(2),(void *)0);
  
  SelectLoadXilinx();
  pause_1000(100);

  Value=read_init_xilinx();  // there must be level '1'
  if(Value != 1)
	return xerror(xtools_er_ID(1),(void *)0);

// down peripheral frequency
//  Clk_mode_store=XintfRegs.XINTCNF2.bit.CLKMODE;
//  xfrequency_peripheral_is_slow(1);

  adr_int= size+1-10;

// fast part of loading 
   for (adr_x=0;adr_x<adr_int;adr_x++)
  {
    wx=i_ReadMemory(adr_x+adr);
    write_byte_xilinx( (wx>>8) & 0xff);
	write_byte_xilinx( wx & 0xff);
  }


// slow part of loading
  adr_x=adr_int;
  wx=i_ReadMemory(adr_x+adr);
  write_byte_xilinx( (wx>>8) & 0xff);
  pause_1000(10000);
  write_byte_xilinx( wx & 0xff);
  pause_1000(10000);
  adr_int++;

//  final part of loading
  for (adr_x=adr_int;adr_x<(size+1);adr_x++)
  {
    unsigned int bx;
	int i;

    done_line=read_done_xilinx();
	if(done_line==1)
	  break;

    wx=i_ReadMemory(adr_x+adr);
    bx=(wx>>8) & 0xff;
    for (i=0;i<=7;i++)
	{
      write_bit_xilinx( (bx >> i) & 1);
      done_line=read_done_xilinx();
	  if(done_line==1)
	    break;
    } 
    if(done_line==1)
      break;

    wx=i_ReadMemory(adr_x+adr);
    bx= wx & 0xff;
    for (i=0;i<=7;i++)
	{
      write_bit_xilinx( (bx >> i) & 1);
      done_line=read_done_xilinx();
	  if(done_line==1)
	    break;
    } 
    if(done_line==1)
      break;
  }
// configure line DO as input    
//  EALLOW;
//  setup_xilinx_line_do_off();
//  EDIS;


// activation part of loading
// restore peripheral frequency
//  xfrequency_peripheral_is_slow(Clk_mode_store);


  // DONE activate on clock 2

  write_bit_xilinx(1); // clock 3, activate GWE

  write_bit_xilinx(1); // clock 4, activate GSR

  write_bit_xilinx(1); // clock 5, activate GTS.  Led is work.

  write_bit_xilinx(1); // clock 6,  activate DLL

  write_bit_xilinx(0); // clock 7

  write_bit_xilinx(1); 
  pause_1000(100);

  write_bit_xilinx(0); 
  pause_1000(100);

// controll line DONE
  Value=read_done_xilinx();  // there must be level '1'
  if(Value != 1)
	return xerror(xtools_er_ID(2),(void *)0);

// pause for DLL in Xilinx
  pause_1000(10000);   

  return 0;
}



int xseeprom_write_all(XSeeprom_t * Ptr)
{

 union XSeeprom_command_reg  command;
 unsigned int data;
 unsigned int i;
 unsigned int er=0;
 unsigned long er_ack=0;
 unsigned int er_for_one_pack=0;
 unsigned int er_consecutive=0;
 unsigned long adr_x=Ptr->Adr;
 unsigned long adr_eeprom=Ptr->Adr_seeprom;
 unsigned int count_word=128;
 unsigned int wx;

 command.bit.bit7=1;
 command.bit.bit6=0;
 command.bit.bit5=1;
 command.bit.bit4=0;
 command.bit.bit3=0;
 command.bit.A1=1;
 command.bit.WR0=0;

 Ptr->ok_write=0;
 Ptr->repeat_error=0;
 Ptr->write_error=0;

  xseeprom_init();
  pause_1000(100);
  xseeprom_adr(Ptr->Adr_device);
 // xseeprom_set_mode_ON(1);

  xeeprom_controll_fast=Controll.all;

  pause_1000(100);

  while ((adr_x-Ptr->Adr)<(Ptr->size)) { // while size
    er=0;
    for(;;){  
  	  Led2_Toggle();
      xseeprom_start(); 
      command.bit.P0=(adr_eeprom>>15 & 0x0001);
      er=xseeprom_write_byte(command.all);
  	  if(er)
  	    break;
  
      data=adr_eeprom>>7 & 0x00ff;
      er=xseeprom_write_byte(data);
  	  if(er)
  	    break;
  
      data=adr_eeprom<<1 & 0x00ff;
      er=xseeprom_write_byte(data);
  	    break;
    }  
         
    i=0;
    while ( (i<count_word) && (er == 0) && ((adr_x+i-Ptr->Adr)<(Ptr->size)) && ((adr_eeprom<<1 & 0x00ff)+2*i < 0x00ff) ) {
      wx=i_ReadMemory(adr_x+i);
      er=xseeprom_write_byte(wx>>8);
  	  if(er)
  	    break;
      er=xseeprom_write_byte(wx);
  	  if(er)
  	    break;
      i+=1;
    }  

    xseeprom_stop();
    xseeprom_delay();
  
    if (er == 0) {
      adr_x+=i;
	  adr_eeprom+=i;
	  Ptr->ok_write+=i;
	  er_consecutive=0;
    } else {
	  er_consecutive++;
	  er_ack++;
	  if (er_consecutive > XSEEPROM_MAX_ERROR_CONSECUTIVE_FRAME) {
        if (er_for_one_pack < XSEEPROM_MIN_LENTH) {
          er_for_one_pack +=1;
	      er_consecutive=0;
        }
	  }
      Led1_Toggle();
    }

    switch (er_for_one_pack) { 
      case 0   :  count_word = 128; break;
      case 1   :  count_word = 64; break;
      case 2   :  count_word = 32; break;
      case 3   :  count_word = 16; break;
      case 4   :  count_word = 8; break;
      case 5   :  count_word = 4; break;
      case 6   :  count_word = 2; break;
      case 7   :  count_word = 1; break;
      default  :  break;
     } 

     Ptr->repeat_error=er_ack;
	 if(er_consecutive > XSEEPROM_MAX_ERROR_CONSECUTIVE_BREAK) {
       xseeprom_undo();
	   return(4);
	 }
  } // while size
  xseeprom_undo();
  return 0;
}

int xseeprom_read_all(unsigned int Mode_is_Verify, XSeeprom_t * Ptr)
{
 union XSeeprom_command_reg  command;
 unsigned int data;
// unsigned int i;

 unsigned long i;

 unsigned int er;
 unsigned long er_ack=0;
 unsigned int er_consecutive=0;
 unsigned long adr_x=Ptr->Adr;
 unsigned long adr_eeprom=Ptr->Adr_seeprom;
 unsigned int count_word=128;
 unsigned int data_rd;
 unsigned int wx;

 command.bit.bit7=1;
 command.bit.bit6=0;
 command.bit.bit5=1;
 command.bit.bit4=0;
 command.bit.bit3=0;
 command.bit.A1=1;

 Ptr->ok_write=0;
 Ptr->repeat_error=0;
 Ptr->write_error=0;

  xseeprom_init();
  xseeprom_adr(Ptr->Adr_device);
 // xseeprom_set_mode_ON(1);
  
  xeeprom_controll_fast=Controll.all;
  

  pause_1000(100);

  while ((adr_x-Ptr->Adr)<(Ptr->size)) { // while size
    er=0;
    for(;;){  
  	  Led2_Toggle();
      xseeprom_start(); 
      command.bit.P0=(adr_eeprom>>15 & 0x0001);
	  command.bit.WR0=0;
      er=xseeprom_write_byte(command.all);
  	  if(er)
  	    break;
  
      data=adr_eeprom>>7 & 0x00ff;
      er=xseeprom_write_byte(data);
  	  if(er)
  	    break;
  
      data=adr_eeprom<<1 & 0x00ff;
      er=xseeprom_write_byte(data);
  	  if(er)
  	    break;

      xseeprom_start(); 
      command.bit.WR0=1;
      er=xseeprom_write_byte(command.all);
	  break;
    }  
         
    i=0;
    while ( (i<count_word) && (er == 0) && ((adr_x-Ptr->Adr)<(Ptr->size)) && (( adr_eeprom<<1 & 0x00ff)+2*i < 0x00ff) ) {
	  data_rd=xseeprom_read_byte(1);
	  data_rd<<=8;
	  if( ((i+1)!=count_word) && ((adr_x-Ptr->Adr)<(Ptr->size-1)) && ((adr_eeprom<<1 & 0x00ff)+2*i+1 < 0x00ff) )
        data_rd|=xseeprom_read_byte(1);  // use ack
      else
        data_rd|=xseeprom_read_byte(0);  // don't use ack
      if(Mode_is_Verify==0)
      {
	    i_WriteMemory((adr_x),data_rd);
      }
      else {
        wx=i_ReadMemory(adr_x);
  	    if(wx!=data_rd)
  	      Ptr->write_error++;
      }
      i++;
	  adr_x++;
    }  

    xseeprom_stop();
//    xseeprom_delay();
  
    if (er == 0) {
	  adr_eeprom+=i;
	  Ptr->ok_write+=i;
	  er_consecutive=0;
    } else {
	  er_consecutive++;
	  er_ack++;
      Led1_Toggle();
    }

     Ptr->repeat_error=er_ack;
	 if(er_consecutive > XSEEPROM_MAX_ERROR_CONSECUTIVE_BREAK) {
       xseeprom_undo();
	   return(4);
	 }
  } // while size
	ResetPeriphPlane();
  xseeprom_undo();
  return 0;
}

void xseeprom_adr(unsigned int adr)
{
  Controll.bit.line_P7_4_Sorce_Is_Tms=1;
  Controll.bit.line_P7_4_Is=adr;
  xControll_wr();
}

void xseeprom_delay(void)
{
	pause_1000(10000);
}

void ResetPeriphPlane()
{
	Controll.bit.line_P7_4_Is = 0xf;
//	Controll.bit.RemotePlane_Is_Reset = 1;
	xControll_wr();
	pause_1000(10000);
//	Controll.bit.RemotePlane_Is_Reset = 0;
	Controll.bit.line_P7_4_Is = 0x0;
	xControll_wr();
}

void xseeprom_init(void)
{
  xeeprom_controll_store=Controll.all;
  Controll.bit.line_CLKS_Sorce_Is_Tms=1;
  Controll.bit.line_CLKS_Is=1;
  Controll.bit.line_ER0_OUT_Sorce_Is_Tms=1;
  Controll.bit.line_ER0_OUT_Is=1;
  Controll.bit.line_P7_4_Sorce_Is_Tms=1;
  Controll.bit.line_P7_4_Is=0xf;
  Controll.bit.line_Z_ER0_OUT_Is=0; // read
  Controll.bit.line_SET_MODE_Is=0; // off
 // ����� ������� �� �����
  Controll.bit.OE_BUF_Is_ON=0;//1;
 // ���� ����� � ������������ ����  
  Controll.bit.RemotePlane_Is_Reset=0;
  xControll_wr();
}

void xControll_wr()
{
  i_WriteMemory(ADR_CONTR_REG_FOR_WRITE, Controll.all);
}
/*
unsigned int xseeprom_case_xilinx (void) {
 xinput_new_uni_rd_status(&Xinput_new_uni_tms0);
   return Xinput_new_uni_tms0.ChanalsPtr.ChanalPtr[XINPUT_NEW_TMS0_NUMBER_LINE_CASE_XILINX].rd_status; 
}
*/
unsigned int xseeprom_read_byte(unsigned int use_ack){
  int i;
  unsigned int data=0;

  xseeprom_dout(1);
  xseeprom_mode_wr(0);
  for (i=7;i>=0;i--)
  {
    xseeprom_pause
    xseeprom_clk(1);
    xseeprom_pause
	data=data<<1|(xseeprom_din() & 0x0001);
    xseeprom_clk(0);
    xseeprom_pause
  }
  
  pause_1000(10);
  
  xseeprom_mode_wr(1);
  xseeprom_dout(!use_ack);  // ack
  xseeprom_pause
  xseeprom_clk(1);
  xseeprom_pause
  xseeprom_clk(0);
  xseeprom_pause
  xseeprom_dout(1);
  xseeprom_mode_wr(0);

  
  pause_1000(10);
  return data;  
}

void xseeprom_set_mode_ON (unsigned int set_mode) {
  Controll.bit.line_SET_MODE_Is=~set_mode;
  xControll_wr();
}

void xseeprom_start(void) {
  xseeprom_clk(1);
  xseeprom_dout(1);
  xseeprom_mode_wr(1);
  xseeprom_pause
  xseeprom_dout(0); // start
  xseeprom_pause
  xseeprom_clk(0);
  xseeprom_pause
}

void xseeprom_stop(void) {
  xseeprom_mode_wr(1);
  xseeprom_dout(0);
  pause_1000(10);
  xseeprom_clk(1);
  pause_1000(10);
  xseeprom_dout(1);
  pause_1000(10);
}

void xseeprom_undo (void){
  Controll.all=xeeprom_controll_store;
  Controll.bit.OE_BUF_Is_ON=1;
  xControll_wr();
}

unsigned int xseeprom_write_byte(unsigned int byte){
  int i;
  unsigned int ack;

  xseeprom_mode_wr(1); 
  for (i=7;i>=0;i--)
  {
    xseeprom_dout((byte >> i) & 1);
    xseeprom_pause
    xseeprom_clk(1);
    xseeprom_pause
    xseeprom_clk(0);
    xseeprom_pause
  }

  xseeprom_dout(1);
  xseeprom_mode_wr(0);
  pause_1000(10);
  
  xseeprom_pause
  xseeprom_clk(1);
  pause_1000(10);
  xseeprom_pause
  ack=xseeprom_din();
  xseeprom_clk(0);
  xseeprom_pause
  
  pause_1000(10);

  /*
//  xseeprom_dout(1);
  xseeprom_mode_wr(0);
  pause_1000(10);
  
//  xseeprom_mode_wr(0);
  xseeprom_dout(1);
  xseeprom_pause
  xseeprom_clk(1);
  xseeprom_pause
  ack=xseeprom_din();
  xseeprom_clk(0);
  xseeprom_pause
  
  pause_1000(10);
  */
  return ack;  // '0' - ok!
}

void xseeprom_clk  (unsigned int clk) {
    xeeprom_controll_fast&=0xfdff;
	xeeprom_controll_fast|=(clk<<9 & 0x0200);
    i_WriteMemory(ADR_CONTR_REG_FOR_WRITE,xeeprom_controll_fast);
}

unsigned int xseeprom_din (void) {
    return (i_ReadMemory(ADR_CONTR_REG_FOR_READ)>>15 & 0x0001);
}

void xseeprom_dout (unsigned int data) {
    xeeprom_controll_fast&=0xff7f;
	xeeprom_controll_fast|=(data<<7 & 0x0080);
    i_WriteMemory(ADR_CONTR_REG_FOR_WRITE,xeeprom_controll_fast);
}

void xseeprom_mode_wr (unsigned int mode) { // '1' - write, '0' - read
    xeeprom_controll_fast&=0xffef;
	xeeprom_controll_fast|=(mode<<4 & 0x0010);
    i_WriteMemory(ADR_CONTR_REG_FOR_WRITE,xeeprom_controll_fast);
}





/***********************  example ******************************************
*  i=xilinx_live_smart(0x5aaa);
*    i=i|xilinx_live_smart(0x0000)
***************************************************************************/
unsigned int xilinx_live_smart(unsigned int d) // dout(15:0) = din(11:8) & din(15:12) & not din(7:0);
{
  unsigned int dout;
  unsigned int d_rd;

  i_WriteMemory(ADR_XTEST_REG,d);
  dout = ~d;
  d_rd = i_ReadMemory(ADR_XTEST_REG);
  if (d_rd!=dout) 
    return 1;
  return 0;
}



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

int enable_er0_control(void)
{
	return xilinx_live_smart(0x5AA5);
}



int test_xilinx_live(void)
{
  unsigned int i;
  //test xilinx controller on read/write operation
  for(i=0;i<10000;i++)
      if(xilinx_live_smart(i))
        return xerror(main_er_ID(1),(void *)0);
  return 0;
}

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


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