#include "CAN_Setup.h"     // DSP281x Headerfile Include File

#include "modbus_table_v2.h"
#include "DSP281x_Examples.h"   // DSP281x Examples Include File
#include "DSP281x_Device.h"
#include "global_time.h"
#include "TuneUpPlane.h"




int CanTimeOutErrorTR = 0;
int enable_can_recive_after_units_box = 0;
int flag_enable_can_from_mpu=0;
int flag_enable_can_from_terminal=0;
long time_pause_enable_can_from_mpu=0;
long time_pause_enable_can_from_terminal=0;

//unsigned long    can_base_adr_terminal, can_base_adr_units, can_base_adr_mpu1, can_base_adr_alarm_log;

unsigned int  enable_profile_led1_can = 1;
unsigned int  enable_profile_led2_can = 0;

#pragma DATA_SECTION(cycle,".slow_vars")
CYCLE cycle[UNIT_QUA];


#pragma DATA_SECTION(new_cycle_fifo,".slow_vars")
NEW_CYCLE_FIFO new_cycle_fifo;

#pragma DATA_SECTION(fifo,".slow_vars")
#pragma DATA_SECTION(refo,".slow_vars")
FIFO fifo, refo;




#pragma DATA_SECTION(BUSY,".slow_vars")
int BUSY = 0;


#pragma DATA_SECTION(Unites, ".slow_vars")
int Unites[UNIT_QUA_UNITS][UNIT_LEN];

#pragma DATA_SECTION(TerminalUnites, ".slow_vars")
int TerminalUnites[TERMINAL_UNIT_QUA_UNITS][TERMINAL_UNIT_LEN];

#pragma DATA_SECTION(CanOpenUnites, ".slow_vars")
int CanOpenUnites[CANOPENUNIT_LEN];


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


//#pragma DATA_SECTION(CAN_timeout,".slow_vars")
#pragma DATA_SECTION(CAN_timeout,".fast_vars")
// ������ ��������� ������ � �����������
int CAN_timeout[UNIT_QUA];
//
#pragma DATA_SECTION(CAN_request_sent,".slow_vars")
int CAN_request_sent[UNIT_QUA];
//
#pragma DATA_SECTION(CAN_answer_wait,".slow_vars")
int CAN_answer_wait[UNIT_QUA];
//
#pragma DATA_SECTION(CAN_no_answer,".slow_vars")
int CAN_no_answer[UNIT_QUA];

// ��� ����� �� �����������, �� ������� ����� �������
#pragma DATA_SECTION(CAN_refresh_cicle,".slow_vars")
int CAN_refresh_cicle[UNIT_QUA];
// ����� ���������� ����� �������
#pragma DATA_SECTION(CAN_count_cycle_input_units,".slow_vars")
int CAN_count_cycle_input_units[UNIT_QUA_UNITS];

#pragma DATA_SECTION(CAN_timeout_cicle,".fast_vars")
//#pragma DATA_SECTION(CAN_timeout_cicle, ".slow_vars")
// �������
int CAN_timeout_cicle[UNIT_QUA];



///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
#pragma DATA_SECTION(unites_can_setup, ".slow_vars")
UNITES_CAN_SETUP unites_can_setup = UNITES_CAN_SETUP_DEFAULT;
#pragma DATA_SECTION(mpu_can_setup, ".slow_vars")
MPU_CAN_SETUP mpu_can_setup = MPU_CAN_SETUP_DEFAULT;
#pragma DATA_SECTION(terminal_can_setup, ".slow_vars")
TERMINAL_CAN_SETUP terminal_can_setup = TERMINAL_CAN_SETUP_DEFAULT;
#pragma DATA_SECTION(alarm_log_can_setup, ".slow_vars")
ALARM_LOG_CAN_SETUP alarm_log_can_setup = ALARM_LOG_CAN_SETUP_DEFAULT;


#pragma DATA_SECTION(mailboxs_can_setup, ".slow_vars")
MAILBOXS_CAN_SETUP mailboxs_can_setup = MAILBOXS_CAN_SETUP_DEFAULT;

#pragma DATA_SECTION(canopen_can_setup, ".slow_vars")
CANOPEN_CAN_SETUP canopen_can_setup = CANOPEN_CAN_SETUP_DEFAULT;



/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
int init_units_can_boxs(UNITES_CAN_SETUP *p)
{
  int c,e;

  e=0;
  for (c=0;c<MAX_COUNT_UNITES_UKSS;c++)
  {
	if (p->active_box[c])
	{
	  p->adr_box[c+UNITS_NUMERATION_FROM_0_OR_1] = e;

	  if (p->revers_box[c]) // ������ ����, ������ ������ ��� �������� Unites ����� ������� TMS
      {
        p->can_in_mbox_adr[e] = p->can_base_adr + c;
        p->can_out_mbox_adr[e]  = p->can_base_adr + OFFSET_CAN_ADR_UNITS + c;
      }
      else
      {
        p->can_out_mbox_adr[e] = p->can_base_adr + c;
        p->can_in_mbox_adr[e]  = p->can_base_adr + OFFSET_CAN_ADR_UNITS + c;
      }
//		p->can_in_mbox_adr[e] = START_CAN_ADR_UNITS + c*2;
//		p->can_out_mbox_adr[e] = START_CAN_ADR_UNITS + OFFSET_CAN_ADR_UNITS + c*2;
	  e++;
	}	
  }

  p->max_number = e;


  return e;
}

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

int init_canopen_can_boxs(CANOPEN_CAN_SETUP *p)
{
	int i;

//  p->max_number = 8;	
	for(i = 0; i < CANOPENUNIT_LEN; i++)
	  CanOpenUnites[i] = 0;	
	
  return 1;
}

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

int init_mpu_can_boxs(MPU_CAN_SETUP *p )
{
  int c,e;

  e = 0;
  for (c=0;c<MAX_COUNT_UNITES_MPU;c++)
  {
	if (p->active_box[c])
	{
	  p->adr_box[c] = e;
      p->can_out_mbox_adr[e] = p->can_base_adr + c;
      p->can_in_mbox_adr[e]  = p->can_base_adr + 0x10 + c;  //OFFSET_CAN_ADR_MPU
	  e++;
	}	
  }

  p->max_number = e;

  return e;
}

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

int init_terminal_can_boxs(TERMINAL_CAN_SETUP *p )
{
  int c,e;

  e = 0;
  for (c=0;c<MAX_COUNT_UNITES_TERMINAL;c++)
  {
    if (p->active_box[c])
    {
      p->adr_box[c] = e;
      p->can_out_mbox_adr[e] = p->can_base_adr + c;
      p->can_in_mbox_adr[e]  = p->can_base_adr + 0x10 + c;  //OFFSET_CAN_ADR_MPU
      e++;
    }
  }

  p->max_number = e;

  return e;
}


