/**
 * \addtogroup BSP
 * \{
 * \addtogroup DEVICES
 * \{
 * \addtogroup UART
 * \{
 */

/**
 ****************************************************************************************
 *
 * @file hw_uart.c
 *
 * @brief Implementation of the UART Low Level Driver.
 *
 * Copyright (c) 2016, Dialog Semiconductor
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its contributors
 *    may be used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 ****************************************************************************************
 */

#if dg_configUSE_HW_UART


#include <stdint.h>
#include <string.h>
#include <core_cm0.h>
#include <hw_uart.h>

#if (dg_configSYSTEMVIEW)
#  include "SEGGER_SYSVIEW_FreeRTOS.h"
#else
#  define SEGGER_SYSTEMVIEW_ISR_ENTER()
#  define SEGGER_SYSTEMVIEW_ISR_EXIT()
#endif

#if (dg_configUART1_SOFTWARE_FIFO_SIZE && dg_configUART_SOFTWARE_FIFO)
#if dg_configUART_RX_CIRCULAR_DMA && (dg_configUART1_RX_CIRCULAR_DMA_BUF_SIZE > 0)
#error UART1 can not be configured to use software FIFO and circular DMA FIFO at the same time
#endif
__RETAINED static uint8_t uart1_sw_fifo[dg_configUART1_SOFTWARE_FIFO_SIZE];
#else
#define uart1_sw_fifo   (NULL)
#endif

#if (dg_configUART2_SOFTWARE_FIFO_SIZE && dg_configUART_SOFTWARE_FIFO)
#if dg_configUART_RX_CIRCULAR_DMA && (dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE > 0)
#error UART2 can not be configured to use software FIFO and circular DMA FIFO at the same time
#endif
__RETAINED static uint8_t uart2_sw_fifo[dg_configUART2_SOFTWARE_FIFO_SIZE];
#else
#define uart2_sw_fifo   (NULL)
#endif

#if dg_configUART1_SOFTWARE_FIFO_SIZE > 255 || dg_configUART2_SOFTWARE_FIFO_SIZE > 255
typedef uint16_t fifo_size_t;
#else
typedef uint8_t fifo_size_t;
#endif

#if dg_configUART1_SOFTWARE_FIFO_SIZE > 256 || dg_configUART2_SOFTWARE_FIFO_SIZE > 256
typedef uint16_t fifo_ptr_t;
#else
typedef uint8_t fifo_ptr_t;
#endif

#if dg_configUART_RX_CIRCULAR_DMA

#if !HW_UART_USE_DMA_SUPPORT
#       error "dg_configUART_RX_CIRCULAR_DMA requires HW_UART_USE_DMA_SUPPORT to be enabled!"
#endif

#if dg_configUART1_RX_CIRCULAR_DMA_BUF_SIZE > 0
__RETAINED static uint8_t uart1_rx_dma_buf[dg_configUART1_RX_CIRCULAR_DMA_BUF_SIZE];
#else
#define uart1_rx_dma_buf (NULL)
#endif

#if dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE > 0
__RETAINED static uint8_t uart2_rx_dma_buf[dg_configUART2_RX_CIRCULAR_DMA_BUF_SIZE];
#else
#define uart2_rx_dma_buf (NULL)
#endif

#endif /* dg_configUART_RX_CIRCULAR_DMA */

typedef struct
{
#ifdef HW_UART_ENABLE_USER_ISR
    hw_uart_interrupt_isr user_isr;
#endif
    const uint8_t       *tx_buffer;
    void                *tx_user_data;
    hw_uart_tx_callback tx_cb;
    uint16_t            tx_len;
    uint16_t            tx_ix;

    void                *rx_user_data;
    uint8_t             *rx_buffer;
    hw_uart_rx_callback rx_cb;
    uint16_t            rx_len;
    uint16_t            rx_ix;

    uint8_t             tx_fifo_on: 1;
    uint8_t             rx_fifo_on: 1;
    uint8_t             tx_fifo_level: 2;
    uint8_t             rx_fifo_level: 2;
#if dg_configUART_SOFTWARE_FIFO
    uint8_t            *rx_soft_fifo;
    fifo_size_t         rx_soft_fifo_size;
    fifo_ptr_t          rx_soft_fifo_rd_ptr;
    fifo_ptr_t          rx_soft_fifo_wr_ptr;
#endif
#if HW_UART_USE_DMA_SUPPORT
    uint8_t             use_dma: 1;
    DMA_setup           tx_dma;
    DMA_setup           rx_dma;
#if dg_configUART_RX_CIRCULAR_DMA
    bool                rx_dma_active;
    uint8_t             *rx_dma_buf;
    uint16_t            rx_dma_buf_size;
    uint16_t            rx_dma_head;
#endif /* dg_configUART_RX_CIRCULAR_DMA */
#endif /* HW_UART_USE_DMA_SUPPORT */
} UART_Data;

__RETAINED_RW static UART_Data uart_data[2];

#define UART_INT(id) ((id) == HW_UART1 ? (UART_IRQn) : (UART2_IRQn))
#define UARTIX(id) ((id) == HW_UART1 ? 0 : 1)
#define UARTDATA(id) (&uart_data[UARTIX(id)])
#define UARTID(ud) ((ud) == uart_data ? HW_UART1 : HW_UART2)

#ifdef HW_UART_ENABLE_USER_ISR
void hw_uart_set_isr(HW_UART_ID uart, hw_uart_interrupt_isr isr)
{
    uart_data[UARTIX(uart)].user_isr = isr;
}
#endif

//===================== Read/Write functions ===================================

uint8_t hw_uart_read(HW_UART_ID uart)
{
    // Wait until received data are available
    while (hw_uart_read_buf_empty(uart));

    // Read element from the receive FIFO
    return UBA(uart)->UART2_RBR_THR_DLL_REG;
}

void hw_uart_write(HW_UART_ID uart, uint8_t data)
{
    // Wait if Transmit Holding Register is full
    while (hw_uart_write_buf_full(uart));

    // Write data to the transmit FIFO
    UBA(uart)->UART2_RBR_THR_DLL_REG = data;
}

void hw_uart_write_buffer(HW_UART_ID uart, const void *data, uint16_t len)
{
    const uint8_t *p = data;

    while (len > 0)
    {
        hw_uart_write(uart, *p++);
        len--;
    }
}

