#include <12F675.h>

#FUSES INTRC_IO,NOPROTECT,NOWDT,PUT,BROWNOUT, NOMCLR
#use delay(clock=4000000)

#use fast_io(A) // we program tri-state register

/* pinout */
                                // 8 Vss
#define DC_IN            PIN_A0 // 7
#define JP1				 PIN_A1 // 6
#define OVERRIDE_SWITCH	 PIN_A2 // 5
#define JP2              PIN_A3 // 4
#define LED              PIN_A4 // 3
#define RELAY	         PIN_A5 // 2
                                // 1 Vcc

/* analog channel voltage divider is connected to */
#define AN_DC_IN     0

#define SHUTDOWN_AFTER 90	   /* n * 10 seconds */
//#define SHUTDOWN_AFTER 1	   /* n * 10 seconds */

const long thresholds[2] = { 755, 835 }; // 11.8 volts, 13.05 volts

/** check the jumpers and return the current threshold voltage setting */
long current_threshold(void) {
	if ( 0==input(JP2) )
		return thresholds[0];
	return thresholds[1];
}

long read_adc_average(int channel) {
	long value;
	int i;

	set_adc_channel(channel); 
	value=0;
	for ( i=0 ; i<8 ; i++ ) {
		value += read_adc(); 
		delay_ms(2);
	}
	/* divide by 8 */
	value = value / 8;

	return value;
}


void init_adc(void) {
	setup_adc( ADC_CLOCK_INTERNAL ); 
	setup_adc_ports( AN0_ANALOG ); 
}

/** change the state of the IPS  
 * @param state 0 to turn off, 1 turns on 
 */
void ps(int state) {
	if ( 0 == state ) {
		output_low(RELAY);
	} else {
		output_high(RELAY);
	}
}


void main(void) {
	int shutdownCount=SHUTDOWN_AFTER;
	int i;

	set_tris_a(0b001111);

	init_adc();
#asm
	movlw 0b01010110 // setup options register to enable pull ups
	movwf 0x81
	movlw 0b110 // enable pullups on A2 and A1
	movwf 0x95
#endasm

	/* flash the LED on startup */
	for ( i=0 ; i<10 ; i++ ) {
		output_high(LED);
		delay_ms(200);
		output_low(LED);
		delay_ms(200);
	}

	/* we start turned on */
	ps(1);

	/* infinite loop */
	for ( ; ; ) {
		/* if the switch is low then we turn output on regardless of DC voltage */
		if ( 0 == input(OVERRIDE_SWITCH) ) {
			ps(1);
		} else if ( read_adc_average(AN_DC_IN) < current_threshold() ) {
			/* turn off */
			if ( 0 == shutdownCount ) {
				ps(0);
				output_low(LED);
			} else {
				shutdownCount--;
				output_high(LED);	/* led lit indicates that we are counting down */
			}
		} else {
			/* voltage is above DC_LOW_THRESHOLD */
			ps(1);
			output_low(LED);
			shutdownCount=SHUTDOWN_AFTER;
		}

		/* pause between measurements */
		delay_ms(10000);
		//delay_ms(1);
	}
}