/////////////////////////////////////////////////////////
int init_alarm_log_can_boxs(ALARM_LOG_CAN_SETUP *p )
{
  int c,e;

  e = 0;
  for (c=0;c<MAX_COUNT_UNITES_TERMINAL;c++)
  {
    if (p->active_box[c])
    {
      p->adr_box[c] = e;
      p->can_out_mbox_adr[e] = p->can_base_adr + c;
      p->can_in_mbox_adr[e]  = p->can_base_adr + 0x10 + c;  //OFFSET_CAN_ADR_MPU
      e++;
    }
  }

  p->max_number = e;

  return e;
}


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

void init_mailboxs_can( UNITES_CAN_SETUP    *p_units, 
					    MPU_CAN_SETUP       *p_mpu,
					    TERMINAL_CAN_SETUP  *p_terminal,
                        ALARM_LOG_CAN_SETUP  *p_alarm_log,
					    CANOPEN_CAN_SETUP   *p_canopen,
					    MAILBOXS_CAN_SETUP *p_mailboxs )
{
   volatile int c,e,max_number_in,max_number_out;

   e = 0;
   max_number_in = 0;
   max_number_out = 0;

   if (p_units->max_number>0)
   {
     for (c=0;c<p_units->max_number;c++)
	 {
		p_mailboxs->can_mbox_adr[e] = p_units->can_in_mbox_adr[c]   | 0x80000000;
		p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN;
		p_mailboxs->local_number_box[e] = c;
		p_mailboxs->type_box[e] = UNITS_TYPE_BOX;

		p_units->adr_in_mbox[c] = e;

		max_number_in++;
		e++;

		p_mailboxs->can_mbox_adr[e] = p_units->can_out_mbox_adr[c]   | 0x80000000;
		p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT;
		p_mailboxs->local_number_box[e] = c;
		p_mailboxs->type_box[e] = UNITS_TYPE_BOX;

		p_units->adr_out_mbox[c] = e;

		max_number_out++;
		e++;		
	 }
   }

   if (p_mpu->max_number>0)
   {
     for (c=0;c<p_mpu->max_number;c++)
	 {
		p_mailboxs->can_mbox_adr[e] = p_mpu->can_in_mbox_adr[c]   | 0x80000000;
		p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN;
		p_mailboxs->local_number_box[e] = c;
		p_mailboxs->type_box[e] = MPU_TYPE_BOX;

		p_mpu->adr_in_mbox[c] = e;

		max_number_in++;
		e++;

		p_mailboxs->can_mbox_adr[e] = p_mpu->can_out_mbox_adr[c]   | 0x80000000;
		p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT;
		p_mailboxs->local_number_box[e] = c;
		p_mailboxs->type_box[e] = MPU_TYPE_BOX;

		p_mpu->adr_out_mbox[c] = e;

		max_number_out++;
		e++;
	 }
   }

   if (p_terminal->max_number>0)
   {
     for (c=0;c<p_terminal->max_number;c++)
     {
        p_mailboxs->can_mbox_adr[e] = p_terminal->can_in_mbox_adr[c]   | 0x80000000;
        p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN;
        p_mailboxs->local_number_box[e] = c;
        p_mailboxs->type_box[e] = TERMINAL_TYPE_BOX;

        p_terminal->adr_in_mbox[c] = e;

        max_number_in++;
        e++;

        p_mailboxs->can_mbox_adr[e] = p_terminal->can_out_mbox_adr[c]   | 0x80000000;
        p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT;
        p_mailboxs->local_number_box[e] = c;
        p_mailboxs->type_box[e] = TERMINAL_TYPE_BOX;

        p_terminal->adr_out_mbox[c] = e;

        max_number_out++;
        e++;
     }
   }


   if (p_alarm_log->max_number>0)
   {
     for (c=0;c<p_alarm_log->max_number;c++)
     {
        p_mailboxs->can_mbox_adr[e] = p_alarm_log->can_in_mbox_adr[c]   | 0x80000000;
        p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN;
        p_mailboxs->local_number_box[e] = c;
        p_mailboxs->type_box[e] = ALARM_LOG_TYPE_BOX;

        p_alarm_log->adr_in_mbox[c] = e;

        max_number_in++;
        e++;

        p_mailboxs->can_mbox_adr[e] = p_alarm_log->can_out_mbox_adr[c]   | 0x80000000;
        p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_OUT;
        p_mailboxs->local_number_box[e] = c;
        p_mailboxs->type_box[e] = ALARM_LOG_TYPE_BOX;

        p_alarm_log->adr_out_mbox[c] = e;

        max_number_out++;
        e++;
     }
   }


   if (p_canopen->max_number>0)
   {
     for (c=0;c<p_canopen->max_number;c++)
	 {
		p_mailboxs->can_mbox_adr[e] = p_canopen->can_in_mbox_adr[c];
		p_mailboxs->type_in_out_box[e] = CAN_BOX_TYPE_IN;
		p_mailboxs->local_number_box[e] = c;
		p_mailboxs->type_box[e] = CANOPEN_TYPE_BOX;

		p_canopen->adr_in_mbox[c] = e;

		max_number_in++;
		e++;
	 }
   }

   p_mailboxs->max_number_in = max_number_in;
   p_mailboxs->max_number_out = max_number_out;
}

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

void init_all_mailboxs(unsigned long can_base_adr_units, unsigned long can_base_adr_mpu, unsigned long can_base_adr_alarm_log, unsigned long can_base_adr_terminal)
{
//
   unites_can_setup.can_base_adr = can_base_adr_units;
   init_units_can_boxs(&unites_can_setup);
//
   mpu_can_setup.can_base_adr = can_base_adr_mpu;
   init_mpu_can_boxs(&mpu_can_setup);
//
   terminal_can_setup.can_base_adr  = can_base_adr_terminal;
   init_terminal_can_boxs(&terminal_can_setup);
//
   alarm_log_can_setup.can_base_adr  = can_base_adr_alarm_log;
   init_alarm_log_can_boxs(&alarm_log_can_setup);
//
   init_canopen_can_boxs(&canopen_can_setup);
//
   init_mailboxs_can(&unites_can_setup, &mpu_can_setup, &terminal_can_setup, &alarm_log_can_setup, &canopen_can_setup, &mailboxs_can_setup);

}


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




void reset_CAN_timeout_cicle(int box)
{
  CAN_timeout_cicle[box]=0;
}


#pragma CODE_SECTION(inc_CAN_timeout_cicle, ".fast_run2");
void inc_CAN_timeout_cicle()
{
	int i;
	
	for(i = 0; i < UNIT_QUA; i++)
	{
		if (CAN_timeout_cicle[i] < MAX_CAN_WAIT_TIMEOUT)
		{
			CAN_timeout_cicle[i]++;
		}
		else
		{
			CAN_timeout[i] = 1;
		}
	}
}



