/*
 * Adc_onchip.c
 *
 *  Created on: Mar 12, 2018
 *      Author: tm
 */

#include "System.h"
#include "Adc_onchip.h"
//#include "IO.h"
#//include "SDCard.h"
#include "uartstdio.h"
#include "driverlib/adc.h"

uint32_t  adc_data[12];

//ADC Definitions
#define ADC_SEQ_NUMBER          0       // make this 1 for 4 channel
#define ADC_PRIORITY_LEVEL      0
#define ADC0_OVERSAMPLE_RATE    64  //Must be exponent of two, no more then 64


void adc_onchip_init(void)
{

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    //Configure ADC0
    ROM_ADCSequenceDisable(ADC0_BASE, 1);


    ROM_GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_5);        // pressure sensor AIN6
    ROM_GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);        // battery AIN4

    ROM_GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);        // humidity  AIN10

    ROM_GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0);        // battery AIN16
    ROM_GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_1);        // battery AIN17

    //#define ADC_SEQ_NUMBER          0

    ROM_ADCSequenceConfigure(ADC0_BASE, ADC_SEQ_NUMBER, ADC_TRIGGER_PROCESSOR, ADC_PRIORITY_LEVEL);

    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 0, ADC_CTL_CH4);     // AIN4 is PD7  VBAT
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 1, ADC_CTL_CH6);     // AIN6 is PD5  VPRESS
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 2, ADC_CTL_CH10);    // AIN10 is PB4 VHUM
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 3, ADC_CTL_CH16);    // AIN16 is PK0 VWATER
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 4, ADC_CTL_CH17);    // AIN17 is PK1 VTEMP
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 5, ADC_CTL_CH4);     // AIN4 is PD7  VBAT
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 6, ADC_CTL_CH4);     // AIN4 is PD7  VBAT
    ROM_ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQ_NUMBER, 7, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);  // chip temperature, final step: give int, stop

    //ROM_ADCHardwareOversampleConfigure(ADC0_BASE,64);   // NEW, average 64 samples

    //
    // Since sample sequence 1 is now configured, it must be enabled.
    //
    ROM_ADCSequenceEnable(ADC0_BASE, ADC_SEQ_NUMBER);

    //
    // Clear the interrupt status flag.  This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    ROM_ADCIntClear(ADC0_BASE, ADC_SEQ_NUMBER);


#ifdef EIGHTCHANBATT_DEBUG   // read battery voltage on all channels except the last which is onchip temp
    //#define ADC_SEQ_NUMBER          0
    ROM_ADCSequenceConfigure(ADC0_BASE, ADC_SEQ_NUMBER, ADC_TRIGGER_PROCESSOR, ADC_PRIORITY_LEVEL);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH4);    // AIN4 is PD7  VBAT
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH4);    // AIN6 is PD5  VPRESS
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH4);    // AIN10 is PB4 VHUM
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH4);    // AIN16 is PK0 VWATER
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4);    // AIN17 is PK1 VTEMP
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH4);    // AIN4 is PD7  VBAT
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH4);    // AIN4 is PD7  VBAT
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);  // chip temperature, final step: give int, stop

    //ROM_ADCHardwareOversampleConfigure(ADC0_BASE,64);   // NEW, average 64 samples

    //
    // Since sample sequence 1 is now configured, it must be enabled.
    //
    ROM_ADCSequenceEnable(ADC0_BASE, 0);

    //
    // Clear the interrupt status flag.  This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    ROM_ADCIntClear(ADC0_BASE, 0);

#endif


}

uint32_t * read_all_adc(void)
{

    //
    // Trigger the ADC conversion.
    //
    ROM_ADCProcessorTrigger(ADC0_BASE, ADC_SEQ_NUMBER);

    //
    // Wait for conversion to be completed.
    //
    while(! ROM_ADCIntStatus(ADC0_BASE, ADC_SEQ_NUMBER, false))
    {
    }

    //
    // Clear the ADC interrupt flag.
    //
    ROM_ADCIntClear(ADC0_BASE, ADC_SEQ_NUMBER);

    //
    // Read ADC Value.
    //
    ROM_ADCSequenceDataGet(ADC0_BASE, ADC_SEQ_NUMBER, adc_data);

    return(adc_data);


}

