/*
 * Copyright (c) 2021, 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.
 */

#include "ti_msp_dl_config.h"




#define UART_PACKET_SIZE (2)

/* Data for UART to transmit */
uint8_t txPacket[UART_PACKET_SIZE] = {0x9A, 0x5A};

/* Hall-Lid closed */
volatile bool LidClosed = false;
// UART Sequence finished:
bool UARTfinished = false;

/* Timer interrupt times */
uint8_t Times = 0;

// Data sent and received
uint8_t txData1 = 0xA2, txData2 = 0xB2, rxData = 0x0;

// Left ear/ Right ear buds status:
bool LeftEarBudsIn = false;
bool RightEarBudsIn = false;

int main(void)
{
    /* Power on GPIO, initialize pins as digital outputs */
    SYSCFG_DL_init();

    //Hiz-UART
    DL_GPIO_initPeripheralOutputFunctionFeatures(
            GPIO_UART_R_IOMUX_TX, GPIO_UART_R_IOMUX_TX_FUNC,
            DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
            DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE
    );

    DL_GPIO_initPeripheralOutputFunctionFeatures(
            GPIO_UART_L_IOMUX_TX, GPIO_UART_L_IOMUX_TX_FUNC,
            DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
            DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE
    );

    //Set up interrupt//
    //Hall_IN
    NVIC_EnableIRQ(GPIO_General_INT_IRQN);
    //Timer
    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
    //UART
    NVIC_ClearPendingIRQ(UART_R_INST_INT_IRQN);
    NVIC_EnableIRQ(UART_R_INST_INT_IRQN);
    NVIC_ClearPendingIRQ(UART_L_INST_INT_IRQN);
    NVIC_EnableIRQ(UART_L_INST_INT_IRQN);

    while (1) {

        /*
        while(!UARTfinished)
        {
            //Wait for the Com sequence
            //__WFI();
        }

        UARTfinished = false;
        */

        __WFI();

    }
}


//Hall in control, Lid closed
void GROUP1_IRQHandler(void)
{
    switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
        case GPIO_General_INT_IIDX :
            /////////////////////////////
            //  Initialization
            ////////////////////////////
            /* If Lid closed, start the timer */
            DL_TimerG_startCounter(TIMER_0_INST);
            break;
        default:
            break;
    }
}

//Timer triggered every 10ms.
void TIMER_0_INST_IRQHandler(void)
{

    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {
        case DL_TIMER_IIDX_ZERO:

            switch (Times){

            //Right EAR buds:
            case 1:
                //@10ms:UART_TX->LOW; Disable 5V
                DL_GPIO_initPeripheralOutputFunctionFeatures(
                        GPIO_UART_R_IOMUX_TX, GPIO_UART_R_IOMUX_TX_FUNC,
                        DL_GPIO_INVERSION_ENABLE, DL_GPIO_RESISTOR_NONE,
                        DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE
                );
                DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_REN_PIN);
                break;

            case 3:
                //@30ms: Enable 5V
                DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_REN_PIN);
                break;

            case 4:
                //40ms: UART_TX->Normal Hiz UART.
                DL_GPIO_initPeripheralOutputFunctionFeatures(
                        GPIO_UART_R_IOMUX_TX, GPIO_UART_R_IOMUX_TX_FUNC,
                        DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                        DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE
                );
                break;

            case 5:
                //@50ms: Disable 5V;
                DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_REN_PIN);
                break;

            case 6:
                //@60ms: send data;
                //DL_UART_Main_fillTXFIFO(UART_R_INST, &txPacket[0], UART_PACKET_SIZE);
                DL_UART_Main_transmitData(UART_R_INST, txData1);
                break;

            case 25:
                //@250ms: Enable 5V, check received data
                DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_REN_PIN);
                break;



                //Left ear buds:
            case 26:
                //@10ms:UART_TX->LOW; Disable 5V
                DL_GPIO_initPeripheralOutputFunctionFeatures(
                        GPIO_UART_L_IOMUX_TX, GPIO_UART_L_IOMUX_TX_FUNC,
                        DL_GPIO_INVERSION_ENABLE, DL_GPIO_RESISTOR_NONE,
                        DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE
                );
                DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_LEN_PIN);
                break;

            case 27:
                //@30ms: Enable 5V
                DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_LEN_PIN);
                break;

            case 28:
                //40ms: UART_TX->Normal Hiz UART.
                DL_GPIO_initPeripheralOutputFunctionFeatures(
                        GPIO_UART_L_IOMUX_TX, GPIO_UART_L_IOMUX_TX_FUNC,
                        DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
                        DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE
                );
                break;

            case 29:
                //@50ms: Disable 5V;
                DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_LEN_PIN);
                break;

            case 30:
                //@60ms: send data;
                //DL_UART_Main_fillTXFIFO(UART_R_INST, &txPacket[0], UART_PACKET_SIZE);
                DL_UART_Main_transmitData(UART_L_INST, txData2);
                break;

            case 50:
                //@250ms: Enable 5V, check received data
                DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_LEN_PIN);

                //Reset Flag
                Times = 0;
                UARTfinished = true;
                //Stop Timer
                DL_TimerG_stopCounter(TIMER_0_INST);

                //Check received data:
                if (DL_UART_Main_receiveDataBlocking(UART_R_INST) == 0x42)
                {
                    DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_LED_PIN);
                    delay_cycles(10000000);
                    DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_LED_PIN);
                    delay_cycles(10000000);
                    DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_LED_PIN);
                    delay_cycles(10000000);
                    DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_LED_PIN);
                    delay_cycles(10000000);
                    LeftEarBudsIn = false;
                }

                if (DL_UART_Main_receiveDataBlocking(UART_L_INST) == 0x52)
                {
                    DL_GPIO_setPins(GPIO_General_PORT, GPIO_General_O_LED_PIN);
                    delay_cycles(10000000);
                    DL_GPIO_clearPins(GPIO_General_PORT, GPIO_General_O_LED_PIN);
                    delay_cycles(10000000);
                    RightEarBudsIn = false;
                }
                break;
            default:
                break;
            }
            //Add to time counter:
            Times++;
            break;
        default:
            break;
    }

}

//Right UART received data check:
void UART_R_INST_IRQHandler(void)
{
    switch (DL_UART_Main_getPendingInterrupt(UART_R_INST)) {
        case DL_UART_MAIN_IIDX_RX:
            rxData       = DL_UART_Main_receiveDataBlocking(UART_R_INST);
            if (rxData == 0x42)
            {
                RightEarBudsIn = true;
            }
            break;
        default:
            break;
    }
}

void UART_L_INST_IRQHandler(void)
{
    switch (DL_UART_Main_getPendingInterrupt(UART_L_INST)) {
        case DL_UART_MAIN_IIDX_RX:
            rxData       = DL_UART_Main_receiveDataBlocking(UART_L_INST);
            if (rxData == 0x52)
            {
                LeftEarBudsIn = true;
            }
            break;
        default:
            break;
    }
}
