/*********************************************************************************************************                                               
*                                     MCU ACH118X driver library
*                             COPYRIGHT(c) 2019 Amped RF Technology (ART)
*                                        All Rights Reserved
*
* File    : ach118x_uart.h
* Version : V1.0.0
* Brief   : UART Features and registers--
*   - Modeled after the industry-standard 16550. 
*   - Number of data bits supported per character (5-9).
*   - Baud rate up to 2M baud.
*   - Parity generation/checking - odd, even select or Stick Parity.
*   - Number of stop bits (1, 1.5 or 2).
*   - Interrupt generation.
*   - Transmit and receive data FIFO size 256 bytes.
*   - Auto Flow Control mode, as specified in the 16750 standard.
*   - Programmable Transmit Holding Register Empty (THRE) interrupt.
*     When FIFOs and the THRE Mode are selected and enabled, THRE Interrupts 
*     are active at or below a programmed TX FIFO threshold level. Additionally, 
*     the Line Status THRE switches from indicating TX FIFO empty to TX FIFO full, 
*     which allows software to set a threshold that keeps the transmitter FIFO 
*     from running empty whenever there is data to transmit.
**********************************************************************************************************/

#ifndef __ACH118X_UART_H
#define __ACH118X_UART_H

/**********************************************/
/*         UART Register Memory Map           */
/**********************************************/
#define UART_RBR            0x00    // Receive Buffer Register
#define UART_THR            0x00    // Transmit Holding Register
#define UART_DLL            0x00    // Divisor Latch (Low)
#define UART_DLH            0x04    // Divisor Latch (High)
#define UART_IER            0x04    // Interrupt Enable Register
#define UART_IIR            0x08    // Interrupt Identification Register
#define UART_FCR            0x08    // FIFO Control Register
#define UART_LCR            0x0C    // Line Control Register
#define UART_MCR            0x10    // Modem Control Register
#define UART_LSR            0x14    // Line Status Register
#define UART_MSR            0x18    // Modem Status Register
#define UART_SCR            0x1C    // Scratchpad Register
#define UART_LPDLL          0x20    // Low Power Divisor Latch (Low) Register
#define UART_LPDLH          0x24    // Low Power Divisor Latch (High) Register
#define UART_SRBR           0x30    // Shadow Receive Buffer Register
#define UART_STHR           0x30    // Shadow Transmit Holding Register
#define UART_FAR            0x70    // FIFO Access Register
#define UART_TFR            0x74    // Transmit FIFO Read
#define UART_RFW            0x78    // Receive FIFO Write
#define UART_USR            0x7C    // UART Status Register
#define UART_TFL            0x80    // Transmit FIFO Level
#define UART_RFL            0x84    // Receive FIFO Level
#define UART_SRR            0x88    // Software Reset Register
#define UART_SRTS           0x8C    // Shadow Request to Send
#define UART_SBCR           0x90    // Shadow Break Control Register
#define UART_SDMAM          0x94    // Shadow DMA Mode
#define UART_SFE            0x98    // Shadow FIFO Enable
#define UART_SRT            0x9C    // Shadow RCVR Trigger
#define UART_STET           0xA0    // Shadow TX Empty Trigger
#define UART_HTX            0xA4    // Halt TX
#define UART_DMASA          0xA8    // DMA Software Acknowledge
#define UART_TCR            0xAC    // Transceiver Control Register
#define UART_DE_EN          0xB0    // Driver Output Enable Register
#define UART_RE_EN          0xB4    // Receiver Output Enable Register
#define UART_DET            0xB8    // Driver Output Enable Timing Register
#define UART_TAT            0xBC    // TurnAround Timing Register
#define UART_DLF            0xC0    // Divisor Latch Fractional Value
#define UART_RAR            0xC4    // Receive Address Register
#define UART_TAR            0xC8    // Transmit Address Register
#define UART_LCR_EXT        0xCC    // Line Extended Control Register
#define UART_CPR            0xF4    // Component Parameter Register
#define UART_UCV            0xF8    // UART Component Version
#define UART_CTR            0xFC    // Component Type Register -- 0x44570110

