#ifndef __UART_H__
#define __UART_H__




#define UART0_BASE                        ( 0x38028000UL )                        /* MCom02 - UART 0 */
#define UART1_BASE                        ( 0x38029000UL )                        /* MCom02 - UART 1 */
#define UART2_BASE                        ( 0x3802a000UL )                        /* MCom02 - UART 2 */
#define UART3_BASE                        ( 0x3802b000UL )                        /* MCom02 - UART 3 */

#define UART_RBR(x)        ( (unsigned long *)        ( (x) + 0x0000UL ) )        /* Register */
#define UART_THR(x)        ( (unsigned long *)        ( (x) + 0x0000UL ) )        /* Register */
#define UART_DLL(x)        ( (unsigned long *)        ( (x) + 0x0000UL ) )        /* Register */
#define UART_DLH(x)        ( (unsigned long *)        ( (x) + 0x0004UL ) )        /* Register */
#define UART_IER(x)        ( (unsigned long *)        ( (x) + 0x0004UL ) )        /* Register */
#define UART_IIR(x)        ( (unsigned long *)        ( (x) + 0x0008UL ) )        /* Register */
#define UART_FCR(x)        ( (unsigned long *)        ( (x) + 0x0008UL ) )        /* Register */
#define UART_LCR(x)        ( (unsigned long *)        ( (x) + 0x000CUL ) )        /* Register */
#define UART_MCR(x)        ( (unsigned long *)        ( (x) + 0x0010UL ) )        /* Register */
#define UART_LSR(x)        ( (unsigned long *)        ( (x) + 0x0014UL ) )        /* Register */
#define UART_MSR(x)        ( (unsigned long *)        ( (x) + 0x0018UL ) )        /* Register */
#define UART_SCR(x)        ( (unsigned long *)        ( (x) + 0x001CUL ) )        /* Register */
#define UART_SRBR(x)       ( (unsigned long *)        ( (x) + 0x0030UL ) )        /* Register */
#define UART_STHR(x)       ( (unsigned long *)        ( (x) + 0x0030UL ) )        /* Register */
#define UART_USR(x)        ( (unsigned long *)        ( (x) + 0x007CUL ) )        /* Register */
#define UART_TFL(x)        ( (unsigned long *)        ( (x) + 0x0080UL ) )        /* Register */
#define UART_RFL(x)        ( (unsigned long *)        ( (x) + 0x0084UL ) )        /* Register */
#define UART_SRR(x)        ( (unsigned long *)        ( (x) + 0x0088UL ) )        /* Register */
#define UART_SRTS(x)       ( (unsigned long *)        ( (x) + 0x008CUL ) )        /* Register */
#define UART_SBCR(x)       ( (unsigned long *)        ( (x) + 0x0080UL ) )        /* Register */
#define UART_SFE(x)        ( (unsigned long *)        ( (x) + 0x0098UL ) )        /* Register */
#define UART_SRT(x)        ( (unsigned long *)        ( (x) + 0x009CUL ) )        /* Register */
#define UART_STET(x)       ( (unsigned long *)        ( (x) + 0x00A0UL ) )        /* Register */
#define UART_HTX(x)        ( (unsigned long *)        ( (x) + 0x00A4UL ) )        /* Register */

        /* IER register fields */
#define UART_IER_ERBFI_ENABLE       ( 1 << 0 )
#define UART_IER_ETBEI_ENABLE       ( 1 << 1 )
#define UART_IER_ELSI_ENABLE        ( 1 << 2 )
#define UART_IER_EDSSI_ENABLE       ( 1 << 3 )
#define UART_IER_PITME_ENABLE       ( 1 << 7 )

        /* IIR register fields */
#define UART_IIR_INTERRUPT_STATUS_MODEM                (  0 << 0 )
#define UART_IIR_INTERRUPT_STATUS_EMPTYQ        (  1 << 0 )
#define UART_IIR_INTERRUPT_STATUS_THR                (  2 << 0 )
#define UART_IIR_INTERRUPT_STATUS_TX                (  8 << 0 )
#define UART_IIR_TIMEOUT_STATUS_MASK                ( 12 << 0 )
#define UART_IIR_FIFO_ENABLE_STATUS_MASK        (  3 << 6 )

        /* FCR register fields */