void hw_uart_send(HW_UART_ID uart, const void *data, uint16_t len, hw_uart_tx_callback cb,
                  void *user_data)
{
    UART_Data *ud = &uart_data[UARTIX(uart)];

    if (cb == NULL)
    {
        hw_uart_write_buffer(uart, data, len);
        ud->tx_ix = 0;
        ud->tx_len = 0;
        return;
    }

    ud->tx_buffer = data;
    ud->tx_user_data = user_data;
    ud->tx_len = len;
    ud->tx_ix = 0;
    ud->tx_cb = cb;

#if HW_UART_USE_DMA_SUPPORT

    if (ud->tx_dma.channel_number != HW_DMA_CHANNEL_INVALID && len > 1)
    {
        ud->tx_dma.src_address = (uint32) data;
        ud->tx_dma.length = len;
        // DMA requested
        hw_uart_clear_dma_request(uart);
        hw_dma_channel_initialization(&ud->tx_dma);
        hw_dma_channel_enable(ud->tx_dma.channel_number, HW_DMA_STATE_ENABLED);
        return;
    }

#endif
    // Interrupt driven
    NVIC_DisableIRQ(UART_INT(uart));
    // Enable transmit interrupts
    uint16_t ier_dlh_reg = UBA(uart)->UART2_IER_DLH_REG;
    ier_dlh_reg |= ((1 << UART_UART_IER_DLH_REG_ETBEI_dlh1_Pos) | (1 << UART_UART_IER_DLH_REG_PTIME_dlh7_Pos));
    UBA(uart)->UART2_IER_DLH_REG = ier_dlh_reg;

    NVIC_EnableIRQ(UART_INT(uart));
}

static inline void hw_uart_enable_rx_int(HW_UART_ID uart, bool enable)
{
    NVIC_DisableIRQ(UART_INT(uart));
    HW_UART_REG_SETF(uart, IER_DLH, ERBFI_dlh0, enable);
    NVIC_EnableIRQ(UART_INT(uart));
}

#if dg_configUART_SOFTWARE_FIFO

#define SOFTWARE_FIFO_PRESENT(ud) ((ud)->rx_soft_fifo != NULL)

/*
 * Copy bytes from software FIFO to user provided buffer.
 * This function allows software FIFO interrupts to read more data while copy takes place.
 *
 * Function returns true if all requested data is already in user buffer.
 */
static bool hw_uart_drain_rx(HW_UART_ID uart, UART_Data *ud, int len)
{
    /*
     * This function is called with RX interrupt disabled.
     *
     * Get current software FIFO pointers before enabling interrupt again.
     * ud->rx_len is still set to 0, so interrupt will not try to copy data to
     * application buffer till all data from software FIFO is drained to user buffer.
     */
    fifo_ptr_t rd_ptr = ud->rx_soft_fifo_rd_ptr;
    fifo_ptr_t wr_ptr = ud->rx_soft_fifo_wr_ptr;
    int idx = 0;

    /*
     * ud->rx_ix is 0, set ud->rx_len to 0 to prevent interrupt from using it
     * before all data from software FIFO is moved to application buffer.
     */
    ud->rx_len = 0;

    hw_uart_enable_rx_int(uart, true);

    while (idx < len)
    {

        if (wr_ptr == rd_ptr)
        {
            /*
             * No more data in software FIFO, at least from state before
             * interrupt was enabled.
             * Disable interrupt and update read pointer to reflect position
             * of already copied data.
             */
            hw_uart_enable_rx_int(uart, false);
            ud->rx_soft_fifo_rd_ptr = rd_ptr;

            /*
             * Check if write pointer moved, if so interrupt put some more data
             * in buffer. Remember current write position and try again with
             * interrupts enabled.
             */
            if (ud->rx_soft_fifo_wr_ptr != wr_ptr)
            {
                wr_ptr = ud->rx_soft_fifo_wr_ptr;
                hw_uart_enable_rx_int(uart, true);
                continue;
            }

            /*
             * All was copied from software FIFO.
             * Setup user transaction ix and len so when interrupts are enabled
             * again (not in this function) interrupt or DMA can continue.
             */
            ud->rx_ix = idx;
            ud->rx_len = len;

            return false;
        }

        /* Copy from software FIFO to user provided buffer */
        ud->rx_buffer[idx++] = ud->rx_soft_fifo[rd_ptr++];

        if (rd_ptr >= ud->rx_soft_fifo_size)
        {
            rd_ptr = 0;
        }
    }

    /*
     * User buffer is filled, block interrupt so end of transmission callback will not be
     * called from interrupt.
     */
    hw_uart_enable_rx_int(uart, false);
    ud->rx_soft_fifo_rd_ptr = rd_ptr;
    ud->rx_len = len;
    ud->rx_ix = len;

    return true;
}

void hw_uart_read_buffer(HW_UART_ID uart, void *data, uint16_t len)
{
    UART_Data *ud = UARTDATA(uart);
    uint8_t *p = data;

    /*
     * Disable RX interrupt before draining software FIFO.
     */
    hw_uart_enable_rx_int(uart, false);

    if (SOFTWARE_FIFO_PRESENT(ud))
    {
        /*
         * Drain uses ud fields so setup them accordingly.
         */
        ud->rx_buffer = data;

        hw_uart_drain_rx(uart, ud, len);
        len -= ud->rx_ix;
        p += ud->rx_ix;
    }

    /*
     * Read all remaining bytes with RX interrupt still disabled.
     */
    while (len > 0)
    {
        *p++ = hw_uart_read(uart);
        len--;
    }

    ud->rx_ix = 0;
    ud->rx_len = 0;
    hw_uart_enable_rx_int(uart, SOFTWARE_FIFO_PRESENT(ud));
}

void hw_uart_set_soft_fifo(HW_UART_ID uart, uint8_t *buf, uint8_t size)
{
    UART_Data *ud = UARTDATA(uart);

    hw_uart_enable_rx_int(uart, false);

    ud->rx_soft_fifo = buf;
    ud->rx_soft_fifo_size = size;
    ud->rx_soft_fifo_rd_ptr = 0;
    ud->rx_soft_fifo_wr_ptr = 0;

    hw_uart_enable_rx_int(uart, buf != NULL);
}

#else

#define SOFTWARE_FIFO_PRESENT(ud)  false

void hw_uart_read_buffer(HW_UART_ID uart, void *data, uint16_t len)
{
    uint8_t *p = data;

    while (len > 0)
    {
        *p++ = hw_uart_read(uart);
        len--;
    }
}
#endif

static void hw_uart_fire_callback(UART_Data *ud)
{
    hw_uart_rx_callback cb = ud->rx_cb;
    ud->rx_cb = NULL;
    /* Just finished receiving, disable RX interrupts unless software FIFO is enabled */
    hw_uart_enable_rx_int(UARTID(ud), SOFTWARE_FIFO_PRESENT(ud));

    if (cb)
    {
        cb(ud->rx_user_data, ud->rx_len);
    }
}

