/**  Header Files **************************************************/     
#include <p18f4520.h> 
#include "LCD Module.h" // Part A
#include <stdio.h> // Part A
#include <timers.h> // Part B
#include <portb.h> // Part C

/** Configuration Bits *********************************************/     
#pragma config OSC = EC
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config BOREN = OFF
#pragma config XINST = OFF

/** Define Constants Here ******************************************/
#define START_TIME 49911  // Part B

/** Local Function Prototypes **************************************/
void low_isr(void);
void high_isr(void);
void updateLcd(void);

/** Declare Interrupt Vector Sections ****************************/
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
   _asm goto high_isr _endasm
}

#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
   _asm goto low_isr _endasm
}

/** Global Variables ***********************************************/
int counter = 0; // Part B
char line1[17]; // Part A
	
/*******************************************************************
* Function:        void main(void)
********************************************************************/
#pragma code
void main (void)
{
  ADCON1 = 0x0F; // Part C
  TRISB = 0xFF; // Part C
  XLCDInit(); // Part A
  XLCDClear(); // Part A
  updateLcd(); // Part A
  WriteTimer0(START_TIME);  // Part B
  OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_32 ); // Part B

  OpenRB0INT( PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_OFF); // Part c
  INTCONbits.INT0IF = 0;  // Not required
  INTCONbits.GIE = 1; // Part B
  while (1) {
  }
}

/*****************************************************************
* Additional Helper Functions
******************************************************************/

/*****************************************************************
* Function:			void sample(void)
* Input Variables:	none
* Output Return:	none
* Overview:			Use a comment block like this before functions
******************************************************************/
void updateLcd()
{
  sprintf(line1,"     %d     ", counter); // Part A
  XLCDL1home(); // Part A
  XLCDPutRamString(line1); // Part A	
}	

/*****************************************************************
* Function:        void high_isr(void)
* Possible sources of interrupt - none
* Overview:
******************************************************************/
#pragma interrupt high_isr
void high_isr(void)
{
  if(INTCONbits.INT0IF)	// Interrupt 0, RB0 (Part C)
  {
    INTCONbits.INT0IF = 0; // Part C
    counter = 0; // Part C
    updateLcd();  // Not required
    WriteTimer0(START_TIME);  // Not required
  }
	
  if(INTCONbits.TMR0IF)  // Timer 0 interrupt (Part B)
  {						
    INTCONbits.TMR0IF = 0; // Part B
    WriteTimer0(START_TIME); // Part B
    counter++; // Part B
    updateLcd(); // Part B
  }
}

/******************************************************************
* Function:        void low_isr(void)
* Possible sources of interrupt - none
* Overview:
********************************************************************/
#pragma interruptlow low_isr
void low_isr(void)
{
	// Add code here for the low priority Interrupt Service Routine (ISR)
}