/*****************************************************************************
 * Copyright (c) 2019, Nations Technologies Inc.
 *
 * 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 disclaimer below.
 *
 * Nations' name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL NATIONS 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.
 * ****************************************************************************/
/** ****************************************************************************
 * @file     auto_uart_baudrate.c
 * @author
 * @date
 * @version  v1.0.0
 * @brief
  *
 ******************************************************************************/
#include "auto_uart_baudrate.h"
#include "n32g003_gpio.h"
#include "n32g003_rcc.h"
#include "n32g003_uart.h"
//Private typedef -------------------------------------------------------------
//Private define --------------------------------------------------------------

//Private macro ---------------------------------------------------------------
//Private variables -----------------------------------------------------------

extern PC_CMD_Type pc_cmd;
extern IC_CMD_Type ic_cmd;

/**
  * @name  UART_Config()
  * @brief UART1 Configuration
  * @param
  * @retval
  */
void UART_Config(void)
{
  NVIC_InitType nvic;
  GPIO_InitType gpio;
  UART_InitType uart;
   
  RCC_APB_Peripheral_Clock_Enable(RCC_APB_PERIPH_IOPA|RCC_APB_PERIPH_UART1); 
    
  nvic.NVIC_IRQChannel = UART1_IRQn;
  nvic.NVIC_IRQChannelPriority = 0; 
  nvic.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Initializes(&nvic);
    
  // pa2 tx
  gpio.Pin         = GPIO_PIN_2;
  gpio.GPIO_Mode        = GPIO_MODE_AF_PP;
  gpio.GPIO_Pull        = GPIO_NO_PULL;
  gpio.GPIO_Alternate   = GPIO_AF5_UART1;
  GPIO_Peripheral_Initialize(GPIOA, &gpio);
  // pa3 rx  
  gpio.Pin         = GPIO_PIN_3;
  gpio.GPIO_Mode        = GPIO_MODE_INPUT;
  gpio.GPIO_Pull        = GPIO_NO_PULL;
  gpio.GPIO_Alternate   = GPIO_AF5_UART1;
  GPIO_Peripheral_Initialize(GPIOA, &gpio);

  
  uart.BaudRate = DEFAULT_BAUD_RATE;
  uart.Mode = UART_MODE_RX | UART_MODE_TX;
  UART_Initializes(UART1, &uart);
  
  UART1->CTRL1 |= 0x20; //Enable RXDNE interrupt
  UART1->CTRL1 |= CTRL1_UEN_SET; //Enable UART1
}

/**
 * @name  fputc()
 * @brief retarget the C library printf function to the UART.
 * @param
 */
int fputc(int ch, FILE* f)
{
  UART_Data_Send(UART1, ch);
  while (UART_Flag_Status_Get(UART1, UART_FLAG_TXC) == RESET);

  return ch;
}

 /**
  * @name  Uart_Receive()
  * @brief Uart_Receive.
  * @param
  * @retval
  */
void Uart_Receive(uint8_t data)
{
  if(pc_cmd.Flag) return;

  switch(pc_cmd.Idx)
  {
    case 0:
      if(data == UART_STA1) pc_cmd.Idx++;
      break;
    case 1:
      if(data == UART_STA2) pc_cmd.Idx++;
      break;

    default:
      if(pc_cmd.Idx <= pc_cmd.LEN + 10)
      {
        if(pc_cmd.Idx == pc_cmd.LEN + 10)
        {
          pc_cmd.Idx  = 0;
          pc_cmd.XOR  = data;
          pc_cmd.Flag = true;
          break;
        }
       *((uint8_t*)(&pc_cmd) + (pc_cmd.Idx++-2)) = data;
      }

      break;
  }
}

/**
  * @name  Uart_Send()
  * @brief Uart_Send.
  * @param
  * @retval
  */
void Uart_Send(uint16_t Num,uint8_t *pData)
{
  uint8_t  xor = UART_STA1^UART_STA2;

  Send_Data(UART_STA1);
  Send_Data(UART_STA2);
  for(uint32_t i = 0; i < Num; i++)
  {
    Send_Data(pData[i]);
    xor ^= pData[i];
  }
  Send_Data(ic_cmd.CR1);
  Send_Data(ic_cmd.CR2);
  xor ^= ic_cmd.CR1;
  xor ^= ic_cmd.CR2;
  Send_Data(xor);
}

/**
  * @name  Send_Data()
  * @brief Send Data.
  * @param
  * @retval
  */
void Send_Data(uint16_t data)
{
  while((UART1->STS & UART_FLAG_TXDE) == (uint16_t)RESET);
  UART1->DAT = data;
}


