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

#ifndef __HAL_UART_ADAPTER_H__
#define __HAL_UART_ADAPTER_H__

#if defined(FSL_RTOS_FREE_RTOS)
#include "FreeRTOS.h"
#endif

/*!
 * @addtogroup UART_Adapter
 * @{
 */

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @brief Enable or disable UART adapter non-blocking mode (1 - enable, 0 - disable)
 * 
 * When defined DEBUG_CONSOLE_TRANSFER_NON_BLOCKING and the interrupt of the UART peripheral with 
 * setting instance is not routed to interrupt controller directly, the enablement and priority of 
 * the peripheral interrupt are not configured by UART adapter. 
 * Please configure the interrupt in the application layer. Such as, if the interrupt of UART peripheral routes to INTMUX,
 * please call function INTMUX_EnableInterrupt of INTMUX to enable the interrupt of the instance.
 */
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
#define UART_ADAPTER_NON_BLOCKING_MODE (1U)
#else
#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
#define UART_ADAPTER_NON_BLOCKING_MODE (0U)
#else
#define UART_ADAPTER_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE
#endif
#endif

#if defined(__GIC_PRIO_BITS)
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (25U)
#endif
#else
#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#endif
#else
/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
 * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
 * priority is 3 (2^2 - 1). So, the default value is 3.
 */
#ifndef HAL_UART_ISR_PRIORITY
#define HAL_UART_ISR_PRIORITY (3U)
#endif
#endif
#endif

#ifndef HAL_UART_ADAPTER_LOWPOWER
#define HAL_UART_ADAPTER_LOWPOWER (0U)
#endif /* HAL_UART_ADAPTER_LOWPOWER */

/*! @brief Definition of uart adapter handle size. */
#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#define HAL_UART_HANDLE_SIZE (90U + HAL_UART_ADAPTER_LOWPOWER * 16U)
#else
#define HAL_UART_HANDLE_SIZE (4U + HAL_UART_ADAPTER_LOWPOWER * 16U)
#endif

/*!
 * @brief Defines the uart handle
 *
 * This macro is used to define a 4 byte aligned uart handle.
 * Then use "(hal_uart_handle_t)name" to get the uart handle.
 *
 * The macro should be global and could be optional. You could also define uart handle by yourself.
 *
 * This is an example,
 * @code
 * UART_HANDLE_DEFINE(uartHandle);
 * @endcode
 *
 * @param name The name string of the uart handle.
 */
#define UART_HANDLE_DEFINE(name) uint32_t name[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]

/*! @brief Whether enable transactional function of the UART. (0 - disable, 1 - enable) */
#ifndef HAL_UART_TRANSFER_MODE
#define HAL_UART_TRANSFER_MODE (0U)
#endif

/*! @brief The handle of uart adapter. */
typedef void *hal_uart_handle_t;

/*! @brief UART status */
typedef enum _hal_uart_status
{
    kStatus_HAL_UartSuccess = kStatus_Success,                       /*!< Successfully */
    kStatus_HAL_UartTxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 1), /*!< TX busy */
    kStatus_HAL_UartRxBusy  = MAKE_STATUS(kStatusGroup_HAL_UART, 2), /*!< RX busy */
    kStatus_HAL_UartTxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 3), /*!< HAL UART transmitter is idle. */
    kStatus_HAL_UartRxIdle  = MAKE_STATUS(kStatusGroup_HAL_UART, 4), /*!< HAL UART receiver is idle */
    kStatus_HAL_UartBaudrateNotSupport =
        MAKE_STATUS(kStatusGroup_HAL_UART, 5), /*!< Baudrate is not support in current clock source */
    kStatus_HAL_UartProtocolError = MAKE_STATUS(
        kStatusGroup_HAL_UART,
        6),                                                        /*!< Error occurs for Noise, Framing, Parity, etc.
                                                                        For transactional transfer, The up layer needs to abort the transfer and then starts again */
    kStatus_HAL_UartError = MAKE_STATUS(kStatusGroup_HAL_UART, 7), /*!< Error occurs on HAL UART */
} hal_uart_status_t;

/*! @brief UART parity mode. */
typedef enum _hal_uart_parity_mode
{
    kHAL_UartParityDisabled = 0x0U, /*!< Parity disabled */
    kHAL_UartParityEven     = 0x1U, /*!< Parity even enabled */
    kHAL_UartParityOdd      = 0x2U, /*!< Parity odd enabled */
} hal_uart_parity_mode_t;

