#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"
#include "profile_interrupt.h"




unsigned int CanTimeOutErrorTR = 0;
unsigned int CanBusOffError = 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;
int flag_disable_update_modbus_in_can_from_mpu=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")
// счетчик
unsigned 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_ALARM_LOG;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()
{
	unsigned int i, t_refresh;
	static unsigned int old_time = 0;

	t_refresh = get_delta_milisec(&old_time, 1);
	if (t_refresh>1000)
	    t_refresh = 1000;
	

	for(i = 0; i < UNIT_QUA; i++)
	{
		if (CAN_timeout_cicle[i] < MAX_CAN_WAIT_TIMEOUT)
		{
		        CAN_timeout_cicle[i] += t_refresh;
		}
		else
		{
			CAN_timeout[i] = 1;
			CAN_refresh_cicle[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==125000)
//    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)
//    ECanaShadow.CANBTC.bit.SJWREG=1;
    ECanaShadow.CANBTC.bit.BRPREG   = 63;//29;//11;// 47;              //59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
    ECanaShadow.CANBTC.bit.TSEG1REG = 9;//9;//  15;        //5;//7;//14;//10;//7;  // Bit time = 15
    ECanaShadow.CANBTC.bit.TSEG2REG = 3;//4; //  2;     //4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
    ECanaShadow.CANBTC.bit.SJWREG   = 3;//3;
//    ECanaShadow.CANBTC.bit.BRPREG   = 31;//29;//11;// 47;              //59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
//    ECanaShadow.CANBTC.bit.TSEG1REG = 6;//9;//  15;        //5;//7;//14;//10;//7;  // Bit time = 15
//    ECanaShadow.CANBTC.bit.TSEG2REG = 1;//4; //  2;     //4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
//    ECanaShadow.CANBTC.bit.SJWREG   = 1;//3;
#else
#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)
//    ECanaShadow.CANBTC.bit.SJWREG   = 1;


    ECanaShadow.CANBTC.bit.BRPREG   = 47;//29;//11;// 47;              //59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
    ECanaShadow.CANBTC.bit.TSEG1REG = 6;//9;//  15;        //5;//7;//14;//10;//7;  // Bit time = 15
    ECanaShadow.CANBTC.bit.TSEG2REG = 1;//4; //  2;     //4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
    ECanaShadow.CANBTC.bit.SJWREG   = 1;//3;
#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)
    ECanaShadow.CANBTC.bit.SJWREG=1;
#else
#error "Set Can speed in CAN_project.h!!!"

#endif
#endif
#endif

    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; //Abort Acknowledge Interrupt Mask.
	ECanaShadow.CANGIM.bit.BOIM=1; // Bus-off interrupt mask
	ECanaShadow.CANGIM.bit.EPIM=1; // Error-passive interrupt mask
	ECanaShadow.CANGIM.bit.RMLIM=1; // Received-message-lost interrupt mask
	ECanaShadow.CANGIM.bit.WUIM=1; // Wake-up interrupt mask
	ECanaShadow.CANGIM.bit.WLIM=1; // Warning level interrupt mask
	ECanaShadow.CANGIM.bit.WDIM=1; // Write denied interrupt mask
	ECanaShadow.CANGIM.bit.TCOM=1; // Time stamp counter overflow mask

	ECanaShadow.CANGIM.bit.MTOM = 1; //Mailbox time-out interrupt mask
	ECanaShadow.CANGIM.bit.I1EN = 1; //Interrupt 1 enable
	ECanaShadow.CANGIM.bit.GIL = 1; // Global interrupt level for the interrupts TCOF, WDIF, WUIF, BOIF, EPIF, RMLIF, AAIF and WLIF.
	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] = MAX_CAN_WAIT_TIMEOUT;
		 CAN_refresh_cicle[i] = -1;
    }


	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]++;
	    if (box<MAX_COUNT_UNITES_UKSS)
	        unites_can_setup.CAN_count_cycle_input_units[box]++;
	}
}

