#include "bsp_uart.h"
#include "lwrb.h"
#include "CH59x_uart.h"
#include "shell_port.h"



lwrb_t Uart1Rx;
lwrb_t Uart1Tx;
uint8_t uart1_tx_buf[UART1_TX_BUFFER_LENGTH] = {0};
uint8_t uart1_rx_buf[UART1_RX_BUFFER_LENGTH] = {0};

// 串口接收
unsigned int BSP_Uart1_Receive_Data(void *buf, unsigned int len)
{
    return lwrb_read(&Uart1Rx, buf, len);
}

// 串口发送数据
unsigned int BSP_Uart1_Send_Data(const void *buf, unsigned int len)
{
    unsigned int ret;

    ret = lwrb_write(&Uart1Tx, buf, len);
    BSP_UART1_TxLoop();
    // UART1_INTCfg(ENABLE, RB_IER_THR_EMPTY);
    return ret;
}

unsigned int BSP_Uart1_Send_String(const void *buf)
{
    return BSP_Uart1_Send_Data(buf, strlen((const char *)buf));
}

/**
 * \brief           Buffer event function
 */
static void Uart1_evt_fn(struct lwrb *buff, lwrb_evt_type_t evt, lwrb_sz_t bp)
{
    switch (evt)
    {
        case LWRB_EVT_RESET:
            printf("[EVT] Buffer reset event!\r\n");
            break;
        case LWRB_EVT_READ:
            printf("[EVT] Buffer read event: %d byte(s)!\r\n", (int)bp);
            break;
        case LWRB_EVT_WRITE:
            printf("[EVT] Buffer write event: %d byte(s)!\r\n", (int)bp);
            break;
        default:
            break;
    }
}

void UART1_FifoInit(void)
{
    lwrb_init(&Uart1Tx, uart1_tx_buf, sizeof(uart1_tx_buf));
    lwrb_init(&Uart1Rx, uart1_rx_buf, sizeof(uart1_rx_buf));

    //    lwrb_set_evt_fn(&Uart1Rx, Uart1_evt_fn);
}

// DEBUG
void BSP_UART1_Init(uint32_t baudrate)
{
    // GPIOPinRemap(ENABLE, RB_PIN_UART1);

    /* 配置串口1：先配置IO口模式，再配置串口 */
    GPIOA_SetBits(bTXD1);
    // GPIOB_ModeCfg(bRXD1, GPIO_ModeIN_PU);      // RXD-配置上拉输入
    GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出，注意先让IO口输出高电平
    // UART1_DefInit();
    {
        UART1_BaudRateCfg(baudrate);
        R8_UART1_FCR = (2 << 6) | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; // FIFO打开，触发点4字节
        R8_UART1_LCR = RB_LCR_WORD_SZ;
        R8_UART1_IER = RB_IER_TXD_EN;
        R8_UART1_DIV = 1;
    }
    // UART1_ByteTrigCfg(UART_1BYTE_TRIG);
    // 中断方式接收数据
    // UART1_INTCfg(ENABLE, RB_IER_LINE_STAT | RB_IER_RECV_RDY);
    // UART1_INTCfg(ENABLE, RB_IER_LINE_STAT | RB_IER_RECV_RDY);
    // PFIC_EnableIRQ(UART1_IRQn);

    UART1_FifoInit();

    SHELL_Init();
}

// https://www.cnblogs.com/iot-fan/p/13439293.html
// tx process
// 本查询函数需要扔到主循环不断调用
void BSP_UART1_TxLoop(void)
{
    uint8_t data;
    while (R8_UART1_TFC < UART_FIFO_SIZE)
    {
        // 判断发送软件缓冲区,是否空,如果不空,就一个一个读出来,填到硬件fifo里
        if (lwrb_get_full(&Uart1Tx))
        {
            lwrb_read(&Uart1Tx, &data, 1);
            // 把软件缓冲区的数据填到uart的硬件发送fifo里
            UART1_SendByte(data);
        }
        else
        {
            break;
        }
    }
}

/*********************************************************************
 * @fn      UART1_IRQHandler
 *
 * @brief   UART1中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void UART1_IRQHandler(void)
{
    switch (UART1_GetITFlag())
    {
        case UART_II_LINE_STAT: // 线路状态错误
        {
            UART1_GetLinSTA();
            break;
        }
        case UART_II_RECV_RDY:
        case UART_II_RECV_TOUT: // 接收超时
            // lwrb_write(&Uart1Rx, &R8_UART1_RBR, 1);
            while (R8_UART1_RFC)
            {
                shellHandler(&shell, R8_UART1_RBR);
            }
            break;
        case UART_II_THR_EMPTY: // 发送缓存区空，可继续发送
        // 串口中断发送会可能影响蓝牙
            break;

        case UART_II_MODEM_CHG: // 只支持串口0
            break;

        default:
            break;
    }
}

int reboot(void)
{
    PFIC_SystemReset();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
                 reboot, reboot, "reboot");
