#include "htc.h"

#define _XTAL_FREQ						4000000

#define OW_SET_OUTPUT()					GP5 = 1;
#define OW_CLEAR_OUTPUT()				GP5 = 0;
#define OW_CHECK_INPUT()				GP5;
#define OW_SET_TO_INPUT()				TRISIO = TRISIO | 0x20;
#define OW_SET_TO_OUTPUT()				TRISIO = TRISIO & 0xDF; 
#define OW_TIME_480()					TMR1IF = 0; TMR1 = 65056; while(TMR1IF == 0) continue;
#define OW_TIME_70()					TMR1IF = 0; TMR1 = 65466; while(TMR1IF == 0) continue;
#define OW_TIME_410()					TMR1IF = 0; TMR1 = 65126; while(TMR1IF == 0) continue;
#define OW_TIME_55()					TMR1IF = 0; TMR1 = 65481; while(TMR1IF == 0) continue;
#define OW_TIME_64()					TMR1IF = 0; TMR1 = 65472; while(TMR1IF == 0) continue;
#define OW_TIME_60()					TMR1IF = 0; TMR1 = 65476; while(TMR1IF == 0) continue;
#define OW_TIME_6()						asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
#define OW_TIME_9()						asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
#define OW_TIME_10()					asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");

#define BUZZER							GP4
#define BUTTON_INPUT					GP3
#define RED_LED							GP2
#define GREEN_LED						GP1
#define CORRECT							8
#define OFF								0
#define ON								1

unsigned char CheckEEPROM(unsigned char *pData);
unsigned char WriteEEPROM(unsigned char *pData);
unsigned char OWReset(void); 
unsigned char OWReadBit(void);   
unsigned char OWReadByte(void);  
void OWWriteBit(unsigned char Dbit); 
void OWWriteByte(unsigned char Dbyte);  

__CONFIG(0x37D4);

void main( void )
{
unsigned char IDstring[8] = {0};
unsigned char *pIDstring = IDstring;
unsigned char k = 0;
unsigned char iskeyonlist = 0;

ADCON0 = 0x00;					// 
ANSEL = 0x00;					// 
OSCCON = 0x60;					// internal oscillator of 8 mhz
CMCON0 = 0x07;					// comparators off
TRISIO = 0x08;					// 
T1CON = 0x01;					// 
GPIO = 0x00;					// 

while(1)
	{
	OW_SET_TO_INPUT();
	
	while(OWReset() == 1)
		{
		RED_LED = OFF;
		GREEN_LED = OFF;
		}
	OWWriteByte(0x33);  			// send read command
	
	for (k = 0; k < 8; k++) 
		IDstring[k] = OWReadByte(); 

	iskeyonlist = CheckEEPROM(pIDstring);
	if(iskeyonlist == 1) 
		{
		GREEN_LED = ON; 
		RED_LED = OFF;
		BUZZER = ON;
		__delay_us(10);
		BUZZER = OFF;
		__delay_us(10);
		}
	else 
		{
		GREEN_LED = OFF; 
		RED_LED = ON;
		BUZZER = ON;
		__delay_ms(10);
		BUZZER = OFF;
		__delay_ms(10);
		}

	if(BUTTON_INPUT == 0)
		{
		__delay_ms(1000);
		if(BUTTON_INPUT == 0);
			{
			WriteEEPROM(pIDstring);
			__delay_ms(500);
			GREEN_LED = ON;
			__delay_ms(500);
			GREEN_LED = OFF;
			__delay_ms(500);
			GREEN_LED = ON;
			__delay_ms(500);
			GREEN_LED = OFF;
			}  
		}
	}
}

unsigned char WriteEEPROM(unsigned char *pData)
{
unsigned char keys = 0;
unsigned char bytes = 0;
unsigned char counter = 0;
unsigned char returnvalue = 0;

for(keys = 0; keys < 32; keys++)
	{
	for(bytes = 0; bytes < 8; bytes++)
		{
		if(eeprom_read((keys * 8) + bytes) == 0xFF)
			counter++;
		}

	if(counter == 8) break;
	else counter = 0;
	}

for(bytes = 0; bytes < 8; bytes++)
	{
	eeprom_write(((keys * 8) + bytes), pData[bytes]);
	}

if(counter == 8) returnvalue = 1;
	else returnvalue = 0;

return returnvalue;
}

unsigned char CheckEEPROM(unsigned char *pData)
{
unsigned char keys = 0;
unsigned char bytes = 0;
unsigned char counter = 0;
unsigned char returnvalue = 0;

for(keys = 0; keys < 32; keys++)
	{
	for(bytes = 0; bytes < 8; bytes++)
		{
		if(eeprom_read((keys << 3) + bytes) == pData[bytes])
			counter++;
		}

	if(counter == 8) break;
	else counter = 0;
	}

if(counter == CORRECT) returnvalue = 1;
	else returnvalue = 0;

return returnvalue;
}

unsigned char OWReset(void)
{              
unsigned char DallasPresence = 0;		// Detect Dallas fob

	OW_SET_TO_OUTPUT();
	OW_CLEAR_OUTPUT();
	OW_TIME_480();
	OW_SET_TO_INPUT();
	OW_TIME_70();
	DallasPresence = OW_CHECK_INPUT();
	OW_TIME_410();
	
	return DallasPresence;   
}
 
unsigned char OWReadBit(void)
{
unsigned char Dbit = 0;					// Dallas bit result 

	OW_SET_TO_OUTPUT();
	OW_CLEAR_OUTPUT();
	OW_TIME_6();
	OW_SET_TO_INPUT(); 
	OW_TIME_9();
	Dbit = OW_CHECK_INPUT();
	OW_TIME_55();
	OW_TIME_10();

	return Dbit;          
}
  
unsigned char OWReadByte(void)
{
unsigned char k = 0;  					// counter variable     
unsigned char Dbyte = 0;				// Dallas byte result

for (k = 0; k < 8; k++) 
	{
	Dbyte = Dbyte >> 1; 
	if (OWReadBit() == 1) Dbyte |= 0x80;          
	}

return Dbyte; 
}
  
void OWWriteBit(unsigned char Dbit)
{
	if (Dbit == 1)				// write '1'
		{ 
		OW_SET_TO_OUTPUT();
		OW_CLEAR_OUTPUT();
		OW_TIME_6();
		OW_SET_TO_INPUT();
		OW_TIME_64();
		}
	else						// write '0'
		{
		OW_SET_TO_OUTPUT();
		OW_CLEAR_OUTPUT();
		OW_TIME_60();
		OW_SET_TO_INPUT();
		}
	OW_TIME_10();
}

void OWWriteByte(unsigned char Dbyte)
{
unsigned char k = 0;
	
	for (k = 0; k < 8; k++)
		{
		OWWriteBit(Dbyte & 0x01); 
		Dbyte = Dbyte >> 1;
		}
}