/**
 *	Simple alarm interface to work with 16F84. - William Dubel 09.01.2002
 *  PORTB represents the 8 possible alarm zones (RB0 is FrontDoor w/delayed ALARM)
 *  PORTA are status indicators and alarm activation switch
 */
#include <sys.h>
#include <pic.h>

//#define	RC	1000000		// RC Frequency - 1 MHz

#define	ALARM_LED		RA0
#define	ZONE_LED		RA1
#define	SPEAKER			RA2
#define SIREN			RA3
#define	ALARM_SWITCH	RA4
#define FRONT_DOOR		RB0		//special because has delay
#define PANIC_BUTTON	RB7

#define	UNARMED			0
#define	ARMED			1

char status;
int time = 0;

char zoneCheck()
{
	CLRWDT();
	//  update the zones okay LED indicator
	if (PORTB==255)
		return ZONE_LED = 1;
	else
		return ZONE_LED = 0;
}

void init()
{
	// I/O definition masks
	TRISB = 0xFF;	// 8 bit input value
	TRISA = 0xF0;	// bottom four output enabled (status and speakers)	
	
	PORTA = 0;
	PORTB = 0;
	
	status = UNARMED;
	zoneCheck();
}

void delay()		//  attempt at 1/4 second delay
{
	int i;
	for (i = 0; i<2000; i++)
		zoneCheck();
}

void beep()			//  1/4 second beep
{
	int i;
	int j;
	for (i = 0; i<600; i++)
	{
		SPEAKER = 1;
		for (j = 0; j<2; j++)
			zoneCheck();
		SPEAKER = 0;
		for (j = 0; j<2; j++)
			zoneCheck();
	}
}

void main()
{
	init();

	while (1)
	{
		if (status == UNARMED)
		{
			SIREN = 0;
			ALARM_LED = 0;
			//wait for alarm switch to be set on
			while (!ALARM_SWITCH)
			{
				zoneCheck();
				if (!PANIC_BUTTON)
				{
					SIREN = 1;
					while (!PANIC_BUTTON)
					{
						// flash alarm indicator quickly
						ALARM_LED = 1;
						delay();
						ALARM_LED = 0;
						delay();
					}
					SIREN = 0;
				}
			}
			beep();
			beep();

			//wait for escape delay to time out or alarm switch to be turned off,
			time = 60;
			while (--time && ALARM_SWITCH)
			{
				//flash alarm indicator slowly
				ALARM_LED = 1;
				delay();
				delay();
				ALARM_LED = 0;
				delay();
				delay();
			}
			if (ALARM_SWITCH)
				status = ARMED;
		}
		if (status == ARMED)
		{
			ALARM_LED = 1;
			//wait for alarm switch to be set off or zone to open
			while (zoneCheck() && ALARM_SWITCH);

			if (ALARM_SWITCH == 0)
			{
				status = UNARMED;
				ALARM_LED = 0;
			}
			else if (FRONT_DOOR == 0)		// Front door is open!
			{
				time = 60;
				while (--time && ALARM_SWITCH)
				{
					//  flash alarm indicator quickly while beeping
					ALARM_LED = 1;
					delay();
					ALARM_LED = 0;
					beep();
					ALARM_LED = 1;
					delay();
					ALARM_LED = 0;
					beep();
				}
				if (time == 0)		// ran out of time!
				{
					// ALARM ALERT! -- sound siren!
					SIREN = 1;
					while (ALARM_SWITCH)
					{
						// flash alarm indicator quickly
						ALARM_LED = 1;
						delay();
						ALARM_LED = 0;
						delay();
					}
				}
				// alarm deactivated
				status = UNARMED;	
			}
			else
			{
				// INSTANT ALARM ALERT! -- sound siren!
				SIREN = 1;
				while (ALARM_SWITCH)
				{
					// flash alarm indicator quickly
					ALARM_LED = 1;
					delay();
					ALARM_LED = 0;
					delay();
				}
				// alarm deactivated
				status = UNARMED;
			}
		}
	}
}