void hw_uart_receive(HW_UART_ID uart, void *data, uint16_t len, hw_uart_rx_callback cb,
                     void *user_data)
{
    UART_Data *ud = UARTDATA(uart);

    if (cb == NULL)
    {
        hw_uart_read_buffer(uart, data, len);
        ud->rx_ix = 0;
        ud->rx_len = 0;
        return;
    }

    ud->rx_buffer = data;
    ud->rx_user_data = user_data;
    hw_uart_enable_rx_int(uart, false);
    ud->rx_len = len;
    ud->rx_ix = 0;
    ud->rx_cb = cb;
#if dg_configUART_SOFTWARE_FIFO

    if (hw_uart_drain_rx(uart, ud, len))
    {
        hw_uart_fire_callback(ud);
        return;
    }

#endif

#if dg_configUART_RX_CIRCULAR_DMA

    if (ud->rx_dma_buf_size > 0)
    {
        ASSERT_ERROR(len < ud->rx_dma_buf_size);

        uint16_t new_int, cur_idx;
        bool data_ready = false;

        ASSERT_ERROR(ud->rx_dma_active == false);

        /* Calculate index of end of requested data (do not wrap it!) */
        new_int = ud->rx_dma_head + ud->rx_len - 1;

        /* Freeze DMA so it does not move pointers while we try to update them */
        hw_dma_freeze();

        cur_idx = hw_dma_transfered_bytes(ud->rx_dma.channel_number);

        /* cur_idx is lower than rx_head only if it wrapped-around - fix it */
        if (cur_idx < ud->rx_dma_head)
        {
            cur_idx += ud->rx_dma_buf_size;
        }

        /*
         * If DMA has not read past the calculated index, we can set it and just wait for an
         * interrupt. In other case, data are ready immediately in buffer.
         */
        if (cur_idx <= new_int)
        {
            new_int %= ud->rx_dma_buf_size;
            hw_dma_channel_update_int_ix(ud->rx_dma.channel_number, new_int);
            ud->rx_dma_active = true;
        }
        else
        {
            hw_dma_channel_update_int_ix(ud->rx_dma.channel_number, cur_idx - 1);
            data_ready = true;
        }

        /* Unfreeze DMA now, it can start reading */
        hw_dma_unfreeze();

        /* Fire callback immediately if data already available in buffer */
        if (data_ready)
        {
            hw_uart_fire_callback(ud);
        }

        return;
    }

#endif

#if HW_UART_USE_DMA_SUPPORT

    if (ud->rx_dma.channel_number != HW_DMA_CHANNEL_INVALID && (ud->rx_len - ud->rx_ix > 1))
    {
        /* rx_ix could already be changed by hw_uart_drain_rx() */
        ud->rx_dma.dest_address = (uint32) data + ud->rx_ix;
        ud->rx_dma.length = ud->rx_len - ud->rx_ix;
        hw_uart_clear_dma_request(uart);
        /* Prepare and start DMA */
        hw_dma_channel_initialization(&ud->rx_dma);
        hw_dma_channel_enable(ud->rx_dma.channel_number, HW_DMA_STATE_ENABLED);
        return;
    }

#endif
    /* Interrupt driven */
    hw_uart_enable_rx_int(uart, true);
}

static void hw_uart_irq_stop_receive(HW_UART_ID uart)
{
    UART_Data *ud = &uart_data[UARTIX(uart)];

    // Disable RX interrupt
    hw_uart_enable_rx_int(uart, false);

    ud->rx_len = ud->rx_ix;

    hw_uart_fire_callback(ud);
}

#if dg_configUART_RX_CIRCULAR_DMA
static void hw_uart_copy_dma_rx_to_user_buffer(HW_UART_ID uart)
{
    UART_Data *ud = &uart_data[UARTIX(uart)];

    uint16_t cur_idx;
    uint16_t to_copy;
    hw_uart_rx_callback cb;

    ud->rx_dma_active = false;
    cb = ud->rx_cb;

    if (cb)
    {
        ud->rx_cb = NULL;
        /*
         * User callback was not fired, since rx_dma_active is false it will not
         * fire even if requested number of bytes was received when abort was initiated.
         */
        cur_idx = hw_dma_transfered_bytes(ud->rx_dma.channel_number);

        if (ud->rx_ix < ud->rx_len)
        {
            if (cur_idx < ud->rx_dma_head)
            {
                cur_idx += ud->rx_dma_buf_size;
            }

            to_copy = cur_idx - ud->rx_dma_head;

            if (to_copy >= ud->rx_len - ud->rx_ix)
            {
                to_copy = ud->rx_len - ud->rx_ix;
            }
        }
    }
    else
    {
        /*
         * Callback already fired, circular buffer holds enough data.
         */
        to_copy = ud->rx_len - ud->rx_ix;
    }

    hw_uart_copy_rx_circular_dma_buffer(uart, ud->rx_buffer + ud->rx_ix, to_copy);
    ud->rx_ix += to_copy;
    ud->rx_len = ud->rx_ix;

    if (cb)
    {
        cb(ud->rx_user_data, ud->rx_len);
    }
}
#endif

uint16_t hw_uart_abort_receive(HW_UART_ID uart)
{
    UART_Data *ud = &uart_data[UARTIX(uart)];

#if HW_UART_USE_DMA_SUPPORT

    if (ud->rx_dma.channel_number != HW_DMA_CHANNEL_INVALID)
    {
#if dg_configUART_RX_CIRCULAR_DMA

        if (ud->rx_dma_buf_size > 0)
        {
            hw_uart_copy_dma_rx_to_user_buffer(uart);
            return ud->rx_ix;
        }

#else
        /* No DMA circular buffer, stop DMA */
        hw_dma_channel_stop(ud->rx_dma.channel_number);
#endif
    }
    else
#endif
        hw_uart_irq_stop_receive(uart);

    return ud->rx_ix;
}

uint16_t hw_uart_peek_received(HW_UART_ID uart)
{
    UART_Data *ud = &uart_data[UARTIX(uart)];

#if HW_UART_USE_DMA_SUPPORT

    if (ud->rx_dma.channel_number != HW_DMA_CHANNEL_INVALID)
    {
        ud->rx_ix = hw_dma_transfered_bytes(ud->rx_dma.channel_number);
    }

#endif
    return ud->rx_ix;
}

//============== Interrupt handling ============================================

static inline void hw_uart_tx_isr(HW_UART_ID uart)
{
    UART_Data *ud = UARTDATA(uart);

    while (ud->tx_ix < ud->tx_len)
    {
        if (ud->tx_fifo_on)
        {
            if (!hw_uart_transmit_fifo_not_full(uart))
            {
                break;
            }
        }
        else if (!hw_uart_thr_empty_getf(uart))
        {
            break;
        }

        hw_uart_txdata_setf(uart, ud->tx_buffer[ud->tx_ix++]);
    }

    // Everything sent?
    if (ud->tx_ix >= ud->tx_len)
    {
        hw_uart_tx_callback cb = ud->tx_cb;
        // Disable TX interrupts
        // They can be re-enabled in user callback
        uint16_t ier_dlh_reg = UBA(uart)->UART2_IER_DLH_REG;
        ier_dlh_reg &= ~((1 << UART_UART_IER_DLH_REG_ETBEI_dlh1_Pos) | (1 << UART_UART_IER_DLH_REG_PTIME_dlh7_Pos));
        UBA(uart)->UART2_IER_DLH_REG = ier_dlh_reg;
        ud->tx_cb = NULL;

        if (cb)
        {
            cb(ud->tx_user_data, ud->tx_len);
        }
    }
}

