#include <16F876A.h>
#device *=16
#device ADC=8
#fuses HS,WDT,PUT,BROWNOUT,NOPROTECT,NOLVP,NOCPD
#use delay(clock=20000000, RESTART_WDT)
#use fast_io(B)
#use fast_io(C)

#define ab_chan      0
#define stdby_chan   1
#define i_chan       2
#define acc_chan     3
#define v_chan       4

const long sine_wave[32] = {81,162,241,318,392,462,527,588,642,691,733,768,795,  // sine wave constants;
                            815,827,831,827,815,795,768,733,691,642,588,527,462,
                            392,318,241,162,81,0};
const int volt_sine_ref[32] = {0,5,9,14,18,23,27,31,34,37,40,42,44,46,47,48,48,
                               48,47,46,44,42,40,37,34,31,27,23,18,14,9,5};
//const int delta_v_h[16] = {7,7,6,6,6,5,5,5,4,4,4,3,3,3,2,2};
//const int delta_v_l[16] = {3,3,3,3,3,3,3,2,2,2,2,1,1,1,0,0};
const int delta_corr[32] = {3,6,9,12,15,18,20,23,25,27,28,30,31,31,32,32,32,31,
                            31,30,28,27,25,23,20,18,15,12,9,6,3,0};


int index, sine_pol, inv_mode, stdby_mode, stdby, i, inv_on, inv_off;
int low_curr_h, low_curr_l, over_curr, short_curr, high_ab, stdby_go_blink;
int low_acc, high_acc, high_t_stop, high_t_blink, low_curr;
int low_acc_delay, acc_avg_counter, volt_ref_counter, volt_l_avg_counter, volt_h_avg_counter;
int volt_h, volt_l, volt_h_avg, volt_l_avg, delta;
int acc_v, acc_v_avg, volt_a, volt_b, stdby_i, stdby_i_h, stdby_i_l, stdby_i_avg_counter;
int volt_ref, volt_ref_avg, curr_h, curr_l, curr_h_avg, curr_l_avg;
signed int delta_h_v, delta_l_v, delta_h_ref, delta_l_ref, volt_ref_delta;
signed long int level_corr[32];
signed int shape_corr[32];
long int pwm_pos, pwm_neg;
long int volt_h_temp, volt_l_temp, volt_ref_temp, acc_v_temp, over_curr_delay;
long int stdby_delay, stdby_go_delay, high_t_delay, curr_h_temp, curr_l_temp, stdby_i_temp;
const long pwm_max=1023;
const int curr_l_max=32, short_curr_l=16, ab_max=96, volt_ref_const_h=168, volt_ref_const_l=87;
const int stdby_i_h_max=239, stdby_i_h_min=143, stdby_max=253, stdby_min=2;
const int curr_h_max=223, curr_h_min=143, curr_l_min=111, short_curr_h=239;
const int acc_max_l=92, acc_max_h=98, acc_min_l=60, acc_min_h=66;


