/*
 * Copyright 2018 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_common.h"
#include "serial_manager.h"
#include "serial_port_internal.h"

#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
#include "uart.h"

#include "serial_port_uart.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#ifndef NDEBUG
#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U))
#undef assert
#define assert(n)
#endif
#endif

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#define SERIAL_PORT_UART_RECEIVE_DATA_LENGTH 1U

typedef struct _serial_uart_send_state
{
    serial_manager_callback_t callback;
    void *callbackParam;
    uint8_t *buffer;
    uint32_t length;
    volatile uint8_t busy;
} serial_uart_send_state_t;

typedef struct _serial_uart_recv_state
{
    serial_manager_callback_t callback;
    void *callbackParam;
    volatile uint8_t busy;
    uint8_t readBuffer[SERIAL_PORT_UART_RECEIVE_DATA_LENGTH];
} serial_uart_recv_state_t;
#endif

typedef struct _serial_uart_state
{
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
    serial_uart_send_state_t tx;
    serial_uart_recv_state_t rx;
#endif
    UART_HANDLE_DEFINE(usartHandleBuffer);
} serial_uart_state_t;

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
/* UART user callback */
static void Serial_UartCallback(hal_uart_handle_t handle, hal_uart_status_t status, void *userData)
{
    serial_uart_state_t *serialUartHandle;
    serial_manager_callback_message_t msg;
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    hal_uart_transfer_t transfer;
#endif

    if (NULL == userData)
    {
        return;
    }

    serialUartHandle = (serial_uart_state_t *)userData;

    if ((hal_uart_status_t)kStatus_HAL_UartRxIdle == status)
    {
        if ((NULL != serialUartHandle->rx.callback))
        {
            msg.buffer = &serialUartHandle->rx.readBuffer[0];
            msg.length = sizeof(serialUartHandle->rx.readBuffer);
            serialUartHandle->rx.callback(serialUartHandle->rx.callbackParam, &msg, kStatus_SerialManager_Success);
        }
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
        transfer.data     = &serialUartHandle->rx.readBuffer[0];
        transfer.dataSize = sizeof(serialUartHandle->rx.readBuffer);
        if (kStatus_HAL_UartSuccess ==
            HAL_UartTransferReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
#else
        if ((hal_uart_status_t)kStatus_HAL_UartSuccess ==
            HAL_UartReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
                                       &serialUartHandle->rx.readBuffer[0], sizeof(serialUartHandle->rx.readBuffer)))
#endif
        {
            serialUartHandle->rx.busy = 1U;
        }
        else
        {
            serialUartHandle->rx.busy = 0U;
        }
    }
    else if ((hal_uart_status_t)kStatus_HAL_UartTxIdle == status)
    {
        if (0U != serialUartHandle->tx.busy)
        {
            serialUartHandle->tx.busy = 0U;
            if ((NULL != serialUartHandle->tx.callback))
            {
                msg.buffer = serialUartHandle->tx.buffer;
                msg.length = serialUartHandle->tx.length;
                serialUartHandle->tx.callback(serialUartHandle->tx.callbackParam, &msg, kStatus_SerialManager_Success);
            }
        }
    }
    else
    {
    }
}
#endif

serial_manager_status_t Serial_UartInit(serial_handle_t serialHandle, void *serialConfig)
{
    serial_uart_state_t *serialUartHandle;
    serial_port_uart_config_t *uartConfig;
    hal_uart_config_t config;
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    hal_uart_transfer_t transfer;
#endif
#endif

    assert(serialConfig);
    assert(serialHandle);
    assert(SERIAL_PORT_UART_HANDLE_SIZE >= sizeof(serial_uart_state_t));

    uartConfig       = (serial_port_uart_config_t *)serialConfig;
    serialUartHandle = (serial_uart_state_t *)serialHandle;

    config.baudRate_Bps = uartConfig->baudRate;
    config.parityMode   = (hal_uart_parity_mode_t)uartConfig->parityMode;
    config.stopBitCount = (hal_uart_stop_bit_count_t)uartConfig->stopBitCount;
    config.enableRx     = uartConfig->enableRx;
    config.enableTx     = uartConfig->enableTx;
    config.srcClock_Hz  = uartConfig->clockRate;
    config.instance     = uartConfig->instance;

    if (kStatus_HAL_UartSuccess != HAL_UartInit(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &config))
    {
        return kStatus_SerialManager_Error;
    }

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))

#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    if (kStatus_HAL_UartSuccess !=
        HAL_UartTransferInstallCallback(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
                                        Serial_UartCallback, serialUartHandle))
#else
    if (kStatus_HAL_UartSuccess != HAL_UartInstallCallback(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
                                                           Serial_UartCallback, serialUartHandle))