static inline void hw_uart_rx_isr(HW_UART_ID uart)
{
    UART_Data *ud = UARTDATA(uart);

    if (SOFTWARE_FIFO_PRESENT(ud))
    {
#if dg_configUART_SOFTWARE_FIFO

        for (;;)
        {
            fifo_ptr_t wr_ptr = ud->rx_soft_fifo_wr_ptr + 1;

            if (wr_ptr >= ud->rx_soft_fifo_size)
            {
                wr_ptr = 0;
            }

            if (wr_ptr == ud->rx_soft_fifo_rd_ptr)
            {
                /* Software FIFO full, disable interrupt since no one is reading */
                hw_uart_enable_rx_int(uart, false);
                return;
            }

            if (!hw_uart_is_data_ready(uart))
            {
                break;
            }

            ud->rx_soft_fifo[ud->rx_soft_fifo_wr_ptr] = hw_uart_rxdata_getf(uart);

            /*
             * Application read is in progress. Copy data from software FIFO to
             * user provided buffer.
             */
            if (ud->rx_ix < ud->rx_len)
            {
                ud->rx_buffer[ud->rx_ix++] = ud->rx_soft_fifo[ud->rx_soft_fifo_wr_ptr];
                /*
                 * When application read is in progress, rx_ix < rx_len
                 * This interrupt is enabled only if all data was already copied from
                 * FIFO to user buffer. It is safe to modify rx_soft_fifo_rd_ptr.
                 */
                ud->rx_soft_fifo_rd_ptr = wr_ptr;
            }

            ud->rx_soft_fifo_wr_ptr = wr_ptr;
        }

#endif
    }
    else
    {
        while (ud->rx_ix < ud->rx_len)
        {
            if (hw_uart_is_data_ready(uart))
            {
                ud->rx_buffer[ud->rx_ix++] = hw_uart_rxdata_getf(uart);
            }
            else
            {
                break;
            }
        }
    }

    // Everything read?
    if (ud->rx_len > 0 && ud->rx_ix >= ud->rx_len)
    {
        // Disable RX interrupts, fire callback if present
        hw_uart_irq_stop_receive(uart);
    }

}

static inline void hw_uart_rx_timeout_isr(HW_UART_ID uart)
{
    UART_Data *ud = UARTDATA(uart);

    hw_uart_rx_isr(uart);

    /*
     * Not everything was received yet, disable interrupt anyway since
     * some data was received.
     */
    if (ud->rx_ix > 0 && ud->rx_ix < ud->rx_len)
    {
        // Disable RX interrupts fire callback if present
        hw_uart_irq_stop_receive(uart);
    }
}

void UART_Interrupt_Handler(HW_UART_ID uart)
{
    HW_UART_INT int_id;

    for (;;)
    {
        int_id = hw_uart_get_interrupt_id(uart);

        switch (int_id)
        {
        case HW_UART_INT_TIMEOUT:
            hw_uart_rx_timeout_isr(uart);
            break;

        case HW_UART_INT_MODEM_STAT:
            break;

        case HW_UART_INT_NO_INT_PEND:
            return;
            break;

        case HW_UART_INT_THR_EMPTY:
            hw_uart_tx_isr(uart);
            break;

        case HW_UART_INT_RECEIVED_AVAILABLE:
            hw_uart_rx_isr(uart);
            break;

        case HW_UART_INT_RECEIVE_LINE_STAT:
            break;

        case HW_UART_INT_BUSY_DETECTED:
#ifdef CONFIG_UART_IGNORE_BUSY_DETECT
            hw_uart_transmit_fifo_empty(uart);
#else
            /*
             * Stop here means that timing rules for access divisor latch were not
             * followed. See description of register RBR_THR_DLL.
             */
            __BKPT(0);
#endif
            break;
        }
    }
}

/**
 * \brief HW_UART1 Interrupt Handler
 *
 */
void UART_Handler(void)
{
    SEGGER_SYSTEMVIEW_ISR_ENTER();

#ifdef HW_UART_ENABLE_USER_ISR

    if (uart_data[UARTIX(HW_UART1)].user_isr)
    {
        uart_data[UARTIX(HW_UART1)].user_isr();
    }
    else
    {
#endif
        UART_Interrupt_Handler(HW_UART1);
#ifdef HW_UART_ENABLE_USER_ISR
    }

#endif

    SEGGER_SYSTEMVIEW_ISR_EXIT();
}

/**
 * \brief UART2 Interrupt Handler
 *
 */
void UART2_Handler(void)
{
    SEGGER_SYSTEMVIEW_ISR_ENTER();

#ifdef HW_UART_ENABLE_USER_ISR

    if (uart_data[UARTIX(HW_UART2)].user_isr)
    {
        uart_data[UARTIX(HW_UART2)].user_isr();
    }
    else
    {
#endif
        UART_Interrupt_Handler(HW_UART2);
#ifdef HW_UART_ENABLE_USER_ISR
    }

#endif

    SEGGER_SYSTEMVIEW_ISR_EXIT();
}

//==================== Configuration functions =================================

HW_UART_BAUDRATE hw_uart_baudrate_get(HW_UART_ID uart)
{
    uint32_t baud_rate;

    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Read baud rate low byte from DLL register
    baud_rate = (0xFF & UBA(uart)->UART2_RBR_THR_DLL_REG) << 8;
    // Read baud rate high byte from DLH register
    baud_rate += (0xFF & UBA(uart)->UART2_IER_DLH_REG) << 16;
    // Read baud rate fraction byte from DLF register
    baud_rate += 0xFF & UBA(uart)->UART2_DLF_REG;
    // Reset Divisor Latch Access Bit in Line Control Register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);

    return (HW_UART_BAUDRATE) baud_rate;
}

void hw_uart_baudrate_set(HW_UART_ID uart, HW_UART_BAUDRATE baud_rate)
{
    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Set fraction byte of baud rate
    UBA(uart)->UART2_DLF_REG = 0xFF & baud_rate;
    // Set low byte of baud rate
    UBA(uart)->UART2_RBR_THR_DLL_REG = 0xFF & (baud_rate >> 8);
    // Set high byte of baud rare
    UBA(uart)->UART2_IER_DLH_REG = 0xFF & (baud_rate >> 16);
    // Reset Divisor Latch Access Bit in LCR register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);
}

//=========================== FIFO control functions ===========================

uint8_t hw_uart_fifo_en_getf(HW_UART_ID uart)
{
    uint16_t fifo_enabled;

    /* Only UART2 has a FIFO */
    ASSERT_ERROR(uart == HW_UART2);

    fifo_enabled = (UBA(uart)->UART2_IIR_FCR_REG & 0x00C0); /* Bits[7:6] */

    switch (fifo_enabled)
    {
    case 0x00C0:
        return 1;

    case 0x0000:
        return 0;

    default:
        ASSERT_ERROR(0);
        return 255;     // To satisfy the compiler
    }
}

uint8_t hw_uart_tx_fifo_tr_lvl_getf(HW_UART_ID uart)
{
    /* Only UART2 has a FIFO */
    ASSERT_ERROR(uart == HW_UART2);

    return (UART2->UART2_STET_REG & HW_UART_REG_FIELD_MASK(2, STET, UART_SHADOW_TX_EMPTY_TRIGGER))
           >> HW_UART_REG_FIELD_POS(2, STET, UART_SHADOW_TX_EMPTY_TRIGGER);
}

//=========================== DMA control functions ============================

#if HW_UART_USE_DMA_SUPPORT

