#include "DSP2833x_Device.h"     // DSP281x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP281x Examples Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"

#include "ADC.h"

#include "log_to_mem.h"
#include "RS485.h"
#include "filter_bat2.h"

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

#include "peripher.h"

float ADC_table[ADC_MAX];
int prev_ok[ADC_MAX];

float MesPerSec;
unsigned int COUNT_ONE_CANAL;
unsigned int COUNT_ONE_CANAL;
unsigned int COUNT_DISCHARGE;
unsigned int COUNT_TRANSICIA;
unsigned int FILTER_CLIP;

long WAKE, WAKE_TIME;

// Prototype statements for functions found within this file.
interrupt void adc_isr(void);

void setup_adc()
{
  long CLKdiv,HSPCLKdiv,Rate;
  int i;

//	Interrupts that are used in this example are re-mapped to
//	ISR functions found within this file.
	EALLOW;  // This is needed to write to EALLOW protected register
	PieVectTable.ADCINT = &adc_isr;
	EDIS;    // This is needed to disable write to EALLOW protected registers

	InitAdc();  // For this example, init the ADC

//	Enable ADCINT in PIE
	PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
	IER |= M_INT1; // Enable CPU Interrupt 1

// Configure ADC
	if(Desk==dsk_BKSD)	
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0000;       // Setup 2 conv's on SEQ1
		AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //0x5;//0x7; // Setup ADCINA3 as 1st SEQ1 conv.
	}

	if(Desk==dsk_COMM)
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0001;       // Setup 2 conv's on SEQ1
		AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5;	//	сначала тоже будут температуры
		AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x4;	//	Setup ADCINA2 as 2nd SEQ1 conv.
/*													А напражений нам тут и не надо
		AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x7;	//	Setup ADCINA2 as 2nd SEQ1 conv.
		AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x2;	//	Setup ADCINA2 as 2nd SEQ1 conv.
		AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x3;	//	Setup ADCINA2 as 2nd SEQ1 conv.
		AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x6;	//	Setup ADCINA2 as 2nd SEQ1 conv.
		AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x1;	//	Setup ADCINA2 as 2nd SEQ1 conv.
*/	}

AdcRegs.ADCREFSEL.bit.REF_SEL=1;

	AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;	//	Enable SOCA from ePWM to start SEQ1
	AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;	//	Enable SEQ1 interrupt (every EOS)
	AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;		//	Clear INT SEQ1 bit
 	AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;		//	1  Cascaded mode
	AdcRegs.ADCTRL1.bit.ACQ_PS = 15;
	AdcRegs.ADCTRL1.bit.CONT_RUN = 0;
//	AdcRegs.ADCTRL1.bit.CPS=1;
	AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;		//	Reset SEQ1
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;	//	Acknowledge interrupt to PIE
	
//	Assumes ePWM1 clock is already enabled in InitSysCtrl();
	EPwm1Regs.ETSEL.bit.SOCAEN = 1;        // Enable SOC on A group
	EPwm1Regs.ETSEL.bit.SOCASEL = 4;       // Select SOC from from CPMA on upcount
	EPwm1Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event
	EPwm1Regs.CMPA.half.CMPA = 0x0080;	  // Set compare A value

	EPwm1Regs.TBCTL.bit.HSPCLKDIV = CLKMULT;
	EPwm1Regs.TBCTL.bit.CLKDIV=2;

	CLKdiv = 1<<EPwm1Regs.TBCTL.bit.CLKDIV;
	if(EPwm1Regs.TBCTL.bit.HSPCLKDIV) HSPCLKdiv = 2*EPwm1Regs.TBCTL.bit.HSPCLKDIV;
	else HSPCLKdiv = 1;

	Rate = (SYSCLKOUT/(HSPCLKdiv*CLKdiv))/ADC_FREQ;

	EPwm1Regs.TBPRD = Rate;//0x4000;       // Set period for ePWM1
	EPwm1Regs.TBCTL.bit.CTRMODE = 0;		  // count up and start

	if(TermoRS)
	{
		MesPerSec = 250;
		COUNT_ONE_CANAL = ADC_FREQ/250;	// 15
		COUNT_DISCHARGE = 4;
		COUNT_TRANSICIA = 9;
		FILTER_CLIP = 40;
		WAKE_TIME =7L * ADC_FREQ;
	}
	if(TermoAD)
	{
		MesPerSec = 15;
		COUNT_ONE_CANAL = ADC_FREQ/15;	// 250;
		COUNT_DISCHARGE = ADC_FREQ/145;	// 25;
		COUNT_TRANSICIA = ADC_FREQ/25;	// 150;
		FILTER_CLIP = 200;
		WAKE_TIME =5L * ADC_FREQ;
	}
	
	WAKE = WAKE_TIME;

	for(i=0;i<ADC_MAX;i++)
		ADC_table[i]=
		prev_ok[i]=0;
}

interrupt void  adc_isr(void)
{
  static int cownt_one_canal=0;
  static int cownt_cans=0;
  int code_tpl_canal=0;
  float Temper,Filter;
  int i,n;

  static int ok, cwnt_ok[2]={0,0};

	// Set interrupt priority:
	volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER1.all;
	IER |= M_INT1;
	IER	&= MINT1;	  	               // Set "global" priority
	PieCtrlRegs.PIEIER1.all &= MG11;   // Set "group"  priority
	PieCtrlRegs.PIEACK.all = 0xFFFF;   // Enable PIE interrupts
	EINT;

	if( WAKE)
	{	WAKE--;
		if(!WAKE) cCanReset	= 1;
	}

	if(WAKE > WAKE_TIME - 10) goto fin;

	if(Caliber_time)
	{
		if(!--Caliber_time)
		{
			cTermoCal	= 0;
			cSaveParam	= 1;
			cCanReset	= 1;
	}	}

	if(cownt_one_canal==COUNT_DISCHARGE)
	{
		code_tpl_canal = cownt_cans;

		if(TermoAD)
		{
			if(cownt_cans == TPL_CANS  ) code_tpl_canal = TERMOPAIR-1;
			if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2;	// потому что 300 и 400 наоборот
		}
		select_tpl_canal(code_tpl_canal);
	}

	if(cownt_one_canal > COUNT_TRANSICIA)
	for(i=0;i<TermoSW;i++)
	{
		n = TermoSW*cownt_cans+i;

		Temper = *(&AdcRegs.ADCRESULT0 + i) >>4;
		Filter = filterbat(&adc_filter[n],Temper);

		ok = abs(ADC_table[n]-Temper) < FILTER_CLIP;

		if(ok) cwnt_ok[i]++;

		if(ok|!prev_ok[n])
		{
			if(WAKE)ADC_table[n] = Temper;
			else	ADC_table[n] = Filter;
	}	}

	if(++cownt_one_canal>=COUNT_ONE_CANAL)
	{	 cownt_one_canal=0;

		select_tpl_255();

		for(i=0;i<TermoSW;i++)
		{
			n = TermoSW*cownt_cans+i;
			Temper_count(n);
			prev_ok[n] = cwnt_ok[i];
			cwnt_ok[i] = 0;
		}

		if(++cownt_cans>= TPL_CANS+2)
			 cownt_cans = 0;
	}

	fin:

//	Reinitialize for next ADC sequence
	AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
	AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

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

	return;
}
