/*
 * timer_light.c
 */


#include <xc.h>

#define PB1    PORTAbits.RA3
#define PB2    PORTAbits.RA2
#define LIGHT  LATBbits.LATB0
#define SIGNAL LATBbits.LATB5

#define TIMER_VAL   -31250

void timer_setup(void)
{
  T0CONbits.TMR0ON = 0; // stop the timer
  T0CONbits.T08BIT = 0; // timer configured as 16-bit
  T0CONbits.T0CS = 0; // use FOSC
  T0CONbits.PSA = 0; // use prescaler
  T0CONbits.T0PS = 0b111; // prescaler 1:256
  TMR0 = TIMER_VAL;
  T0CONbits.TMR0ON = 1; // start the timer

  INTCONbits.T0IF = 0; // reset timer interrupt flag
  INTCONbits.T0IE = 1; // enable timer interrupts

  RCONbits.IPEN = 0; // no priorities
  INTCONbits.PEIE = 1; // enable peripheral interrupts
  INTCONbits.GIE = 1; // enable interrupts globally
}

unsigned char light_status, tick_count; // 8 bit vars

#define ON    0
#define OFF   1

void interrupt isr(void)
{
  if (INTCONbits.T0IF == 1) {
    TMR0 = TIMER_VAL;
    if (light_status == 0) {
        LIGHT = OFF;
        SIGNAL = OFF;
        tick_count = 0;
    }
    else { // light_status == 1
      LIGHT = ON;
      tick_count++;
      if (tick_count >= 20) { // 20*500 = 10 sec
        light_status = 0;
        LIGHT = OFF;
        SIGNAL = OFF;
      }
      else if (tick_count >= 10) { // 10*500 = 5 sec
        SIGNAL = !SIGNAL; // flashing
      }
    }
    INTCONbits.T0IF = 0;
  }
}


int main(void) {
  TRISAbits.TRISA3 = 1; // input
  TRISAbits.TRISA2 = 1; // input
  TRISBbits.TRISB0 = 0; // output
  TRISBbits.TRISB5 = 0; // output

  light_status = 0;
  tick_count = 0;

  timer_setup();

  for (;;) {
    if (PB1 == ON) {  // turn on the light and re-arm timer
      light_status = 1;
      tick_count = 0;
    }
    if (PB2 == ON) { // turn off the light
      light_status = 0;
    }
  }
  return 0;
}
