/******************************************************************************
 uart_config.c - nRF52840 UART Protocol API Source file
 Version: 0.9.1
 Created on: 07/04/2021
 Created by: Rohit Rajapure

 Copyright (c) 2017 Shalaka Connected Devices LLP.  All rights reserved.
 Software License Agreement

   Redistribution and use in source and binary forms, with or without
   modification, are not permitted.

   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 Shalaka Connected Devices LLP 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 <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "string.h"

#include "app_uart.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "nrf.h"
#include "boards.h"
#include "bsp.h"
#include "nrf_uart.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_timer.h"
#include "nordic_common.h"
#include "sdk_errors.h"
#include "uart_config.h"
#include "timer_config.h"
#include "gpio_config.h"
/******************************************************************************************
*Macro Definitions
*
*******************************************************************************************/
/// Size of the receiving buffer
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
/// Size of the send buffer
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
/******************************************************************************************
*GLOBAL VARIABLES
*
*******************************************************************************************/
/// Buffer index for start
uint8_t tmphead;
uint8_t data;
/// last error
uint8_t lastRxError;
/// Transmit buffer: start of user data
static volatile uint8_t UART_TxHead;
/// Transmit buffer: end of user data
static volatile uint8_t UART_TxTail;
/// Receive buffer: start of user data
static volatile uint8_t UART_RxHead;
/// Receive buffer: end of user data
static volatile uint8_t UART_RxTail;
/// last error on reception
static volatile uint8_t UART_LastRxError;

/// Transmit buffer
static  uint8_t UART_TxBufInit[UART_TX_BUFFER_SIZE];

/// Receive buffer
uint8_t UART_RxBufInit[UART_RX_BUFFER_SIZE];
static uint8_t UART_RxBuf[UART_RX_BUFFER_SIZE];

//unsigned char EOC[]={0xF0};  // End of Communication
/******************************************************************************************
*TYPEDEF
*
*******************************************************************************************/


/******************************************************************************************
*EXTERNAL VARIABLES
*
*******************************************************************************************/
extern uint8_t ui8Count;
extern uint8_t ui8TelegramIndex;
extern uint8_t ui8GetCommandBuffer[BUFFER_SIZE], ui8SetCommandBuffer[BUFFER_SIZE], ui8GetFlagBuffer[BUFFER_SIZE], ui8ResponceValueSend[BUFFER_SIZE], ui8ResponceValueSend2[BUFFER_SIZE], ui8StartFirmwareUpdate[BUFFER_SIZE], ui8TransferFirmware[BUFFER_SIZE], ui8TempGetFlagBuffer[BUFFER_SIZE];
uint8_t ui8GetBuffer = 0;
unsigned char ACK[]={0xCC};  // Positive Acknowledge

/******************************************************************************************
*FUNCTIONS 
*
*******************************************************************************************/
/******************************************************************************************
*Uart error handling routine
*
*******************************************************************************************/
void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_communication);
    }
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_code);
    }
    else if(p_event->evt_type == APP_UART_DATA_READY)
    {
        while(app_uart_get(&ui8GetBuffer)!= NRF_SUCCESS);

        if(ui8GetBuffer ==0xCC)
        {
 
          while(app_uart_put(EOC)!= NRF_SUCCESS);
        }
    }

}


/******************************************************************************************
*Uart pin configuration function
*return void
*******************************************************************************************/
void Uart_Init_Func(void)
{
    uint32_t err_code;

    const app_uart_comm_params_t comm_params =
      {
          RX_PIN_NUMBER,
          TX_PIN_NUMBER,
          RTS_PIN_NUMBER,
          CTS_PIN_NUMBER,
          UART_HWFC,
          false,
          NRF_UART_BAUDRATE_9600
      };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUFFER_SIZE,
                         UART_TX_BUFFER_SIZE,
                         uart_error_handle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);

    APP_ERROR_CHECK(err_code);



}

