/* 
 * File: analoginput.c
 * Author: E. Martin
 * Comments: File for minirov light controller analog inputs
 * Revision history: Git via BitBucket
 */
#include <xc.h>
#include "sys_defs.h"
#include "analoginput.h"
#include "modbus_registers.h"

//#include "mcc_generated_files/adc1.h"
//#include "serial.h" 


void analogInit() {
	
	//Explorer 16 issues
	_LATB15 = 0;
	_TRISB15= 0;

	//Set up registers
	//ADC1PCFGL = 0x00 // TODO SET UP ALREADY IN PIN MANAGER
	AD1CON1 = 0x00E0;
	AD1CSSL = 0;
//    AD1CSSH = 0;
	AD1CON2 = 0x6000; // CSCNA disabled; ALTS disabled; BUFM disabled; SMPI 1; OFFCAL disabled; VCFG1 VREF-; VCFG0 VREF+; 
	AD1CON3 = 0x1F3F;//0x1F3F; //31TAD 64*Tcy Also use system clock  
	AD1CON1bits.ADON = 1;
}

unsigned int analogReadReg(unsigned int address) {
    
    int i;
    MB_INPUT_REGISTER reg = (MB_INPUT_REGISTER) address;   
    //bad ss return
    if (reg < ANALOG_REG_START || reg > ANALOG_REG_END) {
        return 0;
    }
    ADC1_CHANNEL channel;
    unsigned int conversion = 0;
//    int i;
    
    switch (reg) {
        case ANALOG_IN_0:
            channel = ADC1_CHANNEL_AN0; break;
        case ANALOG_IN_1:
            channel = ADC1_CHANNEL_AN1; break;
        case ANALOG_IN_2:
            channel = ADC1_CHANNEL_AN2; break;
        case ANALOG_IN_3:
            channel = ADC1_CHANNEL_AN3; break;
        case AMB_TEMP:
            channel = ADC1_AMB_TEMP; break;
        case GF_CURRENT:
            channel = ADC1_GF_CURRENT; break;
        default: 
            return 0; break;
    }
    
    
    // Let's average this 16 times.
    for (i = 0; i<32;i++) {
        conversion +=  analogReadADC(channel);
	}
    conversion >>= 5;//divide by 16
    
   /* 
    ADC1_ChannelSelect(channel);
    ADC1_Start();
    //Provide Delay
    for (i = 0; i < 5000; i++) {
    }
    ADC1_Stop();
    while (!ADC1_IsConversionComplete()) {
        ADC1_Tasks();
    }
    conversion = ADC1_ConversionResultGet();
	*/
    return conversion;
}

unsigned int analogReadADC(ADC1_CHANNEL channel){
    
    unsigned int conversion;
    
    // non-scanning
	AD1CHS= channel;
	AD1CON1bits.SAMP = 1;
	while (!AD1CON1bits.DONE);
	AD1CON1bits.DONE = 0;
	conversion = ADC1BUF0;
    return conversion;
}
