#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h" 
#include "filter_bat2.h"
#include "package.h"

#include "measure.h"
#include "package.h"

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

#include "RS485.h"
#include "message.h"
#include "log_to_mem.h"

#include <math.h>	//	Это чтобы мерить амплитуду! sqrt без этого будет крив!!!

int TPL_CANS=0;	// Количество температурных каналов 
int tpl_cans=0;
int cal_addr=0;

FLAG chk,sig;

int sens_type[SIZE];
int sens_pair[SIZE];

float Kt[2];

FILTERBAT def_FILTERBAT = DEF_FILTERBAT;
FILTERBAT adc_filter[ADC_MAX];
float out_filter[ADC_MAX];

unsigned int CanPowse=CANPOWSE,CanGO=0;
unsigned long Caliber_time=0;

int GOOD[0x10];
int ZERO[0x10];

ERROR okay;

void calc_sensor_koef()
{
	if(TermoRS)
	{
		Kt[0] = 129.0/(K150_D - K100_D); 
	}

	if(TermoAD)
	{
		Kt[0] = 100.0/(K400_1 - K300_1);
		Kt[1] = 100.0/(K400_2 - K300_2);
}	}


interrupt void cpu_timer1_isr_SENS()
{
  static unsigned int count_blink, count_bright, count_mode,
  blink_over, blink_alarm, work_lamp, heat_lamp;  
  
  int TST;
  static int preTest;

	EALLOW;
	CpuTimer1.InterruptCount++;
	IER |= MINT13;                 // Set "global" priority
	EINT;
  	EDIS;    // This is needed to disable write to EALLOW protected registers

	if(!cReset)
	ServiceDog();

	if(++CanPowse >= CANPOWSE)
	{
		CanPowse = 0;
		CanGO = 1;
	}

	TST = cTestLamp|bTestLamp;

	if(!sig.bit.Error|TST)	toggle_READY();
	else					clear_READY();			

	if(++count_bright >= maximum_bright)
	{
		count_bright = 0 ;

		if(work_lamp)	set_LED_OUT_1();
		else			clear_LED_OUT_1();
		if(heat_lamp)	set_LED_OUT_2();
		else			clear_LED_OUT_2();
	}	

	if(!TST)
	{
		if(count_bright == Bright[0]) clear_LED_OUT_1();
		if(count_bright == Bright[1]) clear_LED_OUT_2();
	}

	if(TST & !preTest) 
	{
		count_blink = BLINK_TIME; 
		count_mode = 0;
	}
	preTest = TST;

	if(++count_blink >= BLINK_TIME)
	{
		count_blink=0; count_mode++;
		blink_over  = (count_mode & 1)?1:0;
		blink_alarm = (count_mode & 7)?1:0;

		if(TST)
		{
			heat_lamp = blink_over;
			work_lamp = blink_over;
		}
		else
		{
			if(Light[0] == 0)
			{
				if(sig.bit.Error)		work_lamp  = blink_over;
				else					work_lamp  = 1;

				if(bSecretBt|cSecretBt)	work_lamp  = blink_alarm;
			}
			else	if(Light[0] == 2)		work_lamp  = 1; 
			else	if(Light[0] == 3)		work_lamp  = blink_over;
			else	if(Light[0] == 4)		work_lamp  = blink_alarm; 
			else	if(Light[0] == 5)		work_lamp  = !blink_alarm;
			else							work_lamp  = 0;

			if(Light[1] == 0)
			{
					 if(sig.bit.OverHeat)	heat_lamp  = 1;
				else if(sig.bit.SubHeat)	heat_lamp  = blink_over;
				else if(sig.bit.OutHeat)	heat_lamp  = !blink_alarm;
				else						heat_lamp  = 0;
			}
			else	if(Light[1] == 2)		heat_lamp  = 1; 
			else	if(Light[1] == 3)		heat_lamp  = blink_over;
			else	if(Light[1] == 4)		heat_lamp  = blink_alarm; 
			else	if(Light[1] == 5)		heat_lamp  = !blink_alarm;
			else							heat_lamp  = 0;
}	}	}

void Init_sensors()
{
  int i,cans;

	GOOD[TERMO_AD ]=40;
	GOOD[TERMO_RS ]=40;
	ZERO[TERMO_AD ]=27;
	ZERO[TERMO_RS ]=0;

	okay.all=0;
	okay.bit.Tear=1;
	okay.bit.Bypas=1;
	okay.bit.Ignor=1;
	okay.bit.Imit=1;

	for(i=0;i<SIZE;i++) 
	{
		sens_type[i]=0;
		sens_pair[i]=i;
	}

	for(i=0;i<ADC_MAX;i++) 
	{
		adc_filter[i] = def_FILTERBAT;
		out_filter[i] = 0;
	}

	if(Desk==dsk_COMM)
	{
		if(Mode==adr_INV1 || Mode==adr_INV2) TPL_CANS = TPL_INV;
		if(Mode==adr_FLT1 || Mode==adr_FLT2) TPL_CANS = TPL_FLT;

		tpl_cans = TPL_CANS*2; cal_addr = tpl_cans; cans = TPL_CANS + 2;

		for(i=0;i<tpl_cans;i++) sens_type[i] = TERMO_AD;
	}

	if(Desk==dsk_BKSD)
	{
		TPL_CANS = TPL_ENG; tpl_cans = TPL_CANS; cal_addr = tpl_cans; cans = TPL_CANS + 2;

		for(i=0;i<tpl_cans;i++) sens_type[i] = TERMO_RS;
	}

	MesPerSec = MesPerSec*3/cans;	//	типа, три секунды
}

