/* --COPYRIGHT--,BSD_EX
 * Copyright (c) 2013, 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--*/
//******************************************************************************
//  IR Thermometer MSP430I2040 Demo
//
//  Description: Commercial grade IR thermometer for measuring peoples temperatures from a few centimeters away.
//  Refer to IR Thermometer app note for application details
//
//  ACLK = 32kHz, MCLK = SMCLK = Calibrated DCO = 16.384MHz
//  * Ensure low_level_init.c is included when building/running this example *
//
//               MSP430i20xx
//             -----------------
//         /|\|                |
//          | |                |
//          --|RST             |
//            |                |
//
//  J.D. Crutchfield
//  Texas Instruments, Inc
//  May 2020
//  Built with Code Composer Studio v9.3
//******************************************************************************

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

void InitMCU(void);
void Shutdown(void);
void CheckButtons(void);


//global variable for final object temperature
unsigned long GlobalTemperature = 0;

//global flag for fahrenheit = 1 or celsius = 0
unsigned char TemperatureMode_Fahr_nCel = 1;

//Global flags for button states
unsigned int g_uiButton2State, g_uiButton3State = 0;

unsigned int Test_counter = 0;
long test_global = 0;


void main(void) {
    WDTCTL = WDTPW | WDTHOLD;     // Stop Watchdog Timer

    // Determine whether we are coming out of an LPMx.5 or any other RESET.
    if ( !(LPM45CTL&LPM45IFG) ){
        // Initial power up.  shutdown and wait for ON/OFF button press
        Shutdown();
    }

    InitMCU();      // Init Clock and system GPIO
    InitLCD();      // Init LCD SEG and COM lines, LCD statemachine
    InitSD24();     // Init all SD24 channels
    InitTimers();   // Init and start all Timers

    __bis_SR_register(GIE); // Global Interrupt Enable

    //Enables Boost converter and then monitors battery and Vref voltage levels
    if(InitBoostConverter()){
        //Low Battery Detected
        LcdDisplayLowBattery();     //Display batt low
        delay_ms(2000);             //Low power timer delay

        Shutdown();                 //Go to LPM4.5
        while(1);                   //Should never reach
    }

    //beep on successful power up
    PiezoBuzzerEnable(PIEZO_BUZZER_PERIOD_MS);

    //Start measuring sensors and fill temperature buffer for software averaging.
    InitTemperatureMeasurement();


    //Main Loop
    while(1){

        //Timeout and shutdown a few seconds after measurement button is no long pressed
        if(g_uiGlobalShutdownTimeout_ms == 0){
            Shutdown();                 //Go to LPM4.5
            while(1);                   //Should never reach
        }

        //Check for button presses
        CheckButtons();

        //Calculate the object temperature
        GlobalTemperature = ThermoCompensation();

        //Display object temperature on LCD
        LcdDisplayTemperature(GlobalTemperature , TemperatureMode_Fahr_nCel);

        //Enter LPM3 until the next ADC conversion is completed
        LPM3;
    }
}


void InitMCU(void){
    //Clocking- DCO defaults to 16.384 MHz
    CSCTL1 =  0x00;     // MCLK = SMCLK = DCO = 16.374MHz

    //GPIOs
    P2OUT &=  ~BOOST_ENABLE_PIEZO_PWM;
    P2DIR |= BOOST_ENABLE_PIEZO_PWM;
    P2DIR &= ~ON_OFF_SIGNAL;    //Wakeup signal

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings.
    LPM45CTL &= ~LOCKLPM45;
}

//Check the 3 input buttons
void CheckButtons(void){
    // Power button still pressed, reset sleep timeout
    if(P2IN & ON_OFF_SIGNAL){
        g_uiGlobalShutdownTimeout_ms = SHUTDOWN_TIMEOUT_MS;
    }

    //Check Button 2 - Toggle mode Fahrenheit or Celsius
    if(g_lSD24VbattResult < BUTTON_VOLTAGE_THRESHOLD){// Button pressed.

        if(g_uiButton2State == 0){
            //A new press of the button
            g_uiButton2State = 1;
            TemperatureMode_Fahr_nCel ^= 0x01;
        }
    }else{
        // button not pressed
        g_uiButton2State = 0;
    }

    //Check Button 3 - not currently used
    if(g_lSD24VrefResult < BUTTON_VOLTAGE_THRESHOLD){// Button pressed.

        if(g_uiButton3State == 0){
            //A new press of the button
            g_uiButton3State = 1;
            //function TBD
        }
    }else{
        //Button not pressed
        g_uiButton3State = 0;
    }
}


//Configure MCU for entering LPM4.5
void Shutdown(void){

    //Stop timers
    TA0CTL = MC_0 | TACLR;
    TA1CTL = MC_0 | TACLR;

    //Shutdown SD24
    SD24CCTL3 &= ~SD24SC; //Stops any on-going conversions and shuts down SD24


    //Configure GPIOs for lowest power.
    P1OUT = 0x00;
    P2OUT = 0x00;

#ifdef HARDWARE_I2C
    P1DIR = 0xFF ^ (SCL_BIT | SDA_BIT);

    //Port 2 - Configure ON_OFF_SIGNAL (P2.2) for Wake interrupt
    P2DIR = 0xFF ^ (ON_OFF_SIGNAL);
//    P2DIR = 0xFF ^ (ON_OFF_SIGNAL);
#else
    //Configure GPIOs for lowest power.
    P1DIR = 0xFF;

    //Port 2 - Configure ON_OFF_SIGNAL (P2.2) for Wake interrupt
    P2DIR = 0xFF ^ (ON_OFF_SIGNAL | SCL_BIT | SDA_BIT);
//    P2DIR = 0xFF ^ (ON_OFF_SIGNAL);
#endif

    P2IES &= ~ON_OFF_SIGNAL;            // Lo/Hi edge
    P2IFG = 0;                          // Clear all interrupt flags
    P2IE |= ON_OFF_SIGNAL;              // Enable interrupt

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings and set REGOFF
    LPM45CTL &= ~LOCKLPM45;
    LPM45CTL |= PMMREGOFF;

    // Enter LPM4 Note that this operation does not return. The LPM4.5
    // will exit through a RESET event, resulting in a re-start
    // of the code.
    __bis_SR_register(LPM4_bits);

    // Should never get here...
    while (1);
}


















