#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File

#include "cntrl_adr.h"
#include "RS485.h"
#include "BIOS_DSP.h"
#include "Message.h"
#include "filter_bat2.h"
#include "measure.h"
#include "package.h"

#include "spise2p.h"
#include "i2c.h"


#include "tools.h"
#include "peripher.h"
#include "ADC.h"

#include "ecan.h"
#include "kanal.h"
#include "pulto.h"
#include "log_to_mem.h"

#include "measure.h"

extern void DSP28x_usDelay(Uint32 Count);

void timer_Init()
{
	EALLOW;  // This is needed to write to EALLOW protected registers
	if(Desk==dsk_PULT)	PieVectTable.XINT13 = &cpu_timer1_isr_PULT;
	else				PieVectTable.XINT13 = &cpu_timer1_isr_SENS;
	EDIS;    // This is needed to disable write to EALLOW protected registers

	ConfigCpuTimer(&CpuTimer1, SYSCLKOUT/1000000, 1000000/(READY_FREQ*2));
	CpuTimer1Regs.TCR.all = 0x4020; // Use write-only instruction to set TSS bit = 0
	IER |= M_INT13;
}

int Isit(int num, int i, int z)
{
  int res, pls;

	if((num<0)||(num>=0x80)) return 0;
	res = Maska[i][num/0x10];
	res &= (1<<(num&0x0F));

	if(z)	//	данные реально изменилис
	{
		pls = (espero[num]>CanRestart[i]/2);
		pls = pls || county[num];
		res = res && pls;
	}

	return res;
}

