
#include <driverlib.h>

/* Sensor settings*/
#define KEY_LVL     220                     // Defines threshold for a key press
/*Set to ~ half the max delta expected*/

#define LED   (0x01)                        // P1.0 LED output

// Global variables for sensing
unsigned int base_cnt, meas_cnt;
int delta_cnt;
char key_pressed;
/* System Routines*/
void measure_count(void);                   // Measures each capacitive sensor
void pulse_LED(void);                       // LED gradient routine

volatile uint32_t n;

int main( void )
{

    unsigned int i,j;
    WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;

    P1DIR |= LED;                             // P1.0 = LED
    P1OUT = 0x00;

    measure_count();                          // Establish baseline capacitance
    base_cnt = meas_cnt;

    for(i=15; i>0; i--)                       // Repeat and avg base measurement
    {
        measure_count();
        base_cnt = (meas_cnt+base_cnt)/2;
    }

    /* Main loop starts here*/
    while (1)
    {

        j = KEY_LVL;
        key_pressed = 0;                        // Assume no keys are pressed

        measure_count();                        // Measure all sensors

        delta_cnt = base_cnt - meas_cnt;  // Calculate delta: c_change

        /* Handle baseline measurment for a base C decrease*/
        if (delta_cnt < 0)                    // If negative: result increased
        {                                     // beyond baseline, i.e. cap dec
            base_cnt = (base_cnt+meas_cnt) >> 1; // Re-average quickly
            delta_cnt = 0;                    // Zero out for pos determination
        }
        if (delta_cnt > j)                    // Determine if each key is pressed
        {                                     // per a preset threshold
            j = delta_cnt;
            key_pressed = 1;                    // key pressed
        }
        else
            key_pressed = 0;

        /* Handle baseline measurment for a base C increase*/
        if (!key_pressed)                       // Only adjust baseline down
        {                                       // if no keys are touched
            base_cnt = base_cnt - 1;        // Adjust baseline down, should be
        }                                       // slow to accomodate for genuine
        pulse_LED();                           // changes in sensor C

    }
}                                           // End Main

/* Measure count result (capacitance) of each sensor*/
/* Routine setup for four sensors, not dependent on NUM_SEN value!*/

void measure_count(void)
{
    TA2CTL = TASSEL_3 + MC_2;               // TACLK, cont mode, TASSEL_3 ties the Timer clock to the output of the capacitive Touch IO oscilator
    TA2CCTL1 = CM_3 + CCIS_2 + CAP;         // Pos&Neg,GND,Cap

    /*Configure Ports for relaxation oscillator*/
    CAPSIO0CTL |= CAPTIOEN + CAPSIOPOSEL0 + CAPSIOPISEL2; //P1.4

    for(n=1; n>0; n--);

    TA2CCTL1 ^= CCIS0;                      // Create SW capture of CCR1, this is an arbitraty thing, just provides a starting point for the counter

    TA2CTL |= TACLR;                        // Clear Timer_A TAR

    for(n=50; n>0; n--);                    // Set a defined time interval for the counter. This is better than through a timer and interrupt to allow leaving of active mode and/or free up CPU for other tasks

    TA2CCTL1 ^= CCIS0;                      // Create SW capture of CCR1, this ends the counter
    meas_cnt = TA2CCR1;                     // Save result, at this point the register contains the number of oscillation cycles of the capacitive touch oscillator

    CAPSIO0CTL = 0;                         // Switch off oscillator
}

void pulse_LED(void)
{
    if(key_pressed)
    {
        P1OUT ^= LED;
    }
    else
    {
        P1OUT &= ~LED;
    }
}
