#ifndef __PERIPH_UART_H__
#define __PERIPH_UART_H__

#include "t1001.h"

#define UART0_BASE                              UART_BASE
#define UART1_BASE                              0x41002000

#define UART0                                   ((UART_Type*) UART0_BASE)
#define UART1                                   ((UART_Type*) UART1_BASE)

//UART Init Structure definition
typedef struct
{
  uint32_t UART_BaudRate;            
  uint16_t UART_WordLength;          
  uint16_t UART_StopBits;            
  uint16_t UART_Parity;              
  uint16_t UART_FIFO;                
  uint16_t UART_HardwareFlowControl;
} UART_InitTypeDef;

//UART_Baudrate
#define UART_BAUDRATE_4800                      4800       
#define UART_BAUDRATE_9600                      9600       
#define UART_BAUDRATE_14400                     14400          // 14400UART_BAUDRATE_audrate
#define UART_BAUDRATE_19200                     0x00004B00     // 19200Baudrate
#define UART_BAUDRATE_38400                     0x00009600     // 38400Baudrate
#define UART_BAUDRATE_56000                     0x0000DAC0     // 56000Baudrate
#define UART_BAUDRATE_57600                     0x0000E100     // 57600Baudrate
#define UART_BAUDRATE_115200                    0x0001C200     // 115200Baudrate
#define UART_BAUDRATE_128000                    0x0001F400     // 128000Baudrate
#define UART_BAUDRATE_230400                    0x00038400     // 230400Baudrate
#define UART_BAUDRATE_256000                    0x0003E800     // 256000Baudrate
#define UART_BAUDRATE_460800                    0x00070800     // 460800Baudrate
#define UART_BAUDRATE_500000                    0x0007A120     // 500000Baudrate
#define UART_BAUDRATE_512000                    0x0007D000     // 512000Baudrate
#define UART_BAUDRATE_600000                    0x000927C0     // 600000Baudrate
#define UART_BAUDRATE_750000                    0x000B71B0     // 750000Baudrate
#define UART_BAUDRATE_921600                    0x000E1000     // 921600Baudrate
#define UART_BAUDRATE_1000000                   0x000F4240     // 1000000Baudrate
#define UART_BAUDRATE_1500000                   0x0016E360     // 1500000Baudrate
#define UART_BAUDRATE_2000000                   0x001E8480     // 2000000Baudrate

#define UART_USR_BUSY                           ((uint8_t)0x01)
#define UART_FCR_FIFO_CLEAR                     ((uint8_t)0x0E)
#define UART_LCR_DLAB                           ((uint8_t)0x80)
#define UART_LCR_CLEAR                          ((uint8_t)0xE0)

//UART_FIFO
#define UART_FIFO_ENABLE                        ((uint16_t)0x01)
#define UART_FIFO_DISABLE                       ((uint16_t)0x00)

//UART_Word_Length 
#define UART_WORD_LENGTH_5BIT                   ((uint8_t)0x00)
#define UART_WORD_LENGTH_6BIT                   ((uint8_t)0x01)
#define UART_WORD_LENGTH_7BIT                   ((uint8_t)0x02)
#define UART_WORD_LENGTH_8BIT                   ((uint8_t)0x03)
#define UART_WORD_LENGTH_9BIT                   ((uint8_t)0x09)                         
//UART_9bit_data_transfers
#define UART_9BIT_DATA_TRANSFER_ENABLE          ((uint8_t)0x09)
#define UART_9BIT_DATA_TRANSFER_DISABLE         ((uint8_t)0x00)

//UART_Stop_Bits
#define UART_STOPBITS_1BIT                      ((uint16_t)0x0000)   //1 stop bit
#define UART_STOPBITS_2BIT                      ((uint16_t)0x0004)   //if the data length is 5 bits,1.5 stop bit;else,2 stop bit 

//UART_Parity 
#define UART_PARITY_NONE                        ((uint16_t)0x0000)  //Disable Parity
#define UART_PARITY_ODD                         ((uint16_t)0x0008)  //Enable ODD Parity
#define UART_PARITY_EVEN                        ((uint16_t)0x0018)  //Enable EVEN Parity

//UART_RX_FIFO_Trigger
#define UART_RX_FIFO_ALMOST_FULL                0xC0 // FIFO 2 less than full
#define UART_RX_FIFO_HALF_FULL                  0x80
#define UART_RX_FIFO_QUARTER_FULL               0x40
#define UART_RX_FIFO_CHAR_1                     0x00

//UART_TX_FIFO_Trigger
#define UART_TX_FIFO_HALF_FULL                  0x30
#define UART_TX_FIFO_QUARTER_FULL               0x20
#define UART_TX_FIFO_CHAR_2                     0x10
#define UART_TX_FIFO_EMPTY                      0x00