#endif
    {
        return kStatus_SerialManager_Error;
    }

    if (0U != uartConfig->enableRx)
    {
        serialUartHandle->rx.busy = 1U;
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
        transfer.data     = &serialUartHandle->rx.readBuffer[0];
        transfer.dataSize = sizeof(serialUartHandle->rx.readBuffer);
        if (kStatus_HAL_UartSuccess !=
            HAL_UartTransferReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
#else
        if (kStatus_HAL_UartSuccess !=
            HAL_UartReceiveNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
                                       &serialUartHandle->rx.readBuffer[0], sizeof(serialUartHandle->rx.readBuffer)))
#endif
        {
            serialUartHandle->rx.busy = 0U;
            return kStatus_SerialManager_Error;
        }
    }
#endif

    return kStatus_SerialManager_Success;
}

serial_manager_status_t Serial_UartDeinit(serial_handle_t serialHandle)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    (void)HAL_UartTransferAbortReceive(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
#else
    (void)HAL_UartAbortReceive(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
#endif
#endif
    (void)HAL_UartDeinit(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
    serialUartHandle->tx.busy = 0U;
    serialUartHandle->rx.busy = 0U;
#endif

    return kStatus_SerialManager_Success;
}

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))

serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
{
    serial_uart_state_t *serialUartHandle;
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    hal_uart_transfer_t transfer;
#endif

    assert(serialHandle);
    assert(buffer);
    assert(length);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    if (0U != serialUartHandle->tx.busy)
    {
        return kStatus_SerialManager_Busy;
    }
    serialUartHandle->tx.busy = 1U;

    serialUartHandle->tx.buffer = buffer;
    serialUartHandle->tx.length = length;

#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    transfer.data     = buffer;
    transfer.dataSize = length;
    if (kStatus_HAL_UartSuccess !=
        HAL_UartTransferSendNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), &transfer))
#else
    if (kStatus_HAL_UartSuccess !=
        HAL_UartSendNonBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), buffer, length))
#endif
    {
        serialUartHandle->tx.busy = 0U;
        return kStatus_SerialManager_Error;
    }
    return kStatus_SerialManager_Success;
}

#else

serial_manager_status_t Serial_UartWrite(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);
    assert(buffer);
    assert(length);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    return (serial_manager_status_t)HAL_UartSendBlocking(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]),
                                                         buffer, length);
}

serial_manager_status_t Serial_UartRead(serial_handle_t serialHandle, uint8_t *buffer, uint32_t length)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);
    assert(buffer);
    assert(length);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    return (serial_manager_status_t)HAL_UartReceiveBlocking(
        ((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]), buffer, length);
}

#endif

#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
serial_manager_status_t Serial_UartCancelWrite(serial_handle_t serialHandle)
{
    serial_uart_state_t *serialUartHandle;
    serial_manager_callback_message_t msg;
    uint32_t primask;
    uint8_t isBusy = 0U;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    primask                   = DisableGlobalIRQ();
    isBusy                    = serialUartHandle->tx.busy;
    serialUartHandle->tx.busy = 0U;
    EnableGlobalIRQ(primask);

#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))
    (void)HAL_UartTransferAbortSend(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
#else
    (void)HAL_UartAbortSend(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
#endif
    if (0U != isBusy)
    {
        if ((NULL != serialUartHandle->tx.callback))
        {
            msg.buffer = serialUartHandle->tx.buffer;
            msg.length = serialUartHandle->tx.length;
            serialUartHandle->tx.callback(serialUartHandle->tx.callbackParam, &msg, kStatus_SerialManager_Canceled);
        }
    }
    return kStatus_SerialManager_Success;
}

serial_manager_status_t Serial_UartInstallTxCallback(serial_handle_t serialHandle,
                                                     serial_manager_callback_t callback,
                                                     void *callbackParam)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    serialUartHandle->tx.callback      = callback;
    serialUartHandle->tx.callbackParam = callbackParam;

    return kStatus_SerialManager_Success;
}

serial_manager_status_t Serial_UartInstallRxCallback(serial_handle_t serialHandle,
                                                     serial_manager_callback_t callback,
                                                     void *callbackParam)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    serialUartHandle->rx.callback      = callback;
    serialUartHandle->rx.callbackParam = callbackParam;

    return kStatus_SerialManager_Success;
}

void Serial_UartIsrFunction(serial_handle_t serialHandle)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    HAL_UartIsrFunction(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0]));
}
#endif

serial_manager_status_t Serial_UartEnterLowpower(serial_handle_t serialHandle)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    if (kStatus_HAL_UartSuccess != HAL_UartEnterLowpower(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0])))
    {
        return kStatus_SerialManager_Error;
    }

    return kStatus_SerialManager_Success;
}

serial_manager_status_t Serial_UartExitLowpower(serial_handle_t serialHandle)
{
    serial_uart_state_t *serialUartHandle;

    assert(serialHandle);

    serialUartHandle = (serial_uart_state_t *)serialHandle;

    if (kStatus_HAL_UartSuccess != HAL_UartExitLowpower(((hal_uart_handle_t)&serialUartHandle->usartHandleBuffer[0])))
    {
        return kStatus_SerialManager_Error;
    }

    return kStatus_SerialManager_Success;
}

#endif