void main()
{
  int i,j,n,z,mask,qua;
  static int rscount, cancount[2]={1,2},cancell[2]={0,0},candid[2]={0,0};
  static unsigned int masca[8], presbyt;
  static int precom=0;

  RS_DATA * rs;

	InitSysCtrl();

//	Disable CPU interrupts and clear all CPU interrupt flags:
	DINT;

	InitPieCtrl();

	IER = 0x0000;
	IFR = 0x0000;

	InitPieVectTable();

	init_zone7();

	setup_leds_line();
	led1_on();
	led2_off();
	for (i=0;i<10;i++)
	{
		pause_us(50000);
		led2_toggle();
		led1_toggle();
	}
	led1_off();
	led2_off();

	get_Mode();

	set_cntrl_addr(Mode,16);
	create_uart_vars(sizeof(CMD_TO_TMS));
	setup_uart(COM_1,115200);
	setup_uart(COM_2,115200);
	InitSeeprom();
	InitCan(0,CanDevAdr);
	timer_Init();
	clear_mem();

	if(Desk!=dsk_PULT)
	{
		setup_adc();
	}
	Init_sensors();

	EnableInterrupts();

	Load_params();

	Init_packMask();

	LastMode = Mode;
	Protokol = PROTOKOL;
	precom = Commands;

	for(i=0;i<0x80;i++)
	county[i]=1;
	for(i=0;i<8;i++)
	masca[i]=0;
	for(i=0;i<2;i++)
	CanRound[i]=
	CanCycle[i]=0;

    EALLOW;
    SysCtrlRegs.WDCR= 0x2F;
    EDIS;

	while(1)
	{
		if( CanGO)
		{	CanGO = 0;

			if(Desk==dsk_PULT)
			if(RScount)
			if(++rscount >= RScount) 
			{
				rscount = 0;
				SendCorreoRS(&rs_b);
				led1_toggle();
			}
			
			for(i=0;i<0x80;i++)
			if(espero[i]<30000) espero[i]++;
				
			for(i=0;i<2;i++)
			if(cancount[i]) cancount[i]--;
			else cancell[i] = 0;
		}	

		for(i=0;i<2;i++)
		if( Cancount[i])
		if(!cancount[i]) 
		{
			while(1)
			{

				if( cancell[i]>= 0x80)
				{	cancell[i]=0;

					if( candid[i])
					{	candid[i]=0;
						CanCycle[i]++;
						cancount[i] += CanWait[i];
						goto Next;
				}	}

				mask = Maska[i][cancell[i]/0x10] >> (cancell[i]&0x0F);
				if(!mask) cancell[i] = (cancell[i] + 0x10) & 0xFFF0 ;
				else
				{
					while(!(mask & 1))
					{
						cancell[i]++; mask >>= 1;
					}
					break;
			}	}
			
			z=1;
			if(espero[cancell[i]]>CanRestart[i])
			{
				county[cancell[i]]=1;
				z=0;
			}

			n=1;
			if( (Desk==dsk_COMM)||(Desk==dsk_BKSD) )
			if(cancell[i]>=start_data)
			if(cancell[i]<=start_hi_edge)
			if(sens_type[cancell[i]-start_data]>=TERMO_AD)
			n=5;

			if(abs(modbus[cancell[i]]-archiv[cancell[i]])>=n)
			{	
				if(cancell[i]==keys)
				for(j=0;j<CanRptLen;j++)
				county[cancell[i]+j] = CanRptVez;
				else	
				county[cancell[i]] = 1;
			}

			if (county[cancell[i]])
			{
				for(j=  3; j>0 && !Isit(cancell[i]+j,i,z); j--);
				for(n=j-3; n<0 && !Isit(cancell[i]+n,i,1); n++);

				qua = 1 + j - n;
				cancell[i]+= n;

				for(j=0;j<qua;j++)
				{
					n=cancell[i]+j;
					archiv[n]= modbus[n];
					espero[n]=0;

					if( county[n])
					{	county[n]--;
						if(!county[n] && n != cancyclo+i)	candid[i]=1;
					}	
					if(!county[n]) masca[n/0x10] |= (1<<(n&0x0F));
				}	

				CAN_send(0,archiv,cancell[i],qua);

				cancount[i] = Cancount[i];
				cancell[i]+=qua; 

				for(j=0;j<8;j++)
				if((masca[j] & Maska[i][j]) != Maska[i][j]) break;
				if(j==8)
				{
					for(j=0;j<8;j++) masca[j]&=~Maska[i][j];
					CanRound[i]++;
				}

				if( Cancount[i]>1)
				if(!cancount[!i])
					cancount[!i]=1;	// чтобы не сразу
			}
			else	cancell[i]++;
		}	

		Next:

		get_Buttons();

		if(Commands!=precom)
		komanda = Commands & (~precom|komanda);
		precom = Commands;

		if(cDefParam)
		{
			cDefParam=0;
			Default_params();
			Commands=precom;
		}

		if(cSaveParam)
		{
			cSaveParam=0;
			Save_params();
		}

		if(cLoadParam)
		{
			cLoadParam=0;
			Load_params();
			Commands=precom;
		}

		if(cKoefCalc)
		{
			cKoefCalc=0;
			calc_sensor_koef();
		}

		if(!bTermoCal & presbyt) 
		{
			cSaveParam	= 1;
			cCanReset	= 1;
		}
		presbyt = bTermoCal;

		if(cCanReset)
		{
			cCanReset=0;

			for(i=0;i<0x80;i++)
			county[i]=1;
			for(i=0;i<2;i++)
			CanCycle[i]=
			CanRound[i]=
			cancount[i]=
			cancell[i]=0;
			for(i=0;i<8;i++)
			masca[i]=0;
		}

		for(i=0;i<2;i++)
		{
			if(i)	rs = &rs_a;
			else	rs = &rs_b;

			j = get_command(rs);

			if(j!=-1)
			{
				LoneLeft=0;
				LoneRite=0;
				led2_toggle();
				switch(j)
				{
					case CMD_INIT:		init(rs);		 break;	// начальные установки
					case CMD_INITLOAD:	initload(rs);	 break;	// настройка загрузки
					case CMD_RUN:		run(rs);		 break;	// загрузить блок
					case CMD_LOAD:		load(rs);		 break;	// загрузить блок
					case CMD_PEEK:		peek(rs);		 break;	// прочитать  ачейку памати
					case CMD_POKE:		poke(rs);		 break;	// записать в ачейку памати
					case CMD_UPLOAD:	upload(rs);		 break;	// передать блок памати
					case CMD_EXTEND:	extendbios(rs);	 break;	// расширенные команды дла биоса
			    	case CMD_TFLASH:	tflash(rs);		 break;	// прошить TMS
			    	case CMD_MODBUS_3: 	ReceiveCommandModbus3(rs);	 break;
			    	case CMD_MODBUS_6: 	ReceiveCommandModbus6(rs);	 break;

					default:   break;
}	}	}	}	}
