#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"

#define SIZE_ADC_BUF 1000
Uint16 adc_table_lem[16];
Uint16 adc_table_tpl[32];
Uint16 ConversionCount;

unsigned long COUNT_WAIT_ONE_CANAL;

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

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

   #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
     #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
   #endif
   #if (CPU_FRQ_100MHZ)
     #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
   #endif

// Specific clock setting for this example:
//   EALLOW;
//   SysCtrlRegs.HISPCP.all = ADC_MODCLK;	// HSPCLK = SYSCLKOUT/ADC_MODCLK
//   EDIS;

// 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
//   EINT;          // Enable Global interrupt INTM
//   ERTM;          // Enable Global realtime interrupt DBGM

// Configure ADC
	if(Desk==dsk_LOAD)	
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0005;       // Setup 2 conv's on SEQ1

		AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3;	//	температура (которой нет)
		AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;	//	омега
		AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5;	//	напруга 1
		AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4;	//	напруга 2
		AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7;	//	ток 1
		AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2;	//	ток 2
	}

	if(Desk==dsk_BKST)
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0002;       // Setup 2 conv's on SEQ1
		AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //0x5;//0x7; // Setup ADCINA3 as 1st SEQ1 conv.
		AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; //0x4;// Setup ADCINA2 as 2nd SEQ1 conv.
		AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; //0x4;// Setup ADCINA2 as 2nd SEQ1 conv.
	}

	if(Desk==dsk_COMM)
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0006;       // 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.
	}

	if(Desk==dsk_BKSD)	
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0001;       // Setup 2 conv's on SEQ1
		AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //0x5;//0x7; // Setup ADCINA3 as 1st SEQ1 conv.
		AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; //0x4;// Setup ADCINA2 as 2nd SEQ1 conv.
	}

	if(Desk==dsk_SHKF)	
	{
		AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x000F;       // Setup 2 conv's on SEQ1
		AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2;	//	380В Ф1
		AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3;	//	380В Ф2
		AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6;	//	31В Ф1
		AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC;	//	31В Ф2	?
		AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA;	//	31В UC1
		AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB;	//	31В UC2
		AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7;	//  24В ПУ
		AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4;	//  24В ПУ

		AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5;	//	24В ПК было 5
		AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1;	//	15В Др
		AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE;	// +24В Дт
		AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0;	// +24В Дт
		AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8;	// -24В Дт было 8

		AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;	//	ДТ° 1
		AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;	//	ДТ° 2
		AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x9;
	}

   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.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(TermoAD)	COUNT_WAIT_ONE_CANAL = (ADC_FREQ/10);
	if(TermoRS)	COUNT_WAIT_ONE_CANAL = (ADC_FREQ/100);
}

interrupt void  adc_isr(void)
{
  static int count_run_one_canal=0;
  static int number_tpl_canal=0;
  int code_tpl_canal=0;
  float Temper;
  int i;

	// 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(WAKEpowse) WAKEpowse--;

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

	if(READY)
	{
		if(Currentoz)
		{
			for(i=0;i<4;i++)
			{
				adc_table_lem[i] = *((&AdcRegs.ADCRESULT0)+i+2) >>4; Current_count(i);
		}	}	

		if(Mode==adr_SHKF)
		{
			for(i=0;i<16;i++)
			{
				Temper= *((&AdcRegs.ADCRESULT0)+i) >>4;
				adc_table_lem[i]=filterbat(&adc_filter[i],Temper);
				adc_table_tpl[i]=adc_table_lem[i];
			}
			measure_all();
		}

		if(TermoSW)
		{
			if (count_run_one_canal>COUNT_WAIT_ONE_CANAL/2)
			{
				for(i=0;i<TermoSW;i++)
				{
					Temper = *((&AdcRegs.ADCRESULT0)+i) >>4;
					Temper = filterbat(&adc_filter[TermoSW*number_tpl_canal+i],Temper);
					adc_table_tpl[TermoSW*number_tpl_canal+i]=(int)Temper;
			}	}

			if (count_run_one_canal>=COUNT_WAIT_ONE_CANAL)
			{
				for(i=0;i<TermoSW;i++)
				Temper_count(TermoSW*number_tpl_canal+i);

				if (++number_tpl_canal>=(TPL_CANS + 2*(cTermoCal|bTermoCal|TermoRS)))
				{  
					number_tpl_canal=0;
				}

				code_tpl_canal = number_tpl_canal;

				count_run_one_canal=0;

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

				select_tpl_canal(code_tpl_canal);
			}
			count_run_one_canal++;
	}	}

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