/*****************************************************************************
*
* Copyright (C) 2013 - 2017 Texas Instruments Incorporated - http://www.ti.com/
*
* 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.
*
******************************************************************************
*
* UART Driver
* -----------
*
* For the UART to work required items are:
*
*   A. A UART port                        [Port 3, Pins 3.2 and 3.3 chosen]
*   B. UART Port Select Lines             [Port 3, SEL1=0 SEL0=1, UART Mode]
*   C. Clock for Baud rate                [12 MHz chosen]
*   D. Set up Clock registers             [Clock configuration]
*   E. Set up UART registers              [UART configuration]
*
* The recommended initialization procedure from the data sheet is as follows:
*
*   1. Set UCSWRST[UART Reset Flag].
*   2. Initialize all eUSCI_x registers with UCSWRST = 1 (including UCAxCTL1).
*   3. Configure ports.
*   4. Clear UCSWRST with software.
*   5. Enable interrupts (optional) with UCRXIE or UCTXIE.
*
* After the initialization is complete,
*
*  > Data can be transmitted using the TX Buffer and TX Interrupt
*  > Data can be read using the RX Buffer and RX Interrupt
*
******************************************************************************/

#include <stdint.h>
#include "msp.h"
#define __uart2_off() {UCA2CTLW0 |= EUSCI_A_CTLW0_SWRST;}      // Lock UART2
#define __uart2_on()  {UCA2CTLW0 &= (~EUSCI_A_CTLW0_SWRST);}   // Unlock UART2

void uart2clocksetup(void){

    /* Sets up the internal clock of the MSP432p401R
     *
     * Clock Registers Setup (CS)
     * --------------------------
     *
     * Choice of clock is 12 MHz (DCOCLK - SMCLK). While UART itself does not
     * need a clock, a baud rate is generated off of the clock and so it must be
     * configured. Clock registers are also keyed. All bits need to be written
     * together. We then configure the clock registers to set a DCO clock to
     * 12 MHz.
     *
     * Procedure to do this:
     *
     *      1. Unlock clock registers
     *      2. Configure Clock Control register 0
     *      3. Configure Clock Control register 1
     *      4. Lock clock register
     *
    */

    // Set up power for the clock needed. VCORE1 = 1.4 V
    PCM -> CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR__AM_LDO_VCORE1;

    CS -> KEY = CS_KEY_VAL;                           // Unlock CS registers

    // Control Word 0 Set up
    CS -> CTL0 |= CS_CTL0_DCOEN;                      // Enable DCO
    CS -> CTL0 |= CS_CTL0_DCORSEL_0;                  // Reset Tune
    CS -> CTL0 |= CS_CTL0_DCORSEL_3;                  // Set DCO to 12MHz
    CS -> CTL1 |= CS_CTL1_SELS_3;                     // Select DCO CLock
    CS -> CTL1 |= CS_CTL1_DIVS__1;                    // SMCLK divider is 1
    CS -> CTL1 |= CS_CLKEN_SMCLK_EN;                  // Small CLock Enabled

    CS -> KEY = (~CS_KEY_VAL);                        // Lock CS registers

    return;
}


void uart2configure(void){

    /* Sets up the EUSCI_A2 UART registers corresponding to the EUSCI_A2
     * UART module of the MSP432p401R.
     *
     * EUSCI_A2 Registers Setup (UCA2)
     * -------------------------------
     *
     * Protocol requirements for the UART driver are:
     *
     *      1. Parity check disabled
     *      2. LSB first data
     *      3. 8 Data bits
     *      4. 1 Stop bit
     *      5. Baud Rate of 115200
     *
     * Procedure to do this:
     *
     *      1. Reset UART2 flag
     *      2. Configure Control Word0 of EUSCI_A2
     *      3. Configure Control Word1 of EUSCI_A2
     *      4. Configure baud rate register of EUSCI_A2
     *      5. Configure interrupt register of EUSCI_A2
     *
     * Baud Rate Calculation [As per data sheet slau356h.pdf]
     * ---------------------
     *
     * N determines the clock pre-scaler needed to achieve
     * required baud rate
     * N=clock/baud rate
     * N= SMCLK/115200 = 12000000/115200 = 104.166
     * Since N > 16, OS16 = 1 [Meaning Over sampling enabled]
     * UCBR2 = INT(N/16) = INT(6.510) = 6
     * UCBRF2 = INT([(N/16) – INT(N/16)] × 16) = 8
     * UCBRS2 = Fractional part of N = (N - INT(N)) = 0.166 i.e. 0x20
     *
    */

    // Set the UART select lines on PORT3. According to the data
    // sheet, P3.2 and P3.3 are UART RX and TX pins respectively
    // for eUSCIA2. Port 3 select lines needs to be set to 0b01
    // for it to be in UART mode.

    P3 -> DIR = 0;
    P3 -> SEL0 = 0b1;
    P3 -> SEL1 = 0b0;
    P3 -> IE = 0x0C;

    // Control Word0 Set Up
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_PEN);               // Parity Disabled
    UCA2CTLW0 |= EUSCI_A_CTLW0_MSB;                  // MSB First
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SEVENBIT);          // 8-bit Data
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SPB);               // 1 stop bit
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_SYNC);              // Asynchronous X
    UCA2CTLW0 |= EUSCI_A_CTLW0_MODE_0;               // UART Mode
    UCA2CTLW0 |= EUSCI_A_CTLW0_UCSSEL_2;             // 12Mhz Clock
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_RXEIE);             // No Error Receive
    UCA2CTLW0 &= (~EUSCI_A_CTLW0_BRKIE);             // No Break Receive

    // Control Word1 Set Up
    UCA2CTLW1 = EUSCI_A_CTLW1_GLIT_0;                // 50ns De-Glitch

    // Modulation Control Word settings
    UCA2MCTLW |= EUSCI_A_MCTLW_OS16;                 // COS16 Enabled
    UCA2BRW = 0x0006;                                // Clock
    UCA2MCTLW |= (EUSCI_A_MCTLW_BRF_MASK & 0x0080);
    UCA2MCTLW |= (EUSCI_A_MCTLW_BRS_MASK & 0x2000);

    // Loop Back Set up
    UCA2STATW &= (~EUSCI_A_STATW_LISTEN);            // Listen OFF

    return;
}

void main(void)
{
    /* Main function of the UART Driver
     *
    */

    WDTCTL = WDTPW | WDTHOLD;                        // Hold Watch dog Timer

    __disable_interrupts();                          // Disable Interrupts
    __uart2_off();                                   // Turn off UART

    uart2clocksetup();                               // Configure CLK for UART
    uart2configure();                                // Configure UART module

    __uart2_on();                                    // Turn on UART

    UCA2IE |= (UCRXIE | UCTXIE | UCTXCPTIE);         // RX & TX Interrupt Enabled

    __enable_interrupts();

    uint16_t cfgin[8] = {0x0042, 0x0057, 0x0002, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002};

    int i;
    uint16_t rxb;

    for(i=0; i<8; i++){
        if(UCA2IFG & UCTXIFG){
            UCA2TXBUF = cfgin[i];
            }
    }


    /*while(1){

        if(UCA2IFG & UCRXIFG){
            rxb = UCA2RXBUF;
        }

    }*/

    return;
}