void Init_packMask()
{
  int i,j;

	for(i=0;i<2; i++)
	for(j=0;j<8;j++) { Maska[i][j]=0; }

	switch(Mode)
	{
		case adr_PLT1:	
			Maska[m_SLOW][0]|= 0x3CFF;						//	Полученное
			Maska[m_SLOW][6]|= 0x7F00;						//	Яркость 7 ламп
			break;

		case adr_PLT2:	
			Maska[m_SLOW][0]|= 0x000F;						//	Полученное
			Maska[m_SLOW][6]|= 0x0F00;						//	Яркость 4 ламп
			break;

		default: 	
			for(i=0;i<start_data;i++)
			if(sens_type[i])
			{
				Maska[m_FAST][ i    /16]|=(1<<( i    %16));	//	Диагностика
				Maska[m_FAST][(i+24)/16]|=(1<<((i+24)%16));	//	Показаниа
			}
			for(i=0;i<3; i++)
				Maska[m_SLOW][i+3] = Maska[m_FAST][i];		//	Уставки
				
			Maska[m_SLOW][6]|=0x0F00;						//	Яркость и управление 2 ламп 
			
			if(Desk == dsk_BKSD)
			Maska[m_SLOW][7]|=0x0003;						//	Калибр термодатчиков
			else
			Maska[m_SLOW][7]|=0x000F;						//	Калибр термодатчиков

			break;
	}

	if(Desk==dsk_PULT)
	{
		Maska[m_SLOW][2]|= 0x0003;	j=0x0004;
		for(i=0;i<RSleng;i++)
		{
			Maska[m_SLOW][2]|= j<<i;
	}	}

	Maska[m_FAST][1]|= 0x0003;								// Дискретные kнопки
	Maska[m_SLOW][6]|= 0x00FF;								// Периоды посылок
	Maska[m_FAST][7]|= 0x0100;								// Счетчик посылок
	Maska[m_SLOW][7]|= 0x0E00;								// Счетчик посылок
	Maska[m_SLOW][7]|= 0x6000;								// Протокол, адрес
	Maska[m_FAST][7]|= 0x8000;								// Команды
}

int er_anal(int term, long * count, int edge, int pre)
{                                 
	if (term)
	{
		if((*count)>=edge)	return 1;
		(*count)++;			return pre;
	} 
	if( (*count) == 0 ) 	return 0;
	(*count)--;				return pre;
}   

void reset_errs(int sens, ERROR err)
{
  ERROR set;

	set = sens_error[sens];
	if(!set.bit.Latch) set.all &= NOER;
	set.all |= err.all;
	chk.bit.Error|= set.bit.Stop;
	set.bit.Ready = !set.bit.Stop;
	sens_error[sens] = set;
}

void Temper_count(int chan)
{
  float Numb,Temper,s;
  ERROR error;
  int i,j,kun;

	if(!chan)
	{
		sig.all = chk.all;
		chk.all = 0;
	}

	if(sens_error[chan].bit.Bypas)
	if(chan<tpl_cans)	// чтоб калибровку не сломать
	{
		sens_error[chan].all = 0;		
		sens_error[chan].bit.Bypas = 1;
		sens_data[chan] = 0;
		return;
	}

	Numb = ADC_table[chan];

	if(cRawMeat)
	{
		sens_data[chan] = Numb;
		return;
	}

	if(sens_error[chan].bit.Imit)
	if(chan<tpl_cans)
	{
		s=j=0;

		for(i=0;i<SIZE;i++)
		{
			if( sens_type[i]==sens_type[chan])
			if(!(sens_error[i].all & okay.all))
			{
				s+=ADC_table[i];
				j++;
		}	}

		if(j) s/=j;
		Numb = s;
	}

	if(WAKE)out_filter[chan] = Numb;
	else	out_filter[chan]+=(Numb-out_filter[chan])/MesPerSec;
	Numb = out_filter[chan];

	kun = chan - cal_addr;

	if(kun>=0)
	{
		if(TermoRS|cTermoCal|bTermoCal)
		if(!WAKE)
		{
			TCaliber[kun] = Numb;
			calc_sensor_koef();
		}
		return;
	}

	kun = chan&1 & !TermoRS;

	Temper = (Numb - TCaliber[kun])*Kt[kun]+ZERO[sens_type[chan]];

	if(Temper < -10.0) Temper =-100.0;
	if(Temper > 200.0) Temper = 200.0;

	if(bSecretBt|cSecretBt) Temper = GOOD[sens_type[chan]];

	sens_data[chan] = Temper*10;

	error.all = 0;

	if(!sens_error[chan].bit.Ignor)
	{
//		Обрыв или неисправность
		if(Temper<=-10 || Temper>=200)
		{
			error.bit.Tear	= 1;
			chk.bit.OutHeat	= 1;
		}
		else

//		Перегрев
	  	if(((Temper>sens_hi_edge[chan]-Cooling) && (sens_error[chan].bit.Hyper)) ||
			(Temper>sens_hi_edge[chan]) )
		{  	
			error.bit.Hyper	= 1;
			error.bit.Stop	= 1;
			chk.bit.OverHeat= 1;
		}
		else

//		Предупреждение по температуре
		if(Temper>sens_lo_edge[chan])
		{
			error.bit.Over	= 1;
			chk.bit.SubHeat	= 1;
	}	}

	if(!WAKE)
	reset_errs(chan,error);
}

