#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP, NOBROWNOUT, NOPUT
#use delay(clock=20000000)
#use rs232(baud=10400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,FORCE_SW)
#include <lcd.c>

int block_length, block_cnt, block_title, block_end;

block_counter ()
{
   block_cnt++;
   if (block_cnt == 0xFF)
   {
      block_cnt = 0;
   }
      return block_cnt;
}

void wakeup_ECU(void)
{

   output_high (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);

   output_high (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);
   output_low (PIN_C6);
   Delay_ms(200);

   output_low (PIN_C6);
   Delay_ms(200);
   output_high (PIN_C6);
   Delay_ms(200);

}

void kw1281_ecu_sync ()
{
	//int ecu[10] = {0x55,0x01,0x8A, 0xCD, 0xED, 0xF0, 0x8A, 0x8A, 0x8A, 0x8A}, i;
   int ecu[10], i;

	for (i=0; i<=9; i++){
   		ecu[i] = getc();
     }
      printf(lcd_putc, "%X", ecu[0]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[1]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[2]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[3]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X\n", ecu[4]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[5]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[6]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[7]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[8]);
      printf(lcd_putc, "%s", ",");
      printf(lcd_putc, "%X", ecu[9]);

	if ((ecu[0] == 0x55) && (ecu[1] == 0x01) && (ecu[2] == 0x8A))
	  {
		putc (0xFF-ecu[2]);
		getc();
      //printf(lcd_putc,"\fConnection.. OK!");
     }
	//else
		//printf(lcd_putc,"\fNO Connection...");
}

kw1281_get_byte ()
{
   int ecu;
   ecu = getc();
   putc(0xFF-ecu);
   getc();
   return ecu;

}

kw1281_send_ack ()
{
   putc(0x03);
   getc();
   getc();

   putc(block_counter());
   getc();
   getc();

   putc(0x09);
   getc();
   getc();

   putc(0x03);
   getc();
}

kw1281_get_ack ()
{
   int ecu;

   ecu = getc();
   putc(0xFF-ecu);
   getc();

   ecu = getc();
   putc(0xFF-ecu);
   getc();
   block_cnt = ecu;

   ecu = getc();
   putc(0xFF-ecu);
   getc();

   ecu = getc();
}

int kw1281_get_id_device ()
{
   int i, cnt;
   char text[4][16];
   cnt = 0;

   do
     {
      block_length = kw1281_get_byte();
      block_cnt = kw1281_get_byte();
      block_title = kw1281_get_byte();
      if (block_title == 0xF6)
         {
            for (i=1; i<=block_length-3; i++)
	              {
		             text[cnt][i-1] =kw1281_get_byte();
                   //lcd_gotoxy(i,2);
                   //printf(lcd_putc,"%c", text[cnt][i-1]);
                 }
              getc();
              cnt++;
              kw1281_send_ack();
         }
      else
         getc();  //* Край на блок, когато block_title не е равен на 0xF6 (няма ascii данни)
     } while (block_title == 0xF6);
}

void kw1281_get_group (int group)
{
   putc(0x04);
   getc();
   getc();

   putc(block_counter());
   getc();
   getc();

   putc(0x29);
   getc();
   getc();

   putc(group);
   getc();
   getc();

   putc(0x03);
   getc();
}

kw1281_display_values ()
{
   int ecu, i;
   int values[12];
   double rpm, kmh, lh, l_100;

   while (1)
   {
      //Izmervane na Oboroti - rpm
      //lcd_gotoxy(1,2);
      kw1281_get_group(1);

      block_length = kw1281_get_byte();
      block_cnt = kw1281_get_byte();
      block_title = kw1281_get_byte();
      //if (block_title == 0xE7)
      //{
         for(i=1; i<=block_length-3; i++)
         {
           ecu = getc();
           putc(0xFF-ecu);
           getc();
           values[i-1] = ecu;
         }
         getc();
         rpm = 0.2*values[1]*values[2];
         printf(lcd_putc,"\f%1.2f rpm", rpm);
      //}


      /*Izmervane na Skorost - km/h
      lcd_gotoxy(1,10);
      kw1281_get_group(6);

      block_length = kw1281_get_byte();
      block_cnt = kw1281_get_byte();
      block_title = kw1281_get_byte();
      //if (block_title == 0xE7)
      //{
         for(i=1; i<=block_length-3; i++)
         {
           ecu = getc();
           putc(0xFF-ecu);
           getc();
           values[i-1] = ecu;
         }
         getc();
         kmh = (0.01*values[1]*values[2])/1.0398;
         printf(lcd_putc,"%1.2f km/h", kmh);
      //}


      //Izmervane na Razhod v Litri na 100km
      lcd_gotoxy(2,1);
      kw1281_get_group(15);

      block_length = kw1281_get_byte();
      block_cnt = kw1281_get_byte();
      block_title = kw1281_get_byte();
      //if (block_title == 0xE7)
      //{
         for(i=1; i<=block_length-3; i++)
         {
           ecu = getc();
           putc(0xFF-ecu);
           getc();
           values[i-1] = ecu;
         }
         getc();
         lh = 0.01*values[7]*values[8];
         printf(lcd_putc,"%1.2f l/h", lh);

         if ((kmh > 00) && (lh > 0))
         {
            l_100 = (lh/kmh)*100;
            lcd_gotoxy(2,9);
            printf(lcd_putc,"%1.2f l/100", l_100);
         }
         else
            l_100 = 0;
            printf(lcd_putc,"%1.2f l/100", l_100);

      //}*/
   }
}

void main() {

   lcd_init();
   wakeup_ECU();
   kw1281_ecu_sync();
   kw1281_get_id_device();
   kw1281_display_values();
}