#define UART_FCR_RFTL_STATE_IDX                ( 6 )
#define UART_FCR_RFTL_STATE                ( 3 << 6 )
#define UART_FCR_TET_STATE_IDX                ( 4 )
#define UART_FCR_TET_STATE                ( 3 << 4 )
#define UART_FCR_RESET_TX_FLAG                ( 1 << 2 )
#define UART_FCR_RESET_RX_FLAG                ( 1 << 1 )
#define UART_FCR_FEWO                        ( 1 << 0 )

        /* LCR register fields */
#define UART_LCR_DLAB                   ( 1 << 7 )
#define UART_LCR_BC                     ( 1 << 6 )
#define UART_LCR_STP                    ( 1 << 5 )
#define UART_LCR_EPS                    ( 1 << 4 )
#define UART_LCR_PEN                    ( 1 << 3 )
#define UART_LCR_STOP                   ( 1 << 2 )
#define UART_LCR_DLS                    ( 3 << 0 )

        /* MCR register fields */
#define UART_MCR_AFCE                        ( 1 << 5 )
#define UART_MCR_RTS                      ( 1 << 1 )

        /* LSR register fields */
#define UART_LSR_EIRF                   ( 1 << 7 )
#define UART_LSR_TEMT                   ( 1 << 6 )
#define UART_LSR_THRE                   ( 1 << 5 )
#define UART_LSR_BI                         ( 1 << 4 )
#define UART_LSR_FE                         ( 1 << 3 )
#define UART_LSR_PE                          ( 1 << 2 )
#define UART_LSR_OE                        ( 1 << 1 )
#define UART_LSR_RDR                        ( 1 << 0 )

        /* MSR register fields */
#define UART_MSR_CTS                    ( 1 << 4 )
#define UART_MSR_DCTS                   ( 1 << 0 )

        /* USR register fields */
#define UART_LSR_RFF                        ( 1 << 4 )
#define UART_LSR_RFNE                        ( 1 << 3 )
#define UART_LSR_TFE                         ( 1 << 2 )
#define UART_LSR_TFNF                   ( 1 << 1 )
#define UART_LSR_BUSY                   ( 1 << 0 )

        /* SRR register fields */
#define UART_SRR_XFR                         ( 1 << 2 )
#define UART_SRR_RFR                    ( 1 << 1 )
#define UART_SRR_UR                     ( 1 << 0 )

        /* SRTS register fields */
#define UART_SRTS_SRTS                  ( 1 << 0 )

        /* SBCR register fields */
#define UART_SBCR_SBCR                  ( 1 << 0 )

        /* SFE register fields */
#define UART_SFE_SBCR                   ( 1 << 0 )

         /* SRT register fields */
#define UART_SRT_SBCR                   ( 1 << 0 )

         /* STET register fields */
#define UART_STET_SBCR                  ( 1 << 0 )

         /* HTX register fields */
#define UART_HTX_HTX                    ( 1 << 0 )

#define UART_CLK_HZ                        ( 216000000UL )
#define UART0_VECTOR_ID                        ( 32 )

#define UART_FIFO_SIZE_BYTES        ( 32UL )
#define UART1_VECTOR_ID                        ( 33 )
#define UART2_VECTOR_ID                        ( 34 )
#define UART3_VECTOR_ID                        ( 35 )

#define TX_QUEUE                                ( 0 )
#define RX_QUEUE                                ( 1 )

#define min(a,b) ((a)<(b))?(a):(b)









unsigned get_l3comm_freq(void);
unsigned get_cpu_clock(void);

//
// @name: uart_config
// @description: Setup uart port to transfer at given speed and frequency
//
// @in unsigned int khz   - frequency
// @in unsigned long baud - data transfer speed
//
void uart_config(unsigned int id, unsigned int khz, unsigned long baud);

//
// @name: uart_putchar
// @description: Send symbol
//
// @in short c   -
//
void uart_putchar (unsigned int id, short c);

//
// @name: uart_getchar
// @description: Wait for the byte to be received and return it.
// @return: unsigned short - received symbol
//
unsigned short uart_getchar (unsigned int id);

// Function: uart_puts
// Sends buffer to uart port
//
// Parameters: const char* str - string 
//
int uart_puts(unsigned int id, const char* str);

#endif