
#define _SUPPRESS_PLIB_WARNING
#define _DISABLE_OPENADC10_CONFIGPORT_WARNING
#include <plib.h>
#include <xc.h>
#include "adc.h"
#include "util.h"

volatile int ADCResults[2];
volatile unsigned char ADCResultsUpdated;

__attribute__((mips16)) void setup_ADC() {
    int adcs;

    adcs = get_PBCLK() >> 16;
    if( adcs > 255 )
        adcs = 255;
    else if( adcs < 32 )
        adcs = 32;

    ADCResults[0] = 0;
    ADCResults[1] = 0;

    TRISAbits.TRISA0 = 1;
    ANSELAbits.ANSA0 = 1;
    TRISAbits.TRISA1 = 1;
    ANSELAbits.ANSA1 = 1;

    AD1CON1bits.ASAM = 1; // auto-sampling
    AD1CON1bits.SSRC = 7; // auto-convert
    AD1CON2bits.SMPI = 15; // interrupt every 16th sample
    AD1CON2bits.ALTS = 1; // alternate between MUXA and MUXB
    AD1CON3bits.SAMC = 31; // sampling time = 32 clocks
    AD1CON3bits.ADCS = adcs;
    AD1CHSbits.CH0SA = 0; // MUXA = AN0
    AD1CHSbits.CH0SB = 1; // MUXB = AN1
    IFS0bits.AD1IF = 0;
    IPC5bits.AD1IP = 1;
    IEC0bits.AD1IE = 1;
    AD1CON1bits.ON = 1;
    AD1CON1bits.SAMP = 1;

#ifndef __DEBUG
    while( !get_LDR_val() )
        ;
#endif
}

__attribute__((mips16)) void teardown_ADC() {
    AD1CON1bits.ON = 0;
    AD1CON1 = 0;
    AD1CON2 = 0;
    AD1CON3 = 0;
    AD1CHS = 0;
}

void __ISR(_ADC_VECTOR,IPL1AUTO) ADCinterrupt(void) {
    int i;
    int ADCTemp[2];

    ADCTemp[0] = ADC1BUF0;
    ADCTemp[1] = ADC1BUF1;
    ADCTemp[0] += ADC1BUF2;
    ADCTemp[1] += ADC1BUF3;
    ADCTemp[0] += ADC1BUF4;
    ADCTemp[1] += ADC1BUF5;
    ADCTemp[0] += ADC1BUF6;
    ADCTemp[1] += ADC1BUF7;
    ADCTemp[0] += ADC1BUF8;
    ADCTemp[1] += ADC1BUF9;
    ADCTemp[0] += ADC1BUFA;
    ADCTemp[1] += ADC1BUFB;
    ADCTemp[0] += ADC1BUFC;
    ADCTemp[1] += ADC1BUFD;
    ADCTemp[0] += ADC1BUFE;
    ADCTemp[1] += ADC1BUFF;

    if( ADCTemp[0] > 10*8 && ADCTemp[0] < 1020*8 )
        ADCResults[0] = ADCTemp[0];
    ADCResults[1] = ADCTemp[1];
    ADCResultsUpdated = 1;
    IFS0bits.AD1IF = 0;
}

__attribute__((mips16)) int get_LDR_val() {
    return ADCResults[0] / 8;
}

__attribute__((mips16)) int get_supply_voltage() {
    return ADCResults[1] * 9075 / 2048;
}