static void hw_uart_rx_dma_callback(void *user_data, uint16_t len)
{
    UART_Data *ud = user_data;
    hw_uart_rx_callback cb = ud->rx_cb;

    ud->rx_cb = NULL;
    ud->rx_ix += len;

    if (cb)
    {
        ud->rx_len = ud->rx_ix;
        hw_uart_enable_rx_int(UARTID(ud), SOFTWARE_FIFO_PRESENT(ud));
        cb(ud->rx_user_data, ud->rx_ix);
    }
}

static void hw_uart_tx_dma_callback(void *user_data, uint16_t len)
{
    UART_Data *ud = user_data;
    hw_uart_tx_callback cb = ud->tx_cb;

    ud->tx_cb = NULL;
    ud->tx_ix = len;

    if (cb)
    {
        cb(ud->tx_user_data, len);
    }
}

void hw_uart_set_dma_channels(HW_UART_ID uart, int8_t channel, HW_DMA_PRIO pri)
{
    UART_Data *ud = UARTDATA(uart);

    /* Only specific DMA channels (or -1 for no DMA) are allowed */
    ASSERT_ERROR(channel < 0 ||
                 channel == HW_DMA_CHANNEL_0 ||
                 channel == HW_DMA_CHANNEL_2 ||
                 channel == HW_DMA_CHANNEL_4 ||
                 channel == HW_DMA_CHANNEL_6 ||
                 channel == HW_DMA_CHANNEL_INVALID);

    if (channel < 0)
    {
        ud->use_dma = 0;
        ud->rx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
        ud->tx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
    }
    else
    {
        ud->use_dma = 1;

        ud->rx_dma.channel_number = channel;
        ud->rx_dma.bus_width = HW_DMA_BW_BYTE;
        ud->rx_dma.irq_enable = HW_DMA_IRQ_STATE_ENABLED;
        ud->rx_dma.dma_req_mux = UARTIX(uart) == 0 ? HW_DMA_TRIG_UART_RXTX :
                                 HW_DMA_TRIG_UART2_RXTX;
        ud->rx_dma.irq_nr_of_trans = 0;
        ud->rx_dma.a_inc = HW_DMA_AINC_FALSE;
        ud->rx_dma.b_inc = HW_DMA_BINC_TRUE;
        ud->rx_dma.circular = HW_DMA_MODE_NORMAL;
        ud->rx_dma.dma_prio = pri;
        ud->rx_dma.dma_idle = HW_DMA_IDLE_INTERRUPTING_MODE; /* Not used by the HW in this case */
        ud->rx_dma.dma_init = HW_DMA_INIT_AX_BX_AY_BY;
        ud->rx_dma.dreq_mode = HW_DMA_DREQ_TRIGGERED;
        ud->rx_dma.src_address = (uint32_t) &UBA(uart)->UART2_RBR_THR_DLL_REG;
        ud->rx_dma.dest_address = 0;  // Change during transmission
        ud->rx_dma.length = 0; // Change during transmission
        ud->rx_dma.callback = hw_uart_rx_dma_callback;
        ud->rx_dma.user_data = ud;

        ud->tx_dma.channel_number = channel + 1;
        ud->tx_dma.bus_width = HW_DMA_BW_BYTE;
        ud->tx_dma.irq_enable = HW_DMA_IRQ_STATE_ENABLED;
        ud->tx_dma.dma_req_mux = UARTIX(uart) == 0 ? HW_DMA_TRIG_UART_RXTX :
                                 HW_DMA_TRIG_UART2_RXTX;
        ud->tx_dma.irq_nr_of_trans = 0;
        ud->tx_dma.a_inc = HW_DMA_AINC_TRUE;
        ud->tx_dma.b_inc = HW_DMA_BINC_FALSE;
        ud->tx_dma.circular = HW_DMA_MODE_NORMAL;
        ud->tx_dma.dma_prio = pri;
        ud->tx_dma.dma_idle = HW_DMA_IDLE_INTERRUPTING_MODE; /* Not used by the HW in this case */
        ud->tx_dma.dma_init = HW_DMA_INIT_AX_BX_AY_BY;
        ud->tx_dma.dreq_mode = HW_DMA_DREQ_TRIGGERED;
        ud->tx_dma.src_address = 0; // Change during transmission
        ud->tx_dma.dest_address = (uint32_t) &UBA(uart)->UART2_RBR_THR_DLL_REG;
        ud->tx_dma.length = 0; // Change during transmission
        ud->tx_dma.callback = hw_uart_tx_dma_callback;
        ud->tx_dma.user_data = ud;
    }
}

void hw_uart_set_dma_channels_ex(HW_UART_ID uart, int8_t tx_channel, int8_t rx_channel, HW_DMA_PRIO pri)
{
    UART_Data *ud = UARTDATA(uart);

    /* Only specific DMA channels are allowed (or HW_DMA_CHANNEL_INVALID for no DMA) */
    ASSERT_ERROR(tx_channel >= HW_DMA_CHANNEL_0 &&
                 tx_channel <= HW_DMA_CHANNEL_INVALID);

    /* Only specific DMA channels are allowed (or HW_DMA_CHANNEL_INVALID for no DMA) */
    ASSERT_ERROR(rx_channel >= HW_DMA_CHANNEL_0 &&
                 rx_channel <= HW_DMA_CHANNEL_INVALID);

    if (tx_channel == HW_DMA_CHANNEL_INVALID && rx_channel == HW_DMA_CHANNEL_INVALID)
    {
        ud->use_dma = 0;
        ud->rx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
        ud->tx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
    }
    else
    {
        if (tx_channel != HW_DMA_CHANNEL_INVALID && rx_channel != HW_DMA_CHANNEL_INVALID) //not both invalid
        {
            ASSERT_ERROR(tx_channel != rx_channel);//not equal
            ASSERT_ERROR(tx_channel >> 1 == rx_channel >> 1); //on same pair
        }

        if (tx_channel != HW_DMA_CHANNEL_INVALID)
        {
            ASSERT_ERROR(tx_channel & 1);//odd number
        }

        if (rx_channel != HW_DMA_CHANNEL_INVALID)
        {
            ASSERT_ERROR((rx_channel & 1) == 0);//odd number
        }

        ud->use_dma = 1;

        ud->rx_dma.channel_number = rx_channel;
        ud->rx_dma.bus_width = HW_DMA_BW_BYTE;
        ud->rx_dma.irq_enable = HW_DMA_IRQ_STATE_ENABLED;
        ud->rx_dma.dma_req_mux = UARTIX(uart) == 0 ? HW_DMA_TRIG_UART_RXTX :
                                 HW_DMA_TRIG_UART2_RXTX;
        ud->rx_dma.irq_nr_of_trans = 0;
        ud->rx_dma.a_inc = HW_DMA_AINC_FALSE;
        ud->rx_dma.b_inc = HW_DMA_BINC_TRUE;
        ud->rx_dma.circular = HW_DMA_MODE_NORMAL;
        ud->rx_dma.dma_prio = pri;
        ud->rx_dma.dma_idle = HW_DMA_IDLE_INTERRUPTING_MODE; /* Not used by the HW in this case */
        ud->rx_dma.dma_init = HW_DMA_INIT_AX_BX_AY_BY;
        ud->rx_dma.dreq_mode = HW_DMA_DREQ_TRIGGERED;
        ud->rx_dma.src_address = (uint32_t) &UBA(uart)->UART2_RBR_THR_DLL_REG;
        ud->rx_dma.dest_address = 0;  // Change during transmission
        ud->rx_dma.length = 0; // Change during transmission
        ud->rx_dma.callback = hw_uart_rx_dma_callback;
        ud->rx_dma.user_data = ud;

        ud->tx_dma.channel_number = tx_channel;
        ud->tx_dma.bus_width = HW_DMA_BW_BYTE;
        ud->tx_dma.irq_enable = HW_DMA_IRQ_STATE_ENABLED;
        ud->tx_dma.dma_req_mux = UARTIX(uart) == 0 ? HW_DMA_TRIG_UART_RXTX :
                                 HW_DMA_TRIG_UART2_RXTX;
        ud->tx_dma.irq_nr_of_trans = 0;
        ud->tx_dma.a_inc = HW_DMA_AINC_TRUE;
        ud->tx_dma.b_inc = HW_DMA_BINC_FALSE;
        ud->tx_dma.circular = HW_DMA_MODE_NORMAL;
        ud->tx_dma.dma_prio = pri;
        ud->tx_dma.dma_idle = HW_DMA_IDLE_INTERRUPTING_MODE; /* Not used by the HW in this case */
        ud->tx_dma.dma_init = HW_DMA_INIT_AX_BX_AY_BY;
        ud->tx_dma.dreq_mode = HW_DMA_DREQ_TRIGGERED;
        ud->tx_dma.src_address = 0; // Change during transmission
        ud->tx_dma.dest_address = (uint32_t) &UBA(uart)->UART2_RBR_THR_DLL_REG;
        ud->tx_dma.length = 0; // Change during transmission
        ud->tx_dma.callback = hw_uart_tx_dma_callback;
        ud->tx_dma.user_data = ud;
    }
}

