/*
 * uart_send.c
 *
 *  Created on: 2024年11月19日
 *      Author: psx
 */

#include "uart_send.h"
#include "parameter.h"
#include <string.h>

//static uint8_t dataLocation1[RS485_MAX_PACK_DATA_LEN];
//static uint8_t dataLocation2[RS485_MAX_PACK_DATA_LEN];
//static uint8_t dataLocation3[RS485_MAX_PACK_DATA_LEN];

static uint8_t dataLocation1[RS485_MAX_PACK_DATA_LEN];
static uint8_t dataLocation2[RS485_MAX_PACK_DATA_LEN];
static uint8_t dataLocation3[RS485_MAX_PACK_DATA_LEN];

uart_send_info uart_send;

/**
  * @brief  串口中断发送的初始化，通过空闲中断来判断总线空闲状态
  * @param
  * @retval
  *
  */
void send_init(void)
{
    uart_send.data1.data = dataLocation1;
    uart_send.data2.data = dataLocation2;
    uart_send.data3.data = dataLocation3;
    uart_send.insertData = &uart_send.data1;
    uart_send.sendDataGw = NULL;
    uart_send.sendDataBat = NULL;

    //有3个位置可以写入数据
    uart_send.insertState = 3;

    //没有数据能够发送
    uart_send.sendStateGw = 0;
    uart_send.sendStateBat = 0;
    //发送完成
    uart_send.sendOverStateBat = 1;
    uart_send.sendOverStateGw = 1;

    //485总线空闲
    uart_send.GwState = 1;
    uart_send.idleStateGw = 1;
    uart_send.BatState = 1;
    uart_send.idleStateBat = 1;
}

/**
  * @brief  发送检测函数，当有数据并且总线空闲时，将数据通过中断发送
  * @param
  * @retval
  *
  */
void check_sendState(void)
{
    static uint8_t tempGwT = 0;
    static uint8_t tempBatT = 0;
    /* 进入空闲中断一段时间后，仍然没有数据到来判断485总线空闲 */
    if (!uart_send.GwState) {
        if (uart_send.idleStateGw) {
            tempGwT++;
            if (tempGwT >= g_otherParameter.randomNumber) {
                uart_send.GwState = 1;
            }
        }
    } else {
        tempGwT = 0;
    }

    /* 进入空闲中断一段时间后，仍然没有数据到来判断485总线空闲 */
    if (!uart_send.BatState) {
        if (uart_send.idleStateBat) {
            tempBatT++;
            if (tempBatT >= g_otherParameter.randomNumber) {
                uart_send.BatState = 1;
            }
        }
    } else {
        tempBatT = 0;
    }

    /* 向上通信总线空闲时，检测到有数据需要发送，同时上一次数据发送完成 */
//    if (uart_send.GwState && uart_send.sendStateGw && uart_send.sendOverStateGw) {
    if (uart_send.GwState && uart_send.sendStateGw && uart_send.sendOverStateGw) {
        printf("Gw in Tx\n");
        gw485_tx_enabla();
//        USART_ITConfig(USART4, USART_IT_TXE, ENABLE);
        uartDMA_Init(g_gw485_uart4_handle, uart_send.sendDataGw->data, uart_send.sendDataGw->dataLen);
        USART_DMACmd(USART4, USART_DMAReq_Tx, ENABLE);
//        uart_send.sendOverStateGw = 0;
        uart_send.sendOverStateGw = 0;
    }

    /* 向下通信总线空闲时，检测到有数据需要发送，同时上一次数据发送完成 */
//    if (uart_send.BatState && uart_send.sendStateBat && uart_send.sendOverStateBat) {
    if (uart_send.BatState && uart_send.sendStateBat && uart_send.sendOverStateBat) {

        printf("Bat in Tx\n");
        bat485_tx_enabla();
//        USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
//        uartDMA_Init(g_bat485_uart3_handle, uart_send.sendDataBat->data, uart_send.sendDataBat->dataLen);
        USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
//        uart_send.sendOverStateBat = 0;
        uart_send.sendOverStateBat = 0;
    }

    /* 向上通信时，依次查看有无向上通信的数据 */
    if (!uart_send.sendStateGw && (uart_send.insertState + uart_send.sendStateBat < 3)) {
        if (uart_send.data1.dataState) {
            if (uart_send.data1.device == g_gw485_uart4_handle) {
                uart_send.sendStateGw = 1;
                uart_send.sendDataGw = &uart_send.data1;
            }
        }
        if (uart_send.data2.dataState) {
            if (uart_send.data2.device == g_gw485_uart4_handle) {
                uart_send.sendStateGw= 1;
                uart_send.sendDataGw = &uart_send.data2;
            }
        }
        if (uart_send.data3.dataState) {
            if (uart_send.data3.device == g_gw485_uart4_handle) {
                uart_send.sendStateGw = 1;
                uart_send.sendDataGw = &uart_send.data3;
            }
        }
    }

    /* 向下通信时，依次查看有无向下通信的数据 */
    if (!uart_send.sendStateBat && (uart_send.insertState + uart_send.sendStateGw < 3)) {
        if (uart_send.data1.dataState) {
            if (uart_send.data1.device == g_bat485_uart3_handle) {
                uart_send.sendStateBat = 1;
                uart_send.sendDataBat = &uart_send.data1;
            }
        }
        if (uart_send.data2.dataState) {
            if (uart_send.data2.device == g_bat485_uart3_handle) {
                uart_send.sendStateBat = 1;
                uart_send.sendDataBat = &uart_send.data2;
            }
        }
        if (uart_send.data3.dataState) {
            if (uart_send.data3.device == g_bat485_uart3_handle) {
                uart_send.sendStateBat = 1;
                uart_send.sendDataBat = &uart_send.data3;
            }
        }
    }
}