#separate
void sine_pwm_start(void)                                                        // Start mode;
{
   set_pwm1_duty((sine_wave[index]+level_corr[index])>>1);                       // positive start sine half wave;
   output_high(PIN_C1);                                                          // A=1;
   output_low(PIN_C0);                                                           // Z=0;
   output_low(PIN_B1);
   set_adc_channel(ab_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   volt_a=read_adc(ADC_READ_ONLY);
   if(volt_a>=ab_max) {
      high_ab++;
      if(high_ab>8) break;
   }
   else high_ab=0;
   output_low(PIN_C3);
   set_adc_channel(i_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   curr_h=read_adc(ADC_READ_ONLY);
   if(curr_h>=short_curr_h) {
      short_curr++;
      if(short_curr>8) break;
   }
   else {
      short_curr=0;
      if(curr_h>curr_h_max) over_curr_delay++;
      else over_curr_delay=0;
   }
}


#separate
void sine_pwm_norm(void)                                                         // Normal mode;
{
   switch (sine_pol) {
      case 0:                                                                    // negative sine half wave;
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_l=read_adc(ADC_READ_ONLY);
         volt_l_temp+=volt_l;
         pwm_neg=sine_wave[index] + shape_corr[index] + level_corr[index];
         if(pwm_neg>pwm_max) pwm_neg=pwm_max;
         //if(pwm_neg<0) pwm_neg=0;
         set_pwm1_duty(pwm_neg);
         output_low(PIN_C1);                                                     // A=0;
         output_low(PIN_C0);                                                     // Z=0;
         output_high(PIN_B1);
         //set_pwm2_duty(volt_l);
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_b=read_adc(ADC_READ_ONLY);
         if(volt_b>=ab_max) {
            high_ab++;
            if(high_ab>4) break;
         }
         else high_ab=0;
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         if(curr_l<=short_curr_l) {
            short_curr++;
            if(short_curr>4) break;
         }
         else {
            short_curr=0;
            if(curr_l<curr_l_max){
               over_curr_delay++;
               //level_corr[index+1]-=delta_corr[index+1];
            }
            else over_curr_delay=0;
         }
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         curr_h_temp+=curr_h;
         /*if(index) {
            delta_l_v=(127-volt_sine_ref[index])-volt_l;
            delta=delta_corr[index-1]>>2;
            if(delta_l_v>delta) shape_corr[index-1]--;
            else if(delta_l_v<-delta) shape_corr[index-1]++;
         }*/
         if(index==31) {
            curr_h_avg=curr_h_temp>>5;
            if((curr_h_avg<stdby_i_h)&&(!inv_on)) low_curr_l=1;
            else low_curr_l=0;
            volt_l_avg=volt_l_temp>>5;
            delta_l_ref=volt_l_avg-(volt_ref_const_l-volt_ref_delta);
            if(delta_l_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            else if(delta_l_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_h_temp=0;
            volt_l_temp=0;
            high_ab=0;
            short_curr=0;
            sine_pol=1;
         }
         break;
      case 1:                                                                    // positive sine half wave;
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_h=read_adc(ADC_READ_ONLY);
         volt_h_temp+=volt_h;
         pwm_pos=sine_wave[index] + shape_corr[index] + level_corr[index];
         if(pwm_pos>pwm_max) pwm_pos=pwm_max;
         //if(pwm_pos<0) pwm_pos=0;
         set_pwm1_duty(pwm_pos);
         output_high(PIN_C1);                                                    // A=1;
         output_low(PIN_C0);                                                     // Z=0;
         output_low(PIN_B1);
         //set_pwm2_duty(volt_h);
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_a=read_adc(ADC_READ_ONLY);
         if(volt_a>=ab_max) {
            high_ab++;
            if(high_ab>4) break;
         }
         else high_ab=0;
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         if(curr_h>=short_curr_h) {
            short_curr++;
            if(short_curr>4) break;
         }
         else {
            short_curr=0;
            if(curr_h>curr_h_max) {
               over_curr_delay++;
               //level_corr[index+1]-=delta_corr[index+1];
            }
            else over_curr_delay=0;
         }
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         curr_l_temp+=curr_l;
         /*if(index) {
            delta_h_v=(127+volt_sine_ref[index])-volt_h;
            delta=delta_corr[index-1]>>2;
            if(delta_h_v>delta) shape_corr[index-1]++;
            else if(delta_h_v<-delta) shape_corr[index-1]--;
         }*/
         if(index==31) {
            curr_l_avg=curr_l_temp>>5;
            if((curr_l_avg>stdby_i_l)&&(!inv_on)) low_curr_h=1;
            else low_curr_h=0;
            volt_h_avg=volt_h_temp>>5;
            delta_h_ref=(volt_ref_const_h+volt_ref_delta)-volt_h_avg;
            if(delta_h_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            else if(delta_h_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_l_temp=0;
            volt_h_temp=0;
            high_ab=0;
            short_curr=0;
            sine_pol=0;
         }
         break;
   }
}


#separate
void sine_pwm_stop(void)                                                         // Stop mode;
{
   set_pwm1_duty((sine_wave[index]+level_corr[index])>>1);                       // negative stop sine half wave;
   output_low(PIN_C1);                                                           // A=0;
   output_low(PIN_C0);                                                           // Z=0;
   output_high(PIN_B1);
   set_adc_channel(ab_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   volt_b=read_adc(ADC_READ_ONLY);
   if(volt_b>=ab_max) {
      high_ab++;
      if(high_ab>4) break;
   }
   else high_ab=0;
   output_low(PIN_C3);
   set_adc_channel(i_chan);
   delay_us(10);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   curr_l=read_adc(ADC_READ_ONLY);
   if(curr_l<=short_curr_l) {
      short_curr++;
      if(short_curr>4) break;
   }
   else {
      short_curr=0;
      if (curr_l<curr_l_max){
         over_curr_delay++;
         //shape_corr[index+1]-=delta_i[index+1];
      }
      else over_curr_delay=0;
   }
}


#separate
void sine_pwm_stdby(void)                                                        // Standby mode;
{
   switch (stdby_mode) {
      case 0:
         sine_pwm_start();
         if(index==31) {
            high_ab=0;
            short_curr=0;
            stdby_mode++;
         }
         break;
      case 1:                                                                    // negative sine half wave;
         pwm_neg=sine_wave[index] + level_corr[index];
         if(pwm_neg>pwm_max) pwm_neg=pwm_max;
         //if(pwm_neg<0) pwm_neg=0;
         set_pwm1_duty(pwm_neg);
         output_low(PIN_C1);                                                     // A=0;
         output_low(PIN_C0);                                                     // Z=0;
         output_high(PIN_B1);
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_l=read_adc(ADC_READ_ONLY);
         volt_l_temp+=volt_l;
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_b=read_adc(ADC_READ_ONLY);
         if(volt_b>=ab_max) {
            high_ab++;
            if(high_ab>4) break;
         }
         else high_ab=0;
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         if(curr_l<=short_curr) {
            short_curr++;
            if(short_curr>4) break;
         }
         else {
            short_curr=0;
            if (curr_l<curr_l_max){
               over_curr_delay++;
               //shape_corr[index+1]-=delta_i[index+1];
            }
            else over_curr_delay=0;
         }
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         curr_h_temp+=curr_h;
         if(index==31) {
            curr_h_avg=curr_h_temp>>5;
            if(curr_h_avg>=stdby_i_h) stdby=0;
            volt_l_avg=volt_l_temp>>5;
            delta_l_ref=volt_l_avg-(volt_ref_const_l-volt_ref_delta);
            if(delta_l_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            if(delta_l_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_h_temp=0;
            volt_l_temp=0;
            high_ab=0;
            short_curr=0;
            stdby_mode++;
         }
         break;
      case 2:                                                                    // positive sine half wave;
         pwm_pos=sine_wave[index] + level_corr[index];
         if(pwm_pos>pwm_max) pwm_pos=pwm_max;
         //if(pwm_pos<0) pwm_pos=0;
         set_pwm1_duty(pwm_pos);
         output_high(PIN_C1);                                                    // A=1;
         output_low(PIN_C0);                                                     // Z=0;
         output_low(PIN_B1);
         set_adc_channel(v_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_h=read_adc(ADC_READ_ONLY);
         volt_h_temp+=volt_h;
         set_adc_channel(ab_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_a=read_adc(ADC_READ_ONLY);
         if(volt_a>=ab_max) {
            high_ab++;
            if(high_ab>4) break;
         }
         else high_ab=0;
         output_low(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_h=read_adc(ADC_READ_ONLY);
         if(curr_h>=short_curr_h) {
            short_curr++;
            if(short_curr>4) break;
         }
         else {
            short_curr=0;
            if(curr_h>curr_h_max) {
               over_curr_delay++;
               //shape_corr[index+1]-=delta_i[index+1];
            }
            else over_curr_delay=0;
         }
         output_high(PIN_C3);
         set_adc_channel(i_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         curr_l=read_adc(ADC_READ_ONLY);
         curr_l_temp+=curr_l;
         if(index==31) {
            curr_l_avg=curr_l_temp>>5;
            if((curr_l_avg<=stdby_i_l)) stdby=0;
            volt_h_avg=volt_h_temp>>5;
            delta_h_ref=(volt_ref_const_h+volt_ref_delta)-volt_h_avg;
            if(delta_h_ref>2) for(i=0; i<32; i++) level_corr[i]+=delta_corr[i]>>1;
            else if(delta_h_ref<-2) for(i=0; i<32; i++) level_corr[i]-=delta_corr[i]>>1;
            curr_l_temp=0;
            volt_h_temp=0;
            high_ab=0;
            short_curr=0;
            stdby_mode++;
         }
         break;
      case 3:
         sine_pwm_stop();
         if(index==31) {
            high_ab=0;
            short_curr=0;
            stdby_mode=0;
            inv_mode++;
         }
         break;
   }
}


#int_timer0
void sine_pwm(void)
{
   restart_wdt();
   clear_interrupt(int_timer0);
   set_timer0(60);
   if((!low_acc)&&(!high_acc)&&(!inv_off)) {                                     // check acc value and inverter state;
      switch (inv_mode) {                                                        // check invereter mode;
         case 0:                                                                 // start mode;
            sine_pwm_start();
            if(index==31) {
               high_ab=0;
               short_curr=0;
               sine_pol=0;
               inv_mode++;
            }
            break;
         case 1:                                                                 // normal mode;
            if((!high_t_stop)&&(!low_curr)&&(!low_acc_delay)) {
               output_high(PIN_B4);                                              // Green LED-ON;
               output_low(PIN_B5);                                               // Red LED-OFF;
            }
            sine_pwm_norm();
            if(index==31) {
               if((low_curr_l)&&(low_curr_h)) {                                  // check for low current;
                  low_curr=1;
                  stdby_go_delay++;
                  if((!low_acc_delay)&&(!high_t_stop)) {
                     if(stdby_go_blink>30) {
                        output_high(PIN_B4);                                     // Blink Green&Red LEDs;
                        output_high(PIN_B5);
                     }
                     else {
                        output_low(PIN_B4);
                        output_low(PIN_B5);
                     }
                     if(!stdby_go_blink) stdby_go_blink=60;
                     else stdby_go_blink--;
                  }
                  if((stdby_go_delay>600)&&(!sine_pol)) {
                     stdby=1;
                     stdby_go_delay=0;
                     stdby_go_blink=60;
                     low_curr_l=0;
                     low_curr_h=0;
                     low_curr=0;
                     inv_mode++;
                     output_low(PIN_B4);
                     output_low(PIN_B5);
                  }
               }
               else {
                  low_curr=0;
                  stdby_go_delay=0;
                  stdby_go_blink=60;
               }
            }
            break;
         case 2:                                                                 // stop mode;
            sine_pwm_stop();
            if(index==31) {
               high_ab=0;
               short_curr=0;
               inv_mode=4;
            }
            break;
         case 3:                                                                 // standby mode;
            sine_pwm_stdby();
            stdby_delay--;
            break;
         case 4:                                                                 // idle mode;
            set_pwm1_duty(0);                                                    // M=0;
            if((!high_t_stop)&&(!low_curr)&&(!low_acc_delay)) {
               if(stdby_delay>1023) output_high(PIN_B4);                         // Blink Green LED;
               else output_low(PIN_B4);
            }
            if(!stdby_delay) {
               stdby_delay=2047;
               if(stdby) inv_mode=3;
               else inv_mode=0;
            }
            else stdby_delay--;
            break;
      }
      if(index==15) {
         set_adc_channel(acc_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         acc_v=read_adc(ADC_READ_ONLY);
         acc_v_temp+=acc_v;
         acc_avg_counter++;
         if(acc_avg_counter==32) {
            acc_avg_counter=0;
            acc_v_avg=acc_v_temp>>5;
            if(acc_v_avg<=acc_min_l) {
               low_acc_delay++;
               if(!high_t_stop) {
                  output_low(PIN_B4);
                  output_high(PIN_B5);
               }
               if(low_acc_delay==16) {
                  low_acc=1;
                  low_acc_delay=0;
               }
            }
            else {
               if(acc_v_avg>=acc_max_h) high_acc=1;
               low_acc_delay=0;
            }
            acc_v_temp=0;
            acc_v_avg=0;
         }
         output_low(PIN_C3);                                                     // check vref value;
         set_adc_channel(stdby_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         volt_ref=read_adc(ADC_READ_ONLY);
         volt_ref_temp+=volt_ref;
         volt_ref_counter++;
         if(volt_ref_counter==32) {
            volt_ref_avg=volt_ref_temp>>8;
            volt_ref_delta=volt_ref_avg-30;
            volt_ref_counter=0;
            volt_ref_temp=0;
         }
      }
      if(index==31) {
         if(over_curr_delay>1600) over_curr=1;
         if(!input(PIN_C4)) {
            high_t_delay++;
            output_high(PIN_C5);
            if((high_t_delay>255)&&(high_t_delay<1024)) {
               high_t_stop=1;
               output_low(PIN_B4);
               if(high_t_blink>45) output_high(PIN_B5);                          // Blink Red LED;
               else output_low(PIN_B5);
               if(!high_t_blink) high_t_blink=90;
               else high_t_blink--;
            }
            else if(high_t_delay>1023) high_t_stop++;
         }
         else {
            high_t_delay=0;
            high_t_stop=0;
            high_t_blink=90;
            output_low(PIN_C5);
         }
         output_high(PIN_C3);                                                    // check stdby current value;
         set_adc_channel(stdby_chan);
         delay_us(10);
         read_adc(ADC_START_ONLY);
         delay_us(20);
         stdby_i=read_adc(ADC_READ_ONLY);
         stdby_i_temp+=stdby_i;
         stdby_i_avg_counter++;
         if(stdby_i_avg_counter==32) {
            stdby_i=stdby_i_temp>>5;
            if(stdby_i>=stdby_max) inv_on=1;
            else inv_on=0;
            if(stdby_i<=stdby_min) inv_off=1;
            stdby_i_h=(stdby_i>>1)+128;
            //if(stdby_i_h>stdby_i_h_max) stdby_i_h=stdby_i_h_max;
            //else if(stdby_i_h<stdby_i_h_min) stdby_i_h=stdby_i_h_min;
            stdby_i_l=255-stdby_i_h;
            stdby_i_avg_counter=0;
            stdby_i_temp=0;
         }
      }
   index++;
   if(index>31) index=0;
   }
   else {                                                                        // acc low mode;
      set_pwm1_duty(0);                                                          // M=0;
      output_high(PIN_C0);                                                       // Z=1;
      output_low(PIN_B4);                                                        // Green LED-OFF;
      if(!inv_off) output_high(PIN_B5);                                          // Red LED-ON;
      inv_mode=0;
      index=0;
      short_curr=0;
      over_curr=0;
      over_curr_delay=0;
      high_ab=0;
      high_t_delay=0;
      high_t_stop=0;
      stdby=0;
      pwm_pos=0;
      pwm_neg=0;
      delta_h_v=0;
      delta_l_v=0;
      //delta_h_ref_v=0;
      //delta_l_ref_v=0;
      //diff_h_v=0;
      //diff_l_v=0;
      delta_h_ref=0;
      delta_l_ref=0;
      //delta_h_ref_adj=0;
      //delta_l_ref_adj=0;
      low_curr_h=0;
      low_curr_l=0;
      curr_h_temp=0;
      curr_h_avg=0;
      curr_l_temp=0;
      curr_l_avg=0;
      low_curr=0;
      volt_h_temp=0;
      volt_h_avg=0;
      volt_l_temp=0;
      volt_l_avg=0;
      volt_ref_temp=0;
      volt_ref_avg=0;
      volt_ref_delta=0;
      volt_ref_counter=0;
      volt_h_avg_counter=0;
      volt_l_avg_counter=0;
      //volt_l_avg_counter=0;
      stdby_i_temp=0;
      //stdby_i_avg_counter=0;
      stdby_go_delay=0;
      stdby_delay=2047;
      high_t_blink=90;
      low_acc_delay=0;
      stdby_go_blink=60;
      //level=0;
      //level_corr=0;
      //level_l_corr=0;
      for(i=0; i<32; i++) {
         shape_corr[i]=0;
         //shape_l_corr[i]=0;
         level_corr[i]=0;
         //level_adj[i]=0;
         //shape_h_corr_temp[i]=0;
         //shape_l_corr_temp[i]=0;
      }
      output_high(PIN_C3);                                                       // check stdby current value;
      set_adc_channel(stdby_chan);
      delay_us(10);
      read_adc(ADC_START_ONLY);
      delay_us(20);
      stdby_i=read_adc(ADC_READ_ONLY);
      stdby_i_temp+=stdby_i;
      stdby_i_avg_counter++;
      if(stdby_i_avg_counter==32) {
         stdby_i=stdby_i_temp>>5;
         if(stdby_i>stdby_min) inv_off=0;
         //else inv_off=0;
         stdby_i_h=(stdby_i>>1)+128;
         //if(stdby_i_h>stdby_i_h_max) stdby_i_h=stdby_i_h_max;
         //else if(stdby_i_h<stdby_i_h_min) stdby_i_h=stdby_i_h_min;
         stdby_i_l=255-stdby_i_h;
         stdby_i_avg_counter=0;
         stdby_i_temp=0;
      }
      set_adc_channel(acc_chan);
      delay_us(10);
      read_adc(ADC_START_ONLY);
      delay_us(20);
      acc_v=read_adc(ADC_READ_ONLY);
      acc_v_temp+=acc_v;
      acc_avg_counter++;
      if(acc_avg_counter==32) {
         acc_avg_counter=0;
         acc_v_avg=acc_v_temp>>5;
         if(acc_v_avg<=acc_max_l) high_acc=0;
         if(acc_v_avg>=acc_min_h) low_acc=0;
         acc_v_temp=0;
         acc_v_avg=0;
      }
      if(input(PIN_C4)) output_low(PIN_C5);
   }
}


void main()
{
   set_tris_b(0xCD);
   set_tris_c(0x90);
   output_high(PIN_C0);                                                          // Z=1;
   //output_high(PIN_B4);                                                          // test LED's;
   //output_low(PIN_B5);
   //delay_ms(1000);
   output_low(PIN_B4);
   //output_high(PIN_B5);
   //delay_ms(1000);
   output_low(PIN_B5);
   index=0;
   inv_mode=0;                                                                   // init to normal start mode;
   inv_on=0;
   inv_off=0;
   stdby_mode=0;
   short_curr=0;
   over_curr=0;
   over_curr_delay=0;
   high_ab=0;
   high_t_delay=0;
   high_t_stop=0;
   low_acc=0;
   high_acc=0;
   acc_v_temp=0;
   acc_avg_counter=0;
   acc_v_avg=0;
   stdby=0;
   pwm_pos=0;
   pwm_neg=0;
   delta_h_v=0;
   delta_l_v=0;
   //delta_h_ref_v=0;
   //delta_l_ref_v=0;
   //diff_h_v=0;
   //diff_l_v=0;
   delta_h_ref=0;
   delta_l_ref=0;
   //delta_h_ref_corr=0;
   //delta_l_ref_corr=0;
   low_curr_h=0;
   low_curr_l=0;
   low_curr=0;
   curr_h_temp=0;
   curr_h_avg=0;
   curr_l_temp=0;
   curr_l_avg=0;
   low_curr=0;
   volt_h_temp=0;
   volt_h_avg=0;
   volt_l_temp=0;
   volt_l_avg=0;
   volt_ref_temp=0;
   volt_ref_avg=0;
   volt_ref_delta=0;
   volt_ref_counter=0;
   volt_h_avg_counter=0;
   volt_l_avg_counter=0;
   //volt_l_avg_counter=0;
   stdby_i_temp=0;
   stdby_i_avg_counter=0;
   stdby_go_delay=0;
   stdby_delay=2047;
   high_t_blink=90;
   low_acc_delay=0;
   stdby_go_blink=60;
   //level=0;
   //level_corr=0;
   //level_l_corr=0;
   for(i=0; i<32; i++) {
      shape_corr[i]=0;
      //shape_l_corr[i]=0;
      level_corr[i]=0;
      //shape_h_corr_temp[i]=0;
      //shape_l_corr_temp[i]=0;
      //level_adj[i]=0;
   }
   setup_adc_ports(ALL_ANALOG);                                                  // init the ADC;
   setup_adc(ADC_CLOCK_DIV_32);                                                  // Tad=1.6us;
   set_adc_channel(acc_chan);
   delay_us(10);
   for(i=0; i<32; i++) {      
      acc_v=read_adc();
      acc_v_temp+=acc_v;
      if(i==31) {
         acc_v_avg=acc_v_temp>>5;
         if(acc_v_avg<=acc_min_l) low_acc=1;
         if(acc_v_avg>=acc_max_h) high_acc=1;
         acc_v_temp=0;
         acc_v_avg=0;
      }
   }
   output_high(PIN_C3);                                                          // check stdby current value;
   set_adc_channel(stdby_chan);
   delay_us(10);
   for(i=0; i<32; i++) {      
      stdby_i=read_adc();
      stdby_i_temp+=stdby_i;
      if(i==31) {
         stdby_i=stdby_i_temp>>5;
         if(stdby_i<=stdby_min) inv_off=1;
         else if(stdby_i>=stdby_max) inv_on=1;
         stdby_i_h=(stdby_i>>1)+128;         
         stdby_i_l=255-stdby_i_h;
         stdby_i_temp=0;
      }
   }
   output_low(PIN_C3);
   set_adc_channel(stdby_chan);                                                  // check vref value;
   delay_us(10);
   for(i=0; i<32; i++) {      
      volt_ref=read_adc();
      volt_ref_temp+=volt_ref;
      if(i==31) {
         volt_ref_avg=volt_ref_temp>>8;
         volt_ref_delta=volt_ref_avg-29;
         volt_ref_temp=0;
      }
   }
   setup_timer_2(T2_DIV_BY_1, 255, 1);                                           // Init the PWM;
   setup_ccp1(CCP_PWM);
   set_pwm1_duty(0);
   //setup_ccp2(CCP_PWM);
   //set_pwm2_duty(0);
   setup_wdt(WDT_18MS);
   set_timer0(60);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);                                      // Init the TIMER0;
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   while(TRUE) {
      restart_wdt();
      if((short_curr)||(high_ab)||(over_curr)||(high_t_stop>1)) {                // stop and wait for 60 sec;
         set_pwm1_duty(0);                                                       // M=0;
         output_high(PIN_C0);                                                    // Z=1;
         disable_interrupts(GLOBAL);
         output_low(PIN_B4);
         output_low(PIN_B5);
         short_curr=0;
         over_curr=0;
         over_curr_delay=0;
         high_ab=0;
         high_t_stop=0;
         high_t_delay=0;
         low_acc=0;
         high_acc=0;
         acc_avg_counter=0;
         acc_v_temp=0;
         acc_v_avg=0;
         low_curr_h=0;
         low_curr_l=0;
         index=0;
         inv_mode=0;
         inv_on=0;
         inv_off=0;
         stdby_mode=0;
         stdby=0;
         pwm_pos=0;
         pwm_neg=0;
         delta_h_v=0;
         delta_l_v=0;
         //delta_h_ref_v=0;
         //delta_l_ref_v=0;
         //diff_h_v=0;
         //diff_l_v=0;
         delta_h_ref=0;
         delta_l_ref=0;
         //delta_h_ref_corr=0;
         //delta_l_ref_corr=0;
         //level=0;
         //level_corr=0;
         //level_l_corr=0;
         for(i=0; i<32; i++) {
            shape_corr[i]=0;
            //shape_l_corr[i]=0;
            level_corr[i]=0;
            //level_adj[i]=0;
            //shape_h_corr_temp[i]=0;
            //shape_l_corr_temp[i]=0;
         }
         curr_h_temp=0;
         curr_h_avg=0;
         curr_l_temp=0;
         curr_l_avg=0;
         low_curr=0;
         volt_h_temp=0;
         volt_h_avg=0;
         volt_l_temp=0;
         volt_l_avg=0;
         volt_ref_temp=0;
         volt_ref_avg=0;
         volt_ref_delta=0;
         volt_ref_counter=0;
         volt_h_avg_counter=0;
         volt_l_avg_counter=0;
         //volt_l_avg_counter=0;
         stdby_i_temp=0;
         stdby_i_avg_counter=0;
         stdby_go_delay=0;
         stdby_delay=2047;
         high_t_blink=90;
         low_acc_delay=0;
         stdby_go_blink=60;
         delay_ms(30000);
         if(input(PIN_C4)) output_low(PIN_C5);
         clear_interrupt(int_timer0);
         set_timer0(60);
         enable_interrupts(GLOBAL);
      }
   }
}