//UART_Hardware_Flow_Control
#define UART_HARDWARE_FLOW_CONTROL_DISABLE      0x02
#define UART_HARDWARE_FLOW_CONTROL_ENABLE       0x22 // AFCE=1, RTS=1

//UART_DATA
// #define UART_DATA(DATA) ((DATA) <= 0x1FF)


//UART_Line_Status_Flags 
#define UART_LINE_FLAG_RFE              ((uint8_t)0x80)    //Receiver FIFO Error bit
#define UART_LINE_FLAG_TE               ((uint8_t)0x40)    //Transmitter Empty bit
#define UART_LINE_FLAG_THRE             ((uint8_t)0x20)    //Transmit Holding Register Empty bit
#define UART_LINE_FLAG_BI               ((uint8_t)0x10)    //Break Interrupt bit
#define UART_LINE_FLAG_FE               ((uint8_t)0x08)    //Framing Error bit
#define UART_LINE_FLAG_PE               ((uint8_t)0x04)    //Parity Error bit
#define UART_LINE_FLAG_OE               ((uint8_t)0x02)    //Overrun error bit
#define UART_LINE_FLAG_DR               ((uint8_t)0x01)    //Data Ready bit

//UART_Modem_Status_Flags 
#define UART_MSR_DCD                ((uint8_t)0x80)    //Data Carrier Detect
#define UART_MSR_RI                 ((uint8_t)0x40)    //Ring Indicator
#define UART_MSR_DSR                ((uint8_t)0x20)    //Data Set Ready
#define UART_MSR_CTS                ((uint8_t)0x10)    //Clear to Send
#define UART_MSR_DDCD               ((uint8_t)0x08)    //Delta Data Carrier Detect
#define UART_MSR_TERI               ((uint8_t)0x04)    //Trailing Edge of Ring Indicator
#define UART_MSR_DDSR               ((uint8_t)0x02)    //Delta Data Set Ready
#define UART_MSR_DCTS               ((uint8_t)0x01)    //Delta Clear to Send

//UART_Status_Flags 
#define UART_FLAG_RFF               ((uint8_t)0x10)     //Receive FIFO Full, unavailable here!
#define UART_FLAG_RFNE              ((uint8_t)0x08)     //Receive FIFO Not Empty, unavailable here!
#define UART_FLAG_TFE               ((uint8_t)0x04)     //Transmit FIFO Empty, unavailable here!
#define UART_FLAG_TFNF              ((uint8_t)0x02)     //Transmit FIFO Not Full, unavailable here!
#define UART_FLAG_BUSY              ((uint8_t)0x01)     //UART Busy

//UART_Interrupt
#define UART_IT_THRE                ((uint8_t)0x80)      // Programmable THRE Interrupt Mode Enable
#define UART_IT_MSR                 ((uint8_t)0x08)      //Modem Status Interrupt
#define UART_IT_ELSI                ((uint8_t)0x04)      //Receiver Line Status Interrupt
#define UART_IT_TXE                 ((uint8_t)0x02)      //Transmit Holding Register Empty Interrupt
#define UART_IT_RXF                 ((uint8_t)0x01)      //Received Data Available Interrupt
#define UART_IT_ALL                 ((uint8_t)0x8f)

//UART_Interrupt_Flag
#define UART_IT_FLAG_MODEM_STATUS              ((uint16_t)0x00)
#define UART_IT_FLAG_THR_EMPTY                 ((uint16_t)0x02)
#define UART_IT_FLAG_RECEIVED_AVAILABLE        ((uint16_t)0x04)
#define UART_IT_FLAG_RECEIVER_LINE_STATUS      ((uint16_t)0x06)
#define UART_IT_FLAG_BUSY_DETECT               ((uint16_t)0x07)
#define UART_IT_FLAG_CHARACTER_TIMEOUT         ((uint16_t)0x0c)

//UART_Exported_Functions
void UART_Init(UART_Type* UARTx, UART_InitTypeDef* UART_InitStruct);
void UART_StructInit(UART_InitTypeDef* UART_InitStruct);
void UART_DeInit(UART_Type* UARTx);
void UART_ITConfig(UART_Type* UARTx, uint8_t UART_IT, FunctionalState NewState);
ITStatus UART_GetITStatus(UART_Type* UARTx, uint8_t ITFlag);
void UART_SendData(UART_Type* UARTx, uint16_t Data);
uint16_t UART_ReceiveData(UART_Type* UARTx);
FlagStatus UART_GetLineStatus(UART_Type* UARTx, uint8_t LineFlag);
FlagStatus UART_GetUsrStatus(UART_Type* UARTx, uint8_t Flag);
FlagStatus UART_GetMsrStatus(UART_Type* UARTx, uint8_t Flag);
void UART_FIFOTrigConfig(UART_Type* UARTx, uint8_t RxTrig, uint8_t TxTrig);

#endif