//LCR
#define UART_LCR_DLAB           0x80    // Divisor Latch Access Bit
#define UART_LCR_BREAK          0x40    // Break Control Bit
#define UART_LCR_STICK_PARITY   0x20    // Stick Parity
#define UART_LCR_EPS            0x10    // Even Parity Select
#define UART_LCR_PEN            0x80    // Parity Enable
#define UART_LCR_STOP           0x40    // Number of stop bits
#define UART_LCR_DLS_5BITS      0x00    // Data Length 5 bits
#define UART_LCR_DLS_6BITS      0x01    // Data Length 6 bits
#define UART_LCR_DLS_7BITS      0x02    // Data Length 7 bits
#define UART_LCR_DLS_8BITS      0x03    // Data Length 8 bits

//FCR
#define UART_FCR_RX_1CHAR       0x00
#define UART_FCR_RX_QFULL       0x40
#define UART_FCR_RX_HFULL       0x80
#define UART_FCR_RX_2CHARFULL   0xC0
#define UART_FCR_TX_EMPTY       0x00
#define UART_FCR_TX_2CHAR       0x10
#define UART_FCR_TX_QFULL       0x20
#define UART_FCR_TX_HFULL       0x30
#define UART_FCR_DMA_MODE_0     0x00
#define UART_FCR_DMA_MODE_1     0x08
#define UART_FCR_TX_FIFO        0x04
#define UART_FCR_RX_FIFO        0x02
#define UART_FCR_FIFO_ENABLE    0x01


//IER
#define UART_IER_PTIME          0x80    // Enable the generation of THRE Interrupt
#define UART_IER_EDSSI          0x08    // Enable Modem Status Interrupt
#define UART_IER_ELSI           0x04    // Enable Receiver Line Status Interrupt
#define UART_IER_ETBEI          0x02    // Enable Transmit Holding Register Empty Interrupt
#define UART_IER_ERBFI          0x01    // Enable Received Data Available Interrupt

//IIR
#define UART_IIR_FIFOSE_DISABLED            0x00
#define UART_IIR_FIFOSE_ENABLED             0xC0
#define UART_IIR_IID_MODEM_STATUS           0x00
#define UART_IIR_IID_NO_INTERRUPT_PENDING   0x01
#define UART_IIR_IID_THR_EMPTY              0x02
#define UART_IIR_IID_RX_DATA_AVAILABLE      0x04
#define UART_IIR_IID_RX_LINE_STATUS         0x06
#define UART_IIR_IID_BUSY_DETECT            0x07
#define UART_IIR_IID_CHAR_TIMEOUT           0x0C
#define UART_IIR_IID_MASK                   0x0F

//LSR
#define UART_LSR_ADDR_RCVD      0x100   // 9th bit of the receive data is set to 1.
#define UART_LSR_RFE            0x080   // Receiver FIFO Error bit
#define UART_LSR_TEMT           0x040   // Transmitter Empty bit
#define UART_LSR_THRE           0x020   // Transmit Holding Register Empty bit
#define UART_LSR_BI             0x010   // Break Interrupt bit
#define UART_LSR_FE             0x008   // Framing Error bit
#define UART_LSR_PE             0x004   // Parity Error bit
#define UART_LSR_OE             0x002   // Overrun error bit
#define UART_LSR_DR             0x001   // Data Ready bit


//USR
#define UART_USR_RFF            0x10
#define UART_USR_RFNE           0x08
#define UART_USR_TFE            0x04
#define UART_USR_TFNF           0x02
#define UART_USR_BUSY           0x01


/*UART register define*/
typedef union
{
    vu32 RBR;   //0x00,
    vu32 THR;   //0x00,
    vu32 DLL;   //0x00,
} regRTD;