void InitCan(unsigned long can_base_adr_units, unsigned long can_base_adr_mpu, unsigned long can_base_adr_alarm_log, unsigned long can_base_adr_terminal)
{
  struct ECAN_REGS ECanaShadow; 
  int i, c;
  volatile struct MBOX *tmbox;
  volatile Uint32 *tmoto;

  unsigned long canme_bits  = 0;
  unsigned long canmd_bits  = 0;
  unsigned long canmim_bits = 0;
	

	init_all_mailboxs(can_base_adr_units, can_base_adr_mpu, can_base_adr_alarm_log, can_base_adr_terminal);

//	Configure CAN pins using GPIO regs here
	EALLOW;

	GpioMuxRegs.GPFMUX.bit.CANTXA_GPIOF6 = 1;
	GpioMuxRegs.GPFMUX.bit.CANRXA_GPIOF7 = 1;
	    
//	Configure the eCAN RX and TX pins for eCAN transmissions
	ECanaRegs.CANTIOC.all = 8;	//	only 3rd bit, TXFUNC, is significant
	ECanaRegs.CANRIOC.all = 8;	//	only 3rd bit, RXFUNC, is significant


//	Specify that 8 bits will be sent/received
	for (c=0;c<32;c++)
	{
	  tmbox = &ECanaMboxes.MBOX0 + c;
	  tmbox->MSGCTRL.all = 0x00000008;
	}
     
//	Disable all Mailboxes
//	Required before writing the MSGIDs
    ECanaRegs.CANME.all = 0;

	canme_bits  = 0;
	canmd_bits  = 0;
    canmim_bits = 0;

	// receive+transive	//Ura
	for (c=0;c<32;c++)
	{
	    
		if (mailboxs_can_setup.can_mbox_adr[c])
		{
		  tmbox = &ECanaMboxes.MBOX0 + c;
		   if(mailboxs_can_setup.type_box[c] == UNITS_TYPE_BOX)
		   {
//				tmbox->MSGID.bit.IDE = 0;
//				tmbox->MSGID.bit.STDMSGID = mailboxs_can_setup.can_mbox_adr[c];
		  		tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c];
		   }
		   else
		   {
				if(mailboxs_can_setup.type_box[c] == CANOPEN_TYPE_BOX)
				{
					tmbox->MSGID.bit.IDE = 0;
					tmbox->MSGID.bit.STDMSGID = mailboxs_can_setup.can_mbox_adr[c];
		  			//tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c];
				}
				else
				    tmbox->MSGID.all = mailboxs_can_setup.can_mbox_adr[c];
		    }

  		  canme_bits |= ((unsigned long)1<<c); // set select box bits
		  canmim_bits |= ((unsigned long)1<<c); // set interrupt bits

		  if (mailboxs_can_setup.type_in_out_box[c] == CAN_BOX_TYPE_IN)
		  {
			canmd_bits |= ((unsigned long)1<<c); // set receive bits
		  }
		    

		  if (mailboxs_can_setup.type_in_out_box[c] == CAN_BOX_TYPE_OUT)
		  {
		  }
		  		  
		}
	}
//	����� ������ ������ (����-��������)
	ECanaRegs.CANMD.all = canmd_bits;//0x0000FFFF; 
//	�������� ����� ��� ������
	ECanaRegs.CANME.all = canme_bits;

//	Clear all TAn bits
	ECanaRegs.CANTA.all	= 0xFFFFFFFF;
//	Clear all RMPn bits
	ECanaRegs.CANRMP.all = 0xFFFFFFFF;
//	Clear all interrupt flag bits
	ECanaRegs.CANGIF0.all = 0xFFFFFFFF;
	ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
//	Clear all error and status bits
    ECanaRegs.CANES.all=0xffffffff;

    ECanaRegs.CANMIM.all = 0xFFFFFFFF;

//	Request permission to change the configuration registers
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.all = 0;
	ECanaShadow.CANMC.bit.MBCC = 1;	//	Mailbox timestamp counter clear bit
    ECanaShadow.CANMC.bit.TCC = 1;	//	Time stamp counter MSB clear bit
    ECanaShadow.CANMC.bit.SCB = 1;	//	eCAN mode (reqd to access 32 mailboxes)
	ECanaShadow.CANMC.bit.WUBA = 1;	//	Wake up on bus activity
	ECanaShadow.CANMC.bit.ABO = 1;	//	Auto bus on
    ECanaShadow.CANMC.bit.CCR = 1;
//    ECanaShadow.CANMC.bit.CCE = 0;
    	          
 //   ECanaShadow.CANMC.bit.STM = 1;	//	self-test loop-back
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    EDIS;
    do 
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );  // Wait for CCE bit to be set..
//    while(!ECanaRegs.CANES.bit.CCE);	
   
// ���������� �������� CAN
    EALLOW;
    ECanaShadow.CANBTC.all = ECanaRegs.CANBTC.all;
//    ECanaShadow.CANBTC.bit.SJWREG = 1;


#if (CAN_SPEED_BITS==250000)
    ECanaShadow.CANBTC.bit.BRPREG = 23;//11;// 47;				//59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
    ECanaShadow.CANBTC.bit.TSEG1REG = 15;//  15;		//5;//7;//14;//10;//7;  // Bit time = 15
    ECanaShadow.CANBTC.bit.TSEG2REG = 2; //  2;		//4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
#else
#if (CAN_SPEED_BITS==500000)
    ECanaShadow.CANBTC.bit.BRPREG = 14;//11;//23;//11;// 47;             //59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
    ECanaShadow.CANBTC.bit.TSEG1REG = 11;//12;//15;//  15;        //5;//7;//14;//10;//7;  // Bit time = 15
    ECanaShadow.CANBTC.bit.TSEG2REG = 2; //  2;     //4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
#else
#error "Set Can speed in CAN_project.h!!!"

#endif
#endif
	ECanaShadow.CANBTC.bit.SJWREG=1;
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0; 			// Set CCR = 0
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    EDIS;


    // Wait until the CPU no longer has permission to change the
    // configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 ); 

//    while(ECanaRegs.CANES.bit.CCE);	// Wait for CCE bit to be cleared..

    EALLOW;
//	������ �������� ��� �������� �������� ��������� �������
	for (c=0;c<32;c++)
	{
		tmoto = &ECanaMOTORegs.MOTO0 + c;
		(*(volatile Uint32 *)( tmoto )) = 550000;
	}

	ECanaRegs.CANTOC.all = 0;//0x000000ff;
	ECanaRegs.CANTOS.all = 0;	//	clear all time-out flags
	ECanaRegs.CANTSC = 0;		//	clear time-out counter

	ECanaShadow.CANGIM.all = 0;


    ECanaRegs.CANMIM.all = canmim_bits;	//	26.01.2011 Dimas    
	ECanaRegs.CANMIL.all = 0x00000000; // All mailbox interrupts are generated on interrupt line 0.
	ECanaShadow.CANGIM.bit.I0EN = 1;

	PieVectTable.ECAN0INTA = &CAN_handler;
	PieCtrlRegs.PIEIER9.bit.INTx5=1;     // PIE Group 9, INT6

	ECanaShadow.CANGIM.bit.AAIM=1;
	ECanaShadow.CANGIM.bit.BOIM=1;
	ECanaShadow.CANGIM.bit.EPIM=1;
	ECanaShadow.CANGIM.bit.RMLIM=1;
	ECanaShadow.CANGIM.bit.WUIM=1;
	ECanaShadow.CANGIM.bit.WLIM=1;
	ECanaShadow.CANGIM.bit.WDIM=1;
	ECanaShadow.CANGIM.bit.TCOM=1;

	ECanaShadow.CANGIM.bit.MTOM = 1;
	ECanaShadow.CANGIM.bit.I1EN = 1;
	ECanaShadow.CANGIM.bit.GIL = 1;
	ECanaRegs.CANGIM.all = ECanaShadow.CANGIM.all;

	PieVectTable.ECAN1INTA = &CAN_reset_err;
	PieCtrlRegs.PIEIER9.bit.INTx6=1;     // PIE Group 9, INT6