/*! @brief UART stop bit count. */
typedef enum _hal_uart_stop_bit_count
{
    kHAL_UartOneStopBit = 0U, /*!< One stop bit */
    kHAL_UartTwoStopBit = 1U, /*!< Two stop bits */
} hal_uart_stop_bit_count_t;

/*! @brief UART configuration structure. */
typedef struct _hal_uart_config
{
    uint32_t srcClock_Hz;                   /*!< Source clock */
    uint32_t baudRate_Bps;                  /*!< Baud rate  */
    hal_uart_parity_mode_t parityMode;      /*!< Parity mode, disabled (default), even, odd */
    hal_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
    uint8_t enableRx;                       /*!< Enable RX */
    uint8_t enableTx;                       /*!< Enable TX */
    uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information please refer to the
                           SOC corresponding RM.
                           Invalid instance value will cause initialization failure. */
} hal_uart_config_t;

/*! @brief UART transfer callback function. */
typedef void (*hal_uart_transfer_callback_t)(hal_uart_handle_t handle, hal_uart_status_t status, void *callbackParam);

/*! @brief UART transfer structure. */
typedef struct _hal_uart_transfer
{
    uint8_t *data;   /*!< The buffer of data to be transfer.*/
    size_t dataSize; /*!< The byte count to be transfer. */
} hal_uart_transfer_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */

/*!
 * @name Initialization and deinitialization
 * @{
 */

/*!
 * @brief Initializes a UART instance with the UART handle and the user configuration structure.
 *
 * This function configures the UART module with user-defined settings. The user can configure the configuration
 * structure. The parameter handle is a pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by
 * the caller. Example below shows how to use this API to configure the UART.
 *  @code
 *   UART_HANDLE_DEFINE(g_UartHandle);
 *   hal_uart_config_t config;
 *   config.srcClock_Hz = 48000000;
 *   config.baudRate_Bps = 115200U;
 *   config.parityMode = kHAL_UartParityDisabled;
 *   config.stopBitCount = kHAL_UartOneStopBit;
 *   config.enableRx = 1;
 *   config.enableTx = 1;
 *   config.instance = 0;
 *   HAL_UartInit((hal_uart_handle_t)g_UartHandle, &config);
 *  @endcode
 *
 * @param handle Pointer to point to a memory space of size #HAL_UART_HANDLE_SIZE allocated by the caller.
 * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
 * You can define the handle in the following two ways:
 * #UART_HANDLE_DEFINE(handle);
 * or
 * uint32_t handle[((HAL_UART_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
 * @param config Pointer to user-defined configuration structure.
 * @retval kStatus_HAL_UartBaudrateNotSupport Baudrate is not support in current clock source.
 * @retval kStatus_HAL_UartSuccess UART initialization succeed
 */
hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, hal_uart_config_t *config);

/*!
 * @brief Deinitializes a UART instance.
 *
 * This function waits for TX complete, disables TX and RX, and disables the UART clock.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_HAL_UartSuccess UART de-initialization succeed
 */
hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle);

/*! @}*/

/*!
 * @name Blocking bus Operations
 * @{
 */

/*!
 * @brief Reads RX data register using a blocking method.
 *
 * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
 * have data, and reads data from the RX register.
 *
 * @note The function #HAL_UartReceiveBlocking and the function HAL_UartTransferReceiveNonBlocking
 * cannot be used at the same time.
 * And, the function HAL_UartTransferAbortReceive cannot be used to abort the transmission of this function.
 *
 * @param handle UART handle pointer.
 * @param data Start address of the buffer to store the received data.
 * @param length Size of the buffer.
 * @retval kStatus_HAL_UartError An error occurred while receiving data.
 * @retval kStatus_HAL_UartParityError A parity error occurred while receiving data.
 * @retval kStatus_HAL_UartSuccess Successfully received all data.
 */
hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);

/*!
 * @brief Writes to the TX register using a blocking method.
 *
 * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
 * to have room and writes data to the TX buffer.
 *
 * @note The function #HAL_UartSendBlocking and the function HAL_UartTransferSendNonBlocking
 * cannot be used at the same time.
 * And, the function HAL_UartTransferAbortSend cannot be used to abort the transmission of this function.
 *
 * @param handle UART handle pointer.
 * @param data Start address of the data to write.
 * @param length Size of the data to write.
 * @retval kStatus_HAL_UartSuccess Successfully sent all data.
 */
hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length);

/*! @}*/

#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U))

/*!
 * @name Transactional
 * @note The transactional API and the functional API cannot be used at the same time. The macro
 * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
 * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
 * @{
 */

/*!
 * @brief Installs a callback and callback parameter.
 *
 * This function is used to install the callback and callback parameter for UART module.
 * When any status of the UART changed, the driver will notify the upper layer by the installed callback
 * function. And the status is also passed as status parameter when the callback is called.
 *
 * @param handle UART handle pointer.
 * @param callback The callback function.
 * @param callbackParam The parameter of the callback function.
 * @retval kStatus_HAL_UartSuccess Successfully install the callback.
 */
hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle,
                                                  hal_uart_transfer_callback_t callback,
                                                  void *callbackParam);

/*!
 * @brief Receives a buffer of data using an interrupt method.
 *
 * This function receives data using an interrupt method. This is a non-blocking function, which
 * returns directly without waiting for all data to be received.
 * The receive request is saved by the UART driver.
 * When the new data arrives, the receive request is serviced first.
 * When all data is received, the UART driver notifies the upper layer
 * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
 *
 * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartTransferReceiveNonBlocking
 * cannot be used at the same time.
 *
 * @param handle UART handle pointer.
 * @param transfer UART transfer structure, see #hal_uart_transfer_t.
 * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
 * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
 * @retval kStatus_HAL_UartError An error occurred.
 */
hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);

/*!
 * @brief Transmits a buffer of data using the interrupt method.
 *
 * This function sends data using an interrupt method. This is a non-blocking function, which
 * returns directly without waiting for all data to be written to the TX register. When
 * all data is written to the TX register in the ISR, the UART driver calls the callback
 * function and passes the @ref kStatus_UART_TxIdle as status parameter.
 *
 * @note The function #HAL_UartSendBlocking and the function #HAL_UartTransferSendNonBlocking
 * cannot be used at the same time.
 *
 * @param handle UART handle pointer.
 * @param transfer UART transfer structure. See #hal_uart_transfer_t.
 * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
 * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
 * @retval kStatus_HAL_UartError An error occurred.
 */
hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer);

/*!
 * @brief Gets the number of bytes that have been received.
 *
 * This function gets the number of bytes that have been received.
 *
 * @param handle UART handle pointer.
 * @param count Receive bytes count.
 * @retval kStatus_HAL_UartError An error occurred.
 * @retval kStatus_Success Get successfully through the parameter \p count.
 */
hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count);

/*!
 * @brief Gets the number of bytes written to the UART TX register.
 *
 * This function gets the number of bytes written to the UART TX
 * register by using the interrupt method.
 *
 * @param handle UART handle pointer.
 * @param count Send bytes count.
 * @retval kStatus_HAL_UartError An error occurred.
 * @retval kStatus_Success Get successfully through the parameter \p count.
 */
hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count);

/*!
 * @brief Aborts the interrupt-driven data receiving.
 *
 * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
 * how many bytes are not received yet.
 *
 * @note The function #HAL_UartTransferAbortReceive cannot be used to abort the transmission of
 * the function #HAL_UartReceiveBlocking.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_Success Get successfully abort the receiving.
 */
hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle);

/*!
 * @brief Aborts the interrupt-driven data sending.
 *
 * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
 * how many bytes are not sent out.
 *
 * @note The function #HAL_UartTransferAbortSend cannot be used to abort the transmission of
 * the function #HAL_UartSendBlocking.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_Success Get successfully abort the sending.
 */
hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle);

/*! @}*/

#else

/*!
 * @name Functional API with non-blocking mode.
 * @note The functional API and the transactional API cannot be used at the same time. The macro
 * #HAL_UART_TRANSFER_MODE is used to set which one will be used. If #HAL_UART_TRANSFER_MODE is zero, the
 * functional API with non-blocking mode will be used. Otherwise, transactional API will be used.
 * @{
 */

/*!
 * @brief Installs a callback and callback parameter.
 *
 * This function is used to install the callback and callback parameter for UART module.
 * When non-blocking sending or receiving finished, the adapter will notify the upper layer by the installed callback
 * function. And the status is also passed as status parameter when the callback is called.
 *
 * @param handle UART handle pointer.
 * @param callback The callback function.
 * @param callbackParam The parameter of the callback function.
 * @retval kStatus_HAL_UartSuccess Successfully install the callback.
 */
hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle,
                                          hal_uart_transfer_callback_t callback,
                                          void *callbackParam);

/*!
 * @brief Receives a buffer of data using an interrupt method.
 *
 * This function receives data using an interrupt method. This is a non-blocking function, which
 * returns directly without waiting for all data to be received.
 * The receive request is saved by the UART adapter.
 * When the new data arrives, the receive request is serviced first.
 * When all data is received, the UART adapter notifies the upper layer
 * through a callback function and passes the status parameter @ref kStatus_UART_RxIdle.
 *
 * @note The function #HAL_UartReceiveBlocking and the function #HAL_UartReceiveNonBlocking
 * cannot be used at the same time.
 *
 * @param handle UART handle pointer.
 * @param data Start address of the data to write.
 * @param length Size of the data to write.
 * @retval kStatus_HAL_UartSuccess Successfully queue the transfer into transmit queue.
 * @retval kStatus_HAL_UartRxBusy Previous receive request is not finished.
 * @retval kStatus_HAL_UartError An error occurred.
 */
hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);

/*!
 * @brief Transmits a buffer of data using the interrupt method.
 *
 * This function sends data using an interrupt method. This is a non-blocking function, which
 * returns directly without waiting for all data to be written to the TX register. When
 * all data is written to the TX register in the ISR, the UART driver calls the callback
 * function and passes the @ref kStatus_UART_TxIdle as status parameter.
 *
 * @note The function #HAL_UartSendBlocking and the function #HAL_UartSendNonBlocking
 * cannot be used at the same time.
 *
 * @param handle UART handle pointer.
 * @param data Start address of the data to write.
 * @param length Size of the data to write.
 * @retval kStatus_HAL_UartSuccess Successfully start the data transmission.
 * @retval kStatus_HAL_UartTxBusy Previous transmission still not finished; data not all written to TX register yet.
 * @retval kStatus_HAL_UartError An error occurred.
 */
hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length);

/*!
 * @brief Gets the number of bytes that have been received.
 *
 * This function gets the number of bytes that have been received.
 *
 * @param handle UART handle pointer.
 * @param count Receive bytes count.
 * @retval kStatus_HAL_UartError An error occurred.
 * @retval kStatus_Success Get successfully through the parameter \p count.
 */
hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount);

/*!
 * @brief Gets the number of bytes written to the UART TX register.
 *
 * This function gets the number of bytes written to the UART TX
 * register by using the interrupt method.
 *
 * @param handle UART handle pointer.
 * @param count Send bytes count.
 * @retval kStatus_HAL_UartError An error occurred.
 * @retval kStatus_Success Get successfully through the parameter \p count.
 */
hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount);

/*!
 * @brief Aborts the interrupt-driven data receiving.
 *
 * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know
 * how many bytes are not received yet.
 *
 * @note The function #HAL_UartAbortReceive cannot be used to abort the transmission of
 * the function #HAL_UartReceiveBlocking.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_Success Get successfully abort the receiving.
 */
hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle);

/*!
 * @brief Aborts the interrupt-driven data sending.
 *
 * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out
 * how many bytes are not sent out.
 *
 * @note The function #HAL_UartAbortSend cannot be used to abort the transmission of
 * the function #HAL_UartSendBlocking.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_Success Get successfully abort the sending.
 */
hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle);

/*! @}*/

#endif
#endif

/*!
 * @brief Prepares to enter low power consumption.
 *
 * This function is used to prepare to enter low power consumption.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_HAL_UartSuccess Successful operation.
 * @retval kStatus_HAL_UartError An error occurred.
 */
hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle);

/*!
 * @brief Restores from low power consumption.
 *
 * This function is used to restore from low power consumption.
 *
 * @param handle UART handle pointer.
 * @retval kStatus_HAL_UartSuccess Successful operation.
 * @retval kStatus_HAL_UartError An error occurred.
 */
hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle);

#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U))
/*!
 * @brief UART IRQ handle function.
 *
 * This function handles the UART transmit and receive IRQ request.
 *
 * @param handle UART handle pointer.
 */
void HAL_UartIsrFunction(hal_uart_handle_t handle);
#endif

#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __HAL_UART_ADAPTER_H__ */
