#include "FreeRTOS.h"
#include "task.h"

#include "downUartParse.h"
#include "upUartParse.h"
#include "queueUart.h"

// /* 1秒的节拍数 */
// #define tick_1S configTICK_RATE_HZ

// /* 状态机 */
// typedef enum {
//     wait                        = 0,    /* 串口状态机初始状态 */
//     startFlag,                          /* 接收到帧头 */
//     // address,                            /* 设备地址 */
//     functionCode,                       /* 接收到功能码 */
//     dataLen,                            /* 接收到数据长度 */
//     crcCheckBitGW,                      /* 接收到校验位 */
//     endFlagGW,                          /* 接收到帧尾 */
// } uartStateMachine;


/* 储存gw485数据 */
static uint8_t J1_485RxBuffer[128];
static uint16_t J1_485RxBufferIndex = 0;
static uint8_t J2_485RxBuffer[128];
static uint16_t J2_485RxBufferIndex = 0;
static uint8_t J3_485RxBuffer[128];
static uint16_t J3_485RxBufferIndex = 0;
static uint8_t J4_485RxBuffer[128];
static uint16_t J4_485RxBufferIndex = 0;
static uint8_t J5_0_485RxBuffer[128];
static uint16_t J5_0_485RxBufferIndex = 0;

/* 100ms */
#define delayTick 50
#define maxdataLen 100

/**
  * @brief  接收J1口传来的数据
  * @param 
  * @retval
  */
void J1_SensorDataAnalysis(void)
{
    static uint32_t tick;

    if (J1_485RxBufferIndex == 0) {
        tick = xTaskGetTickCount();
    }

    /* 单次进入最多6ms(3个时钟周期),串口中有数据 */
    uint32_t nowTick = xTaskGetTickCount();
    while ((getTickDiff(nowTick) < 3)
            && (uart_dev_char_present(g_J1_uart6_handle) == 1)
            && (maxdataLen > J1_485RxBufferIndex)) {
        J1_485RxBuffer[J1_485RxBufferIndex++] = uart_dev_in_char(g_J1_uart6_handle);
    }

    /* 当时间到达或者数据量到达,就打包发送给智能模块 */
    if ((J1_485RxBufferIndex >= maxdataLen) || (getTickDiff(tick) > delayTick)) {
        uint32_t tempLen = 6 + J1_485RxBufferIndex + queueUartSendInfoSize;
        if (xPortGetFreeHeapSize() < tempLen + 1024) {
            J1_485RxBufferIndex = 0;
            return;
        }

        uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen);
        queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        sendBuff->length = 6 + J1_485RxBufferIndex;        
        sendBuff->data = Buff + sizeof(queueUartSendInfo);
        uint8_t *send = sendBuff->data;

        /* 起始标志 */
        *send = 'S';
        *(send + 1) = 'L';

        /* 端口号 */
        send += 2;
        *send = 1;

        /* 数据包长度 */
        send += 1;
        *send = (uint8_t)(J1_485RxBufferIndex >> 8);
        *(send + 1) = (uint8_t)(J1_485RxBufferIndex);

        /* 数据包 */
        send += 2;
        strlcpy((char *)send, (char *)J1_485RxBuffer, J1_485RxBufferIndex);

        /* 结束标志 */
        send += J1_485RxBufferIndex;
        *send = 0x17;

        /* 队列中有空间,则将发送数据 */
        if (uxQueueSpacesAvailable(upward_uart_Queue)) {
            xQueueSend(upward_uart_Queue, &Buff, 10);
        }
        /* 队列无空间,将数据丢弃 */
        else {
            vPortFree(Buff);
        }

        /* 发送完成或遇到问题,将buff中的数据清零 */
        J1_485RxBufferIndex = 0;
    }
}

/**
  * @brief  接收J2口传来的数据
  * @param 
  * @retval
  */
