#include "main.h"
#include "YHPID.h"

/**
	@* 野火PID串口工具
	@* 所有多字节的低字节在前
	@* 包头固定为四字节的0x59485A53；
	@* 通道地址1到5对应软件上的CH1到CH5，CH1为0x01，CH2为0x02；
	@* 包长度为从包头到校验的所有数据长度。
	@* 指令为相应的功能码。
	@* 参数为指令需要参数时加入。
	@* 校验为校验和方式——8位。
***/

// 包头常量
#define PACK_HEADER   0x59485A53
#define CMD_DATA_UPLOAD 0x02
#define CMD_PID_UPLOAD 0x03

uint32_t g_dwinbuffer[23] ; // 当用DMA发送的时候 帧头要四字节对齐

// 发送 PID 参数到上位机
void Send_PID_To_PC(uint8_t channel, float P, float I, float D)
{
		uint8_t index = 0, *tx_buf;
		tx_buf = (uint8_t *)g_dwinbuffer;
	
    // 包头（4字节，高字节在前）
    tx_buf[index++] = (uint8_t)((PACK_HEADER >> 24) & 0xFF);
    tx_buf[index++] = (uint8_t)((PACK_HEADER >> 16) & 0xFF);
    tx_buf[index++] = (uint8_t)((PACK_HEADER >> 8) & 0xFF);
    tx_buf[index++] = (uint8_t)(PACK_HEADER & 0xFF);

    // 通道地址（1字节）
    tx_buf[index++] = channel;

    // 包长度（4字节，从包头到校验，含校验共 0x17 = 23）
    uint32_t length = 0x17;
    tx_buf[index++] = (uint8_t)(length & 0xFF);
    tx_buf[index++] = (uint8_t)((length >> 8) & 0xFF);
    tx_buf[index++] = (uint8_t)((length >> 16) & 0xFF);
    tx_buf[index++] = (uint8_t)((length >> 24) & 0xFF);

    // 指令（1字节）
    tx_buf[index++] = CMD_PID_UPLOAD;

    // P 参数（4字节 float）
    memcpy(&tx_buf[index], &P, 4);
    index += 4;

    // I 参数（4字节 float）
    memcpy(&tx_buf[index], &I, 4);
    index += 4;

    // D 参数（4字节 float）
    memcpy(&tx_buf[index], &D, 4);
    index += 4;

    // 校验和（1字节，前面所有字节的累加和的低8位）
    uint8_t checksum = 0;
    for (uint8_t i = 0; i < index; i++) {
        checksum += tx_buf[i];
    }
    tx_buf[index++] = checksum;
		
		HAL_GPIO_WritePin(GPIOB, RS485_RE_Pin, GPIO_PIN_SET);
    HAL_UART_Transmit_DMA(&huart1, tx_buf, index);
}

// 发送 实际值 参数到上位机
void Send_DATA_To_PC(uint8_t channel, float data)
{
    uint8_t tx_buf[15]; // 总长度 0x0F = 15字节
    uint32_t index = 0;

    // 包头（4字节，高字节在前）
    tx_buf[index++] = (uint8_t)((PACK_HEADER >> 24) & 0xFF);
    tx_buf[index++] = (uint8_t)((PACK_HEADER >> 16) & 0xFF);
    tx_buf[index++] = (uint8_t)((PACK_HEADER >> 8) & 0xFF);
    tx_buf[index++] = (uint8_t)(PACK_HEADER & 0xFF);

    // 通道地址（1字节）
    tx_buf[index++] = channel;

    // 包长度（4字节，从包头到校验，含校验共 0x0F = 15）
    uint32_t length = 0x0F;
    tx_buf[index++] = (uint8_t)(length & 0xFF);
    tx_buf[index++] = (uint8_t)((length >> 8) & 0xFF);
    tx_buf[index++] = (uint8_t)((length >> 16) & 0xFF);
    tx_buf[index++] = (uint8_t)((length >> 24) & 0xFF);

    // 指令（1字节）
    tx_buf[index++] = CMD_DATA_UPLOAD;

    // SPEED 参数（4字节 float）
    memcpy(&tx_buf[index], &data, 4);
    index += 4;

    // 校验和（1字节，前面所有字节的累加和的低8位）
    uint8_t checksum = 0;
    for (uint8_t i = 0; i < index; i++) {
        checksum += tx_buf[i];
    }
    tx_buf[index++] = checksum;
		HAL_GPIO_WritePin(GPIOB, RS485_RE_Pin, GPIO_PIN_SET);
    HAL_UART_Transmit_DMA(&huart1, tx_buf, index);
}