#if dg_configUART_RX_CIRCULAR_DMA

static void hw_uart_rx_circular_dma_callback(void *user_data, uint16_t len)
{
    UART_Data *ud = user_data;
    hw_uart_rx_callback cb = ud->rx_cb;

    if (!ud->rx_dma_active)
    {
        return;
    }

    ud->rx_cb = NULL;
    ud->rx_dma_active = false;

    if (cb)
    {
        cb(ud->rx_user_data, ud->rx_len);
    }
}

void hw_uart_enable_rx_circular_dma(HW_UART_ID uart)
{
    UART_Data *ud = UARTDATA(uart);

    ASSERT_ERROR(ud->rx_dma_buf_size > 0);

    hw_dma_channel_enable(ud->rx_dma.channel_number, HW_DMA_STATE_DISABLED);

    /* Need to reconfigure few things for circular operation... */
    ud->rx_dma.circular = HW_DMA_MODE_CIRCULAR;
    ud->rx_dma.dest_address = (uint32_t) ud->rx_dma_buf;
    ud->rx_dma.length = ud->rx_dma_buf_size;
    ud->rx_dma.callback = hw_uart_rx_circular_dma_callback;
    ud->rx_dma.user_data = ud;

    /* Reset DMA buffer read pointer */
    ud->rx_dma_head = 0;

    /* Start DMA now since it should be always-running */
    hw_uart_clear_dma_request(uart);
    hw_dma_channel_initialization(&ud->rx_dma);
    hw_dma_channel_enable(ud->rx_dma.channel_number, HW_DMA_STATE_ENABLED);
}

void hw_uart_copy_rx_circular_dma_buffer(HW_UART_ID uart, uint8_t *buf, uint16_t len)
{
    UART_Data *ud = UARTDATA(uart);

    ASSERT_ERROR(len < ud->rx_dma_buf_size);

    if (ud->rx_dma_head + len <= ud->rx_dma_buf_size)
    {
        memcpy(buf, &ud->rx_dma_buf[ud->rx_dma_head], len);
    }
    else
    {
        uint16_t chunk_len = ud->rx_dma_buf_size - ud->rx_dma_head;
        memcpy(buf, &ud->rx_dma_buf[ud->rx_dma_head], chunk_len);
        memcpy(buf + chunk_len, &ud->rx_dma_buf[0], len - chunk_len);
    }

    /* This should be protected so ISR does not try to read rx_dma_head while we update it */
    GLOBAL_INT_DISABLE();
    ud->rx_dma_head = (ud->rx_dma_head + len) % ud->rx_dma_buf_size;
    GLOBAL_INT_RESTORE();
}

#endif /* dg_configUART_RX_CIRCULAR_DMA */

#endif /* HW_UART_USE_DMA_SUPPORT */

//=========================== Line control functions ============================
void hw_uart_init_ex(HW_UART_ID uart, const uart_config_ex *uart_init)
{
    UART_Data *ud = UARTDATA(uart);

    /*
     * Read UART_USR_REG to clear any pending busy interrupt.
     */
    hw_uart_transmit_fifo_empty(uart);


    if (uart == HW_UART1)
    {
        // there is no FIFO for UART0 as yet
        ud->rx_fifo_on = 0;
        ud->tx_fifo_on = 0;
        hw_uart_disable_fifo(uart);
    }
    else
    {
        if (uart_init->use_fifo)
        {
            ud->rx_fifo_on = 1;
            ud->tx_fifo_on = 1;
            hw_uart_enable_fifo(uart);
            ud->rx_fifo_level = uart_init->rx_fifo_tr_lvl;
            hw_uart_rx_fifo_tr_lvl_setf(uart, uart_init->rx_fifo_tr_lvl);
            ud->tx_fifo_level = uart_init->tx_fifo_tr_lvl;
            hw_uart_tx_fifo_tr_lvl_setf(uart, uart_init->tx_fifo_tr_lvl);
        }
        else
        {
            ud->rx_fifo_on = 0;
            ud->tx_fifo_on = 0;
            hw_uart_disable_fifo(uart);
        }
    }

    GLOBAL_INT_DISABLE();
    REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
    GLOBAL_INT_RESTORE();

    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Set fraction byte of baud rate
    UBA(uart)->UART2_DLF_REG = 0xFF & uart_init->baud_rate;
    // Set low byte of baud rate
    UBA(uart)->UART2_RBR_THR_DLL_REG = 0xFF & (uart_init->baud_rate >> 8);
    // Set high byte of baud rate
    UBA(uart)->UART2_IER_DLH_REG = 0xFF & (uart_init->baud_rate >> 16);
    // Reset Divisor Latch Access Bit in LCR register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);
    // Set Parity
    UBA(uart)->UART2_LCR_REG = (uart_init->parity) << 3;
    // Set Data Bits
    HW_UART_REG_SETF(uart, LCR, UART_DLS, uart_init->data);
    // Set Stop Bits
    HW_UART_REG_SETF(uart, LCR, UART_STOP, uart_init->stop);
    // Set Auto flow control
    HW_UART_REG_SETF(uart, MCR, UART_AFCE, uart_init->auto_flow_control);
    HW_UART_REG_SETF(uart, MCR, UART_RTS, uart_init->auto_flow_control);
    ud->tx_cb = NULL;
    ud->rx_cb = NULL;
    ud->rx_len = 0;
    ud->tx_len = 0;
    ud->use_dma = 0;
    ud->rx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
    ud->tx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
#if HW_UART_USE_DMA_SUPPORT

    if (uart_init->use_dma)
    {
        hw_uart_set_dma_channels_ex(uart, uart_init->tx_dma_channel, uart_init->rx_dma_channel, HW_DMA_PRIO_2);
    }

#endif
}