void vUART_CleanUpUart(void){
	UART_TxHead = 0;
	UART_TxTail = 0;
	UART_RxHead = 0;
	UART_RxTail = 0;
}

////////////////////////////////////////////////////////////////////////////////
///
/// \brief Read one byte from the ring buffer
///
/// The low byte contains the data byte, the high byte contains the
/// last error during reception. UART_NO_DATA is returned if no /// data is present.
/// data are present
///
/// \return Low-Byte: received byte from the ring buffer
/// High-Byte: last receive status
/// - \b 0 Data successfully received from UART
/// - \b UART_NO_DATA
/// <br>no receive data available
/// - \b UART_BUFFER_OVERFLOW
/// <br>Receive buffer overflow.
/// The receive buffer is not read fast enough,
/// or one or more characters were swallowed.
/// - \b UART_OVERRUN_ERROR
/// <br>UART overflow.
/// A character in the UDR register has not been read by the interrupt handler
/// before the next character has arrived.
/// or one or more characters were swallowed.
/// - \b UART_FRAME_ERROR
/// <br>Framing error from UART
///
/// \par example
/// Call e.g. UART_GetData()                                  \n
///
////////////////////////////////////////////////////////////////////////////////
S_UartData UART_GetData(void)
{
    /// Buffer index for end
    uint8_t tmptail;
    /// Data
    uint8_t data;
    /// temporary variable to suppress IAR warning Pa082
    uint8_t rxhead;
    /// temporary variable to suppress IAR warning Pa082
    uint8_t rxtail;
    /// Return value in structure, separated by error and data
    S_UartData s_returnValue;

    // Assignment to temporary variable
    rxhead = UART_RxHead;
    rxtail = UART_RxTail;


    if (rxhead == rxtail)
    {
        // no data available
        s_returnValue.Error = UART_NO_DATA;
        return (s_returnValue);
        //return UART_NO_DATA;
    }

    // Calculate/save the index
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    UART_RxTail = tmptail;

    // get new data from the receive buffer
    data = UART_RxBuf[tmptail];

    s_returnValue.Data = data;
    s_returnValue.Error = UART_LastRxError;

    return (s_returnValue);

//    data = (UART_LastRxError << 8) + data;
//    UART_LastRxError = 0;
//    return data;

}
////////////////////////////////////////////////////////////////////////////////
///
/// \brief Write a byte to the ring buffer to send it
///
/// \param data Data to be sent
///
/// \param example
/// Call e.g. vUART_PutByte(0xFE) \n
///
////////////////////////////////////////////////////////////////////////////////
void vUART_PutByte(uint8_t data) 
{
  while (app_uart_put(data) != NRF_SUCCESS);
}
////////////////////////////////////////////////////////////////////////////////
///
/// \brief Write a string to the ring buffer to send it.
///
/// \param *s String to be sent
///
/// \note block if the string to be sent does not fit into the buffer
///
/// \param example
/// Call e.g. vUART_PutString("Hello Hessen")                   \n
///
////////////////////////////////////////////////////////////////////////////////
void vUART_PutString(const char *s )
{
    while (*s)
      vUART_PutByte(*s++);
}
////////////////////////////////////////////////////////////////////////////////
///
/// \brief Deleting any reception errors that may have occurred.
///
/// \param no parameters (void)
///
/// \par example
/// Call e.g. vUART_ClearRxErrors()                           \n
///
////////////////////////////////////////////////////////////////////////////////
void vUART_ClearRxErrors(void)
{
    UART_LastRxError = UART_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
///
/// \brief Readout of the reception errors
///
/// \param no parameters (void)
///
/// \note The last receive error is actually in the
/// byte structure. Here the error summed up over the bytes is read.
/// is read out.
///
/// \par example
/// Call e.g. UART_GetRxErrors()                             \n
///
////////////////////////////////////////////////////////////////////////////////
uint8_t UART_GetRxErrors(void)
{
    return (UART_LastRxError);
}