/**
 * @file main.c
 * @brief Demo ADC12 continuous conversion using timer
 *
 * Timer A0 periodically (2Hz) triggers the conversion
 * on channel A0 of ADC12, which is connected to a potentiometer.
 * High 8 bits of the conversion are sent through USCI to PC.
 *
 * @date 2021
 * @author Marija Bezulj (meja@etf.bg.ac.rs)
 *
 * @version [1.0 @ 05/2021] Initial version
 */
#include <msp430.h>
#include <stdint.h>

#define BR9600      (109)

#define BRS9600      (UCBRS_2)

/**
 * @brief Timer period for ADC12 conversion triggering
 *
 * Timer is clocked by ACLK (32768Hz).
 * A 8x divider is set.
 * We want ~500ms period, so use 2048 for CCR1
 */
#define CONV_PERIOD        (2048)  /* 500ms */

/**
 * @brief Main function
 *
 * Peripheral initialization. USCI_A1 is used in UART mode
 * for transfer of ADC12 conversion result.
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;       // Stop watchdog timer

    // Initialize UART
    P4SEL |= BIT4 | BIT5;           // enable P4.4 and P4.5 for UART

    UCA1CTL1 |= UCSWRST;            // set software reset

    UCA1CTL0 = 0;                   // no parity, 8bit, 1 stop bit
    UCA1CTL1 |= UCSSEL__SMCLK;      // use SMCLK = 1 048 576 Hz
    UCA1BRW = BR9600;              // BR = 109
    UCA1MCTL |=BRS9600 + UCBRF_0;  // BRS = 2 for 9600 bps

    UCA1CTL1 &= ~UCSWRST;           // release software reset

    /* ADC12_A channel A0 init */
    P6SEL |= BIT0;              // input pin P6.0 - pot2
                                // set pin P6.0 as alternate function - A0 analog

    ADC12CTL0 &= ~ADC12ENC;     // disable ADC before configuring
    /* 32 cycles for sampling, ref voltage is set by REF module, ADC ON */
    ADC12CTL0 |= ADC12ON;
    ADC12CTL1 |= ADC12SHS_1 + ADC12SSEL_3 + ADC12CONSEQ_2;
                                  // start address ADC12MEM0, timer starts conv
                                  // single channel continuous conversion, SMCLK clock
                                  // SAMPCON sourced from the sampling timer
    ADC12CTL2 |= ADC12RES_2;      // 12 bit conversion result
    ADC12MCTL0 |= ADC12INCH_0;    //reference AVCC and AVSS, channel A0
    ADC12CTL0 |= ADC12ENC;        // enable ADC12

    /* initialize Timer A0 for ADC12 trigger */
    // CBOUT TA0 -> ADC12SHS1 this is internal, ports and pins not used (P1.2)
    TA0CCR0 = (CONV_PERIOD/2  - 1);// f_OUT = 2 Hz, f_ACLK = 32768 Hz ID=8 => T_OUT = 2048.
                                   // TOGGLE outmod => T_OUT = 2 * T_CCR0 =>
                                   // T_CCR0 = T_OUT/2 = 1024 (TA0CCR0 = T_CCR0 - 1)
    TA0CCTL1 |= OUTMOD_4;      // toggle mode
    //TA0CCR1 = 5;             // any number since CCR0 defines period
    TA0CTL |= TASSEL__ACLK + ID__8 + MC__UP;

    while(1){
        if ((ADC12IFG & ADC12IFG0) != 0)    // wait for conversion to end
        {
            UCA1TXBUF = (ADC12MEM0 >> 4) & 0xff; // send the converted 8bit value to PC

        }
    }
}
