/*!
    \file    uart.h
    \brief   the header file of uart

*/

#ifndef UART_H
#define UART_H

/* UART serial clock frequency */
#define UART_SERIAL_CLK               LISOC_ARM_PERIPH_CLK

/* UART baud rate definition */
#define UART_BAUD_115200_DIV          ((UART_SERIAL_CLK + (8u * 115200u)) / (16u * 115200u))
#define UART_BAUD_57600_DIV           ((UART_SERIAL_CLK + (8u * 57600u)) / (16u * 57600u))
#define UART_BAUD_38400_DIV           ((UART_SERIAL_CLK + (8u * 38400u)) / (16u * 38400u))
#define UART_BAUD_19200_DIV           ((UART_SERIAL_CLK + (8u * 19200u)) / (16u * 19200u))
#define UART_BAUD_9600_DIV            ((UART_SERIAL_CLK + (8u * 9600u)) / (16u * 9600u))

#ifndef CFG_FPGA
#define UART_BAUD_DIV_SEL             UART_BAUD_115200_DIV   /* == 9 @ 8MHz */
#else
#define UART_BAUD_DIV_SEL             UART_BAUD_57600_DIV    /* == 9 @ 8MHz */
#endif

/* UART_LSR bit definition */
#define UART_LSR_FIFO_ERR             0x80u
#define UART_LSR_TX_EMT               0x40u
#define UART_LSR_TX_HRE               0x20u
#define UART_LSR_BRK_IND              0x10u
#define UART_LSR_FRM_ERR              0x08u
#define UART_LSR_PAR_ERR              0x04u
#define UART_LSR_OVR_ERR              0x02u
#define UART_LSR_DAT_RDY              0x01u

/* uart init */
void    uart0_init(void);
void    uart1_init(void);

/* uart0 send and receive */
__INLINE void    uart0_tx(uint8_t data) { UART0_RBR_THR_DLL = data; }
__INLINE uint8_t uart0_rx(void)   { return UART0_RBR_THR_DLL; }
__INLINE uint8_t uart0_trdy(void) { return (UART0_LSR & UART_LSR_TX_HRE); }
__INLINE uint8_t uart0_rrdy(void) { return (UART0_LSR & UART_LSR_DAT_RDY); }

__INLINE void uart0_send(uint8_t data) {
  while (!uart0_trdy()) {
    /* Do nothing */
  }
  uart0_tx(data);
}

__INLINE uint8_t uart0_recv(void) {
  while (!uart0_rrdy()) {
    /* Do nothing */
  }
  return uart0_rx();
}

/* uart1 send and receive */
__INLINE void    uart1_tx(uint8_t data) { UART1_RBR_THR_DLL = data; }
__INLINE uint8_t uart1_rx(void)   { return UART1_RBR_THR_DLL; }
__INLINE uint8_t uart1_trdy(void) { return (UART1_LSR & UART_LSR_TX_HRE); }
__INLINE uint8_t uart1_rrdy(void) { return (UART1_LSR & UART_LSR_DAT_RDY); }

__INLINE void uart1_send(uint8_t data) {
  while (!uart1_trdy()) {
    /* Do nothing */
  }
  uart1_tx(data);
}

__INLINE uint8_t uart1_recv(void) {
  while (!uart1_rrdy()) {
    /* Do nothing */
  }
  return uart1_rx();
}

uint8_t uart0_recv_timeout(uint32_t timeout_val);
uint8_t uart1_recv_timeout(uint32_t timeout_val);


extern uint8_t Uart1_Buffer[256];
extern uint8_t Uart1_Rx_Num;

#endif  /* UART_H */