typedef union
{
    vu32 DLH;   //0x04,
    vu32 IER;   //0x04,
} regDI;

typedef union
{
    vu32 IIR;   //0x08,
    vu32 FCR;   //0x08,
} regIF;

typedef union
{
    vu32 SRBR[16];
    vu32 STHR[16];
} regSS;

typedef struct
{
    regRTD RTD;     //0x00 (RBR + THR + DLL)
    regDI  DI;      //0x04	(DLH+IER)
    regIF  IF;      //0x08  (IIR+FCR)
    vu32 LCR;       //0x0c,

    vu32 MCR;       //0x10,
    vu32 LSR;       //0x14,
    vu32 MSR;       //0x18,
    vu32 SCR;       //0x1c,

    vu32 LPDLL;     //0x20
    vu32 LPDLH;     //0x24
    vu32 Resever28; //0x28
    vu32 Resever2c; //0x2c

    regSS SS;       //0x30-0x6c

    vu32 FAR;       //0x70,
    vu32 TFR;       //0x74,
    vu32 RFW;       //0x78,
    vu32 USR;       //0x7c,

    vu32 TFL;       //0x80,
    vu32 RFL;       //0x84
    vu32 SRR;       //0x88
    vu32 SRTS;      //0x8c

    vu32 SBCR;      //0x90
    vu32 SDMAM;     //0x94
    vu32 SFE;       //0x98
    vu32 SRT;       //0x9c

    vu32 STET;      //0xa0
    vu32 HTX;       //0xa4
    vu32 DMASA;     //0xa8
    vu32 TCR;       //0xac

    vu32 DE_EN;     //0xb0
    vu32 RE_EN;     //0xb4;
    vu32 DET;       //0xb8;
    vu32 TAT;       //0xbc

    vu32 DLF;       //0xc0
    vu32 RAR;       //0xc4
    vu32 TAR;       //0xc8
    vu32 LCR_EXT;   //0xcc

    vu32 ReseverD0; //0xD0
    vu32 ReseverD4; //0xD4
    vu32 ReseverD8; //0xD8
    vu32 ReseverDC; //0xDC

    vu32 ReseverE0; //0xe0
    vu32 ReseverE4; //0xe4
    vu32 ReseverE8; //0xe8
    vu32 ReseverEC; //0xeC

    vu32 ReseverF0; //0xf0
    vu32 CPR;       //0xf4
    vu32 UCV;       //0xf8
    vu32 CTR;       //0xfc
}UART_Typedef;

typedef enum{
	UART_LEN_5=0,
	UART_LEN_6,
	UART_LEN_7,
	UART_LEN_8
}WordLenType;

typedef enum{
	UART_STOP_1=0x0,
	UART_STOP_2=0x4
}StopBitType;

typedef enum{
	NONE_PARITY = 0x00,
	EVEN_PARITY = 0x38,
	ODD_PARITY = 0x28
}ParityType;

typedef enum{
	FLOWCON_DISABLE=0x00,
	FLOWCON_ENABLE=0x20,
}FlowConType;

typedef struct
{
    uint32_t UART_BaudRate;
    WordLenType UART_WordLength;
    StopBitType UART_StopBits;
    ParityType  UART_Parity;
    FlowConType UART_HardwareFlowControl;
} UART_InitTypeDef;

//IER (Interrupt Enable Register)
#define ERBFI_ENABLE        (0x01)
#define ETBEI_ENABLE        (0x02)
#define ELSI_ENABLE         (0x04)
#define EDSSI_ENABLE        (0x08)
#define PTIME_ENABLE        (0x80)

#define ERBFI_DISABLE       (~ERBFI_ENABLE)
#define ETBEI_DISABLE       (~ERBFI_ENABLE)
#define ELSI_DISABLE        (~ELSI_ENABLE)
#define EDSSI_DISABLE       (~EDSSI_ENABLE)
#define PTIME_DISABLE       (~PTIME_ENABLE)
//IIR(Interrupt Identity Register)
#define MODEM_STATUS        (0x00)
#define NO_INTPENDING       (0x01)
#define THR_EMPTY           (0x02)
#define RXD_AVAILABLE       (0x04)
#define RXD_LINE_STATUS     (0x06)
#define BUSY_DETECT         (0x07)
#define CHAR_TIMEOUT        (0x0c)
#define FIFOSE              (0xc0)

