#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 без этого будет крив!!!

unsigned int CanPowse,CanGO;

unsigned int Maska[2][8]; 

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

FLAG chk,sig;
long time_1_5sec, time_5msec, time_5sec;

int sens_type[24];
int sens_pair[24];

int adc0[24];
int tmp0[24];
float tmpK[24];

FILTERBAT def_FILTERBAT = DEF_FILTERBAT;
FILTERBAT filter[40];

interrupt void cpu_timer1_isr_SENS(void);

/********************************************************************/    
/* Расчет модула тока из показаний двух фаз */                                
/********************************************************************/
float im_calc(float ia,float ib)
{
  float isa,isb;
  
	isa  = - 1.5 * (ia + ib);
	isb  = COSPi6 * (ia - ib);
	return  (2*sqrt(isa*isa+isb*isb)/3);
}


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

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

	if(!cReset)	ServiceDog();

	if(Read_Log) return;

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

	if((!sig.bit.Error)|(cTestLamp))	toggle_READY();
	else								set_READY();

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

		if(work_lamp)	GpioDataRegs.GPBCLEAR.bit.GPIO60=1;
		else			GpioDataRegs.GPBSET.bit.GPIO60=1;
		if(heat_lamp)	GpioDataRegs.GPBCLEAR.bit.GPIO58=1;
		else			GpioDataRegs.GPBSET.bit.GPIO58=1;
		if(errr_lamp)	GpioDataRegs.GPBCLEAR.bit.GPIO62=1;
		else			GpioDataRegs.GPBSET.bit.GPIO62=1;
	}

	if(count_bright == Brightness)
	if(!cTestLamp)
	{
		GpioDataRegs.GPBSET.bit.GPIO60=1;
		GpioDataRegs.GPBSET.bit.GPIO58=1;
		GpioDataRegs.GPBSET.bit.GPIO62=1;
	}

	if(cTestLamp & !preTest) 
	{
		count_blink = period_blink; 
		count_mode = 0;
	}
	preTest = cTestLamp;
	
	if(++count_blink >= period_blink)
	{
		count_blink=0;
		count_mode++;
		blink_over  = (count_mode & 1)?1:0;
		blink_alarm = (count_mode & 7)?1:0;

GpioDataRegs.GPBTOGGLE.bit.GPIO63=1;

/*	это чтоб доску тестить
if(cTestLamp)
{GpioDataRegs.GPBTOGGLE.bit.GPIO49=1;
toggle_READY();
GpioDataRegs.GPBTOGGLE.bit.GPIO52=1;}
*/

	}

	if(cExtLamp)
	{
		work_lamp = cExtLite;
		heat_lamp = cExtLite;
		errr_lamp = cExtLite;
	}
	else
	{
		if(cTestLamp)
		{
			work_lamp = blink_over;
			heat_lamp = blink_over;
			errr_lamp = blink_over;
		}
		else
		{
			work_lamp  = 1;	//	Горит всегда, ведь это "оперативное питание"

				 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;
}	}	}	


void Init_sensors()
{
  int i;

	period_blink = READY_FREQ;

	time_1_5sec	= (3 * ADC_FREQ) / 2;
	time_5msec	= (5 * ADC_FREQ) / 1000;
	time_5sec	= (5 * ADC_FREQ);

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

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

	for(i=0;i<40;i++) filter[i] = def_FILTERBAT;

	for(i=0;i<24;i++) modbus[i] &= NOER;

	MAX_TPL_CANAL = 12;
}

void Init_packMask()
{
  int i,j;

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

	for(i=0;i<24;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_FAST][1]|=0x0080;				//	Дискретные входы

	Maska[m_SLOW][6] = 0x0070;				//	Яркость ламп, период посылок

	Maska[m_SLOW][7]|= 0xE000;				// Адрес, команды, и чтоб не вылазило
}

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 er)
{
  unsigned int set;
  ERROR err;

	err=er;

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

void Temper_count(int chan)
{
  float Numb;
  int Temper;
  int no_ignor;
  ERROR error;

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

	if(chan<MAX_TPL_CANAL*2)
	if(sens_error[chan].bit.Bypas)
	{
		sens_error[chan].all = 0;		
		sens_error[chan].bit.Bypas = 1;
		sens_data[chan] = 0;
		return;
	}

	Numb = ADC_table[chan];

	if(cTermoCal)
	{
		sens_data[chan] = Numb;
		return;	//	штобы структура ошибок не влезала в данные
	}

	error.all = 0; 
	no_ignor = !sens_error[chan].bit.Ignor;

	Numb = (Numb-adc0[chan])*tmpK[chan]+tmp0[chan]-273;

	if(Numb < -20) Numb = -20;
	if(Numb > 200) Numb = 200;

	Temper = sens_data[chan] = calres[chan] = (int)(Numb*10);

//	Обрыв или неисправность
	if(Temper<=-200 || Temper>=2000)
	{
		error.bit.Tear  = 1;
		chk.bit.OutHeat = no_ignor;
	}
	
	if(!error.bit.Tear)
	{
	  	if(((Temper>sens_hi_edge[chan]-Cooling) && (sens_error[chan].bit.Hyper)) ||
			(Temper>sens_hi_edge[chan]) )
		{  	
			error.bit.Hyper	= 1;
			error.bit.Stop	= no_ignor;
			chk.bit.OverHeat= no_ignor;
		}

		else

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

	reset_errs(chan,error);
}

