#include<18F4431.h>
#device adc=10
#device HIGH_INTS=TRUE
#fuses H4, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=40000000)

#include <math.h>
/*
BYTE CONST SINE_WAVE[200] = {
128,132,136,139,143,147,150,154,158,161,165,169,172,176,179,
182,186,189,192,195,199,202,204,207,210,213,215,218,220,223,
225,227,229,231,233,235,237,238,240,241,242,243,244,245,246,
247,247,247,248,248,248,248,248,247,247,247,246,245,244,243,
242,241,240,238,237,235,233,231,229,227,225,223,220,218,215,
213,210,207,204,202,199,195,192,189,186,182,179,176,172,169,
165,161,158,154,150,147,143,139,136,132,128,124,120,117,113,
109,106,102,98,95,91,87,84,80,77,74,70,67,64,61,57,54,52,49,
46,43,41,38,36,33,31,29,27,25,23,21,19,18,16,15,14,13,12,11,
10,9,9,9,8,8,8,8,8,9,9,9,10,11,12,13,14,15,16,18,19,21,23,
25,27,29,31,33,36,38,41,43,46,49,52,54,57,61,64,67,70,74,77,
80,84,87,91,95,98,102,106,109,113,117,120,124};
*/
//#define POWER_PWM_PERIOD 1999  // 1 KHz pwm freq with 8 MHz osc.
#BYTE port_a = 0xF80
#BYTE port_b = 0xF81
#BYTE port_c = 0xF82
#BYTE port_d = 0xF83
#BYTE port_e = 0xF84
#BYTE lat_a = 0xF89
#BYTE lat_b = 0xF8a
#BYTE lat_c = 0xF8b
#BYTE lat_d = 0xF8c
#BYTE lat_e = 0xF8d
#BYTE tris_a = 0xF92
#BYTE tris_b = 0xF93
#BYTE tris_c = 0xF94
#BYTE tris_d = 0xF95
#BYTE tris_e = 0xF96
#BIT  LED1 = lat_d.0
#BIT  LED2 = lat_d.1
#BIT  LED3 = lat_d.2
#BIT  LED4 = lat_c.0
#BIT  SW1 = port_d.6
#BIT  SW2 = port_d.7
#BIT  EN = lat_c.2

#define POWER_PWM_FREQ 4000
#define POWER_PWM_PERIOD (getenv("CLOCK")/4/POWER_PWM_FREQ-1)
#define mult	38
#define T_Base	0xd8ef //55535
#define T_Basem	64900
#define T_B	T_Basem-T_Base//9164
#define V_MIN	50
//=======================================