//FCR(FIFO Control Register)
#define FIFOE                   (0x01)
#define RFIOR                   (0x02)
#define XFIFOR                  (0x04)
#define DMAM_MODE1              (0x08)
#define DMAM_MODE0              (~DMAM_MODE1)
//FCR[5:4] TX Empty Trigger
#define TET_EMPTY               (0x00)
#define TET_2CHAR               (0x10)
#define TET_QFULL               (0x20)
#define TET_HFULL               (0x30)
 //FCR[7:6] RCVR Trigger
#define RCT_1CHAR               (0x00)
#define RCT_QFULL               (0x40)
#define RCT_HFULL               (0x80)
#define RCT_LFULL               (0xc0)
//LCR(Line Control register)
//LCR[1:0]
/*
#define DLS_5BIT                (0x00)
#define DLS_6BIT                (0x01)
#define DLS_7BIT                (0x02)
#define DLS_8BIT                (0x03)
*/
//LCR[2]
/*
#define STOP_1                  (0x00)
#define STOP_2                  (0x04)
#define	NONE_PARITY             (0x00)
#define	EVEN_PARITY             (0x38)
#define	ODD_PARITY              (0x28)
*/

#define ENABLE_BAUDRATE		(0x80)
#define DISABLE_BAUDRATE	(~ENABLE_BAUDRATE)
//MCR(Modem Control Register)
#define DTR_LOW                 (0x01)
#define RTS_LOW                 (0x02)
#define OUT1_LOW                (0x04)
#define OUT2_LOW                (0x08)
#define LOOP_BACK               (0x10)
#define FLOW_CONTROL            (0x20)
#define SIR_MODE_ENABLE         (0x40)

#define ALL_CONFIG              (0xffff)/*The define is used to clear old configuaration,
                                          The following API can use the define:
                                            UART_ITConfig,
                                            UART_FIFOConfig,
                                            UART_LineConfig,
                                            UART_LineExtConfig,
                                            UART_ModemConfig*/


//LSR(Line Status Register)
#define DR_STATUS               (0x01)
#define OE_STATUS               (0x02)
#define PE_STATUS               (0x04)
#define FE_STATUS               (0x08)
#define BI_STATUS               (0x10)
#define THRE_STATUS             (0x20)
#define TEMT_STATUS             (0x40)
#define RFE_STATUS              (0x80)

//MSR(Modem Status Register)
#define DCTS_STATUS             (0x01)
#define DDSR_STATUS             (0x02)
#define TERI_STATUS             (0x04)
#define DDCD_STATUS             (0x08)
#define CTS_STATUS              (0x10)
#define DSR_STATUS              (0x20)
#define RI_STATUS               (0x40)
#define DCD_STATUS              (0x80)
#if (UART_FIFO_ACCESS == 1)
    //FAR(FIFO Access Register)
    //#define FIFO_ACCESS_ENABLE      (0x01)
    //#define FIFO_ACCESS_DISABLE     (~FIFO_ACCESS_ENABLE)
#endif //END UART_FIFO_ACCESS

//USR(UART Status Register)
#define RFF_STATUS		        (0x10)
#define RFNE_STATUS             (0x08)
#define TFE_STATUS		        (0x04)
#define TFNF_STATUS             (0x02)
#define BUSY_STATUS             (0x01)
#if (UART_SHADOW == 1)
//SRR(software reset register)
  #define UR_RESET              (0x01)
  #define RFR_RESET             (0x02)
  #define XFR_RESET             (0x04)