////////////////////////////////////////////////////////////////
//  инкремен счетчика полных посылок для МПУ
////////////////////////////////////////////////////////////////
void detect_time_refresh_mpu(int box, int adr)
{
    if (box>=MPU_UNIT_QUA_UNITS)
      return;

    if (adr==mpu_can_setup.adr_detect_refresh[box])
    {
        //CAN_count_cycle_input_units[box]++;
        if (box<MAX_COUNT_UNITES_MPU)
            mpu_can_setup.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)
					{
					    if (flag_enable_can_from_mpu && flag_disable_update_modbus_in_can_from_mpu==0)
					        modbus_table_can_in[adr-1].all = /*(unsigned int)*/((hiword    ) & 0xffff);
			        	detect_time_refresh_mpu(local_number_box,adr-1);
					}
			        adr++;
				}
				else
				{
				    err++;
				}
			}
			if(bit[1])
			{
				timer_pause_enable_can_from_mpu();
				if (adr<SIZE_MODBUS_TABLE)
				{
		    		if (adr>0)
			        {	
		    		    if (flag_enable_can_from_mpu && flag_disable_update_modbus_in_can_from_mpu==0)
		    		        modbus_table_can_in[adr-1].all = /*(unsigned int)*/((loword>>16) & 0xffff);
			        	detect_time_refresh_mpu(local_number_box,adr-1);
					}
			        adr++;
				}
                else
                {
                    err++;
                }
			}

			if(bit[2])
			{
				timer_pause_enable_can_from_mpu();
				if (adr<SIZE_MODBUS_TABLE)
				{
					if (adr>0)
					{
					    if (flag_enable_can_from_mpu && flag_disable_update_modbus_in_can_from_mpu==0)
					        modbus_table_can_in[adr-1].all = /*(unsigned int)*/((loword) & 0xffff);
	        		   detect_time_refresh_mpu(local_number_box,adr-1);
					}
					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 (profile_interrupt.for_led1.bits.can)
    i_led1_on_off_special(1);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (profile_interrupt.for_led2.bits.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 (profile_interrupt.for_led1.bits.can)
    i_led1_on_off_special(0);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (profile_interrupt.for_led2.bits.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 (profile_interrupt.for_led1.bits.can)
    i_led1_on_off_special(1);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (profile_interrupt.for_led2.bits.can)
    i_led2_on_off_special(1);
#endif

	EINT;


//    ECanaShadow.CANGIM.bit.AAIM=1; //Abort Acknowledge Interrupt Mask.
//    ECanaShadow.CANGIM.bit.BOIM=1; // Bus-off interrupt mask
//    ECanaShadow.CANGIM.bit.EPIM=1; // Error-passive interrupt mask
//    ECanaShadow.CANGIM.bit.RMLIM=1; // Received-message-lost interrupt mask
//    ECanaShadow.CANGIM.bit.WUIM=1; // Wake-up interrupt mask
//    ECanaShadow.CANGIM.bit.WLIM=1; // Warning level interrupt mask
//    ECanaShadow.CANGIM.bit.WDIM=1; // Write denied interrupt mask
//    ECanaShadow.CANGIM.bit.TCOM=1; // Time stamp counter overflow mask
//
//    ECanaShadow.CANGIM.bit.MTOM = 1; //Mailbox time-out interrupt mask


	if (ECanaRegs.CANGIF1.bit.AAIF1) // Abort-acknowledge interrupt flag
	{
		ECanaRegs.CANAA.all = ECanaRegs.CANAA.all;
	}

	if (ECanaRegs.CANGIF1.bit.WDIF1)  //Write-denied interrupt flag
	{
		ECanaRegs.CANGIF1.bit.WDIF1=1;
	}

    if (ECanaRegs.CANGIF1.bit.BOIF1) // Bus off interrupt flag
    {
        ECanaRegs.CANGIF1.bit.BOIF1=1;
        CanBusOffError++;
    }



//	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 (profile_interrupt.for_led1.bits.can)
    i_led1_on_off_special(0);
#endif
#if (_ENABLE_INTERRUPT_PROFILE_LED2)
    if (profile_interrupt.for_led2.bits.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;
}



void InitCanSoft(void)
{
  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;


//  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;
    /*
    EALLOW;
    ECanaShadow.CANBTC.all = ECanaRegs.CANBTC.all;

#if (CAN_SPEED_BITS==125000)
//    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)
//    ECanaShadow.CANBTC.bit.SJWREG=1;
    ECanaShadow.CANBTC.bit.BRPREG   = 63;//29;//11;// 47;              //59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
    ECanaShadow.CANBTC.bit.TSEG1REG = 9;//9;//  15;        //5;//7;//14;//10;//7;  // Bit time = 15
    ECanaShadow.CANBTC.bit.TSEG2REG = 3;//4; //  2;     //4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
    ECanaShadow.CANBTC.bit.SJWREG   = 3;//3;
#else
#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)
//    ECanaShadow.CANBTC.bit.SJWREG   = 1;


    ECanaShadow.CANBTC.bit.BRPREG   = 47;//29;//11;// 47;              //59;//49;//4;//9;    // (BRPREG + 1) = 10 feeds a 15 MHz CAN clock
    ECanaShadow.CANBTC.bit.TSEG1REG = 6;//9;//  15;        //5;//7;//14;//10;//7;  // Bit time = 15
    ECanaShadow.CANBTC.bit.TSEG2REG = 1;//4; //  2;     //4;//5;//7;//2;//5 ; // to the CAN module. (150 / 10 = 15)
    ECanaShadow.CANBTC.bit.SJWREG   = 1;//3;
#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)
    ECanaShadow.CANBTC.bit.SJWREG=1;
#else
#error "Set Can speed in CAN_project.h!!!"

#endif
#endif
#endif

    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; //Abort Acknowledge Interrupt Mask.
    ECanaShadow.CANGIM.bit.BOIM=1; // Bus-off interrupt mask
    ECanaShadow.CANGIM.bit.EPIM=1; // Error-passive interrupt mask
    ECanaShadow.CANGIM.bit.RMLIM=1; // Received-message-lost interrupt mask
    ECanaShadow.CANGIM.bit.WUIM=1; // Wake-up interrupt mask
    ECanaShadow.CANGIM.bit.WLIM=1; // Warning level interrupt mask
    ECanaShadow.CANGIM.bit.WDIM=1; // Write denied interrupt mask
    ECanaShadow.CANGIM.bit.TCOM=1; // Time stamp counter overflow mask

    ECanaShadow.CANGIM.bit.MTOM = 1; //Mailbox time-out interrupt mask
    ECanaShadow.CANGIM.bit.I1EN = 1; //Interrupt 1 enable
    ECanaShadow.CANGIM.bit.GIL = 1; // Global interrupt level for the interrupts TCOF, WDIF, WUIF, BOIF, EPIF, RMLIF, AAIF and WLIF.
    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] = MAX_CAN_WAIT_TIMEOUT;
//         CAN_refresh_cicle[i] = -1;
//    }


//    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++)
//    {
//        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;


}





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