// ��������� ��������� CAN ������

	for(i=0;i<UNIT_QUA;i++)
	{
		cycle[i].busy = 0;
		cycle[i].FLY = 0;
		cycle[i].extended = 0;
		cycle[i].adr = 0;
		cycle[i].adr_from = 0;
        cycle[i].adr_to = 0;
        cycle[i].quant = 0;
	}

	fifo.adr=0;
	refo.adr=0;

	CanTimeOutErrorTR=0;
 	
 	for(i=0;i<UNIT_QUA;i++)
	{
	     CAN_timeout[i]=1;
	     CAN_timeout_cicle[i]=0;
		 CAN_refresh_cicle[i]=0;
    }


	for(i=0;i<UNIT_QUA_UNITS;i++)
	{
		CAN_count_cycle_input_units[i]=0;
		for(c=0;c<UNIT_LEN;c++)
             Unites[i][c]=0;
    }


    for(i=0;i<TERMINAL_UNIT_QUA_UNITS;i++)
    {
 //       CAN_count_cycle_input_units[i]=0;
        for(c=0;c<TERMINAL_UNIT_LEN;c++)
            TerminalUnites[i][c]=0;
    }





    new_cycle_fifo.index_data = 0;
    new_cycle_fifo.index_send = 0;
    new_cycle_fifo.count_lost = 0;
    new_cycle_fifo.count_load = 0;
    new_cycle_fifo.count_free = 0;
    new_cycle_fifo.flag_inter = 0;

    for(i=0;i<NEW_CYCLE_FIFO_LEN;i++)
    {
        new_cycle_fifo.cycle_data[i].busy        = 0;
        new_cycle_fifo.cycle_data[i].FLY         = 0;
        new_cycle_fifo.cycle_data[i].extended    = 0;
        new_cycle_fifo.cycle_data[i].adr         = 0;
        new_cycle_fifo.cycle_data[i].adr_from    = 0;
        new_cycle_fifo.cycle_data[i].adr_to      = 0;
        new_cycle_fifo.cycle_data[i].quant       = 0;
        new_cycle_fifo.cycle_data[i].box         = 0;
        new_cycle_fifo.cycle_data[i].priority    = 0;
        new_cycle_fifo.cycle_data[i].quant_block = 0;
    }


    for(i=0;i<UNIT_QUA;i++)
    {
        new_cycle_fifo.cycle_box[i] = 0;
        new_cycle_fifo.lost_box[i]  = 0;
    }



	//IER |= M_INT9;	// Enable CPU INT

//	EDIS;

	enable_can_recive_after_units_box = 1;


}


void start_can_interrupt(void)
{
    IER |= M_INT9;  // Enable CPU INT
    PieCtrlRegs.PIEACK.all = BIT8;
}

void stop_can_interrupt(void)
{
    IER &= ~M_INT9;  //stop CAN
    PieCtrlRegs.PIEACK.all = BIT8;
}


void new_fifo_calc_load(void)
{
    unsigned int i, free_l = 0;

//    for(i=0;i<NEW_FIFO_LEN;i++)
//        {
//            if (new_fifo.pak[i].box==0)
//                free_l++;
//        }
//    new_fifo.count_load = NEW_FIFO_LEN - free_l;
//    new_fifo.count_free = free_l;
//
//
//

//    for (i=0;i<;i++)
//    {
//
////    new_cycle_fifo.cycle_box[i] = 0;
//    }

}



int CAN_may_be_send_cycle_fifo(void)
{

    volatile struct MBOX *Mailbox;
    unsigned long mask;

    int box;
    unsigned long hiword, loword;

    if (new_cycle_fifo.index_data == new_cycle_fifo.index_send)
    {
        // �� ������ ������ �� ��������, ������� ���������
        //
    }
    else
    {
        CAN_cycle_fifo_step();

    }
    return 0;

}

////////////////////////////////////////////////////////////////////////////
int get_new_cycle_fifo_load_level(void)
{
   volatile int load_level_byte;

   load_level_byte = (new_cycle_fifo.index_data - new_cycle_fifo.index_send)&NEW_CYCLE_FIFO_LEN_MASK;
   load_level_byte = (int)NEW_CYCLE_FIFO_LEN - load_level_byte;

   if (load_level_byte <  (NEW_CYCLE_FIFO_LEN >> 4)   )
       return 3;
   if (load_level_byte <  (NEW_CYCLE_FIFO_LEN >> 2)   )
       return 2;
   if (load_level_byte <  (NEW_CYCLE_FIFO_LEN >> 1)   )
       return 1;

   return 0;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

int new_cycle_fifo_load(int box, unsigned long adr, int * adr_from,  unsigned long addr_to, unsigned long quant, int extended, int priority, int cmd_wait)
{
    unsigned int ind;

    if (((new_cycle_fifo.index_data - new_cycle_fifo.index_send)&NEW_CYCLE_FIFO_LEN_MASK)>=(NEW_CYCLE_FIFO_LEN_MASK-3))
        {
            new_cycle_fifo.count_lost++;
//            may_be_send_cycle_fifo(); // �� ������ ������ ������ ��������, ����� �� �� �������� ������-��, � ������ �����!
            return -1; // �����������!
        }

    if (new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].box==0) // ��� ����� ����� ���������
    {

        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].box = box;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].adr = adr;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].adr_to = addr_to;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].adr_from = adr_from;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].quant = quant;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].extended = extended;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].priority = priority;
        new_cycle_fifo.cycle_data[new_cycle_fifo.index_data].busy = 1;


        // ����������� ����� ������� ��� ����� �����
        new_cycle_fifo.cycle_box[box]++;

          if (new_cycle_fifo.index_data == new_cycle_fifo.index_send)
          {
              // �� ������ ������ �� ��������, ������� ���������
              //

          }

      // �������� ������
      new_cycle_fifo.index_data++;
      new_cycle_fifo.index_data &= NEW_CYCLE_FIFO_LEN_MASK;
//      if (new_cycle_fifo.index_data>=NEW_CYCLE_FIFO_LEN)  // ������� � ���� ������
//          new_cycle_fifo.index_data = 0; // ������� � ���� ������

//      may_be_send_fifo();
//      if (cmd_wait==0)
//        may_be_send_cycle_fifo();

      return 1; // ��� ��!
    }
    else
    {
        new_cycle_fifo.count_lost++;

//        may_be_send_cycle_fifo(); // �� ������ ������ ������ ��������, ����� �� �� �������� ������-��, � ������ �����!
        return -1; // �����������!
    }


}

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


