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

/*
 *  ======== uartecho.c ========
 */
/***** Includes *****/
#include "UartTask.h"

/* XDCtools Header files */
//#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Event.h>

/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include <ti/drivers/UART.h>

/* Example/Board Header files */
#include "Board.h"
#include <time.h>
#include <ti/sysbios/hal/Seconds.h>

//#include <stdint.h>

/***** Defines *****/
#define UART_TASK_STACK_SIZE 1024
#define UART_TASK_PRIORITY   2

//#define UART_EVENT_ALL                  0xFFFFFFFF
//#define UART_EVENT_PRINT                0x00000001

//add by barbara -- begin
   uint8_t len;             ///length of RX'ed packet
  int8_t payload[128]; ///payload of RX'ed packet
//add by barbara -- end   
   
#define UART_ACTIVITY_LED Board_LED4


/***** Variable declarations *****/
static Task_Params uartTaskParams;
Task_Struct uartTask;    /* not static so you can see in ROV */
static uint8_t uartTaskStack[UART_TASK_STACK_SIZE];
Event_Struct uartEvent;  /* not static so you can see in ROV */
static Event_Handle uartEventHandle;

/***** Prototypes *****/
static void uartTaskFunction(UArg arg0, UArg arg1);

char a[10];
void Int_to_Ascii(uint16_t i);

UART_Handle uart;
UART_Params uartParams;
#define UART_FIFO_FULL_SIZE 256
int8_t Uart_RxBuf[UART_FIFO_FULL_SIZE];
int RxBufPos = 0;
int RxBufRead = 0;
uint8_t Uart_TxBuf[UART_FIFO_FULL_SIZE];
int TxBufPos = 0;
char Uart_RxTempBuf[10];
char Uart_TxTempBuf[10];

extern time_t t1;
extern struct tm *ltm;
extern char *curTime;

/***** Function definitions *****/

// Callback function
void Uart_ReadCallback(UART_Handle handle, void *rxBuf, size_t size)
{
  // Copy bytes from RX buffer to TX buffer
 for (size_t i = 0; i < size; i++) {
   if(RxBufPos != UART_FIFO_FULL_SIZE )
   {
     Uart_RxBuf[RxBufPos] = ((uint8_t *)rxBuf)[i];
     RxBufPos++;
   }
   else
   {
     RxBufPos = 0;
     Uart_RxBuf[RxBufPos] = ((uint8_t *)rxBuf)[i];
     RxBufPos++;
   }
 }

//// // Echo the bytes received back to transmitter
// Uart_TxBuf[0] = ((uint8_t *)rxBuf)[0];
// UART_write(handle, Uart_TxBuf, 1);

 // Start another read, with size the same as it was during first call to UART_read()
 UART_read(handle, Uart_RxTempBuf, 1);
  if(Uart_RxBuf[RxBufPos-1] == '\n')
  {
      //post event to rf
      Uart_PostEvent(UART_EVENT_RECEIVED);
  }
  
 
}

// Callback function
void Uart_WriteCallback(UART_Handle handle, void *txBuf, size_t size)
{

 // Start another read, with size the same as it was during first call to UART_read()
 UART_read(handle, Uart_RxTempBuf, 1);

}


void UartTask_init(void) {

    /* Create event used internally for state changes */
    Event_Params eventParam;
    Event_Params_init(&eventParam);
    Event_construct(&uartEvent, &eventParam);
    uartEventHandle = Event_handle(&uartEvent);

    /* Create the node task */
    Task_Params_init(&uartTaskParams);
    uartTaskParams.stackSize = UART_TASK_STACK_SIZE;
    uartTaskParams.priority = UART_TASK_PRIORITY;
    uartTaskParams.stack = &uartTaskStack;
    Task_construct(&uartTask, uartTaskFunction, &uartTaskParams, NULL);
    
        /* Create a UART with data processing off. */
    UART_Params_init(&uartParams);
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.readCallback = Uart_ReadCallback;
    uartParams.writeCallback = Uart_WriteCallback;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 9600;
    uart = UART_open(Board_UART0, &uartParams);

    if (uart == NULL) {
        System_abort("Error opening the UART");
    }
    
}

/*
 *  ======== echoFxn ========
 *  Task for this function is created statically. See the project's .cfg file.
 */
static void uartTaskFunction(UArg arg0, UArg arg1)
{

    UART_read(uart, Uart_RxTempBuf, 1);
    
    /* Loop forever echoing */
    while (1) 
    {  
        /* Wait for event */
       
        uint32_t events = Event_pend(uartEventHandle, 0, UART_EVENT_ALL, BIOS_WAIT_FOREVER);
        /* If new ADC value, send this data */
        if(events & UART_EVENT_PRINT) 
        {   
          UART_write(uart, payload, len);          
        }  
        if(events & UART_EVENT_RECEIVED)
        {
            if(RxBufRead <= RxBufPos)
            {
                SwitchtoTx(&Uart_RxBuf[RxBufRead], RxBufPos-RxBufRead );
                RxBufRead = RxBufPos;
            }
            else
            {
                SwitchtoTx(&Uart_RxBuf[RxBufRead], 256-RxBufRead );
                RxBufRead = 0;
            }
        }
    }
}
/* Post event */
void Uart_PostEvent(uint32_t event)
{
  Event_post(uartEventHandle, event);  
}


void Int_to_Ascii(uint16_t i)
{
  for(unsigned char n=9;n>0;n--)
  {
    a[n]=(i%10);
    if(a[n]!=0)
      a[n]+=0x30;
    else
      a[n]=0;
    i/=10;
  }
}



