/*
 * Copyright (C) 2016 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.
 *
*/

//******************************************************************************
// Version history:
// 1.0 07/17             Initial version. (Nima Eskandari)
// 1.1 07/17             Added Comments. (Nima Eskandari)
//----------------------------------------------------------------------------
//   Designed 2017 by Texas Instruments
//
//   Nima Eskandari
//   Texas Instruments Inc.
//   August 2017
//   Built with CCS Version: Code Composer Studio v7
//******************************************************************************

#include <stdint.h>
#include <stddef.h>
#include <uart_if.h>
#include <config.h>
#include <Board.h>
#include <utils.h>

#include <ti/drivers/UART.h>
#include <debug.h>

UART_Handle uart;
UART_Params uartParams;

uint8_t rec[1024];
//*****************************************************************************
// Initialize UART ************************************************************
// Opens the serial port (UART communication) *********************************
//*****************************************************************************
void UART_Initialize()
{
    /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.readTimeout = READ_TIMEOUT * 1000;
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.parityType = UART_PAR_EVEN;
    uartParams.baudRate = 9600;


    uart = UART_open(Board_UART1, &uartParams);

    if (uart == NULL) {
        /* UART_open() failed */
        while (1);
    }
}

//*****************************************************************************
// Send byte through UART *****************************************************
// byte: the value of the byte to write ***************************************
//*****************************************************************************
void UART_SendByte(uint8_t byte)
{
	UART_write(uart, &byte, 1);
}

//*****************************************************************************
// Send byte array through UART ***********************************************
// byteArray: the array of the bytes to write *********************************
// size: the size of the data array *******************************************
//*****************************************************************************
void UART_SendByteArray(uint8_t * byteArray, uint16_t size)
{
	UART_write(uart, byteArray, size);
}

//*****************************************************************************
// Read byte through UART *****************************************************
//*****************************************************************************
uint8_t UART_ReadByte()
{
	while (1)
	{
		if (UART_read(uart, &rec, 1) > 0)
		{
			return rec[0];
		}
	}
}

//*****************************************************************************
// Read byte through UART with the specified timeout **************************
// timeout: number of seconds before timeout **********************************
// error: data containor for error (whether the communication timed out) ******
//*****************************************************************************
uint8_t UART_ReadByteWithTimeout(uint8_t * error)
{
#if DEBUG
	Debug_UART_printString("Receiving One Byte with timeout\r\n");
#endif

    if (UART_read(uart, &rec, 1) > 0)
    {
        error = UART_Successful;
#if DEBUG
        Debug_UART_printStringWithNumber("0x%x\r\n", rec[0]);
        Debug_UART_printString("Done Receiving One Byte\r\n");
#endif
        return rec[0];
    }

    *error = UART_Timeout;
#if DEBUG
    Debug_UART_printString("Receive Timeout\r\n");
#endif
    return 0xFF;
}

//*****************************************************************************
// Read byte array through UART ***********************************************
// byteArray: The data read from UART is stored in this array *****************
// size: the size of the data to read *****************************************
//*****************************************************************************
void UART_ReadByteArray(uint8_t * byteArray, uint16_t size)
{
	int index = 0;
#if DEBUG
	Debug_UART_printString("Receiving Data:\r\n");
#endif
	while (size)
	{
		if (UART_read(uart, &rec, 1) > 0)
		{
#if DEBUG
		    Debug_UART_printStringWithNumber("0x%x\r\n", rec[0]);
#endif
			byteArray[index++] = rec[0];
			size--;
		}
	}
#if DEBUG
	Debug_UART_printString("Done Receiving Data\r\n");
#endif
}

//*****************************************************************************
// Read byte array through UART ***********************************************
// byteArray: The data read from UART is stored in this array *****************
// size: the size of the data to read *****************************************
// timeout: number of seconds before timeout **********************************
// error: data containor for error (whether the communication timed out) ******
//*****************************************************************************
void UART_ReadByteArrayWithTimeout(uint8_t * byteArray, uint16_t size, uint8_t * error)
{
	int index = 0;
#if DEBUG
	Debug_UART_printString("Receiving Data With Timeout:\r\n");
#endif
	while (size)
	{
		if (UART_read(uart, &rec, 1) > 0)
		{
#if DEBUG
		    Debug_UART_printStringWithNumber("0x%x\r\n", rec[0]);
#endif
			byteArray[index++] = rec[0];
			size--;
		}
		else
		{
		    //timeout
		    *error = UART_Timeout;
#if DEBUG
            Debug_UART_printString("Receive Timeout\r\n");
#endif
            return;
		}
	}
#if DEBUG
	Debug_UART_printString("Done Receiving Data\r\n");
#endif
}

//*****************************************************************************
// Close the serial port and end the UART communication ***********************
//*****************************************************************************
void UART_Close()
{
	UART_close(uart);
}