int CAN_FLY_free(int box)
{
    return !cycle[box].FLY;
}


int CAN_cycle_free(int box)
{
  int i;

#if (CAN_PROTOCOL_VERSION==2)

    if (new_cycle_fifo.cycle_box[box] >= 200)
    {
        new_cycle_fifo.lost_box[box]++;
        return 0;
    }
    else
        return 1;

#endif

#if (CAN_PROTOCOL_VERSION==1)
	return !cycle[box].busy;
#endif
}

int CAN_cycle_full_free(int box, int statistics_flag)
{
  int i;

#if (CAN_PROTOCOL_VERSION==2)

    if (new_cycle_fifo.cycle_box[box] != 0)
    {
        if (statistics_flag==CAN_BOX_STAT_ON)
           new_cycle_fifo.lost_box[box]++;
            return 0;
    }
    else
        return 1;

#endif

#if (CAN_PROTOCOL_VERSION==1)
    return !cycle[box].busy;
#endif
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
       
int CAN_FIFO_free(unsigned int quant)
{
#if (CAN_PROTOCOL_VERSION==2)
    return 0;
#endif

#if (CAN_PROTOCOL_VERSION==1)
	return ((FIFO_LEN-(unsigned int)fifo.adr)>quant);
#endif

}       

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

void CAN_cycle_stop(int box)
{                                                          
	cycle[box].busy=0;
}       


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


#pragma CODE_SECTION(CAN_send2,".fast_run2");
void CAN_send2(int box,unsigned long hiword, unsigned long loword)
{
  volatile struct MBOX *Mailbox;
  unsigned long mask;

//    cycle[box].FLY = 1;

    new_cycle_fifo.flag_inter = 1;

    mask = ((unsigned long)1<<box);

    Mailbox = &ECanaMboxes.MBOX0 + box;

    Mailbox->MDH.all = hiword;
    Mailbox->MDL.all = loword;


    ECanaRegs.CANTRS.all = mask;

}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
///////////////////////////////////////////////
int get_real_out_mbox(int type_box, int box)
{
	if (type_box==FREE_TYPE_BOX)
	  return -1;

	if (type_box==UNITS_TYPE_BOX)
	{
	 if (box<MAX_COUNT_UNITES_UKSS)
	  return unites_can_setup.adr_out_mbox[box];
	 else
	  return -1; 
	}

	if (type_box==MPU_TYPE_BOX)
	{
	    if (box<MAX_COUNT_UNITES_MPU)
	  return mpu_can_setup.adr_out_mbox[box];
	 else
	  return -1;
	}

	if (type_box==TERMINAL_TYPE_BOX)
	{
	    if (box<MAX_COUNT_UNITES_TERMINAL)
      return terminal_can_setup.adr_out_mbox[box];
     else
      return -1;
	}

    if (type_box==ALARM_LOG_TYPE_BOX)
    {
        if (box<MAX_COUNT_UNITES_ALARM_LOG)
      return alarm_log_can_setup.adr_out_mbox[box];
     else
      return -1;
    }

/*
	if (type_box==CANOPEN_TYPE_BOX)
	 if (box<CANOPENUNIT_LEN)
	  return mpu_can_setup.adr_out_mbox[box];
	 else
	  return -1;
*/

	return -1;
}
////////////////////////////////////////////////////////////////
///////////////////////////////////////////////
int get_real_in_mbox(int type_box, int box)
{
    if (type_box==FREE_TYPE_BOX)
      return -1;

    if (type_box==UNITS_TYPE_BOX)
    {
     if (box<MAX_COUNT_UNITES_UKSS)
      return unites_can_setup.adr_in_mbox[box];
     else
      return -1;
    }

    if (type_box==MPU_TYPE_BOX)
    {
        if (box<MAX_COUNT_UNITES_MPU)
      return mpu_can_setup.adr_in_mbox[box];
     else
      return -1;
    }

    if (type_box==TERMINAL_TYPE_BOX)
    {
        if (box<MAX_COUNT_UNITES_TERMINAL)
      return terminal_can_setup.adr_in_mbox[box];
     else
      return -1;
    }

    if (type_box==ALARM_LOG_TYPE_BOX)
    {
        if (box<MAX_COUNT_UNITES_ALARM_LOG)
      return alarm_log_can_setup.adr_in_mbox[box];
     else
      return -1;
    }

/*
    if (type_box==CANOPEN_TYPE_BOX)
     if (box<CANOPENUNIT_LEN)
      return mpu_can_setup.adr_in_mbox[box];
     else
      return -1;
*/

    return -1;
}
////////////////////////////////////////////////////////////////

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


////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// �������������� ������ �� �����������
////////////////////////////////////////////////////////////////
void realign_new_cycle_fifo_on_priority(void)
{
    int cur_send_index, sdvig_index, prev_sdvig_index;
    int next_send_index;

    NEW_CYCLE_DATA new_data, old_data;


    cur_send_index = new_cycle_fifo.index_send;

    if (new_cycle_fifo.index_data == new_cycle_fifo.index_send)
    {
        // �� ������ ������ �� ��������, ������� ���������
        //
        return;
    }


    next_send_index =  new_cycle_fifo.index_send;
    // ��������� ����� ���� � ����� ������� ���������
    do
    {
        next_send_index++;
        next_send_index &= NEW_CYCLE_FIFO_LEN_MASK;

        if (next_send_index==new_cycle_fifo.index_data)
        {
            // �� ������ ������ �� ����� ���������� �� ���� ����, ������� ����� ���������
            //
            return;
        }
        // ���������� ��������� new_cycle_fifo.index_send � next_index
        if ((new_cycle_fifo.cycle_data[next_send_index].priority > new_cycle_fifo.cycle_data[cur_send_index].priority)
                && new_cycle_fifo.cycle_data[next_send_index].box)
        {
            // �������� ������ � ������� �����������
            new_data = new_cycle_fifo.cycle_data[next_send_index];
            new_cycle_fifo.index_send--;
            new_cycle_fifo.index_send &= NEW_CYCLE_FIFO_LEN_MASK;
            // � �������� �� �� ����� ���� � -1
            new_cycle_fifo.cycle_data[new_cycle_fifo.index_send]  = new_data;

            new_cycle_fifo.cycle_data[next_send_index].box = 0;
            new_cycle_fifo.cycle_data[next_send_index].busy = 0;
            return;

        }
    } while (next_send_index!=new_cycle_fifo.index_data);

    return;




}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
//#pragma CODE_SECTION(CAN_cycle_fifo_step,".fast_run1");
int CAN_cycle_fifo_one_box(void)
{
  unsigned long hiword,loword,mask;
  unsigned int * point;
  unsigned int box=0, index;

    index = new_cycle_fifo.index_send;
    // ��� ��� ��������? �������...
    if (index == new_cycle_fifo.index_data)
      return 0;
    // ������� ���� �������� ��� ����... �������.
//    if (new_cycle_fifo.cycle_data[index].box==0)
//        return;

    // �������� �� ���������� �������� ������, ��� ��� ��������, ���� ������ ������ quant ����.
    if(new_cycle_fifo.cycle_data[index].adr>=new_cycle_fifo.cycle_data[index].quant || new_cycle_fifo.cycle_data[index].box==0)
    {
        //��������� ����� ������� ��� ����� �����
        if (new_cycle_fifo.cycle_data[index].box)
            new_cycle_fifo.cycle_box[new_cycle_fifo.cycle_data[index].box]--;
        // �������� ���������� � new_fifo � ����� ������
        new_cycle_fifo.cycle_data[index].busy = 0;
        // ������� ������ ���� ��������, ����� ���������� � ����������
        new_cycle_fifo.cycle_data[index].box  = 0;

        // �������� ������
        new_cycle_fifo.index_send++;
        new_cycle_fifo.index_send &= NEW_CYCLE_FIFO_LEN_MASK;

        return 0;
    }


// ������ ����, �������� ��
    mask = 0xE000;
    if(new_cycle_fifo.cycle_data[index].adr==new_cycle_fifo.cycle_data[index].quant-1)  mask = 0x8000;
    if(new_cycle_fifo.cycle_data[index].adr==new_cycle_fifo.cycle_data[index].quant-2)  mask = 0xC000;

    point = (unsigned int *)&hiword;

    // ����� ������
    if (new_cycle_fifo.cycle_data[index].extended == 0)
      point[1] = mask | (new_cycle_fifo.cycle_data[index].adr_to + new_cycle_fifo.cycle_data[index].adr);
    else
    {
    // ����������, ��� �������� �������� �������, ������� mask ���� ���� ������� �����.
      point[1] = (new_cycle_fifo.cycle_data[index].adr_to + new_cycle_fifo.cycle_data[index].adr)/3L; // ����� �� 3 ���� ���� ������� ����� � �����, ���������� 65535*3 = 196605 ����, ������������ ������ ������������� ������ ���  extended=1
    }

    // ������ ����� ������
    point[0] = new_cycle_fifo.cycle_data[index].adr_from[new_cycle_fifo.cycle_data[index].adr];
    point = (unsigned int *)&loword;
    // ������ ����� ������
    point[1] = new_cycle_fifo.cycle_data[index].adr_from[new_cycle_fifo.cycle_data[index].adr+1];
    // ������ ����� ������
    point[0] = new_cycle_fifo.cycle_data[index].adr_from[new_cycle_fifo.cycle_data[index].adr+2];

    new_cycle_fifo.cycle_data[index].adr+=3;

    box = new_cycle_fifo.cycle_data[index].box;


#if (CAN_PROTOCOL_VERSION==2)
    CAN_send2(box,hiword,loword);
    //new_fifo_load(box,hiword,loword);
#endif


    return 1;

}
////////////////////////////////////////////////////////////////


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

//#pragma CODE_SECTION(CAN_cycle_fifo_step,".fast_run1");
int CAN_cycle_fifo_step(void)
{
  unsigned long hiword,loword,mask;
  unsigned int * point;
  unsigned int box=0, index;

    index = new_cycle_fifo.index_send;
    // ��� ��� ��������? �������...
    if (index==new_cycle_fifo.index_data)
      return 0;
    // ������� ���� �������� ��� ����... �������.
//    if (new_cycle_fifo.cycle_data[index].box==0)
//        return;

    if (new_cycle_fifo.flag_inter==0)
    {
        realign_new_cycle_fifo_on_priority();
        CAN_cycle_fifo_one_box();

    }


    return 1;
}
////////////////////////////////////////////////////////////////

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

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
#define CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK 333L //99 // ������� 3 ���� ������
//#pragma CODE_SECTION(CAN_cycle_send,".fast_run2");
void CAN_cycle_send(int type_box, int box, unsigned long Addr, int * Data, unsigned long quant, int extended, int priority)
{
  int real_mbox;
  unsigned int old_time;

    real_mbox = get_real_out_mbox (type_box, box);
    if (real_mbox<0)
      return;

#if (CAN_PROTOCOL_VERSION==1)
    cycle[real_mbox].adr = 0;
    cycle[real_mbox].adr_from = Data;
    cycle[real_mbox].adr_to = Addr;
    cycle[real_mbox].quant = quant;
    cycle[real_mbox].busy = 1;
    cycle[real_mbox].extended = extended;


    CAN_cycle_step(real_mbox);
#endif


#if (CAN_PROTOCOL_VERSION==2)
    if (priority==CAN_BOX_PRIORITY_LOW)
    {
        do
        {
//            if (get_new_cycle_fifo_load_level()<=2)

            if (quant>CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK)
            {
                if (new_cycle_fifo_load (real_mbox, 0, Data, Addr, CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK, extended, priority, 1) == 1)
                {
                    quant -= CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK;
                    Data += CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK;
                    Addr += CAN_BOX_PRIORITY_LOW_MAX_SIZE_BLOCK;
                }
            }
            else
            {
                new_cycle_fifo_load (real_mbox, 0, Data, Addr, quant, extended, priority, 0);
                quant = 0;
            }

        }
        while (quant>0);

//

    }
    else
       new_cycle_fifo_load (real_mbox, 0, Data, Addr, quant, extended, priority, 0);

#endif

}
////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////
//  �������� �������� ������ �������
////////////////////////////////////////////////////////////////
void detect_time_refresh_units(int box, int adr)
{
	if (box>=UNIT_QUA_UNITS)
	  return;

	if (adr==unites_can_setup.adr_detect_refresh[box])
     CAN_count_cycle_input_units[box]++;

}

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
void messagePaserToUnitesIngitim(int box, unsigned long h_word, unsigned long l_word)
{
    int adr;

	if (box==6) adr = 0;
	if (box==7) adr = 1;
	if (box==8) adr = 2;
	 
	adr = adr*4;

	if (adr<(CANOPENUNIT_LEN-3))
	{
	  CanOpenUnites[adr] = (h_word  >> 16  ) & 0xffff;
	  CanOpenUnites[adr+1] = (h_word   ) & 0xffff;
	  CanOpenUnites[adr+2] = (l_word  >> 16  ) & 0xffff;
	  CanOpenUnites[adr+3] = (l_word   ) & 0xffff;
	}
}

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
void parse_data_from_mbox(unsigned int box, unsigned long hiword, 
											unsigned long loword)
{
  unsigned int bit[3], real_mbox;
  int local_number_box;
  int adr;
  static int reply_box = 0;
  static volatile int err=0;


////////////////////////////////////////////////////////////////////
// CAN OPEN
////////////////////////////////////////////////////////////////////

		if (mailboxs_can_setup.type_box[box] == CANOPEN_TYPE_BOX)
		{
#ifdef BWC_CAN_FATEC
			messageParserToUnites(box, hiword, loword);
#endif
#ifdef BWC_CAN_SIEMENS
			messageParserToUnitesSiemens(box, hiword, loword);
#endif
#ifdef INGITIM_CAN_OPEN
		messagePaserToUnitesIngitim(box, hiword, loword);
#endif
//			messageParser(box, hiword, loword);
			return;
		}
 
	    adr	    = hiword >> 16;
	    bit[0]	= adr & 0x8000;
	    bit[1]	= adr & 0x4000;
		bit[2]	= adr & 0x2000;
		adr    &= 0x1fff;
// -------------------------------------------------------------------------
// ������������ ����������� CAN-���������, � 8 ���� ������ ����� ��������� ������:
// | 3 ���� ����� ������ | ������� (13 ���) | data1 | data2 | data3 |
// ����� ������: [0|1] - ������������ �� ��������������� dataX
// �������: ��������� ������� � ������� ������ ������
//  ��� "������" �������������: �������=data1, �������+1=data2, �������+2=data3
//  ��� "������" �������������: ��������  �������, �������+2, �������+3
//      �� ��� ��� �������, ��� ��� ��� ���� ����� = "1".
// -------------------------------------------------------------------------


////////////////////////////////////////////////////////////////////
//SMPU_CAN_DEVICE - ����������� ���� ��� ��������� �������� ����������� ����� ��� ID = 0x80CEB0E1;
////////////////////////////////////////////////////////////////////

/*		if (mailboxs_can_setup.type_box[box] == SMPU_TYPE_BOX)
		{
			if (adr==5 || adr==1)
			{
  		 	  run_cmd_super_can_5(adr,(unsigned int)((hiword    ) & 0xffff),(unsigned int)((loword>>16) & 0xffff),(unsigned int)((loword) & 0xffff));				  
			}
			else
	 		  ready_run_cmd_super_can(adr,(unsigned int)((hiword    ) & 0xffff),(unsigned int)((loword>>16) & 0xffff),(unsigned int)((loword) & 0xffff));

			return;			 
		}

*/

///////////////////////////////////////////////////////////////////
//MPU
///////////////////////////////////////////////////////////////////

		if (mailboxs_can_setup.type_box[box] == MPU_TYPE_BOX)
		{
		    local_number_box = mailboxs_can_setup.local_number_box[box];
            if (local_number_box>=MPU_UNIT_QUA_UNITS)
                          return;

			if(bit[0])
			{
			    timer_pause_enable_can_from_mpu();
				if (adr<SIZE_MODBUS_TABLE)
				{
					if ((adr>0) && flag_enable_can_from_mpu)
					{
			        	modbus_table_can_in[adr-1].all = /*(unsigned int)*/((hiword    ) & 0xffff); 
					}
			        adr++;
				}
				else
				{
				    err++;
				}
			}
			if(bit[1])
			{
				timer_pause_enable_can_from_mpu();
				if (adr<SIZE_MODBUS_TABLE)
				{
		    		if ((adr>0) && flag_enable_can_from_mpu)
			        {	
			        	modbus_table_can_in[adr-1].all = /*(unsigned int)*/((loword>>16) & 0xffff);
					}
			        adr++;
				}
                else
                {
                    err++;
                }
			}

			if(bit[2])
			{
				timer_pause_enable_can_from_mpu();
				if (adr<SIZE_MODBUS_TABLE)
				{
					if ((adr>0) && flag_enable_can_from_mpu)
					{
	        		   modbus_table_can_in[adr-1].all = /*(unsigned int)*/((loword) & 0xffff);
					}
					adr++;
				}
                else
                {
                    err++;
                }
			}
			real_mbox = get_real_in_mbox (MPU_TYPE_BOX, 0);

			return;
		}

///////////////////////////////////////////////////////////////////
//TERMINAL
////////////////////////////////////////////////////////////////////

		    if (mailboxs_can_setup.type_box[box] == TERMINAL_TYPE_BOX)
		        {
		            local_number_box = mailboxs_can_setup.local_number_box[box];
		            if (local_number_box>=TERMINAL_UNIT_QUA_UNITS)
		                          return;

		            if(bit[0])
		            {
		                timer_pause_enable_can_from_terminal();
		                if (adr<TERMINAL_UNIT_LEN)
		                {
		                    if ((adr>=0) && flag_enable_can_from_terminal)
		                    {
		                        TerminalUnites[local_number_box][adr] = /*(unsigned int)*/((hiword    ) & 0xffff);
		                    }
		                    adr++;
		                }
		            }
		            if(bit[1])
		            {
		                timer_pause_enable_can_from_terminal();
		                if (adr<TERMINAL_UNIT_LEN)
		                {
		                    if ((adr>=0) && flag_enable_can_from_terminal)
		                    {
		                        TerminalUnites[local_number_box][adr] = /*(unsigned int)*/((loword>>16) & 0xffff);
		                    }
		                    adr++;
		                }
		            }

		            if(bit[2])
		            {
		                timer_pause_enable_can_from_terminal();
		                if (adr<TERMINAL_UNIT_LEN)
		                {
		                    if ((adr>=0) && flag_enable_can_from_terminal)
		                    {
		                        TerminalUnites[local_number_box][adr] = /*(unsigned int)*/((loword) & 0xffff);
		                    }
		                    adr++;
		                }
		            }

		            return;
		        }

////////////////////////////////////////////////////////////////////
//UKSS
////////////////////////////////////////////////////////////////////
		if (mailboxs_can_setup.type_box[box] == UNITS_TYPE_BOX)
		{
			local_number_box = mailboxs_can_setup.local_number_box[box];

			if (local_number_box>=UNIT_QUA_UNITS)
			  return;

			if(bit[0]) 
			{
				if ( (adr<UNIT_LEN) && (adr>=0) )
				{
				 		Unites[local_number_box][adr] = (hiword    ) & 0xffff; 
					    detect_time_refresh_units(local_number_box,adr);
				}
				adr++;
			}


			if(bit[1]) 
			{
				if ( (adr<UNIT_LEN) && (adr>=0) )
				{
				        Unites[local_number_box][adr] = ((loword>>16) & 0xffff); 
					    detect_time_refresh_units(local_number_box,adr);
				}
				adr++;
			}

			if(bit[2]) 
			{
				if ( (adr<UNIT_LEN) && (adr>=0) )
				{
						Unites[local_number_box][adr] = (loword    ) & 0xffff;
					    detect_time_refresh_units(local_number_box,adr);
				}
				adr++;
			}

			return;
		}
}


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

//#pragma CODE_SECTION(CAN_handler,".fast_run");
interrupt void CAN_handler(void)
{
  volatile struct MBOX *Mailbox;
  unsigned long hiword, loword, mask = 1;
  int box,type_in_out_box, box_i;

	// Set interrupt priority:
	volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
	IER |= M_INT9;
	IER	&= MINT9;	  	                // Set "global" priority

	PieCtrlRegs.PIEIER9.all &= MG95;   // Set "group"  priority	
	PieCtrlRegs.PIEACK.all = 0xFFFF;   // Enable PIE interrupts	

#if (_ENABLE_INTERRUPT_PROFILE_LED1)
    if (enable_profile_led1_can)
    i_led1_on_off_special(1);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (enable_profile_led2_can)
    i_led2_on_off_special(1);
#endif

	EINT;

	box = ECanaRegs.CANGIF0.bit.MIV0;

	mask <<= box;

	type_in_out_box = mailboxs_can_setup.type_in_out_box[box];

	if(type_in_out_box == CAN_BOX_TYPE_OUT)	   
	{
		cycle[box].FLY=0;
//		new_cycle_fifo.flag_inter = 0;

		ECanaRegs.CANTA.all = mask;
		ECanaRegs.CANAA.all = mask;

#ifdef SUPER_CAN
		if(box == SMPU_CAN_DEVICE_TRANSMIT) // SMPU_CAN_DEVICE_TRANSMIT -  ID = 0x80CEB0F1;
		{
			loword = Mailbox->MDL.all;
			hiword = Mailbox->MDH.all;
			adr = (hiword >> 16) & 0x1FFF;
			if(adr == 5) //
			{
				flag_send_mess_super_can = 1;
			}
		}
#endif

#if (CAN_PROTOCOL_VERSION==1)
		if(!BUSY && fifo.adr && !cycle[fifo.pak[fifo.adr-1].box].FLY)
		{
			BUSY=1;
			fifo.adr--;
			CAN_send(	fifo.pak[fifo.adr].box,
						fifo.pak[fifo.adr].hiword,
						fifo.pak[fifo.adr].loword);
			BUSY=0;
		}
		else if(refo.adr && !cycle[refo.pak[refo.adr-1].box].FLY)
		{
			refo.adr--;
			CAN_send(	refo.pak[refo.adr].box,
						refo.pak[refo.adr].hiword,
						refo.pak[refo.adr].loword);
		}

		if(cycle[box].busy)	//	26.01.2011 Dimas    
		CAN_cycle_step(box);	//	26.01.2011 Dimas    
#endif




#if (CAN_PROTOCOL_VERSION==2)

		new_cycle_fifo.flag_inter = CAN_cycle_fifo_one_box();//CAN_cycle_fifo_step(new_cycle_fifo.index_send);

//		// �������� ��� ���������� � ������
//		new_fifo_unload();
//
//		// ������� ���� �� ������ � ������� ����� �������� ��� ����� ����� ��� �������� ��������
//        if(cycle[box].busy)         //
//             CAN_cycle_step(box);    //
//
//
//        if(cycle[box].busy==0)         //
//        {
//            // � ��� ������� ���� �� ������ � ������� ������ ������
//           for (box_i=0;box_i<UNIT_QUA;box_i++)
//             if(cycle[box_i].busy)
//             {
//                    CAN_cycle_step(box_i);    //
//                    break;
//             }
//        }

#endif

	}
	else
	{
		ECanaRegs.CANRMP.all = mask;
	
		Mailbox = &ECanaMboxes.MBOX0 + box;
		loword = Mailbox->MDL.all;
		hiword = Mailbox->MDH.all;

	    if (enable_can_recive_after_units_box)
	    {
	       parse_data_from_mbox(box, hiword, loword);
        }

	    CAN_timeout[box]=0; // �������� ������ �������� �� ������
		CAN_refresh_cicle[box]=CAN_timeout_cicle[box];
	    CAN_timeout_cicle[box]=0;

//		led2_toggle();
	}

//#if (CAN_PROTOCOL_VERSION==2)
////        // �������� ��� ���������� � ������
////        new_fifo_unload();
////
//            // � ��� ������� ���� �� ������ � ������� ������ ������
//           for (box_i=0;box_i<UNIT_QUA;box_i++)
//             if(cycle[box_i].busy)
//             {
//                    CAN_cycle_step(box_i);    //
//                    break;
//             }
//#endif


//	PieCtrlRegs.PIEACK.bit.ACK9   |= 1;
	PieCtrlRegs.PIEACK.all = BIT8;

	// Restore registers saved:
	DINT;
	PieCtrlRegs.PIEIER9.all = TempPIEIER;

#if (_ENABLE_INTERRUPT_PROFILE_LED1)
    if (enable_profile_led1_can)
    i_led1_on_off_special(0);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (enable_profile_led2_can)
    i_led2_on_off_special(0);
#endif

}


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

interrupt void CAN_reset_err(void)
{
//	Set interrupt priority:
	volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
	IER |= M_INT9;
	IER	&= MINT9;	  	                // Set "global" priority
	PieCtrlRegs.PIEIER9.all &= MG96;   // Set "group"  priority	
	PieCtrlRegs.PIEACK.all = 0xFFFF;   // Enable PIE interrupts	


#if (_ENABLE_INTERRUPT_PROFILE_LED1)
    if (enable_profile_led1_can)
    i_led1_on_off_special(1);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (enable_profile_led2_can)
    i_led2_on_off_special(1);
#endif

	EINT;

	if (ECanaRegs.CANGIF1.bit.AAIF1)
	{
		ECanaRegs.CANAA.all = ECanaRegs.CANAA.all;
	}

	if (ECanaRegs.CANGIF1.bit.WDIF1)
	{
		ECanaRegs.CANGIF1.bit.WDIF1=1;
	}
//	ECanaRegs.CANTRR.all = 1;
	CanTimeOutErrorTR++;

//	PieCtrlRegs.PIEACK.bit.ACK9   |= 1;
	PieCtrlRegs.PIEACK.all = BIT8;

//	Restore registers saved:
	DINT;
	PieCtrlRegs.PIEIER9.all = TempPIEIER;


#if (_ENABLE_INTERRUPT_PROFILE_LED1)
    if (enable_profile_led1_can)
    i_led1_on_off_special(0);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (enable_profile_led2_can)
    i_led2_on_off_special(0);
#endif

}




void timer_pause_enable_can_from_terminal(void)
{
       time_pause_enable_can_from_terminal++;
       if (time_pause_enable_can_from_terminal>=TIME_PAUSE_CAN_FROM_TERMINAL)
       {
           time_pause_enable_can_from_terminal=TIME_PAUSE_CAN_FROM_TERMINAL;
           flag_enable_can_from_terminal = 1;
       }

}


void timer_pause_enable_can_from_mpu(void)
{
       time_pause_enable_can_from_mpu++;
	   if (time_pause_enable_can_from_mpu>=TIME_PAUSE_CAN_FROM_MPU)
	   {
	     time_pause_enable_can_from_mpu=TIME_PAUSE_CAN_FROM_MPU;
         flag_enable_can_from_mpu = 1;
	   }
	
}

unsigned int test_can_live_mpu(void)
{
  if (CAN_timeout[get_real_out_mbox(MPU_TYPE_BOX,0)]==0)
  	return 1;
  else
    return 0;
}


unsigned int test_can_live_terminal(int n)
{
  if (CAN_timeout[get_real_out_mbox(TERMINAL_TYPE_BOX,n)]==0)
    return 1;
  else
    return 0;
}



/*
//===========================================================================
// No more.
//===========================================================================
*/