#include <p18cxxx.h>
#include "main.h"

unsigned char Sample_Buffer[28] = {1}, New_Flag=0;
volatile int counter;
struct Philips_Code Signal;

#pragma code HIGH_INTERRUPT_VECTOR = 0x08
#pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode()
{
	int Temp=0;
	unsigned char i=1;
	
	//if (INTCON3 & 0x01)
	if (INTCON3bits.INT1IF)
	{
		// +++  Interrupt Code  +++
		for (counter = BASIC_DELAY; counter; counter--);		// wait ~400 us

		// Get Samples
		while (i<28)
		{
			Sample_Buffer[i] = PORTCbits.RC7;					// take the sample
			i++;
			for (counter = SAMPLE_DELAY; counter; counter--);	// wait ~860 us
		}
		
		// Convert the samples into a number
		New_Flag = 1;
		Temp = 0;
		for (i=0; i<=26; i=i+2)
			if (Sample_Buffer[i] ^ Sample_Buffer[i+1])
				Temp = (Temp<<1) | Sample_Buffer[i];
			else
			{
				Temp = ERROR;
				New_Flag = 0;
				break;
			}
		if (New_Flag)
		{
			Signal.Start	= (Temp & 0x3000) >> 12;
			Signal.Toggle	= (Temp & 0x0800) >> 11;
			Signal.Address	= (Temp & 0x07C0) >>  6;
			Signal.Data		= (Temp & 0x003F);
		}	
		// ---  Interrupt Code  ---
		
		// Clearing the Interrupt Flag
		//INTCON3 = INTCON3 & (~0x01);
		INTCON3bits.INT1IF = 0;
	}
}

#pragma code
void DelayMs (volatile unsigned int Ms)
{
	volatile unsigned int x;
	while (Ms--)
		for (x=900; x; x--);
	return;
}

void System_Init (void)
{
	Clock_Init ();
    GPIO_Init ();
    Receiver_Init ();
    return;
}

// Clock initialize
void Clock_Init (void)
{
	OSCTUNEbits.PLLEN = 1;  		// Enable the PLL and wait 2+ms until the PLL locks before enabling USB module
	DelayMs (50);
	return;
}


void GPIO_Init (void)
{
	// Analog input/output --> general purpose input/output
	// All outputs set as GPIO
    ANCON0 = 0xFF;
    ANCON1 = 0xFF;
    INTCON2bits.RBPU = 0;
    
	TRISC = TRISC & (~0x40);		// Infrared LED --> Output
	BUTTON_INPUT;					// Button --> Input
    TRISA = TRISA & (~0x07);		// LED0, 1, 2 --> Output
    LATA = (LATA & ~0x02) | 0x05;	// LED0 - OFF (1); LED1 - ON (0), LED2 - OFF (1)
    return;
}

void Receiver_Init (void)
{
    RCON = RCON | 0x80;				// IPEN = 1;	interrupt priority enabled
    INTCON = INTCON | 0xC0;			// high and low priority interrupts enabled
    
	TRISC = TRISC | 0x80;			// PC7 - input
	RPINR1 = 18;					// INT1 function associated with pin 18
    INTCON3bits.INT1IF = 0;			// INT1 flag cleared
	INTCON2 = INTCON2 & (~0x20);	// interrupt on falling edge
	INTCON3 = INTCON3 | 0x48;		// INT1 enabled as High priority interrupt
	return;
}

/*
void main ()
{
	long int i;
	TRISA = TRISA & (~0x01);
	while (1)
	{
		LATA = LATA ^ 0x01;
		for (i=30000; i; i--);
	}	
}
*/

void main ()
{
	System_Init ();

	while (1);
}