/**
  * @brief  当数据塞入发送结构体中
  * @param
  * @retval
  *
  */
void uart_interruptSend(device_handle device, uint8_t buff[], uint8_t len)
{
//    printf("\n");
//    printf("buff");
//    for (int var = 0; var < len; ++var) {
//        printf(" %x ", buff[var]);
//    }
//    printf("\n");
//    printf("\n");

    /* 拷贝数据到发送 */
    do {
        if (uart_send.insertState > 0 && uart_send.insertData != NULL) {
//            memcpy(uart_send.insertData->data, buff, len);
            for (int var = 0; var < len; ++var) {
                uart_send.insertData->data[var] = buff[var];
//                printf(" %x ", uart_send.insertData->data[var]);
            }
            uart_send.insertData->Counter = 0;
            uart_send.insertData->dataLen = len;
            uart_send.insertData->device = device;
//            uart_send.insertData->dataState = 1;
//            uart_send.insertState--;
            break;
        }
    } while (1);

    /* 可插入数据大于0时，将插入指针指向空的储存位置,否则指向NULL */
    if (uart_send.insertState > 0) {
        if (!uart_send.data1.dataState) {
            uart_send.insertData = &uart_send.data1;
        }
        else if (!uart_send.data2.dataState) {
            uart_send.insertData = &uart_send.data2;
        }
        else if (!uart_send.data3.dataState) {
            uart_send.insertData = &uart_send.data3;
        }
    } else {
        uart_send.insertData = NULL;
    }

    printf("uart_send.insertData->data");
    for (int var = 0; var < len; ++var) {
        printf(" %x ", uart_send.insertData->data[var]);
    }
    printf("\n");
    printf("uart_send.insertData->Counter : %d \n", uart_send.insertData->Counter);
    printf("uart_send.insertData->dataLen : %d \n", uart_send.insertData->dataLen);
    printf("uart_send.insertState : %d \n", uart_send.insertState);

    uart_send.insertData->dataState = 1;
    uart_send.insertState--;
}

void DMA1_Channel1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void uartDMA_Init(device_handle device, uint8_t buff[], uint8_t len)
{
    DMA_InitTypeDef DMA_InitStructure = {0};
    RCC_HBPeriphClockCmd(RCC_HBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA1_Channel1);

    DMA_ClearFlag(DMA1_FLAG_TC1);

    if (device == g_bat485_uart3_handle) {
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART3->DATAR);
    }
    else if (device == g_gw485_uart4_handle) {
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART4->DATAR);
    }
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = len;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);      //使能传输完成中断

    DMA_Cmd(DMA1_Channel1, ENABLE);
}

//中断处理函数
void  DMA1_Channel1_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_TC1) != RESET) {
        //中断处理代码
        Delay_Us(100);
        gw485_tx_disenabla();
        uart_send.sendStateGw = 0;
        uart_send.insertState++;
//      printf("\n\n bat uart_send.insertState : %d \n\n", uart_send.insertState);
        /* 插入指针指向为空时 */
        if (uart_send.insertData == NULL) {
            if (!uart_send.data1.dataState) {
                uart_send.insertData = &uart_send.data1;
            }
            if (!uart_send.data2.dataState) {
                uart_send.insertData = &uart_send.data2;
            }
            if (!uart_send.data3.dataState) {
                uart_send.insertData = &uart_send.data3;
            }
        }
        uart_send.sendOverStateGw = 1;
        DMA_ClearITPendingBit(DMA1_IT_TC1);
    }
}
