/*!
    \file    uart.c
    \brief   the uart configuration file

*/

#include "lisoc_test.h"
#include "uart.h"
#include "syscfg.h"

/*!
    \brief      uart initial
    \param[in]  none
    \param[out] none
    \retval     none
*/
void uart0_init(void)
{
  // Write to Modem Control  Register (MCR) to  program SIR mode, auto flow, loopback, modem  control outputs

  //UART0_MCR = 0;
  LISOC_UART0->MCR_W = 0;
  //PAD
  //UART0_IER = 0;
  LISOC_UART0->IER_DLH_W = 0;

  ////////////////////////////////////////////////////////////
  //SYSC_GPIOB_AFR = (0x5<<16);

  // Write 1 to LCR[7] (DLAB) bit
  //UART0_LCR = 0x80;
  LISOC_UART0->LCR_W = 0x80;

  // Write to DLL, DLH to  set up divisor for required baud rate 57600
  LISOC_UART0->RBR_THR_DLL_W = UART_BAUD_DIV_SEL & (uint32_t)0xFFu;  //UART0_RBR_THR_DLL = UART_BAUD_DIV_SEL & (uint32_t)0xFFu;
  LISOC_UART0->IER_DLH_W = (UART_BAUD_DIV_SEL >> 8u) & (uint32_t)0xFFu;  //UART0_DLH = (UART_BAUD_DIV_SEL >> 8u) & (uint32_t)0xFFu;

  // Write 0 to LCR[7]  (DLAB) bit
  //UART0_LCR = 0x0;
  LISOC_UART0->LCR_W = 0x0;

  // Write to LCR to set up  transfer characteristics  such as data length, number of stop bits, parity bits, and so on
  //UART0_LCR = 0x3;
  LISOC_UART0->LCR_W = 0x3;

  // If FIFO_MODE != NONE  (FIFO mode enabled),  write to FCR to enable  FIFOs and set Transmit FIFO threshold level
  //UART0_FCR = 0x0;
  LISOC_UART0->IIR_FCR_W = 0x0;

  // Write to IER to enable  required interrupts
  //UART0_IER = 0;
  LISOC_UART0->IER_DLH_W = 0;
}

/*!
    \brief      uart initial
    \param[in]  none
    \param[out] none
    \retval     none
*/
void uart1_init(void)
{
  #if 1
  // Write to Modem Control  Register (MCR) to  program SIR mode, auto flow, loopback, modem  control outputs
  //UART1_MCR |= 0x01u << 4;            // Enable loopback
  LISOC_UART1->MCR_W = 0;
  //LISOC_UART1->MCR.LoopBack = 1;
  //PAD
  //UART1_IER = 0;
  LISOC_UART1->IER_DLH_W = 0;

  ////////////////////////////////////////////////////////////
  /* Set PB8 PB9 as UART_RX1 UART_TX1 respectively */
  //SYSC_GPIOB_AFR = (SYSC_GPIOB_AFR & (~((uint32_t)0x03 << 16))) | ((uint32_t)0x01 << 16);
  //SYSC_GPIOB_AFR = (SYSC_GPIOB_AFR & (~((uint32_t)0x03 << 18))) | ((uint32_t)0x01 << 18);
  SYSC_GPIOB_AF_SET(GPIO_AF_1, PB8AF | PB9AF);

  // Write 1 to LCR[7] (DLAB) bit
  LISOC_UART1->LCR_W = 0x80;

  // Write to DLL, DLH to  set up divisor for required baud rate 57600
  LISOC_UART1->RBR_THR_DLL_W = UART_BAUD_DIV_SEL & (uint32_t)0xFFu;  //UART0_RBR_THR_DLL = UART_BAUD_DIV_SEL & (uint32_t)0xFFu;
  LISOC_UART1->IER_DLH_W = (UART_BAUD_DIV_SEL >> 8u) & (uint32_t)0xFFu;  //UART0_DLH = (UART_BAUD_DIV_SEL >> 8u) & (uint32_t)0xFFu;

  // Write 0 to LCR[7]  (DLAB) bit
  //UART0_LCR = 0x0;
  LISOC_UART1->LCR_W = 0x0;

  // Write to LCR to set up  transfer characteristics  such as data length, number of stop bits, parity bits, and so on
  //UART0_LCR = 0x3;
  LISOC_UART1->LCR_W = 0x3;

  // If FIFO_MODE != NONE  (FIFO mode enabled),  write to FCR to enable  FIFOs and set Transmit FIFO threshold level

  //LISOC_UART1->IIR_FCR_W = 0x0;

  // Write to IER to enable  required interrupts
  //UART0_IER = 3;
  //LISOC_UART1->IER_DLH_W = 0;         // Enable tx empty int
                                      // Enable rx data avaliable int
  #endif
  
  //LISOC_UART1->LCR_W = 0x3;
  UART1_RBR_THR_DLL;
}

uint8_t uart0_recv_timeout(uint32_t timeout_val)
{
  uint8_t data;
  uint32_t Uart0_Tmo;

  Uart0_Tmo = SysTick1msCount + timeout_val;

  /* Wait until Rx data is ready or time-out */
  while (( !(UART0_LSR & UART_LSR_DAT_RDY)) && IS_TIME_NOT_REACHED(Uart0_Tmo))
  {
    /* Do nothing */
  }

  if (IS_TIME_NOT_REACHED(Uart0_Tmo)) {
    data = UART0_RBR_THR_DLL;    /* receive the data */
  }
  else {
    data = 0U;
  }
  return data;

}

uint8_t uart1_recv_timeout(uint32_t timeout_val)
{
  uint8_t data;
  uint32_t Uart1_Tmo;

  Uart1_Tmo = SysTick1msCount + timeout_val;

  /* Wait until Rx data is ready or time-out */
  while (( !(UART1_LSR & UART_LSR_DAT_RDY)) && IS_TIME_NOT_REACHED(Uart1_Tmo))
  {
    /* Do nothing */
  }

  if (IS_TIME_NOT_REACHED(Uart1_Tmo)) {
    data = UART1_RBR_THR_DLL;    /* receive the data */
  }
  else {
    data = 0U;
  }
  return data;

}