int1 upr,ups,upt;
BYTE sine_indexr;
BYTE sine_indexs;
BYTE sine_indext;
unsigned int16 dutyr, dutys, dutyt;
unsigned int16 result ; 
unsigned int16 freq, tmrv;
float rad=3.141596/180.0;
float mult_v;
float T_ad;
float  vout_l;
int16 vout_m;
signed int s_wave[100];
#locate s_wave=0x100
void sin_gen(signed int *acq,float ampl,int alfa,int n)
{
	int i;
	float temp;
	for (i=0;i<n;i++,acq++)
	{
	   temp=floor(ampl*( sin(alfa*i*rad) ));
	   *acq=(signed int)temp;
	}   
}
/*
void ram_cpy (void)
{
	int i;
	for (i=0;i<200;i++)
	{
		s_wave[i]=SINE_WAVE[i];
	}
}
*/		
#INT_TIMER1 HIGH
void isrt1() 
{

   set_timer1(tmrv);         // frequency of interrrupt = (clock/(4*divisor))/(256-reload)
                          //                 2029 hz = (20000000/(4*16))/(256-102)

    set_power_pwm0_duty(dutyr);
	set_power_pwm2_duty(dutys);
	set_power_pwm4_duty(dutyt);
   if(!upr)
   {
	   if(++sine_indexr==90) 
		{
			upr=1;
      		led2=~led2;
      	}
   }
   else 
   {
	   if(--sine_indexr==0) 
		{
			upr=0;
      	}
   }
   if(!ups)
   {
	   if(++sine_indexs==90) 
		{
			ups=1;
      	}
   }
   else 
   {
	   if(--sine_indexs==0) 
		{
			ups=0;
      }
   }

     if(!upt)
   {
	   if(++sine_indext==90) 
		{
			upt=1;
      }
   }
   else 
   {
	   if(--sine_indext==0) 
		{
			upt=0;
      }
   }

}
/*
#int_rtcc                          // This function is called every time
void clock_isr() 
{                 					// the RTCC (timer0) overflows (255->0).
    set_timer0(100);                // For this program this is apx 76 times
	 if (sample)
	 {
		 Tpwm=Tpwm+Dstep;
		 Ipwm=Tpwm;
		 Duty=Ipwm;
		 Tramp--;
		 if (!Tramp) 
		 {
		 	sample =0;
		 	Tpwm=0;
		 }	
	 }
}
*/
#zero_ram
void main()
{
	setup_timer_0 (RTCC_DIV_32|RTCC_INTERNAL|RTCC_8_BIT);
	setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
	tmrv=T_Base;
	set_timer0(T_Base);
	set_timer1(tmrv);
	sine_indexr=0;
	sine_indexs=30;
	sine_indext=60;
	upr=0;
	ups=0;
	upt=0;
	mult_v=(float)(T_Basem-T_Base)/10240.0*10.64*3.16;	//(float)(0xffff-T_Base);
	setup_adc_ports(sAN0| sAN1);
	setup_adc(ADC_CLOCK_DIV_32);
	set_adc_channel(1);
	port_c=0;
	port_d=0;
	tris_c=0b11111010;
	tris_d=0b11111000;
//	ram_cpy();
	sin_gen(s_wave,250.0,1,91);
	led1=1; 
	led2=1;
	led3=1;
	led4=1;
	en=1;
//	vout_m=1023+V_MIN;
	dutyr=0;
	dutys=0;
	dutyt=0;
// Setup the 4 Power PWM channels as ordinary pwm channels.
//setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
//	setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY, PWM_COMPLEMENTARY, PWM_OFF);
	setup_power_pwm_pins(PWM_BOTH_ON,PWM_BOTH_ON, PWM_BOTH_ON, PWM_OFF);
// Mode = Free Run 
// Postscale = 1   (1-16) Timebase output postscaler
// TimeBase = 0   (0-65355) Initial value of PWM Timebase
// Period = 2000  (0-4095) Max value of PWM TimeBase
// Compare = 0     (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

	setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0); 
//	setup_power_pwm(PWM_CLOCK_DIV_4 | PWM_FREE_RUN |   PWM_DEAD_CLOCK_DIV_16,1,10000,1000,0,1,30);

	set_power_pwm0_duty(0);
	set_power_pwm2_duty(0);
	set_power_pwm4_duty(0);
  	enable_interrupts(INT_TIMER1);
  	enable_interrupts(GLOBAL);

	while(1)
	{
		result = read_adc(); 
//		result=0x400-result;
		if (result)
		{
			t_ad=log10(result);
		}
		else t_ad=(result);
//		vout_l=t_ad*vout_m;
		vout_l=(float)(result+V_MIN)/(1023+V_MIN);
		T_ad=T_ad*100.0;
		T_ad=T_ad*mult_v;
		tmrv=T_Base+(int16)T_ad;
		
//		tmrv=T_Basem-t_ad;
		dutyr=(int16)(s_wave[sine_indexr])*mult*vout_l;
		dutys=(int16)(s_wave[sine_indexs])*mult*vout_l;
		dutyt=(int16)(s_wave[sine_indext])*mult*vout_l;
	}	
}
