/*************************************************************************
 *
 *
 *    (c) Copyright Olimex 2011
 *
 *    File name   : PIR.c
 *    Description : API for the PIR sensor
 *
 *    History :
 *    1. Date        : 05 July 2011
 *       Author      : Aleksandar Mitev
 *       Description : Create
 *
 **************************************************************************/
#include "Compiler.h"
#include "GenericTypeDefs.h"
#include "PIR.h"

/* DEFINE LOCAL TYPES HERE */

/* DEFINE LOCAL CONSTANTS HERE */
#define PIR_IN_TRIS TRISAbits.TRISA3
#define PIR_IN_PORT PORTAbits.RA3

#define PIR_POWER_TRIS TRISAbits.TRISA4
#define PIR_POWER_LAT LATAbits.LATA4

/* DECLARE EXTERNAL VARIABLES HERE */

/* DEFINE LOCAL MACROS HERE */

/* DEFINE LOCAL VARIABLES HERE */
static volatile char pirTriggered;

/* DECLARE EXTERNAL VARIABLES HERE */

/* DECLARE LOCAL FUNCTIONS HERE */

/* DEFINE FUNCTIONS HERE */

/******************************************************************************
* Description: PIR_Initialize(..) - initializes pins and comapartors that the PIR should use
* Input: 	none
* Output: 	none
* Return:	0 if sucessfully initialized, -1 if error occured 
*******************************************************************************/
char PIR_Initialize(void)
{
	// start with power disabled
	PIR_POWER_TRIS = 0;
	PIR_POWER_LAT = 0;
	
	// set input as analogue pin
	PIR_IN_TRIS = 1;
	ANSELH |= 0x02; // AN9
	
	// tune comarator modules
	CM1CON0 = 0x00;
	CM2CON0 = 0x00;
	
	// configure, but do not enable comparators
	CM1CON0 = 0b00000110;
	CM2CON0 = 0b00010110;
	CM2CON1 = 0b00010000; // C1 to FVR, C2 to CVref
	
	CVRCON = 0xB0; // divider of the comparator
	
	pirTriggered = 0;
	
	return 0;
}

/******************************************************************************
* Description: PIR_PowerEnable(..) - enables power to the PIR sensor
* Input: 	enable - TRUE to power the PIR, FALSE to remove power
* Output: 	none
* Return:	none 
*******************************************************************************/
void PIR_PowerEnable(BOOL enable)
{
	if(enable) {
		PIR_POWER_LAT = 1;
		
		// trun on comparators
		CM1CON0bits.C1ON = 1;
		CM2CON0bits.C2ON = 1;
		
		// turn on the references
		CVRCONbits.CVREN = 1;
		CVRCON2bits.FVREN = 1;
		
		// wait for the FVR to stabilize
		while(!CVRCON2bits.FVREN)
			;
	} else {
		PIR_POWER_LAT = 0;
		
		// turn off comparators
		CM1CON0bits.C1ON = 0;
		CM2CON0bits.C2ON = 0;
				
		// turn on the references
		CVRCONbits.CVREN = 0;
		CVRCON2bits.FVREN = 0;
	}
}

/******************************************************************************
* Description: PIR_InterruptEnable(..) - enables interrupt generated by the comparators
* Input: 	enable - TRUE to enable interrupt, FALSE to disable
* Output: 	none
* Return:	none
*******************************************************************************/
void PIR_InterruptEnable(BOOL enable)
{
	unsigned char dummy;
	
	// read output valies of the comparator to update mismatch latches
	dummy = CM1CON0;
	dummy = CM2CON0;
	
	if(enable) {
		// clear flags to prevent immediate interrupt
		PIR2bits.C1IF = 0;
		PIR2bits.C2IF = 0;
		
		PIE2bits.C1IE = 1;
		PIE2bits.C2IE = 1;
	} else {
		// clear flags to exit interrupt routine if running inside one
		PIR2bits.C1IF = 0;
		PIR2bits.C2IF = 0;
	
		PIE2bits.C1IE = 0;
		PIE2bits.C2IE = 0;
	}
}

/******************************************************************************
* Description: PIR_InterruptClear(..) - clear interrupts from comparators
* Input: 	none
* Output: 	none
* Return:	none
*******************************************************************************/
void PIR_InterruptClear(void)
{
	unsigned char dummy;
	
	// read output valies of the comparator to update mismatch latches
	dummy = CM1CON0;
	dummy = CM2CON0;
	
	PIR2bits.C1IF = 0;
	PIR2bits.C2IF = 0;
}

/******************************************************************************
* Description: PIR_GetState(..) - get the current state of the PIR sensor
* Input: 	none
* Output: 	none
* Return:	1 if active, 0 if not
*******************************************************************************/
char PIR_GetState(void)
{
	if(CM1CON0bits.C1OUT || CM2CON0bits.C2OUT)
		return 1;
	else 
		return 0;
}

/******************************************************************************
* Description: PIR_GetTrigger(..) - get a flag that indicates if the comparators have triggered
* Input: 	none
* Output: 	none
* Return:	1 if trigger has been activated, 0 if not
*******************************************************************************/
char PIR_GetTrigger(void)
{
	return pirTriggered;
}

/******************************************************************************
* Description: PIR_ClearTrigger(..) - clears the flag that indicates if the comparators have triggered
* Input: 	none
* Output: 	none
* Return:	none
*******************************************************************************/
void PIR_ClearTrigger(void)
{
	pirTriggered = FALSE;
}

/******************************************************************************
* Description: PIR_Isr(..) - p[lace in the main interrupt service routine
* Input: 	none
* Output: 	none
* Return:	none
*******************************************************************************/
void PIR_Isr(void)
{
    if ( PIR2bits.C1IF || PIR2bits.C2IF)
    {
	    pirTriggered = 1;
	    
	    // clear the interrupt
		PIR_InterruptClear();
	} 
}	