void J2_SensorDataAnalysis(void)
{
    static uint32_t tick;

    if (J2_485RxBufferIndex == 0) {
        tick = xTaskGetTickCount();
    }

    /* 单次进入最多6ms(3个时钟周期),串口中有数据 */
    uint32_t nowTick = xTaskGetTickCount();
    while ((getTickDiff(nowTick) < 3)
            && (uart_dev_char_present(g_J2_uart7_handle) == 1)
            && (maxdataLen > J2_485RxBufferIndex)) {
        J2_485RxBuffer[J2_485RxBufferIndex++] = uart_dev_in_char(g_J2_uart7_handle);
    }

    /* 当时间到达或者数据量到达,就打包发送给智能模块 */
    if ((J2_485RxBufferIndex >= maxdataLen) || (getTickDiff(tick) > delayTick)) {

        uint32_t tempLen = 6 + J2_485RxBufferIndex + queueUartSendInfoSize;
        if (xPortGetFreeHeapSize() < tempLen + 1024) {
            J2_485RxBufferIndex = 0;
            return;
        }

        uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen);        
        queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        sendBuff->length = 6 + J2_485RxBufferIndex;        
        sendBuff->data = Buff + sizeof(queueUartSendInfo);
        uint8_t *send = sendBuff->data;

        /* 起始标志 */
        *send = 'S';
        *(send + 1) = 'L';

        /* 端口号 */
        send += 2;
        *send = 2;

        /* 数据包长度 */
        send += 1;
        *send = (uint8_t)(J2_485RxBufferIndex >> 8);
        *(send + 1) = (uint8_t)(J2_485RxBufferIndex);

        /* 数据包 */
        send += 2;
        strlcpy((char *)send, (char *)J2_485RxBuffer, J2_485RxBufferIndex);

        /* 结束标志 */
        send += J2_485RxBufferIndex;
        *send = 0x17;

        /* 队列中有空间,则将发送数据 */
        if (uxQueueSpacesAvailable(upward_uart_Queue)) {
            xQueueSend(upward_uart_Queue, &Buff, 10);
        }
        /* 队列无空间,将数据丢弃 */
        else {
            vPortFree(Buff);
        }

        J2_485RxBufferIndex = 0;
    }
}

/**
  * @brief  接收J3口传来的数据
  * @param 
  * @retval
  */
void J3_SensorDataAnalysis(void)
{
    static uint32_t tick;

    if (J3_485RxBufferIndex == 0) {
        tick = xTaskGetTickCount();
    }

    /* 单次进入最多6ms(3个时钟周期),串口中有数据 */
    uint32_t nowTick = xTaskGetTickCount();
    while ((getTickDiff(nowTick) < 3)
            && (uart_dev_char_present(g_J3_usart2_handle) == 1)
            && (maxdataLen > J3_485RxBufferIndex)) {
        J3_485RxBuffer[J3_485RxBufferIndex++] = uart_dev_in_char(g_J3_usart2_handle);
    }

    /* 当时间到达或者数据量到达,就打包发送给智能模块 */
    if ((J3_485RxBufferIndex >= maxdataLen) || (getTickDiff(tick) > delayTick)) {

        uint32_t tempLen = 6 + J3_485RxBufferIndex + queueUartSendInfoSize;
        if (xPortGetFreeHeapSize() < tempLen + 1024) {
            J3_485RxBufferIndex = 0;
            return;
        }

        uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen);        
        queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        sendBuff->length = 6 + J3_485RxBufferIndex;        
        sendBuff->data = Buff + sizeof(queueUartSendInfo);
        uint8_t *send = sendBuff->data;

        /* 起始标志 */
        *send = 'S';
        *(send + 1) = 'L';

        /* 端口号 */
        send += 2;
        *send = 3;

        /* 数据包长度 */
        send += 1;
        *send = (uint8_t)(J3_485RxBufferIndex >> 8);
        *(send + 1) = (uint8_t)(J3_485RxBufferIndex);

        /* 数据包 */
        send += 2;
        strlcpy((char *)send, (char *)J3_485RxBuffer, J3_485RxBufferIndex);

        /* 结束标志 */
        send += J3_485RxBufferIndex;
        *send = 0x17;

        /* 队列中有空间,则将发送数据 */
        if (uxQueueSpacesAvailable(upward_uart_Queue)) {
            xQueueSend(upward_uart_Queue, &Buff, 10);
        }
        /* 队列无空间,将数据丢弃 */
        else {
            vPortFree(Buff);
        }
        
        J3_485RxBufferIndex = 0;
    }
}

/**
  * @brief  接收J4口传来的数据
  * @param 
  * @retval
  */
