#include "sr_uart.h"

// 合宙
#include "platform_define.h"
#include "bsp_common.h"
#include "luat_uart.h"
#include "plat_config.h"

static BSP_UART_INFO_T _UartInfo[] =
    {
#ifdef SR_USE_UART0
        {
            .name = "uart0",
            .srId = SR_UART0,

        },
#endif

#ifdef SR_USE_UART1
        {
            .name = "uart1",
            .srId = SR_UART1,
        },
#endif

#ifdef SR_USE_UART2
        {
            .name = "uart2",
            .srId = SR_UART2,
        },
#endif

};

static SR_UART_DEV_T gs_uartDevice[sizeof(_UartInfo) / sizeof(_UartInfo[0])] = {0};

// 合宙默认的串口参数配置
#define LUAT_UART_CONFIG_DEFAULT \
    {                            \
        .id = 0,                 \
        .baud_rate = 115200,     \
        .data_bits = 8,          \
        .stop_bits = 1,          \
        .parity = 0,             \
        .bit_order = 0,          \
        .bufsz = 64,             \
        .pin485 = 0xffffffff,    \
        .delay = 0,              \
        .rx_level = 0,           \
    }

// 合宙的串口发送回调
static void luat_uart_sent_cb_default(int uart_id, uint32_t data_len)
{
    uint8_t devicenNum = sizeof(_UartInfo) / sizeof(BSP_UART_INFO_T);

    // 遍历注册的串口设备
    for (int i = 0; i < devicenNum; i++)
    {
        if (_UartInfo[i].srId == uart_id)
        {
            // 调用朝阳的回调
            if (gs_uartDevice[i].eventCb)
                gs_uartDevice[i].eventCb(&gs_uartDevice[i].parent, SR_UART_EVT_TC, data_len, gs_uartDevice[i].evtCbArgs);

            break;
        }
    }
}

// 合宙的串口接收回调
static void luat_uart_recv_cb_default(int uart_id, uint32_t data_len)
{
    uint8_t devicenNum = sizeof(_UartInfo) / sizeof(BSP_UART_INFO_T);

    // BSP_DEBUG_PRINTF("[BSP] uart(%d) recv len(%d)\n", uart_id, data_len);
    for (int i = 0; i < devicenNum; i++)
    {
        if (_UartInfo[i].srId == uart_id)
        {
            // 调用用户回调
            if (gs_uartDevice[i].eventCb)
            {
                // BSP_DEBUG_PRINTF("[BSP] user callback\r\n");
                gs_uartDevice[i].eventCb(&gs_uartDevice[i].parent, SR_UART_EVT_RXNE, data_len, gs_uartDevice[i].evtCbArgs);
            }
            break;
        }
    }
}

SR_DEVICE_T *BspUartOpen(SR_UART_ID_E uartId)
{
    uint8_t i;
    uint8_t devicenNum = sizeof(_UartInfo) / sizeof(BSP_UART_INFO_T);
    SR_UART_DEV_T *uartDev = SR_NULL;

    for (i = 0; i < devicenNum; i++)
    {
        if (uartId == _UartInfo[i].srId)
        {
            uartDev = &gs_uartDevice[i];
            uartDev->parent.deviceData = &_UartInfo[i]; // 绑定设备数据
            break;
        }
    }

    if (uartDev->parent.deviceData == SR_NULL)
        return SR_NULL;
    return (&(uartDev->parent));
}

extern void soc_uart0_set_log_off(uint8_t is_off);
int BspUartConfig(SR_DEVICE_T *dev, SR_UART_CFG_T *config)
{
    SR_ASSERT(dev!=SR_NULL);
    SR_ASSERT(config!=SR_NULL);
    SR_ASSERT(IS_UART_BAUD(config->baudrate));
    SR_ASSERT(IS_UART_PARITY(config->parity));
    SR_ASSERT(IS_UART_DATA_BIT(config->dataBits));
    SR_ASSERT(IS_UART_STOP_BIT(config->stopBits));
    SR_ASSERT(IS_UART_ORDER(config->bitOrder));
    SR_ASSERT(IS_UART_FC(config->fc));

    BSP_UART_INFO_T *data = (BSP_UART_INFO_T *)dev->deviceData;

    luat_uart_t uart = LUAT_UART_CONFIG_DEFAULT;
    // BSP_DEBUG_PRINTF("dev.name = %s, dev.srId = %d", data->name, data->srId);

    if(data->srId == SR_UART0) //合宙uart0要额外做些处理
    {
        soc_uart0_set_log_off(1);
	    BSP_SetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_PORT_SEL,PLAT_CFG_ULG_PORT_USB);

    }

    uart.id = data->srId;
    if (config)
    {
        uart.baud_rate = config->baudrate;
        uart.data_bits = config->dataBits;
        uart.parity = config->parity;
        uart.bit_order = config->bitOrder;
        uart.bufsz = config->rxBufsz;
        uart.stop_bits = config->stopBits;
    }

    return luat_uart_setup(&uart);
}

int BspUartClose(SR_DEVICE_T *dev)
{
    SR_ASSERT(dev!=SR_NULL);

    BSP_UART_INFO_T *data = (BSP_UART_INFO_T *)dev->deviceData;
    return luat_uart_close(data->srId);
}

srSSize_t BspUartRead(SR_DEVICE_T *dev, void *buffer, srSize_t size)
{
    SR_ASSERT(dev!=SR_NULL);
    SR_ASSERT(buffer!=SR_NULL);
    SR_ASSERT(size>0);

    BSP_UART_INFO_T *data = (BSP_UART_INFO_T *)dev->deviceData;

    return luat_uart_read(data->srId, buffer, size);
}

srSSize_t BspUartWrite(SR_DEVICE_T *dev, void *buffer, srSize_t size)
{
    SR_ASSERT(dev!=SR_NULL);
    SR_ASSERT(buffer!=SR_NULL);
    SR_ASSERT(size>0);

    BSP_UART_INFO_T *data = (BSP_UART_INFO_T *)dev->deviceData;

    return luat_uart_write(data->srId, buffer, size);
}

int BspUartSetCallback(SR_DEVICE_T *dev, UartEventCb cb, void *args)
{
    int ret, ret1;
    SR_ASSERT(dev!=SR_NULL);
    SR_ASSERT(cb!=SR_NULL);

    SR_UART_DEV_T *uartDev = (SR_UART_DEV_T *)dev;
    BSP_UART_INFO_T *data = (BSP_UART_INFO_T *)dev->deviceData;
    if (uartDev)
    {
        uartDev->eventCb = cb;
        uartDev->evtCbArgs = args;
        ret = luat_uart_ctrl(data->srId, LUAT_UART_SET_RECV_CALLBACK, luat_uart_recv_cb_default);
        ret1 = luat_uart_ctrl(data->srId, LUAT_UART_SET_SENT_CALLBACK, luat_uart_sent_cb_default);
        return ((ret | ret1) == 0) ? 0 : -1;
    }

    return -1;
}

int BspUartClkIoSel(SR_DEVICE_T *dev,uint32_t clk,SR_UART_IO_T *io)
{
    //not support
	return  SR_OPT_DENIED;
}
