/* --COPYRIGHT--,BSD_EX
 * Copyright (c) 2014, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************
 *
 *                       MSP430 CODE EXAMPLE DISCLAIMER
 *
 * MSP430 code examples are self-contained low-level programs that typically
 * demonstrate a single peripheral function or device feature in a highly
 * concise manner. For this the code may rely on the device's power-on default
 * register values and settings such as the clock configuration and care must
 * be taken when combining code from several examples to avoid potential side
 * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
 * for an API functional library-approach to peripheral configuration.
 *
 * --/COPYRIGHT--*/
/*
 * SD24.c
 *
 *  Created on: May 25, 2020
 *      Author: JD Crutchfield
 */


#include <msp430.h>
#include "mcu.h"
#include "Thermopile.h"
#include "SD24.h"
#include "Timers.h"


long   g_lSD24VrefBuffer[SD24_NUM_AVERAGE_SAMPLES] = {0};
long   g_lSD24VbattBuffer[SD24_NUM_AVERAGE_SAMPLES] = {0};
unsigned int g_uiSD24SampleDelayMS = SD24_SAMPLE_DELAY_MS;       //miliseconds between samples.  10ms=100sps
unsigned int g_uiSD24BufferPointer = 0;       //miliseconds between samples.  10ms=100sps
long   g_lSD24VrefResult = 0;
long   g_lSD24VbattResult = 0;

float  g_fSD24VrefResult, g_fSD24VbattResult, g_fThermopileVoltage, g_fNTCvoltage  = 0;

//Configure SD24 for reading Thermopile and Thermister
void InitSD24(void){

    SD24CTL = SD24REFS;     // Internal ref

    //Configure SD24 0&1 to measure Temp Sensors
    SD24CCTL0 |= SD24SNGL | SD24DF | SD24OSR_256 | SD24GRP; // Group with CH1, single conversion, OSR=256
    SD24CCTL1 |= SD24SNGL | SD24DF | SD24OSR_256 | SD24GRP; // Single conversion, OSR=256, Iterrupt enabled
    SD24CCTL2 |= SD24SNGL | SD24DF | SD24OSR_256 | SD24GRP; // Group with CH3, single conversion, OSR=256
    SD24CCTL3 |= SD24SNGL | SD24DF | SD24OSR_256 | SD24IE;  // Single conversion, OSR=256, Iterrupt enabled

    __delay_cycles(3200);   // Delay ~200us for 1.2V ref to settle;
}

//This function will enable the Boost Converter.
//It will monitor Vref and Vbatt and wait to stabilize or timeout.
unsigned char InitBoostConverter(void){
    unsigned char BatteryLow = 0;

    //Enable Boost Converter
    P2OUT |= BOOST_ENABLE_PIEZO_PWM;

    //Configure timeout for Vref to stabalize
    g_uiTimeoutMilliseconds = BOOST_TIMEOUT_MS;

    //TODO Need to set realistic voltage thresholds for VREF and BATT
    while(( (g_lSD24VrefBuffer[g_uiSD24BufferPointer] <VREF_LOW_THRESHOLD_VOLTAGE) ||
            (g_lSD24VbattBuffer[g_uiSD24BufferPointer]<VBATT_LOW_THRESHOLD_VOLTAGE)) &&
            (g_uiTimeoutMilliseconds)){

        LPM3;            // LPM0 for lower power waiting
        __no_operation();
    }

    if(g_uiTimeoutMilliseconds == 0){ BatteryLow = 1; }

    return BatteryLow;
}