//SRTS(Shadow request to send)
  #define SRTS_HIGH             (0x01)
  #define SRTS_LOW              (~SRTS_HIGH)
//SBCR(Shadow Break Control Register)
  #define SBCR_HIGH             (0x01)
  #define SBCR_LOW              (~SBCR_HIGH)
//SDMAM(Shadow DMA MODE)
  #define SDMAM_MODE1           (0x01)
  #define SDMAM_MODE0           (~SDMAM_MODE1)
//SFE(Shadow FIFO Enable)
  #define SFIFO_ENABLE          (0x01)
  #define SFIFO_DISABLE         (~SFIFO_ENABLE)
//SRT(Shadow RCVR Trigger)
  #define SRCT_1CHAR            (0x00)
  #define SRCT_QFULL            (0x01)
  #define SRCT_HFULL            (0x02)
  #define SRCT_LFULL            (0x03)
//STET(Shadow TX Empty Trigger)
  #define STET_EMPTY            (0x00)
  #define STET_2CHAR            (0x01)
  #define STET_QFULL            (0x02)
  #define STET_HFULL            (0x03)
#endif
//HTX(Halt TX)
#define HALTTX_ENABLE           (0x01)
#define HALTTX_DISABLE          (~(HALTTX_ENABLE))
//DMASA(DMA Software Acknowledge)
#define DMASW_ACK_ENABLE        (0x01)
#define DMASW_ACK_DISABLE       (~DMASW_ACK_ENABLE)
#if (UART_RS485==1)
//TCR(tramsceiver Control Register)
  #define RS485_EN              (0x01)
  #define RE_POL_HIGH           (0x02)
  #define DE_POL_HIGH           (0x04)
  #define XFER_MODE0            (0x00)
  #define XFER_MODE1            (0x08)
  #define XFER_MODE2            (0x18)
  #define RS232_EN              (~RS485)
  #define RE_POL_LOW            (~RE_POL_HIGH)
  #define DE_POL_LOW            (~DE_POL_HIGH)
//DE_EN(Driver output Enable regsiter)
  #define DE_ENABLE             (0x01)
  #define DE_DISABLE            (~DE_ENABLE)
//RE_EN(Receiver output Enable regsiter)
  #define RE_ENABLE             (0x01)
  #define RE_DISABLE            (~RE_ENABLE)
//DET(Driver output enable)
typedef enum{
    ASSERTION = 0,
    DEASSERTION =1
}DeTimerType;

typedef enum{
    REtoDE = 0,
    DEtoRE =1
}TATimerType;
#endif
//LCR_EXT(Line Extended Control Regsiter)
#define DLS_BIT9_ENABLE         (0x01)
#define ADDR_MATCH_MODE         (0x02)
#define SEND_ADDR_1             (0x04)
#define TRANSMIT_MODE1          (0x08)

//CPR(Component Parameter Register)
#define UART_APB_DATA_WIDTH_8BIT     (0x0000)
#define UART_APB_DATA_WIDTH_16BIT    (0x0001)
#define UART_APB_DATA_WIDTH_32BIT    (0x0002)
#define AFCE_MODE               (0x0010)
#define THRE_MODE               (0x0020)
#define SIR_MODE                (0x0040)
#define SIR_LP_MODE             (0x0080)
#define ADDITIONAL_FEAT         (0x0100)
#define FIFO_ACCESS             (0x0200)
#define FIFO_STAT               (0x0400)
#define SHADOW                  (0x0800)
#define UART_ADD_ENCODED_PARAMS (0x1000)
#define DMA_EXTRA               (0x2000)

#define UART1_ENABLE            (0x0000d7)
#define UART2_ENABLE            (0x550000)

#define UART_FOREVER            0


// macros
#define putstring(s)    ach_uart_send_string(UART0, s)

