/**
 *******************************************************************************
 * @file  console_dev.c
 * @brief This file provides firmware functions to manage console device.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2022-06-30       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2022-2023, Xiaohua Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by XHSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "console_conf.h"
#include "console_dev.h"

/**
 * @addtogroup Serial_Port_Console
 * @{
 */

/**
 * @defgroup Console_Device Console Device
 * @{
 */

/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/

/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/
/**
 * @defgroup Console_Device_Local_Variables Console Device Local Variables
 * @{
 */
static stc_console_dev_t *m_pstcConsoleDev;
/**
 * @}
 */

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 * @defgroup Console_Device_Global_Functions Console Device Global Functions
 * @{
 */

/**
 * @brief  Console device receive character.
 * @param  [in] cData               Character
 * @retval int32_t
 *           - OPCODE_OK:           Receive successfully.
 *           - OPCODE_ERR:          Receive unsuccessfully.
 * @note   Call this function when console device receive data.
 */
int32_t CONSOLE_Port_ReceiveChar(char cData)
{
    int32_t i32Ret = OPCODE_ERR;

    if (m_pstcConsoleDev != NULL) {
        if (1UL == RINGBUF_Write(m_pstcConsoleDev->pstcRxBuf, (uint8_t *)&cData, 1UL)) {
            i32Ret = OPCODE_OK;
        }
    }

    return i32Ret;
}

/**
 * @brief  Console device output character.
 * @param  [in] cData               Character
 * @retval int32_t:
 *           - OPCODE_ERR:          Not implementation.
 */
__WEAK int32_t CONSOLE_Port_SendChar(char cData)
{
    /* please, implement this function. */
    (void)cData;
    return OPCODE_ERR;
}

/**
 * @brief  Console device get character.
 * @param  None
 * @retval Character
 * @note   None character if return value is equal -1
 */
int32_t CONSOLE_GetChar(void)
{
    int32_t ch = -1;

    /* Get char from ringbuffer */
    if (m_pstcConsoleDev != NULL) {
        (void)RINGBUF_Read(m_pstcConsoleDev->pstcRxBuf, (uint8_t *)&ch, 1UL);
    }

    return ch;
}

/**
 * @brief  Output character.
 * @param  [in] pstcConsoleDev      Pointer to a @ref stc_console_dev_t structure
 * @param  [in] cData               character
 * @retval Transmit result
 */
int32_t CONSOLE_OutputChar(char cData)
{
    return CONSOLE_Port_SendChar(cData);
}

/**
 * @brief  Create console device instance.
 * @param  [in] u32RxBufSize        Console device buffer size
 * @retval Pointer of a @ref stc_console_dev_t structure
 */
stc_console_dev_t *CONSOLE_CreateDevice(uint32_t u32RxBufSize)
{
    stc_ring_buf_t *pstcRxBuf;
    stc_console_dev_t *pstcConsoleDev;

    if ((m_pstcConsoleDev == NULL) && (u32RxBufSize > 0UL)) {
        pstcConsoleDev = (stc_console_dev_t *)malloc(ALIGN_WORD(sizeof(stc_console_dev_t)) +
                                                     ALIGN_WORD(sizeof(stc_ring_buf_t)) + u32RxBufSize);
        if (pstcConsoleDev != NULL) {
            pstcRxBuf = (stc_ring_buf_t *)((char *)pstcConsoleDev +
                                           ALIGN_WORD(sizeof(stc_console_dev_t)));
            (void)RINGBUF_Init(pstcRxBuf, (uint8_t *)pstcRxBuf +
                               ALIGN_WORD(sizeof(stc_ring_buf_t)), u32RxBufSize);
            pstcConsoleDev->pstcRxBuf = pstcRxBuf;
            m_pstcConsoleDev = pstcConsoleDev;
        }
    }
    return m_pstcConsoleDev;
}

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
