#include "bsp_uart.h"
#include "bsp_ml307r.h"
#include "lwrb.h"
#include "CH58x_uart.h"
#include "shell_port.h"
#include "SLEEP.h"
#include "CONFIG.h"
#include "log.h"

#define UART1_RX_BUFFER_LENGTH    512U
#define UART1_TX_BUFFER_LENGTH    512U

#define UART3_RX_BUFFER_LENGTH    1024U
#define UART3_TX_BUFFER_LENGTH    1024U

void BSP_Shell_SetActive(void);


lwrb_t uart1_rx_t;
lwrb_t uart1_tx_t;
uint8_t uart1_tx_buf[UART1_TX_BUFFER_LENGTH] = {0};
uint8_t uart1_rx_buf[UART1_RX_BUFFER_LENGTH] = {0};

lwrb_t uart3_rx_t;
lwrb_t uart3_tx_t;
uint8_t uart3_tx_buf[UART3_TX_BUFFER_LENGTH] = {0};
uint8_t uart3_rx_buf[UART3_RX_BUFFER_LENGTH] = {0};

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

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

    ret = lwrb_write(&uart1_tx_t, buf, len);
    UART1_INTCfg(ENABLE, RB_IER_THR_EMPTY);
    return ret;
}

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

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

    ret = lwrb_write(&uart3_tx_t, buf, len);
    UART3_INTCfg(ENABLE, RB_IER_THR_EMPTY);
    return ret;
}
/**
 * \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(&uart1_tx_t, uart1_tx_buf, sizeof(uart1_tx_buf));
    lwrb_init(&uart1_rx_t, uart1_rx_buf, sizeof(uart1_rx_buf));

//    lwrb_set_evt_fn(&uart1_rx_t, Uart1_evt_fn);
}

void UART3_FifoInit(void)
{
    lwrb_init(&uart3_tx_t, uart3_tx_buf, sizeof(uart3_tx_buf));
    lwrb_init(&uart3_rx_t, uart3_rx_buf, sizeof(uart3_rx_buf));

    //lwrb_set_evt_fn(&uart1_rx_t, Uart1_evt_fn);
}


void BSP_UART1_Init(void)
{
    GPIOPinRemap(ENABLE, RB_PIN_UART1);

    /* 配置串口1：先配置IO口模式，再配置串口 */
    GPIOB_SetBits(ML307_UART_TX_PIN);
    GPIOB_ModeCfg(ML307_UART_RX_PIN, GPIO_ModeIN_PU);      // RXD-配置上拉输入
    GPIOB_ModeCfg(ML307_UART_TX_PIN, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出，注意先让IO口输出高电平
    UART1_DefInit();
    UART1_BaudRateCfg(115200);
    UART1_ByteTrigCfg(UART_1BYTE_TRIG);
    // 中断方式接收数据
    UART1_INTCfg(ENABLE, RB_IER_LINE_STAT | RB_IER_RECV_RDY | RB_IER_THR_EMPTY);
    PFIC_EnableIRQ(UART1_IRQn);

    UART1_FifoInit();
}

void BSP_UART3_Init(void)
{
    GPIOPinRemap(ENABLE, RB_PIN_UART3);
    /* 配置串口3：先配置IO口模式，再配置串口 */
    GPIOB_SetBits(UART3_TX_PIN);
    GPIOB_ModeCfg(UART3_RX_PIN, GPIO_ModeIN_PU);      // RXD-配置上拉输入
    GPIOB_ModeCfg(UART3_TX_PIN, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出，注意先让IO口输出高电平
    UART3_DefInit();
    UART3_BaudRateCfg(460800);  //115200
    UART3_ByteTrigCfg(UART_1BYTE_TRIG);

    // 中断方式接收数据
    UART3_INTCfg(ENABLE, RB_IER_LINE_STAT | RB_IER_RECV_RDY | RB_IER_THR_EMPTY);
    PFIC_EnableIRQ(UART3_IRQn);

    UART3_FifoInit();
    userShellInit();
}


static tmosTaskID shell_timeout_task_id = INVALID_TASK_ID;
#define SHELL_TIMEOUT_EVT       0x0001

/**
 * @brief 超时后系统睡眠
 */
static uint16_t BSP_Shell_TimeoutTask(uint8_t task_id, uint16_t events)
{
    if (events & SHELL_TIMEOUT_EVT)
    {
        printf("Shell_Timeout UART3 enter low power mode\r\n");
        BSP_RequestSleep();
        return (events ^ SHELL_TIMEOUT_EVT);
    }
    
    return 0;
}

/**
 * @brief 启动Shell活动超时定时器
 */
void BSP_Shell_StartTimeoutTimer(void)
{
    if (shell_timeout_task_id == INVALID_TASK_ID)
    {
        shell_timeout_task_id = TMOS_ProcessEventRegister(BSP_Shell_TimeoutTask);
    }
    tmos_stop_task(shell_timeout_task_id, SHELL_TIMEOUT_EVT);
    tmos_start_task(shell_timeout_task_id, SHELL_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(SHELL_ACTIVITY_TIMEOUT));
}

/**
 * @brief 将Shell设置为活动状态，阻止系统睡眠
 */
void BSP_Shell_SetActive(void)
{
    BSP_BlockSleep();
    BSP_Shell_StartTimeoutTimer();
}


/*********************************************************************
 * @fn      UART1_IRQHandler
 *
 * @brief   UART1中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void UART1_IRQHandler(void)
{
    uint8_t data,q;
//    q = UART1_GetITFlag();
//    printf("q1 = %#x\r\n", q);
    switch(UART1_GetITFlag())
    {
        case UART_II_LINE_STAT: // 线路状态错误
        {
//            UART1_GetLinSTA();
            break;
        }
        case UART_II_RECV_RDY:
            data = UART1_RecvByte();
            UART3_SendByte(data);
            lwrb_write(&uart1_rx_t, &data, 1);

            break;
        case UART_II_RECV_TOUT: // 接收数据
            break;

        case UART_II_THR_EMPTY: // 发送缓存区空，可继续发送
            if(lwrb_read(&uart1_tx_t, &data, 1))
            {
                UART1_SendByte(data);
            }
            else
            {
                UART1_INTCfg(DISABLE, RB_IER_THR_EMPTY);
            }

            break;

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

        default:
            break;
    }
}

/*********************************************************************
 * @fn      UART3_IRQHandler
 *
 * @brief   UART1中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void UART3_IRQHandler(void)
{
    uint8_t data,q;
//    q = UART3_GetITFlag();
//    printf("q3 = %#x\r\n", q);
    switch(UART3_GetITFlag())
    {
        case UART_II_LINE_STAT: // 线路状态错误
        {
//            UART1_GetLinSTA();
            break;
        }
        case UART_II_RECV_RDY:
        case UART_II_RECV_TOUT: //接收超时
            BSP_Shell_SetActive();
            while(R8_UART3_RFC)
            {
                logDebug("shellHandler \r\n");
                shellHandler(&shell, R8_UART3_RBR);
            }
            break;
        case UART_II_THR_EMPTY: // 发送缓存区空，可继续发送
            if(lwrb_get_full(&uart3_tx_t))
            {
                lwrb_read(&uart3_tx_t, &data, 1);
                UART3_SendByte(data);
            }
            else
            {
                UART3_INTCfg(DISABLE, RB_IER_THR_EMPTY);
            }

            break;

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

        default:
            break;
    }
}