void hw_uart_reinit_ex(HW_UART_ID uart, const uart_config_ex *uart_init)
{
    UART_Data *ud = UARTDATA(uart);

    GLOBAL_INT_DISABLE();
    REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
    GLOBAL_INT_RESTORE();

    /*
     * Read UART_USR_REG to clear any pending busy interrupt.
     */
    hw_uart_transmit_fifo_empty(uart);

    if (uart == HW_UART2)
    {
        if (uart_init->use_fifo)
        {
            hw_uart_enable_fifo(uart);
            hw_uart_rx_fifo_tr_lvl_setf(uart, uart_init->rx_fifo_tr_lvl);
            hw_uart_tx_fifo_tr_lvl_setf(uart, uart_init->tx_fifo_tr_lvl);
        }
        else
        {
            hw_uart_disable_fifo(uart);
        }
    }

    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Set fraction byte of baud rate
    UBA(uart)->UART2_DLF_REG = 0xFF & uart_init->baud_rate;
    // Set low byte of baud rate
    UBA(uart)->UART2_RBR_THR_DLL_REG = 0xFF & (uart_init->baud_rate >> 8);
    // Set high byte of baud rare
    UBA(uart)->UART2_IER_DLH_REG = 0xFF & (uart_init->baud_rate >> 16);
    // Reset Divisor Latch Access Bit in LCR register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);
    // Set Parity
    UBA(uart)->UART2_LCR_REG = (uart_init->parity) << 3;
    // Set Data Bits
    HW_UART_REG_SETF(uart, LCR, UART_DLS, uart_init->data);
    // Set Stop Bits
    HW_UART_REG_SETF(uart, LCR, UART_STOP, uart_init->stop);
    // Set Auto flow control
    HW_UART_REG_SETF(uart, MCR, UART_AFCE, uart_init->auto_flow_control);
    HW_UART_REG_SETF(uart, MCR, UART_RTS, uart_init->auto_flow_control);

    if (ud->rx_cb && ud->rx_len != ud->rx_ix)
    {
        if (ud->rx_len > 1 && uart_init->use_dma && uart_init->rx_dma_channel != HW_DMA_CHANNEL_INVALID)
        {
        }
        else
        {
            // Interrupt driven
            hw_uart_enable_rx_int(uart, true);
        }
    }
}

void hw_uart_init(HW_UART_ID uart, const uart_config *uart_init)
{
    UART_Data *ud = UARTDATA(uart);

    /*
     * Read UART_USR_REG to clear any pending busy interrupt.
     */
    hw_uart_transmit_fifo_empty(uart);


    if (uart == HW_UART1)
    {
        // there is no FIFO for UART0 as yet
        ud->rx_fifo_on = 0;
        ud->tx_fifo_on = 0;
        hw_uart_disable_fifo(uart);
    }
    else
    {
        if (uart_init->use_fifo)
        {
            ud->rx_fifo_on = 1;
            ud->tx_fifo_on = 1;
            hw_uart_enable_fifo(uart);
            hw_uart_rx_fifo_tr_lvl_setf(uart, 0);
            hw_uart_tx_fifo_tr_lvl_setf(uart, 0);
        }
        else
        {
            ud->rx_fifo_on = 0;
            ud->tx_fifo_on = 0;
            hw_uart_disable_fifo(uart);
        }
    }

    GLOBAL_INT_DISABLE();
    REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
    GLOBAL_INT_RESTORE();

    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Set fraction byte of baud rate
    UBA(uart)->UART2_DLF_REG = 0xFF & uart_init->baud_rate;
    // Set low byte of baud rate
    UBA(uart)->UART2_RBR_THR_DLL_REG = 0xFF & (uart_init->baud_rate >> 8);
    // Set high byte of baud rate
    UBA(uart)->UART2_IER_DLH_REG = 0xFF & (uart_init->baud_rate >> 16);
    // Reset Divisor Latch Access Bit in LCR register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);
    // Set Parity
    UBA(uart)->UART2_LCR_REG = (uart_init->parity) << 3;
    // Set Data Bits
    HW_UART_REG_SETF(uart, LCR, UART_DLS, uart_init->data);
    // Set Stop Bits
    HW_UART_REG_SETF(uart, LCR, UART_STOP, uart_init->stop);
    // Set Auto flow control
    HW_UART_REG_SETF(uart, MCR, UART_AFCE, uart_init->auto_flow_control);
    HW_UART_REG_SETF(uart, MCR, UART_RTS, uart_init->auto_flow_control);
    ud->tx_cb = NULL;
    ud->rx_cb = NULL;
    ud->rx_len = 0;
    ud->tx_len = 0;
    ud->use_dma = 0;
    ud->rx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
    ud->tx_dma.channel_number = HW_DMA_CHANNEL_INVALID;
#if HW_UART_USE_DMA_SUPPORT

    if (uart_init->use_dma)
    {
        hw_uart_set_dma_channels_ex(uart, uart_init->tx_dma_channel, uart_init->rx_dma_channel, HW_DMA_PRIO_2);
    }

#endif
}

void hw_uart_reinit(HW_UART_ID uart, const uart_config *uart_init)
{
    UART_Data *ud = UARTDATA(uart);

    GLOBAL_INT_DISABLE();
    REG_SET_BIT(CRG_PER, CLK_PER_REG, UART_ENABLE);
    GLOBAL_INT_RESTORE();

    /*
     * Read UART_USR_REG to clear any pending busy interrupt.
     */
    hw_uart_transmit_fifo_empty(uart);

    if (uart == HW_UART2)
    {
        if (uart_init->use_fifo)
        {
            hw_uart_enable_fifo(uart);
            hw_uart_rx_fifo_tr_lvl_setf(uart, 0);
            hw_uart_tx_fifo_tr_lvl_setf(uart, 0);
        }
        else
        {
            hw_uart_disable_fifo(uart);
        }
    }

    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Set fraction byte of baud rate
    UBA(uart)->UART2_DLF_REG = 0xFF & uart_init->baud_rate;
    // Set low byte of baud rate
    UBA(uart)->UART2_RBR_THR_DLL_REG = 0xFF & (uart_init->baud_rate >> 8);
    // Set high byte of baud rare
    UBA(uart)->UART2_IER_DLH_REG = 0xFF & (uart_init->baud_rate >> 16);
    // Reset Divisor Latch Access Bit in LCR register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);
    // Set Parity
    UBA(uart)->UART2_LCR_REG = (uart_init->parity) << 3;
    // Set Data Bits
    HW_UART_REG_SETF(uart, LCR, UART_DLS, uart_init->data);
    // Set Stop Bits
    HW_UART_REG_SETF(uart, LCR, UART_STOP, uart_init->stop);
    // Set Auto flow control
    HW_UART_REG_SETF(uart, MCR, UART_AFCE, uart_init->auto_flow_control);
    HW_UART_REG_SETF(uart, MCR, UART_RTS, uart_init->auto_flow_control);

    if (ud->rx_cb && ud->rx_len != ud->rx_ix)
    {
        if (ud->rx_len > 1 && uart_init->use_dma && uart_init->rx_dma_channel != HW_DMA_CHANNEL_INVALID)
        {
        }
        else
        {
            // Interrupt driven
            hw_uart_enable_rx_int(uart, true);
        }
    }
}

