/* 
 * File:   my_main.c
 * Author: corrado
 *
 * Created on October 18, 2015, 6:18 PM
 */

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * keyboard states
 */
#define IDLE    0
#define KEY_A   1
#define KEY_B   2
#define KEY_C   3

/*
 * keyboard events
 */
#define EV_NONE     0
#define EV_KEY_A    1
#define EV_KEY_B    2
#define EV_KEY_C    3

int key_state = IDLE;

int get_key_event(void) {
    switch (key_state) {
        case IDLE:
            if (PORTAbits.RA3 == 0) {
                key_state = KEY_A;
                return EV_KEY_A;
            } else if (PORTAbits.RA2 == 0) {
                key_state = KEY_B;
                return EV_KEY_B;
            } else if (PORTCbits.RC2 == 0) {
                key_state = KEY_C;
                return EV_KEY_C;
            } else
                return EV_NONE;

        case KEY_A:
            if (PORTAbits.RA3 == 1)
                key_state = IDLE;
            return EV_NONE;

        case KEY_B:
            if (PORTAbits.RA2 == 1)
                key_state = IDLE;
            return EV_NONE;

        case KEY_C:
            if (PORTCbits.RC2 == 1)
                key_state = IDLE;
            return EV_NONE;
    }
}

void init_ports(void) {
    TRISAbits.TRISA3 = 1;
    TRISAbits.TRISA2 = 1;
    TRISCbits.TRISC2 = 1;
    TRISB = 0xc0; // B0-->B5 = outputs, B6, B7 = inputs
    LATB = 0xff; // all leds off
}

void toggle_led(int led) {
    if (led == 0) LATBbits.LATB0 = !LATBbits.LATB0;
    else if (led == 1) LATBbits.LATB1 = !LATBbits.LATB1;
}

void all_leds_off(void) {
    LATB = 0xff;
}


int overflow_count = 0;

void init_soft_timer(void) {
    T0CONbits.TMR0ON = 0; // stop the timer
    T0CONbits.T08BIT = 0; // timer configured as 16-bit
    T0CONbits.T0CS = 0; // use system clock
    T0CONbits.PSA = 0; // use prescaler
    T0CONbits.T0PS = 0b111; // prescaler 1:256 ('0b' is a prefix for binary)
    TMR0 = -31250; // initial timer value
    INTCONbits.T0IF = 0; // clear the overflow bit initially
    T0CONbits.TMR0ON = 1; // start the timer
    overflow_count = 0;
}

void clear_timer(void) {
    TMR0 = -31250; // initial timer value
    INTCONbits.T0IF = 0; // clear the overflow bit initially
    overflow_count = 0;
}

int timer_elapsed(void) {
    if (INTCONbits.T0IF == 1) {
        TMR0 = -31250; // initial timer value
        INTCONbits.T0IF = 0; // clear the overflow bit initially
        ++overflow_count;
        if (overflow_count == 8) // 4 seconds
            return 1;
        else
            return 0;
    }
    else
        return 0;
}


int main(int argc, char** argv) {
    init_ports();
    init_soft_timer();
    for (;;) {
        switch (get_key_event()) {
            case EV_KEY_A:
                toggle_led(0);
                clear_timer();
                break;
            case EV_KEY_B:
                toggle_led(1);
                clear_timer();
                break;
        }
        if (timer_elapsed()) {
            all_leds_off();
            clear_timer();
        }
    }
    return (EXIT_SUCCESS);
}

