/*
 * File:   adc_test.c
 * Author: corrado
 */

#define _XTAL_FREQ   4000000

#include <xc.h>
#include <pic16f690.h>
#include <delays.h>

// PIC16F690 Configuration Bit Settings

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Selection bits (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

#define OFF  0
#define ON   1

int t_on, t_off, status = OFF;

void interrupt isr(void)
{
    if (INTCONbits.T0IF == 1) {
        if (status == ON) {
            /* We should turn LED on */
            if (t_on == 0) {
                status = OFF;
                TMR0 = -t_off;
            }
            else {
                TMR0 = -t_on;
            }
        }
        else {
            /* We should turn LED off */
            if (t_off == 0) {
                status = ON;
                TMR0 = -t_on;
            }
            else {
                TMR0 = -t_off;
            }
        }

        PORTCbits.RC0 = status;
        PORTCbits.RC1 = status;
        PORTCbits.RC2 = status;
        PORTCbits.RC3 = status;

        status = !status;
        INTCONbits.T0IF = 0;
    }
}

int main(void) {

    int adc;

    OSCCONbits.IRCF = 0b110;

    ANSEL = 0;
    ANSELH = 0;

    /* configure digital I/O */
    TRISCbits.TRISC0 = 0;
    TRISCbits.TRISC1 = 0;
    TRISCbits.TRISC2 = 0;
    TRISCbits.TRISC3 = 0;

    PORTCbits.RC0 = 0;
    PORTCbits.RC1 = 0;
    PORTCbits.RC2 = 0;
    PORTCbits.RC3 = 0;

    /* configure timer */
    OPTION_REGbits.T0CS = 0;
    OPTION_REGbits.PS = 0b110;
    OPTION_REGbits.PSA = 0;

    TMR0 = 0;
    INTCONbits.T0IF = 0;
    INTCONbits.T0IE = 1;

    INTCONbits.GIE = 1;

    /* configure ADC */
    ANSELbits.ANS0 = 1; // AN0 on pin 19

    ADCON0bits.ADFM = 1;  // right justified
    ADCON0bits.VCFG = 0;  // Reference = VDD
    ADCON0bits.CHS = 0;   // Select channel 0
    ADCON0bits.ADON = 1;  // turn adc ok

    ADCON1bits.ADCS = 0b110;   // ADC clock = FOSC/64

    for (;;) {

        ADCON0bits.GO = 1; // start conversion
        while (ADCON0bits.GO == 1); // wait for end of conversion

        adc = (ADRESH << 8) + ADRESL;
        
        t_on = adc / 10;
        t_off = 102 - t_on;

    }

    return 0;
}
