#pragma switch auto

#define	PORTBIT(adr, bit)	((unsigned)(&adr)*8+(bit))
#define	XTAL_FREQ	8MHZ
#define	PIC_CLK 8000000


#include	<pic.h>


#define	RSPRE	(unsigned char)0
#define	RSSTA	(unsigned char)1
#define	RSBR	(unsigned char)2
#define	RSSTO	(unsigned char)3





__CONFIG(INTIO & WDTDIS & PWRTEN & BOREN & MCLRDIS);

void 			interrupt irq_func(void);

//-----------------------------------------
//-----------------------------------------

unsigned char b0;
unsigned char b1;
unsigned char b2;

unsigned char c;


unsigned char recstate;
unsigned char precount;
unsigned char brecount;
unsigned char received;
unsigned char e;



unsigned char recbytebuf;
unsigned char rec[6];
unsigned char recp;
unsigned char dec[6];
unsigned char dec2[6];
unsigned char err;
unsigned char errcount;

#define	ADDRESS	3
#define	DCCIN	GPIO4
#define	LED1	GPIO0
#define	LED2	GPIO5


//-----------------------------------------
//-----------------------------------------
void main(void)
{
unsigned char i;
//       76543210
OSCCON=0b01110001;
//       76543210
TRISIO=0b00011110;
//       76543210
IOC=   0b00010000;

CMCON0=7;
ANSEL=0;
GPIO=0;



e=0;
c=0;
errcount=0;
recstate=RSPRE;
precount=0;
brecount=0;
received=0;

T0CS=0;
PSA=0;
PS2=0;
PS1=1;
PS0=0;

GIE=1;
TMR0=0;
GPIE=1;




elorol:

if (received)
	{
	dec[0]=rec[0];
	dec[1]=rec[1];
	dec[2]=rec[2];
	dec[3]=rec[3];
	dec[4]=rec[4];
	dec[5]=rec[5];
	
	err=0;
	
	for (i=0; i<received; i++)
		{
		err^=dec[i];
		}
	
	
	if (err==dec[received])	
			{
			 if (errcount>0) errcount--;
			 LED2=0;
			}  else
			{
			 errcount++;
			 LED2=1;
			 goto vege;	
			} 
		
	
	
	if (dec[0]==ADDRESS)
		{
		i=dec[1]&(128+64+32);
		if (i==128) // 100ddddd
			{
			if (dec[1]&16) LED1=1; else LED1=0;
			}
		}
	
	vege:
	received=0;
	}

goto elorol;



}

//-----------------------------------------
//-----------------------------------------
void interrupt irq_func(void)
{

if (GPIF)
	{
	//e=GPIO;
	asm ("MOVF 0x5, W");
	
	b2=TMR0;
	if (b2<10) 
		{
		TMR0=0;
		goto tova; // tul rovid bit ido
		}
	
	
	b0=b1;
	b1=b2;
	TMR0=0;
	c++;

	if (c&2)
		{
		b2=b0+b1;
		if (b2<26) e=1; 
		else e=0;

		c=0;
		
		switch (recstate)
			{
			case RSPRE:
				{
				if (e)
					{
					 precount++; 
					}
					else 
					{
					precount=RSPRE;
					break;
					}
				
				
				if (precount==13) 
					{
					recstate=RSSTA; // preamble megvolt
					break;
					}
				
				break;
				}
			
				
			case RSSTA:
				{
				if (!e) // megvan a 0 startbit
					{
					recstate=RSBR;
					recbytebuf=0;
					
					rec[0]=0;
					rec[1]=0;
					rec[2]=0;
					rec[3]=0;
					rec[4]=0;
					rec[5]=precount; 
					recp=0; 
					
					} else
					{
					 precount++; 
					}
				
				break;
				}
			
			
			case RSBR:
				{
				recbytebuf+=e;
				
				if (brecount==7)
					{
					rec[recp]=recbytebuf;
					recstate=RSSTO;
					brecount=0;
							
					break;
					}
					
				brecount++;
				recbytebuf=recbytebuf<<1;
				break;
				}
			
			case RSSTO:
				{
				if (!e)
					{
					 recstate=RSBR; // 0 startbit
					 recbytebuf=0;
					 recp++;
					 break;
						 
					}	else // 1 stopbit
					{
					received=recp;
					precount=0;
					recstate=RSPRE;
					break;
					}
				}
			
			
			
			}


		}
	
	
	tova:
	GPIF=0;
	}




}