void J4_SensorDataAnalysis(void)
{
    static uint32_t tick;

    if (J4_485RxBufferIndex == 0) {
        tick = xTaskGetTickCount();
    }

    /* 单次进入最多6ms(3个时钟周期),串口中有数据 */
    uint32_t nowTick = xTaskGetTickCount();
    while ((getTickDiff(nowTick) < 3)
            && (uart_dev_char_present(g_J4_uart8_handle) == 1)
            && (maxdataLen > J4_485RxBufferIndex)) {
        J4_485RxBuffer[J4_485RxBufferIndex++] = uart_dev_in_char(g_J4_uart8_handle);
    }

    /* 当时间到达或者数据量到达,就打包发送给智能模块 */
    if ((J4_485RxBufferIndex >= maxdataLen) || (getTickDiff(tick) > delayTick)) {

        uint32_t tempLen = 6 + J4_485RxBufferIndex + queueUartSendInfoSize;
        if (xPortGetFreeHeapSize() < tempLen + 1024) {
            J4_485RxBufferIndex = 0;
            return;
        }

        uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen);        
        queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        sendBuff->length = 6 + J4_485RxBufferIndex;        
        sendBuff->data = Buff + sizeof(queueUartSendInfo);
        uint8_t *send = sendBuff->data;

        /* 起始标志 */
        *send = 'S';
        *(send + 1) = 'L';

        /* 端口号 */
        send += 2;
        *send = 4;

        /* 数据包长度 */
        send += 1;
        *send = (uint8_t)(J4_485RxBufferIndex >> 8);
        *(send + 1) = (uint8_t)(J4_485RxBufferIndex);

        /* 数据包 */
        send += 2;
        strlcpy((char *)send, (char *)J4_485RxBuffer, J4_485RxBufferIndex);

        /* 结束标志 */
        send += J4_485RxBufferIndex;
        *send = 0x17;

        /* 队列中有空间,则将发送数据 */
        if (uxQueueSpacesAvailable(upward_uart_Queue)) {
            xQueueSend(upward_uart_Queue, &Buff, 10);
        }
        /* 队列无空间,将数据丢弃 */
        else {
            vPortFree(Buff);
        }
        
        J4_485RxBufferIndex = 0;
    }
}

/**
  * @brief  接收J5_0口传来的数据
  * @param 
  * @retval
  */
void J5_0_SensorDataAnalysis(void)
{
    static uint32_t tick;

    if (J5_0_485RxBufferIndex == 0) {
        tick = xTaskGetTickCount();
    }

    /* 单次进入最多6ms(3个时钟周期),串口中有数据 */
    uint32_t nowTick = xTaskGetTickCount();
    while ((getTickDiff(nowTick) < 3)
            && (uart_dev_char_present(g_J5_0_usart3_handle) == 1)
            && (maxdataLen > J5_0_485RxBufferIndex)) {
        J5_0_485RxBuffer[J5_0_485RxBufferIndex++] = uart_dev_in_char(g_J5_0_usart3_handle);
    }

    /* 当时间到达或者数据量到达,就打包发送给智能模块 */
    if ((J5_0_485RxBufferIndex >= maxdataLen) || (getTickDiff(tick) > delayTick)) {

        uint32_t tempLen = 6 + J5_0_485RxBufferIndex + queueUartSendInfoSize;
        if (xPortGetFreeHeapSize() < tempLen + 1024) {
            J5_0_485RxBufferIndex = 0;
            return;
        }

        uint8_t *Buff = (uint8_t *)pvPortMalloc(tempLen);        
        queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        sendBuff->length = 6 + J5_0_485RxBufferIndex;        
        sendBuff->data = Buff + sizeof(queueUartSendInfo);
        uint8_t *send = sendBuff->data;

        /* 起始标志 */
        *send = 'S';
        *(send + 1) = 'L';

        /* 端口号 */
        send += 2;
        *send = getConnectPort();

        /* 数据包长度 */
        send += 1;
        *send = (uint8_t)(J5_0_485RxBufferIndex >> 8);
        *(send + 1) = (uint8_t)(J5_0_485RxBufferIndex);

        /* 数据包 */
        send += 2;
        strlcpy((char *)send, (char *)J5_0_485RxBuffer, J5_0_485RxBufferIndex);

        /* 结束标志 */
        send += J5_0_485RxBufferIndex;
        *send = 0x17;

        /* 队列中有空间,则将发送数据 */
        if (uxQueueSpacesAvailable(upward_uart_Queue)) {
            xQueueSend(upward_uart_Queue, &Buff, 10);
        }
        /* 队列无空间,将数据丢弃 */
        else {
            vPortFree(Buff);
        }

        J5_0_485RxBufferIndex = 0;
    }
}