void hw_uart_cfg_get(HW_UART_ID uart, uart_config *uart_cfg)
{
#if HW_UART_USE_DMA_SUPPORT
    UART_Data *ud = UARTDATA(uart);
#endif

    // Set Divisor Latch Access Bit in LCR register to access DLL & DLH registers
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 1);
    // Read baud rate low byte from DLL register
    uart_cfg->baud_rate = (0xFF & UBA(uart)->UART2_RBR_THR_DLL_REG) << 8;
    // Read baud rate high byte from DLH register
    uart_cfg->baud_rate += (0xFF & UBA(uart)->UART2_IER_DLH_REG) << 16;
    // Read baud rate fraction byte from DLF register
    uart_cfg->baud_rate += 0xFF & UBA(uart)->UART2_DLF_REG;
    // Reset Divisor Latch Access Bit in Line Control Register
    HW_UART_REG_SETF(uart, LCR, UART_DLAB, 0);

    // Fill-in the rest of the configuration settings
    uart_cfg->data = HW_UART_REG_GETF(uart, LCR, UART_DLS);
    uart_cfg->parity = UBA(uart)->UART2_LCR_REG;
    uart_cfg->parity &= ((1 << UART_UART_LCR_REG_UART_EPS_Pos) | (1 << UART_UART_LCR_REG_UART_PEN_Pos));
    uart_cfg->parity = uart_cfg->parity >> UART_UART_LCR_REG_UART_PEN_Pos;
    uart_cfg->stop = HW_UART_REG_GETF(uart, LCR, UART_STOP);
#if HW_UART_USE_DMA_SUPPORT
    uart_cfg->tx_dma_channel = ud->tx_dma.channel_number;
    uart_cfg->rx_dma_channel = ud->rx_dma.channel_number;
    uart_cfg->use_dma = ud->use_dma;
#endif
    uart_cfg->auto_flow_control = hw_uart_afce_getf(uart);
}

//=========================== Modem control functions ==========================

uint8_t hw_uart_sire_getf(HW_UART_ID uart)
{
    // Get the value of the SIRE bit from the Modem Control Register
    return (uint8_t) HW_UART_REG_GETF(uart, MCR, UART_SIRE);
}

void hw_uart_sire_setf(HW_UART_ID uart, uint8_t sire)
{
    // Set the value of the SIRE bit in the Modem Control Register
    HW_UART_REG_SETF(uart, MCR, UART_SIRE,  sire);
}

uint8_t hw_uart_afce_getf(HW_UART_ID uart)
{
    // Get the value of the AFCE bit from the Modem Control Register
    return 0xFF & HW_UART_REG_GETF(uart, MCR, UART_AFCE);
}

void hw_uart_afce_setf(HW_UART_ID uart, uint8_t afce)
{
    // Set the value of the AFCE bit in the Modem Control Register
    HW_UART_REG_SETF(uart, MCR, UART_AFCE, afce);
}

uint8_t hw_uart_loopback_getf(HW_UART_ID uart)
{
    // Get the value of the loop back (LB) bit from the Modem Control Register
    return (uint8_t) HW_UART_REG_GETF(uart, MCR, UART_LB);
}

void hw_uart_loopback_setf(HW_UART_ID uart, uint8_t lb)
{
    // Set the value of the loop back (LB) bit in the Modem Control Register
    HW_UART_REG_SETF(uart, MCR, UART_LB, lb);
}

uint8_t hw_uart_rts_getf(HW_UART_ID uart)
{
    // Get the value of the RTS bit from the Modem Control Register
    return 0xFF & HW_UART_REG_GETF(uart, MCR, UART_RTS);
}

void hw_uart_rts_setf(HW_UART_ID uart, uint8_t rtsn)
{
    // Set the value of the RTS bit in the Modem Control Register
    HW_UART_REG_SETF(uart, MCR, UART_RTS, rtsn);
}

//=========================== Line status functions ============================

uint8_t hw_uart_rx_fifo_err_getf(HW_UART_ID uart)
{
    /* Only UART2 has a FIFO */
    ASSERT_ERROR(uart == HW_UART2);
    // Get Receiver FIFO Error bit
    return (uint8_t) HW_UART_REG_GETF(uart, LSR, UART_RFE);
}

uint8_t hw_uart_is_tx_fifo_empty(HW_UART_ID uart)
{
    // Get Transmitter Empty bit from Line Status Register
    return HW_UART_REG_GETF(uart, LSR, UART_TEMT) != 0;
}

uint8_t hw_uart_thr_empty_getf(HW_UART_ID uart)
{
    // Get Transmit Holding Register Empty bit value from Line Status Register
    return HW_UART_REG_GETF(uart, LSR, UART_THRE);
}

uint8_t hw_uart_break_int_getf(HW_UART_ID uart)
{
    // Get Break Interrupt bit value from Line Status Register
    return HW_UART_REG_GETF(uart, LSR, UART_BI);
}

uint8_t hw_uart_frame_err_getf(HW_UART_ID uart)
{
    // Get Framing Error bit value from Line Status Register
    return HW_UART_REG_GETF(uart, LSR, UART_FE);
}

uint8_t hw_uart_parity_err_getf(HW_UART_ID uart)
{
    // Get Parity Error bit value from Line Status Register
    return HW_UART_REG_GETF(uart, LSR, UART_PE);
}

uint8_t hw_uart_overrun_err_getf(HW_UART_ID uart)
{
    // Get Overrun Error bit value from Line Status Register
    return HW_UART_REG_GETF(uart, LSR, UART_OE);
}

//=========================== Modem status functions ===========================

uint8_t hw_uart_cts_getf(HW_UART_ID uart)
{
    // Get CTS bit from Modem Control Register
    return (uint8_t) HW_UART_REG_GETF(uart, MSR, UART_CTS);
}

uint8_t hw_uart_delta_cts_getf(HW_UART_ID uart)
{
    // Get the DCTS bit value from the Modem Control Register
    return (uint8_t) HW_UART_REG_GETF(uart, MSR, UART_DCTS);
}

bool hw_uart_tx_in_progress(HW_UART_ID uart)
{
    UART_Data *ud = UARTDATA(uart);
    return ud->tx_cb != NULL;
}

bool hw_uart_rx_in_progress(HW_UART_ID uart)
{
    UART_Data *ud = UARTDATA(uart);
    return ud->rx_cb != NULL;
}

#endif /* dg_configUSE_HW_UART */
/**
 * \}
 * \}
 * \}
 */
