#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(baud=10400,xmit=PIN_C6,rcv=PIN_C7,FORCE_SW)
#include <lcd.c>

int block_length, block_cnt, block_title;

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[3] = {0x55,0x01,0x8A}, i;
   int ecu[3], i;

	for (i=0; i<=2; i++){
   		ecu[i] = getc();
     }

	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;

}

int kw1281_send_ack ()
{
   putc(0x03);
   getc();
   getc();

   putc(block_counter());
   getc();
   getc();

   putc(0x09);
   getc();
   getc();

   putc(0x03);
   getc();
}

void 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_length_counter_title ()
{
   int i;
   int text[12];
   block_length = kw1281_get_byte();
   block_cnt = kw1281_get_byte();

   do
     {
      block_title = kw1281_get_byte();
      if (block_title == 0xF6)
         {
            for (i=1; i<=block_length-3; i++)
	              {
		             text[i-1] = kw1281_get_byte();
                 }
         }
      else
         getc();
     } 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();
}

int kw1281_get_group_data (int values [])
{
   int ecu, i;
   for (i=1; i<=block_length-3; i++)
   {
      ecu = getc();
      putc(0xFF-ecu);
      getc();
      values[i-1] = ecu;
   }
getc();
return 1;
}

void  kw1281_display_values ()
{
   int      values[12];
	double   rpm;

	while (1)
	{
      // Oboroti
      kw1281_get_group(1);
      block_length = kw1281_get_byte();
      block_cnt = kw1281_get_byte();

      if (kw1281_get_group_data(values))
      {
         rpm = 0.2*values[1]*values[2];
		   printf(lcd_putc,"\n%1.2f rpm", rpm);
         //printf("\n%1.2f", rpm);
      }
   }
}

void main() {

   lcd_init();
   wakeup_ECU();
   kw1281_ecu_sync();
   kw1281_get_length_counter_title();
   kw1281_send_ack();
   kw1281_get_ack();
   kw1281_display_values();
}