uint16_t read_adc(uint32_t chan)
{
    uint32_t pui32ADC0Value[1];

    // Need to turn on PM6 for battery voltage
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_6); // PM6, pin 83
    ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, 0xFF);    // Set (turns on FET which provides Vbat to a voltage divider
    ROM_SysCtlDelay(MILLISECOND * 200);  // timeconstant of 500K resistor divider with 0.22 uF cap is about 100msec

    // NOTE: the voltage on

    //
    // The ADC0 peripheral must be enabled for use.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    //
    // For this example ADC0 is used with AIN0 on port D7.
    // The actual port and pins used may be different on your part, consult
    // the data sheet for more information.  GPIO port D needs to be enabled
    // so these pins can be used.
    // TODO: change this to whichever GPIO port you are using.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    //
    // Select the analog ADC function for these pins.
    // Consult the data sheet to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using.
    //
    ROM_GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_7);

    //
    // Enable sample sequence 3 with a processor signal trigger.  Sequence 3
    // will do a single sample when the processor sends a signal to start the
    // conversion.  Each ADC module has 4 programmable sequences, sequence 0
    // to sequence 3.  This example is arbitrarily using sequence 3.
    //
    ROM_ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

    //
    // Configure step 0 on sequence 3.  Sample channel 0 (ADC_CTL_CH0) in
    // single-ended mode (default) and configure the interrupt flag
    // (ADC_CTL_IE) to be set when the sample is done.  Tell the ADC logic
    // that this is the last conversion on sequence 3 (ADC_CTL_END).  Sequence
    // 3 has only one programmable step.  Sequence 1 and 2 have 4 steps, and
    // sequence 0 has 8 programmable steps.  Since we are only doing a single
    // conversion using sequence 3 we will only configure step 0.  For more
    // information on the ADC sequences and steps, reference the datasheet.
    //
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                             ADC_CTL_END);

    ROM_ADCHardwareOversampleConfigure(ADC0_BASE,64);   // NEW, average 64 samples


    //
    // Since sample sequence 3 is now configured, it must be enabled.
    //
    ROM_ADCSequenceEnable(ADC0_BASE, 3);

    //
    // Clear the interrupt status flag.  This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    ROM_ADCIntClear(ADC0_BASE, 3);

    //
    // Sample AIN0 forever.  Display the value on the console.
    //
    //while(1)
    //{
        //
        // Trigger the ADC conversion.
        //
        ROM_ADCProcessorTrigger(ADC0_BASE, 3);

        //
        // Wait for conversion to be completed.
        //
        while(! ROM_ADCIntStatus(ADC0_BASE, 3, false))
        {
        }

        //
        // Clear the ADC interrupt flag.
        //
        ROM_ADCIntClear(ADC0_BASE, 3);

        //
        // Read ADC Value.
        //
        ROM_ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

        //
        // Display the AIN0 (PE3) digital value on the console.
        //
        //uprintf("AIN0 = %4d\r", pui32ADC0Value[0]);

        //
        // This function provides a means of generating a constant length
        // delay.  The function delay (in cycles) = 3 * parameter.  Delay
        // 250ms arbitrarily.
        //
        //SysCtlDelay(SysCtlClockGet() / 12);
    //}

        // Need to turn on PM6 for battery voltage
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTM_BASE, GPIO_PIN_6); // PM6, pin 83
        ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, 0x00);    // Clear - turn off battery voltage

        return(pui32ADC0Value[0]);
}

uint16_t read_adc_temperature(void)
{
    uint32_t ADCValues[1];
    uint32_t TempValueC;
    //uint32_t TempValueF;


    //
    // Display the setup on the console.
    //
    //uprintf("ADC ->\n");
    //uprintf("  Type: Internal Temperature Sensor\n");
    //uprintf("  Samples: One\n");
    //uprintf("  Update Rate: 250ms\n");
    //uprintf("  Input Pin: Internal temperature sensor\n\n");

    //
    // The ADC0 peripheral must be enabled for use (this is done in Init.c)
    //
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    //SysCtlDelay(3);

    //
    // Enable sample sequence 3 with a processor signal trigger.  Sequence 3
    // will do a single sample when the processor sends a signal to start the
    // conversion.  Each ADC module has 4 programmable sequences, sequence 0
    // to sequence 3.  This example is arbitrarily using sequence 3.
    //
    ROM_ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

    //
    // Configure step 0 on sequence 3.  Sample the temperature sensor
    // (ADC_CTL_TS) and configure the interrupt flag (ADC_CTL_IE) to be set
    // when the sample is done.  Tell the ADC logic that this is the last
    // conversion on sequence 3 (ADC_CTL_END).  Sequence 3 has only one
    // programmable step.  Sequence 1 and 2 have 4 steps, and sequence 0 has
    // 8 programmable steps.  Since we are only doing a single conversion using
    // sequence 3 we will only configure step 0.  For more information on the
    // ADC sequences and steps, reference the datasheet.
    //
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_TS | ADC_CTL_IE |
                             ADC_CTL_END);

    ROM_ADCHardwareOversampleConfigure(ADC0_BASE,64);   // NEW, average 64 samples
    // ADC is 500ohm input impedance

    //
    // Since sample sequence 3 is now configured, it must be enabled.
    //
    ROM_ADCSequenceEnable(ADC0_BASE, 3);

    //
    // Clear the interrupt status flag.  This is done to make sure the
    // interrupt flag is cleared before we sample.
    //
    ROM_ADCIntClear(ADC0_BASE, 3);

    //
    // Sample the temperature sensor forever.  Display the value on the
    // console.
    //
    //while(1)
    //{
        //
        // Trigger the ADC conversion.
        //
        ROM_ADCProcessorTrigger(ADC0_BASE, 3);

        //
        // Wait for conversion to be completed.
        //
        while(!ROM_ADCIntStatus(ADC0_BASE, 3, false))
        {
        }

        //
        // Clear the ADC interrupt flag.
        //
        ROM_ADCIntClear(ADC0_BASE, 3);

        //
        // Read ADC Value.
        //
        ROM_ADCSequenceDataGet(ADC0_BASE, 3, ADCValues);

        //
        // Use non-calibrated conversion provided in the data sheet. I use floats in intermediate
        // math but you could use intergers with multiplied by powers of 10 and divide on the end
        // Make sure you divide last to avoid dropout.
        //
        TempValueC = (uint32_t)(147.5 - ((75.0*3.3 *(float)ADCValues[0])) / 4096.0);

        //
        // Get Fahrenheit value.  Make sure you divide last to avoid dropout.
        //
        //TempValueF = ((TempValueC * 9) + 160) / 5;

        //
        // Display the temperature value on the console.
        //
        //uprintf("Temperature = %3d*C or %3d*F\r", (int)TempValueC, (int)TempValueF);

        //
        // This function provides a means of generating a constant length
        // delay.  The function delay (in cycles) = 3 * parameter.  Delay
        // 250ms arbitrarily.
        //
        //SysCtlDelay(80000000 / 12);
    //}


        return((uint16_t)TempValueC);


}