//-----------------------------------------------------------------
//  prototypes
//-----------------------------------------------------------------
void    ach_uart_init(UART_Typedef* UARTx, UART_InitTypeDef* UART_InitStruct);
int     ach_uart_rcv_ready(UART_Typedef* UARTx);
uint8_t ach_uart_read_byte(UART_Typedef* UARTx);
void    ach_uart_send_byte(UART_Typedef* UARTx, uint8_t data);
void    ach_uart_send_bytes(UART_Typedef* UARTx, uint8_t *pdata, uint16_t len);
void    ach_uart_send_string(UART_Typedef* UARTx, char *str);
void    getline(char *buf, uint16_t bufmax);

void UART_Init(UART_Typedef* UARTx, UART_InitTypeDef* UART_InitStruct);
void UART_SendData(UART_Typedef* UARTx, uint16_t Data, uint32_t Timeout);
uint16_t  UART_ReceiveData(UART_Typedef* UARTx, uint32_t Timeout);
void UART_ITConfig(UART_Typedef* UARTx, uint16_t UART_IT, FunctionalState NewState);
void UART_FIFOConfig(UART_Typedef* UARTx, uint16_t UART_FIFO, FunctionalState NewState);
void UART_LineConfig(UART_Typedef* UARTx, uint16_t UART_Line, FunctionalState NewState);
void UART_LineExtConfig(UART_Typedef* UARTx, uint16_t UART_Line, FunctionalState NewState);
void UART_ModemConfig(UART_Typedef* UARTx, uint16_t UART_Modem, FunctionalState NewState);
ITStatus UART_GetITStatus(UART_Typedef* UARTx, uint16_t UART_IT);
FlagStatus UART_GetLineStatus(UART_Typedef* UARTx, uint16_t UART_Line);
FlagStatus UART_GetModemStatus(UART_Typedef* UARTx, uint16_t UART_FLAG);
FlagStatus UART_GetUartStatus(UART_Typedef* UARTx, uint16_t UART_FLAG);

#if (UART_FIFO_ACCESS == 1)
    void UART_FIFOAccessCmd(UART_Typedef* UARTx,FunctionalState NewState);
    uint8_t UART_FIFOAccessReadTranFIFO(UART_Typedef* UARTx);
    void UART_FIFOAccessWriteReceFIFO(UART_Typedef* UARTx,uint16_t data);
    uint32_t UART_FIFOAccessGetTraFIFOLevel(UART_Typedef* UARTx);
    uint32_t UART_FIFOAccessGetRecFIFOLevel(UART_Typedef* UARTx);
#endif //END UART_FIFO_ACCESS

void UART_HaltTXCmd(UART_Typedef* UARTx,FunctionalState NewState);

#if (UART_SHADOW == 1)
    void UART_SendData_Shadow(UART_Typedef* UARTx, uint16_t Data);
    uint16_t  UART_ReceiveData_Shadow(UART_Typedef* UARTx);
    void UART_SWReset_Shadow(UART_Typedef* UARTx, uint16_t UART_Shadow_option, FunctionalState NewState);
    void UART_RTS_Shadow(UART_Typedef* UARTx,LevelState NewState);
#endif // END UART_SHADOW

#if (UART_RS485 == 1)
    void UART_RS485_TranReceConfig(UART_Typedef* UARTx,uint16_t UART_OPTION, FunctionalState NewState);
    void UART_RS485_DE_EN(UART_Typedef* UARTx);
    void UART_RS485_RE_EN(UART_Typedef* UARTx);
    void UART_RS485_SetDETimer(UART_Typedef* UARTx,DeTimerType option,uint16_t value);
    void UART_RS485_SetTurnAroundTimer(UART_Typedef* UARTx,TATimerType option,uint16_t value);
#endif //END UART_RS485

FlagStatus UART_GetComponentParameter(UART_Typedef* UARTx,uint16_t UART_Param);
uint32_t UART_GetComponentVersion(UART_Typedef* UARTx);
uint32_t UART_GetComponentType(UART_Typedef* UARTx);


#endif /* __ACH118X_UART_H */
/************************ (C) COPYRIGHT ART *****END OF FILE****/
