//*****************************************************************************
// uart_cli.c
// utility for receiving commands/ Sending Data over UART
//
// Copyright (C) 2014 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.
//
//*****************************************************************************


#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
/*
#include "hw_types.h"
#include "hw_memmap.h"

#include <driverlib/prcm.h>
#include <driverlib/pin.h>
#include <driverlib/uart.h>
#include <driverlib/rom_map.h>
*/

#include <board.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/SPI.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC3200.h>
#include <ti/drivers/net/wifi/simplelink.h>


#include "uart_cli.h"
#include "radiotool.h"

#define UNUSED(x)           x=x
//*****************************************************************************
// Defining UART Base Address
//*****************************************************************************
#define CONSOLE         UARTA0_BASE

//*****************************************************************************
// Global variable indicating command is present
//*****************************************************************************
unsigned int uiUartCmd;
static unsigned long __Errorlog;

//*****************************************************************************
// Global variable indicating input length
//*****************************************************************************
unsigned int ilen=1;






//*****************************************************************************
//
//! Error Function
//!
//! \param
//!
//! \return none
//!
//*****************************************************************************
void
Error(char *pcFormat, ...)
{
#ifndef NOTERM
    char  cBuf[256];
    va_list list;
    va_start(list,pcFormat);
    vsnprintf(cBuf,256,pcFormat,list);
    Message(cBuf);
#endif
    __Errorlog++;
}



//*****************************************************************************
//
//! Get the Command string from UART
//!
//! \param  ucBuffer to which Command will be populated
//!
//! \return Success or Failure
//!
//*****************************************************************************
unsigned int GETCmd(unsigned char *ucBuffer)
{

    int i=0;
    char c;
    uiUartCmd=0;
    c=getch();
    putch( c);
    ilen=0;
    //
    // Checking the end of Command
    //
    while(c!='\r' && c!='\n' )
    {
        uiUartCmd=1;
        //
        // Copying Data from UART into a buffer
        //
        if(  c!='\b')
        {
            ilen++;
            *(ucBuffer+i)=c;
            i++;
        }
        //
        // Deleting last character when you hit backspace
        //
        if(c=='\b')
        {
            i--;
            ilen--;
        }
        c = getch();
        putch(c);
    }
    Report("\n\r\n\r");
    return uiUartCmd;
}


//*****************************************************************************
//
//! GetPacket() receives a data packet.
//!
//! \param pucData is the location to store the data received from the device.
//! \param pucSize is the number of bytes returned in the pucData buffer that
//!     was provided.
//!
//! This function receives a packet of data from UART port.
//!
//! \returns The function returns zero to indicated success while any non-zero
//!     value indicates a failure.
//
//*****************************************************************************
int GetPacket(unsigned char *pucData, unsigned long *pucSize)
{
    unsigned char ucCheckSum;
    unsigned char ucSize = 0;
    unsigned char sizeBuff[2] = {0,0};
    unsigned char* pSizeBuff = &sizeBuff[0];
    unsigned short ucPacketIndex=0;
    //
    // Get the size what and the checksum.
    //
    do
    {
        *pSizeBuff++ = getch();
        ucPacketIndex++;
    } while(ucPacketIndex <  UART_RX_DATA_SIZE);

    ucSize = sizeBuff[0] << 8;   /* Change for support size > 255 */
    ucSize |= sizeBuff[1];


    ucCheckSum = getch();
    ucPacketIndex++;

    *pucSize = ucSize - 2;

    do
    {
        *pucData++ = getch();
        ucPacketIndex++;
    } while(ucPacketIndex <  ucSize+1);

    ucCheckSum = 0;
    //
    // Calculate the checksum from the data.
    //
#if 0 /*
        * For speed Loader CheckSum was removed. For Ram Memory the Check Sum is not nessary.
        * For Flash need to open the CheckSum and change for support size of two bytes instead 0ne
        */
    if (ucCheckSum != CheckSum(pucData, *pucSize))
    {
        *pucSize = 0;
        return(NakPacket());
    }
#else
    UNUSED(ucCheckSum);
#endif

    //return(AckPacket());
    return 0;
}

//*****************************************************************************
//
//! SendPacket() sends a data packet.
//!
//! \param pucData is the location of the data to be sent to the device.
//! \param ucSize is the number of bytes to send from puData.
//!
//! This function sends a packet of data to the device.
//!
//! \returns The function returns zero to indicated success while any non-zero
//!     value indicates a failure.
//
//*****************************************************************************
int SendPacket(unsigned char *pucData, unsigned long ucSize)
{
    unsigned char ucCheckSum;
    //unsigned char ucAck;
    unsigned char sizeBuff[2];
    unsigned long ulIndex=0;

    ucCheckSum = CheckSum(pucData, ucSize);

    // Make sure that we add the bytes for the size and checksum to the total.
    ucSize += 2;

    // Send the Size in bytes.
    sizeBuff[0] = (unsigned char)((ucSize & 0xFF00) >> 8);  /* Change for support size > 255 */
    sizeBuff[1] = (unsigned char)(ucSize &  0x00FF);

    do
    {
        putch(sizeBuff[ulIndex]);
        ulIndex++;
    }while(ulIndex<UART_RX_DATA_SIZE);

    // Send the CheckSum
    do
    {
        putch(ucCheckSum);
        ulIndex++;
    }while(ulIndex<(UART_RX_DATA_SIZE+UART_RX_CHECKSUM_SIZE));

    // Send the Data
    do
    {
        putch(*pucData++);
        ulIndex++;
    }while(ulIndex<=ucSize);


    return(0);
}

//*****************************************************************************
//
//! SendPacket() sends a data packet.
//!
//! \param pucData is the location of the data to be sent to the device.
//! \param ucSize is the number of bytes to send from puData.
//!
//! This function sends a packet of data to the device.
//!
//! \returns The function returns zero to indicated success while any non-zero
//!     value indicates a failure.
//
//*****************************************************************************
int AckPacket()
{
    unsigned long ulIndex=0;
    unsigned char ucAck[5] = {4, 0, 0xFF, (unsigned char)ACK_RESPONSE_OP, (unsigned char)OK_CODE};//generate checksum here
    do
    {
        putch(ucAck[ulIndex]);
        ulIndex++;
    }while(ulIndex<5);
    return 0;
}
//*****************************************************************************
//
//! CheckSum() Calculates an 8 bit checksum
//!
//! \param pucData is a pointer to an array of 8 bit data of size ucSize.
//! \param ucSize is the size of the array that will run through the checksum
//!     algorithm.
//!
//! This function simply calculates an 8 bit checksum on the data passed in.
//!
//! \return The function returns the calculated checksum.
//
//*****************************************************************************
unsigned char CheckSum(unsigned char *pucData, unsigned long ucSize)
{
    unsigned long i;
    unsigned char ucCheckSum;

    ucCheckSum = 0;

    for(i = 0; i < ucSize; ++i)
    {
        ucCheckSum += pucData[i];
    }

    return(ucCheckSum);
}

//*****************************************************************************
//
//! Sends the Response over UART
//!
//! \param  inBuff - Buffer to Contain the Response Message
//! \param  usLength - Length of the Response Message
//!
//! \return none
//!
//*****************************************************************************

extern void DispatcherUartSendPacket(unsigned char *inBuff, unsigned short usLength)
{
    Report((char*)inBuff);
}