void SD24ReadResults(void){
    //incremented it first so it's always pointing at latest measurement
    g_uiSD24BufferPointer++;

    if(g_uiSD24BufferPointer >= SD24_NUM_AVERAGE_SAMPLES){
        g_uiSD24BufferPointer = 0;
    }

    // Clear LSBACC bits to access upper bits
    SD24CCTL0 &= ~SD24LSBACC;
    SD24CCTL1 &= ~SD24LSBACC;
    SD24CCTL2 &= ~SD24LSBACC;
    SD24CCTL3 &= ~SD24LSBACC;

    //Read out upper 16 bits of SD24MEM
    g_lSD24ThermopileBuffer[g_uiSD24BufferPointer] = (long)SD24MEM0 << 8;
    g_lSD24ThermistorBuffer[g_uiSD24BufferPointer] = (long)SD24MEM1 << 8;
    g_lSD24VrefBuffer[g_uiSD24BufferPointer]       = (long)SD24MEM2 << 8;
    g_lSD24VbattBuffer[g_uiSD24BufferPointer]      = (long)SD24MEM3 << 8;

    // Set LSBACC bits to read lower bits
    SD24CCTL0 |= SD24LSBACC;
    SD24CCTL1 |= SD24LSBACC;
    SD24CCTL2 |= SD24LSBACC;
    SD24CCTL3 |= SD24LSBACC;

    //Read out lower 8 bits of SD24MEM
    g_lSD24ThermopileBuffer[g_uiSD24BufferPointer] |= SD24MEM0 & 0xFF;
    g_lSD24ThermistorBuffer[g_uiSD24BufferPointer] |= SD24MEM1 & 0xFF;
    g_lSD24VrefBuffer[g_uiSD24BufferPointer]       |= SD24MEM2 & 0xFF;
    g_lSD24VbattBuffer[g_uiSD24BufferPointer]      |= SD24MEM3 & 0xFF;
}



void SD24averaging(void){
    int x;

    //Clear result variables
    g_lThermopileResult = 0;
    g_lThermistorResult = 0;
    g_lSD24VrefResult   = 0;
    g_lSD24VbattResult  = 0;

    //Check voltage polarity.  Data is in 2s compliment.  If negative, need to fill top of Long with 1s
    for(x=0; x<SD24_NUM_AVERAGE_SAMPLES; x++){

        if(g_lSD24ThermopileBuffer[x] & 0x800000 ){ // 2s comp sign bit in 24 bit mode = negative voltage
            g_lSD24ThermopileBuffer[x] |= 0xFF000000;
        }

        if(g_lSD24ThermistorBuffer[x] & 0x800000 ){ // 2s comp sign bit in 24 bit mode = negative voltage
            g_lSD24ThermistorBuffer[x] |= 0xFF000000;
        }

        if(g_lSD24VrefBuffer[x] & 0x800000 ){       // 2s comp sign bit in 24 bit mode = negative voltage
            g_lSD24VrefBuffer[x]  |= 0xFF000000;
        }

        if(g_lSD24VbattBuffer[x] & 0x800000 ){      // 2s comp sign bit in 24 bit mode = negative voltage
            g_lSD24VbattBuffer[x] |= 0xFF000000;
        }
    }

    //Sum up all samples in buffer
    for(x=0; x<SD24_NUM_AVERAGE_SAMPLES; x++){
        g_lThermopileResult = g_lThermopileResult + g_lSD24ThermopileBuffer[x];
        g_lThermistorResult = g_lThermistorResult + g_lSD24ThermistorBuffer[x];
        g_lSD24VrefResult   = g_lSD24VrefResult   + g_lSD24VrefBuffer[x];
        g_lSD24VbattResult  = g_lSD24VbattResult  + g_lSD24VbattBuffer[x];
    }

    g_lThermopileResult = g_lThermopileResult / SD24_NUM_AVERAGE_SAMPLES;
    g_lThermistorResult = g_lThermistorResult / SD24_NUM_AVERAGE_SAMPLES;
    g_lSD24VrefResult   = g_lSD24VrefResult   / SD24_NUM_AVERAGE_SAMPLES;
    g_lSD24VbattResult  = g_lSD24VbattResult  / SD24_NUM_AVERAGE_SAMPLES;
    __no_operation();

    //New workaround on NTC measurement.  NTC signal is being routed through Vref buffer, so the Vref signal should contain the ambient temp data
    g_lThermistorResult = g_lSD24VrefResult;

}


//SD24 ISR
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=SD24_VECTOR
__interrupt void SD24_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(SD24_VECTOR))) SD24_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch (__even_in_range(SD24IV,SD24IV_SD24MEM3)) {
        case SD24IV_NONE: break;
        case SD24IV_SD24OVIFG: break;
        case SD24IV_SD24MEM0: break;
        case SD24IV_SD24MEM1: break;
        case SD24IV_SD24MEM2: break;
        case SD24IV_SD24MEM3:   // Conversion complete ISR
            SD24ReadResults();
            break;
        default: break;
    }

    LPM3_EXIT;
}



































