#include "main.h"
#include "Modbussimple.h"
#include "cmsis_os.h"
#include "Callback.h"
#include "uType.h"

JsonDat_Work JsWork;

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


/*阀杆相关参数定义*/
extern volatile float Value_open_percent; // 阀杆开行程百分比
extern volatile float Value_open_mm; // 阀杆开行程mm

extern volatile float MPXV_P0; // 阀杆压力值
extern volatile float ADS_v0; // ads1256 通道0原始电压值
extern volatile float filtered_ADS_v0; // 滤波后的阀杆电压值
extern volatile float ADS_v0_offset; // ads1256 通道0电压偏移（将结果乘1000倍再赋值） 0.008*1000 = 8.0
// extern volatile float // 阀杆压力值滤波滑动窗口大小

/*油水相关参数定义*/
extern volatile float filtered_oil_cap; // 滤波后的油水电容值
extern volatile float oil_percent; // 油水百分比
extern volatile float oil_cap;// 原始电容值
extern volatile float oil_para_indu; // 并联电感值
extern volatile float oil_para_cap; // 并联电容值
extern volatile float oil_cap_offset;// 油水电容偏移值
// extern volatile float // 油水电容值滤波滑动窗口大小

/*余油相关参数定义*/
extern volatile float ADS_v1; // ads1256 通道1原始电压值
extern volatile float filtered_res_oil_cap; // 滤波后的电容值
extern volatile float MPXV_P1; // 余油压力值（kpa）
extern volatile float res_oil_height; // 余油高度值（mm）
extern volatile float res_oil_cap; // // 软件IIC 2号（PB10PB11）测得原始电容值
extern volatile float ADS_v1; // ads1256 通道1原始电压值
extern volatile float filtered_ADS_v1; // 滤波之后ads1256 通道1电压值
extern volatile float res_oil_para_indu; // 并联电感值
extern volatile float res_oil_para_cap; // 并联电容值
extern volatile float res_oil_cap_offset;// 余油电容偏移值
extern volatile float ADS_v1_offset; // ads1256 通道1电压偏移值（将结果乘1000倍再赋值）
// extern volatile float // 余油电容值滤波滑动窗口大小
// extern volatile float // 余油压力值滤波滑动窗口大小

/*温度相关参数定义*/
extern volatile float ADS_v2; // ads1256 通道2原始电压值
extern volatile float filtered_ADS_v2; // 滤波后的电压值
extern volatile float NTC_temp; // 电压查RT表转换后的温度值（℃）
extern volatile float ADS_v2; // ads1256 通道2原始电压值
extern volatile float ADS_v2_offset; // ads1256 通道2电压偏移值（将结果乘1000倍再赋值）
// extern volatile float // 温度滤波滑动窗口大小

// 03读指令应答结构体
ModbusRegister_t modbus_map[] = {
	{0x4000, 2, MODBUS_TYPE_UINT32_BE, &JsRoot.vers_id},// 固件版本号
	{0x4002, 1, MODBUS_TYPE_UINT16, &JsRoot.age},				// 运行时长
	{0x4010, 1, MODBUS_TYPE_UINT16, &JsRoot.addr},	 		// 从机设备地址
	{0x4011, 1, MODBUS_TYPE_UINT16, &JsRoot.baudrate},	// 波特率
	{0x4020, 3, MODBUS_TYPE_UINT16, &JsRoot.mac},    		// 设备SN号
    
	{0x0000, 2, MODBUS_TYPE_FLOAT_BE, (void *)&Value_open_percent}, // 阀杆开行程百分比	
	{0x0002, 2, MODBUS_TYPE_FLOAT_BE, (void *)&oil_percent}, // 油水百分比
	{0x0004, 2, MODBUS_TYPE_FLOAT_BE, (void *)&res_oil_height}, // 余油液位高度值(mm)
	{0x0006, 2, MODBUS_TYPE_FLOAT_BE, (void *)&NTC_temp}, // 温度摄氏度 
	
	{0x0100, 1, MODBUS_TYPE_OILTYPE, (void*)&g_oil_type},	 // 油品
	
	{0x0102, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[0]},	// 阀杆电压标定值（对应0mm行程）
	{0x0104, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[1]},	// 阀杆电压标定值（对应1mm行程）
	{0x0106, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[2]},	// 阀杆电压标定值（对应2mm行程）
	{0x0108, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[3]},	// 阀杆电压标定值（对应3mm行程）
	{0x010A, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[4]},	// 阀杆电压标定值（对应4mm行程）
	{0x010C, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[5]},	// 阀杆电压标定值（对应5mm行程）
	{0x010E, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_rod.vol_values[6]},	// 阀杆电压标定值（对应6mm行程）
	
	{0x0110, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[0]},	// 油水电容标定值（对应90%配比）
	{0x0112, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[1]},	// 油水电容标定值（对应91%配比）
	{0x0114, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[2]},	// 油水电容标定值（对应92%配比）
	{0x0116, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[3]},	// 油水电容标定值（对应93%配比）
	{0x0118, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[4]},	// 油水电容标定值（对应94%配比）
	{0x011A, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[5]},	// 油水电容标定值（对应95%配比）
	{0x011C, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[6]},	// 油水电容标定值（对应96%配比）
	{0x011E, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[7]},	// 油水电容标定值（对应97%配比）
	{0x0120, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[8]},	// 油水电容标定值（对应98%配比）
	{0x0122, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[9]},	// 油水电容标定值（对应99%配比）
	{0x0124, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_oil_water.cap_values[10]},	// 油水电容标定值（对应100%配比）

	{0x0126, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.cap_values[0]},	// 余液电容标定值（1cm液位高度）
	{0x0128, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.cap_values[1]},	// 余液电容标定值（2cm液位高度）
	{0x012A, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.cap_values[2]},	// 余液电容标定值（3cm液位高度）
	{0x012C, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.cap_values[3]},	// 余液电容标定值（4cm液位高度）
	{0x012E, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.cap_values[4]},	// 余液电容标定值（5cm液位高度）
	{0x0130, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.cap_values[5]},	// 余液电容标定值（6cm液位高度）
	
	{0x0132, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.vol_values[0]},	// 余液压力传感器电压标定值（1cm液位高度）
	{0x0134, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.vol_values[1]},	// 余液压力传感器电压标定值（2cm液位高度）
	{0x0136, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.vol_values[2]},	// 余液压力传感器电压标定值（3cm液位高度）
	{0x0138, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.vol_values[3]},	// 余液压力传感器电压标定值（4cm液位高度）
	{0x013A, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.vol_values[4]},	// 余液压力传感器电压标定值（5cm液位高度）	
	{0x013C, 2, MODBUS_TYPE_FLOAT_BE, &JsWork.calib_residual_oil.vol_values[5]},	// 余液压力传感器电压标定值（6cm液位高度）
	
	{0x0200, 2, MODBUS_TYPE_FLOAT_BE, (void *)&ADS_v0},	 // 通道0电压原始数据（阀杆）
	{0x0202, 2, MODBUS_TYPE_FLOAT_BE, (void *)&filtered_ADS_v0},	 // 滤波后通道0电压数据（阀杆）
	{0x0204, 2, MODBUS_TYPE_FLOAT_BE, (void *)&MPXV_P0}, // 电压转换后的压力值（阀杆）
	{0x0206, 2, MODBUS_TYPE_FLOAT_BE, (void *)&ADS_v0_offset}, // 通道0电压数据偏移值（阀杆）
//	{0x0208, 2, MODBUS_TYPE_FLOAT_BE, (void *)&}, // 压力值滤波滑动窗口大小（阀杆）
	
	{0x020A, 2, MODBUS_TYPE_FLOAT_BE, (void *)&oil_cap},	 // 1号电容原始电容值(油水)
	{0x020C, 2, MODBUS_TYPE_FLOAT_BE, (void *)&filtered_oil_cap}, // 滤波后油水电容值
	{0x020E, 2, MODBUS_TYPE_FLOAT_BE, (void *)&oil_para_indu}, // 1号并联电感值(油水)
	{0x0210, 2, MODBUS_TYPE_FLOAT_BE, (void *)&oil_para_cap},	 // 1号并联电容值(油水)
	{0x0212, 2, MODBUS_TYPE_FLOAT_BE, (void *)&oil_cap_offset}, // 1号电容偏移值(油水)
//	{0x0214, 2, MODBUS_TYPE_FLOAT_BE, (void *)&}, // 电容值滤波滑动窗口大小（油水）
	
	{0x0216, 2, MODBUS_TYPE_FLOAT_BE, (void *)&res_oil_cap},	 // 2号电容原始电容值（余油）
	{0x0218, 2, MODBUS_TYPE_FLOAT_BE, (void *)&filtered_res_oil_cap},	 // 滤波之后的电容值（余油）
	{0x021A, 2, MODBUS_TYPE_FLOAT_BE, (void *)&ADS_v1}, // 通道1电压原始数据（余油）
	{0x021C, 2, MODBUS_TYPE_FLOAT_BE, (void *)&filtered_ADS_v1}, // 滤波后电压值（余油）
	{0x021E, 2, MODBUS_TYPE_FLOAT_BE, (void *)&MPXV_P1}, // 电压转换后的压力值（余油）
	{0x0220, 2, MODBUS_TYPE_FLOAT_BE, (void *)&res_oil_para_indu},	 // 2号并联电感值(余油)
	{0x0222, 2, MODBUS_TYPE_FLOAT_BE, (void *)&res_oil_para_cap}, // 2号并联电容值(余油)
	{0x0224, 2, MODBUS_TYPE_FLOAT_BE, (void *)&res_oil_cap_offset}, // 2号电容偏移值(余油)
	{0x0226, 2, MODBUS_TYPE_FLOAT_BE, (void *)&ADS_v1_offset}, // 通道1电压数据偏移值（余油）
//	{0x0228, 2, MODBUS_TYPE_FLOAT_BE, (void *)&}, // 电容值滤波滑动窗口大小（余油）
//	{0x022A, 2, MODBUS_TYPE_FLOAT_BE, (void *)&}, // 压力值滤波滑动窗口大小（余油）

	{0x022C, 2, MODBUS_TYPE_FLOAT_BE, (void *)&ADS_v2},	// 通道2电压原始电压值（温度）
	{0x022E, 2, MODBUS_TYPE_FLOAT_BE, (void *)&filtered_ADS_v2},	// 滤波后通道2电压值（温度）
	{0x0230, 2, MODBUS_TYPE_FLOAT_BE, (void *)&ADS_v2_offset}, // 通道2电压数据偏移值（温度）
//	{0x0232, 2, MODBUS_TYPE_FLOAT_BE, (void *)&}, // 温度值滤波滑动窗口大小（温度）
	
};

// Modbus CRC16（低位在前，高位在后）
uint16_t modbus_crc16(uint8_t *data, uint16_t length) 
{
    uint16_t crc = 0xFFFF;
    for (uint16_t pos = 0; pos < length; pos++) {
        crc ^= data[pos];
        for (int i = 0; i < 8; i++) {
            if (crc & 0x0001)
                crc = (crc >> 1) ^ 0xA001;
            else
                crc >>= 1;
        }
    }
    return crc;
}

// 从映射表中查找寄存器并复制数据
bool read_modbus_registers(uint16_t addr, uint16_t len, uint8_t *dest_buf, uint16_t *out_byte_count)
{
    uint16_t offset = 0;
    uint16_t remaining = len;
    uint16_t curr_addr = addr;

    while (remaining > 0) {
        bool matched = false;

        for (int i = 0; i < sizeof(modbus_map) / sizeof(modbus_map[0]); i++) {
            uint16_t map_start = modbus_map[i].address;
            uint16_t map_end = map_start + modbus_map[i].length;

            if (curr_addr >= map_start && curr_addr < map_end) {
                matched = true;

                uint16_t index_in_map = curr_addr - map_start;
                uint16_t can_read = map_end - curr_addr;
                uint16_t read_count = (remaining < can_read) ? remaining : can_read;

                void *ptr = modbus_map[i].data_ptr;

                switch (modbus_map[i].type) {
                    case MODBUS_TYPE_UINT16: {
                        uint16_t *data_ptr = (uint16_t *)ptr;
                        for (uint16_t j = 0; j < read_count; j++) {
                            uint16_t val = data_ptr[index_in_map + j];
                            dest_buf[offset++] = (val >> 8) & 0xFF;
                            dest_buf[offset++] = val & 0xFF;
                        }
                        break;
                    }

                    case MODBUS_TYPE_UINT32_BE: {
                        uint32_t *data_ptr = (uint32_t *)ptr;
                        for (uint16_t j = 0; j < read_count; j++) {
                            uint16_t reg_idx = index_in_map + j;
                            uint32_t word_idx = reg_idx / 2;
                            bool high = (reg_idx % 2 == 0);
                            uint32_t val = data_ptr[word_idx];
                            uint16_t word = high ? (val >> 16) : (val & 0xFFFF);
                            dest_buf[offset++] = (word >> 8) & 0xFF;
                            dest_buf[offset++] = word & 0xFF;
                        }
                        break;
                    }

                    case MODBUS_TYPE_FLOAT_BE: {
                        float *f_ptr = (float *)ptr;
                        uint32_t temp;
                        for (uint16_t j = 0; j < read_count; j++) {
                            uint16_t reg_idx = index_in_map + j;
                            uint32_t word_idx = reg_idx / 2;
                            bool high = (reg_idx % 2 == 0);

                            memcpy(&temp, &f_ptr[word_idx], sizeof(float)); // 将 float 拷贝为 uint32_t
														uint16_t word = high ? (temp >> 16) : (temp & 0xFFFF); // uint32_t 分为 uint16_t
                            dest_buf[offset++] = (word >> 8) & 0xFF;
                            dest_buf[offset++] = word & 0xFF;
                        }
                        break;
                    }
										case MODBUS_TYPE_OILTYPE: {
											OilType *oil_ptr = (OilType *)ptr;
											uint16_t mapped_val = 0;

											switch (*oil_ptr) {
												case OIL_DIESEL: mapped_val = 0x0000; break;
												case OIL_92:     mapped_val = 0x0092; break;
												case OIL_95:     mapped_val = 0x0095; break;
												case OIL_98:     mapped_val = 0x0098; break;
												default:         mapped_val = 0xFFFF; break;
											}

											dest_buf[offset++] = (mapped_val >> 8) & 0xFF;
											dest_buf[offset++] = mapped_val & 0xFF;
											break;
										}
                    default:
                        return false; 
                }

                curr_addr += read_count;
                remaining -= read_count;
                break;
            }
        }

        if (!matched) return false;
    }

    *out_byte_count = offset;
    return true;
}

// 将 uint32_t 数组按高字节优先方式拷贝为 Modbus 输出格式（每个 uint32_t 占 4 字节）
void copy_uint32_to_modbus_bytes_be(uint32_t *src, uint16_t start_index, uint16_t word_count, uint8_t *dest_buf, uint16_t *offset) 
{
    for (uint16_t i = 0; i < word_count / 2; i++) {
        uint32_t val = src[start_index + i];
        uint16_t high = (val >> 16) & 0xFFFF;
        uint16_t low  = val & 0xFFFF;

        dest_buf[(*offset)++] = (high >> 8) & 0xFF;
        dest_buf[(*offset)++] = high & 0xFF;
        dest_buf[(*offset)++] = (low >> 8) & 0xFF;
        dest_buf[(*offset)++] = low & 0xFF;
    }
}


// 功能码 0x03 响应帧（角度浮点数值float）
uint16_t modbus_03response_float(uint8_t device_addr, uint8_t num, float value, uint8_t *out_buf) 
{
    uint8_t i = 0;

    out_buf[i++] = device_addr;    // 设备地址
    out_buf[i++] = 0x03;           // 功能码 0x03
    out_buf[i++] = num;           // 字节数（float = 4字节）

    // 将 float 转为 4 字节 IEEE 754 格式
    uint8_t float_bytes[4];
    memcpy(float_bytes, &value, 4);

    // 注意字节序是否和主机匹配
    out_buf[i++] = float_bytes[3];
    out_buf[i++] = float_bytes[2];
	  out_buf[i++] = float_bytes[1];
    out_buf[i++] = float_bytes[0];

    // 计算 CRC
    uint16_t crc = modbus_crc16(out_buf, i);
    out_buf[i++] = crc & 0xFF;      // CRC低位
    out_buf[i++] = crc >> 8;        // CRC高位

    return i; // 返回总长度
}





// 返回错误响应帧，例如非法功能码、非法地址等错误
uint16_t modbus_error_response(uint8_t addr, uint8_t func_code, uint8_t err_code, uint8_t *buf) 
{
    buf[0] = addr;
    buf[1] = func_code | 0x80; // 错误码 = 功能码 + 0x80
    buf[2] = err_code;

    uint16_t crc = modbus_crc16(buf, 3);
    buf[3] = crc & 0xFF;
    buf[4] = crc >> 8;

    return 5;
}

// 修改485串口1的波特率
void Set_485_Baudrate(uint16_t baudrate_id)
{
    uint32_t baudrate = 9600; // 默认值

    // 根据 ID 映射波特率
    switch (baudrate_id)
    {
				case 0x0000: baudrate = 9600; break;
        case 0x0001: baudrate = 4800; break;
        case 0x0002: baudrate = 9600; break;
        case 0x0003: baudrate = 14400; break;
        case 0x0004: baudrate = 19200; break;
        case 0x0005: baudrate = 38400; break;
        case 0x0006: baudrate = 56000; break;
        case 0x0007: baudrate = 57600; break;
        case 0x0008: baudrate = 115200; break;
        default:   baudrate = 9600; break; // 非法 ID，默认 9600
    }

    // 重新设置 huart1 配置并初始化
		huart1.Instance = USART1;
		huart1.Init.BaudRate = baudrate;
		huart1.Init.WordLength = UART_WORDLENGTH_8B;
		huart1.Init.StopBits = UART_STOPBITS_1;
		huart1.Init.Parity = UART_PARITY_NONE;
		huart1.Init.Mode = UART_MODE_TX_RX;
		huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
		huart1.Init.OverSampling = UART_OVERSAMPLING_16;
		huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
		huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	
    if (HAL_UART_DeInit(&huart1) != HAL_OK)
    {
        Error_Handler();
    }

    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}

/**
	* 06写单寄存器相关函数
***/
// 设置从机地址
bool handle_slave_addr(uint16_t value) {
		JsRoot.addr = value;
		DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_ADDR , JsRoot.addr ); // addr 存入到SNAPSHOT数据库
    return true;
}
// 设置波特率并立即生效
bool handle_baudrate(uint16_t value) {
    if (value <= 0x0008) {
        JsRoot.baudrate = value;
        DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_BAUDRATE , JsRoot.baudrate ); // 波特率存入到SNAPSHOT数据库
				osDelay(100);
        Set_485_Baudrate(value);
        const char* msg = "New baudrate applied\r\n";
        HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
        Restart_UART1_DMA();
        return true;
    }
    return false;
}

// 重启命令
bool handle_reboot(uint16_t value) {
    if (value == 0x0001) {
				// 构造应答
				uint16_t len = 0;
				uint8_t tx_buf[8] = {0};
				tx_buf[len++] = JsRoot.addr;
				tx_buf[len++] = 0x06;
				tx_buf[len++] = 0x40;
				tx_buf[len++] = 0x40;
				tx_buf[len++] = 0x00;
				tx_buf[len++] = 0x01;
				uint16_t crc = modbus_crc16(tx_buf, len);
				tx_buf[len++] = crc & 0xFF;
				tx_buf[len++] = (crc >> 8) & 0xFF;

				uart485send(tx_buf, len);
			
        osDelay(50);
        NVIC_SystemReset();
        return true;
    }
    return false;
}

// 恢复出厂
bool handle_factory_reset(uint16_t value) {

    if (value == 0x55AA) {
				JsRoot.iapLoadStatus = 0;
				JsRoot.ubootback = 1;
				DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_UBOOTBACK , JsRoot.ubootback ); // bootloader 状态码存入到SNAPSHOT数据库
				DB_SaveUInt(DB_ID_SNAPSHOT, KV_KEY_IAP_LOAD , JsRoot.iapLoadStatus ); // 装载状态存入到SNAPSHOT数据库
			
        osDelay(100);
			
				// 构造应答
				uint16_t len = 0;
				uint8_t tx_buf[8] = {0};
				tx_buf[len++] = JsRoot.addr;
				tx_buf[len++] = 0x06;
				tx_buf[len++] = 0x40;
				tx_buf[len++] = 0x42;
				tx_buf[len++] = 0x55;
				tx_buf[len++] = 0xAA;
				uint16_t crc = modbus_crc16(tx_buf, len);
				tx_buf[len++] = crc & 0xFF;
				tx_buf[len++] = (crc >> 8) & 0xFF;
				uart485send(tx_buf, len);
				osDelay(100);
        NVIC_SystemReset();
        return true;
    }
    return false;
}

bool handle_float_write(uint16_t raw, float* target) {
    float value;
    memcpy(&value, &raw, sizeof(uint16_t));
    *target = value;
//    Save_CalibPoints_ToFlash();
    return true;
}
bool handle_uint16_t_write(uint16_t raw, uint16_t* target) {
    *target = raw;   // 直接赋值
//    Save_CalibPoints_ToFlash();  // 保存到Flash
    return true;
}
static bool handle_uint16_t_oil_type(uint16_t v) {
    switch (v) {
        case 0x00:              // 写 0x00 -> 柴油
            g_oil_type = OIL_DIESEL;
            break;
        case 0x92:              // 写 0x92 -> 92#
            g_oil_type = OIL_92;
            break;
        case 0x95:
            g_oil_type = OIL_95;
            break;
        case 0x98:
            g_oil_type = OIL_98;
            break;
        default:
            return false;
    }

//    Save_CalibPoints_ToFlash(); // 保存到 Flash
    return true;
}



// 06写指令应答结构体
ModbusWriteRegister_t WriteReg_map[] = {
    {0x4010, handle_slave_addr},
    {0x4011, handle_baudrate},
    {0x4040, handle_reboot},
    {0x4042, handle_factory_reset},

		{0x0100, handle_uint16_t_oil_type}, // 油品
};
size_t REGISTER_MAP_SIZE = sizeof(WriteReg_map) / sizeof(WriteReg_map[0]);

/**
	* 10写多寄存器相关函数
***/

bool handle_float_multi(uint16_t *values, void *arg) {
    float f;
    memcpy(&f, values, sizeof(float));
    *(float *)arg = f;  // 直接写到目标变量
//    Save_CalibPoints_ToFlash();
    return true;
}

// 10多寄存器写映射表
ModbusWriteMultiRegister_t WriteMultiReg_map[] = {

		// --- 阀杆电压标定值 ---
		{0x0102, 2, handle_float_multi, &JsWork.calib_rod.vol_values[0]},
    {0x0104, 2, handle_float_multi, &JsWork.calib_rod.vol_values[1]},
    {0x0106, 2, handle_float_multi, &JsWork.calib_rod.vol_values[2]},
    {0x0108, 2, handle_float_multi, &JsWork.calib_rod.vol_values[3]},
    {0x010A, 2, handle_float_multi, &JsWork.calib_rod.vol_values[4]},
    {0x010C, 2, handle_float_multi, &JsWork.calib_rod.vol_values[5]},
    {0x010E, 2, handle_float_multi, &JsWork.calib_rod.vol_values[6]},
		
    // --- 油水电容标定值 ---
		{0x0110, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[0]},
		{0x0112, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[1]},
		{0x0114, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[2]},
		{0x0116, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[3]},
		{0x0118, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[4]},
		{0x011A, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[5]},
		{0x011C, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[6]},
		{0x011E, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[7]},
		{0x0120, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[8]},
		{0x0122, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[9]},
		{0x0124, 2, handle_float_multi, &JsWork.calib_oil_water.cap_values[10]},

		// --- 余油电容标定值 ---
		{0x0126, 2, handle_float_multi, &JsWork.calib_residual_oil.cap_values[0]},
		{0x0128, 2, handle_float_multi, &JsWork.calib_residual_oil.cap_values[1]},
		{0x012A, 2, handle_float_multi, &JsWork.calib_residual_oil.cap_values[2]},
		{0x012C, 2, handle_float_multi, &JsWork.calib_residual_oil.cap_values[3]},
		{0x012E, 2, handle_float_multi, &JsWork.calib_residual_oil.cap_values[4]},
		{0x0130, 2, handle_float_multi, &JsWork.calib_residual_oil.cap_values[5]},

		// --- 余油电压标定值 ---
		{0x0132, 2, handle_float_multi, &JsWork.calib_residual_oil.vol_values[0]},
		{0x0134, 2, handle_float_multi, &JsWork.calib_residual_oil.vol_values[1]},
		{0x0136, 2, handle_float_multi, &JsWork.calib_residual_oil.vol_values[2]},
		{0x0138, 2, handle_float_multi, &JsWork.calib_residual_oil.vol_values[3]},
		{0x013A, 2, handle_float_multi, &JsWork.calib_residual_oil.vol_values[4]},
		{0x013C, 2, handle_float_multi, &JsWork.calib_residual_oil.vol_values[5]},
		
		// --- 阀杆计算相关 ---
		{0x0206, 2, handle_float_multi, (void *)&ADS_v0_offset}, // 通道0电压数据偏移值（阀杆）
//		{0x0208, 2, handle_float_multi, (void *)&}, // 电压值滤波滑动窗口大小（阀杆）
		
		// --- 油水计算相关 ---
		{0x020E, 2, handle_float_multi, (void *)&oil_para_indu}, // 1号并联电感值(油水)
		{0x0210, 2, handle_float_multi, (void *)&oil_para_cap}, // 1号并联电容值(油水)
		{0x0212, 2, handle_float_multi, (void *)&oil_cap_offset}, // 1号电容偏移值(油水)
//		{0x0214, 2, handle_float_multi, (void *)&}, // 电容值滤波滑动窗口大小（油水）
		
		// --- 余油计算相关 ---
		{0x0220, 2, handle_float_multi, (void *)&res_oil_para_indu}, // 2号并联电感值(余油)
		{0x0222, 2, handle_float_multi, (void *)&res_oil_para_cap}, // 2号并联电容值(余油)
		{0x0224, 2, handle_float_multi, (void *)&res_oil_cap_offset}, // 2号电容偏移值(余油)
		{0x0226, 2, handle_float_multi, (void *)&ADS_v1_offset}, // 通道1电压数据偏移值（余油）
//		{0x0228, 2, handle_float_multi, (void *)&}, // 电容值滤波滑动窗口大小（余油）
//		{0x022A, 2, handle_float_multi, (void *)&}, // 电压值滤波滑动窗口大小（余油）

		// --- 温度计算相关 ---
		{0x0230, 2, handle_float_multi, (void *)&ADS_v2_offset}, // 通道2电压数据偏移值（温度）
//		{0x0232, 2, handle_float_multi, (void *)&}, // 温度值滤波滑动窗口大小（温度）

};

size_t MULTI_REGISTER_MAP_SIZE = sizeof(WriteMultiReg_map) / sizeof(WriteMultiReg_map[0]);

/********************************************************************************************************************
	* 做主机时使用
	*
*********************************************************************************************************************/	
	
//  Modbus 读保持寄存器命令帧（功能码 0x03）
uint16_t build_modbus_read_cmd(uint8_t device_addr, uint16_t reg_addr, uint16_t reg_num, uint8_t *out_buf) 
{
    uint16_t i = 0;

    out_buf[i++] = device_addr;             // 设备地址
    out_buf[i++] = 0x03;                    // 功能码 0x03 读保持寄存器
    out_buf[i++] = (reg_addr >> 8) & 0xFF;  // 起始寄存器地址高位
    out_buf[i++] = reg_addr & 0xFF;         // 起始寄存器地址低位
    out_buf[i++] = (reg_num >> 8) & 0xFF;   // 读取寄存器数量高位
    out_buf[i++] = reg_num & 0xFF;          // 读取寄存器数量低位

    uint16_t crc = modbus_crc16(out_buf, i);
    out_buf[i++] = crc & 0xFF;              // CRC低位
    out_buf[i++] = crc >> 8;                // CRC高位

    return i;  // 命令帧总长度
}

// Modbus 功能码0x10的写寄存器命令
// data: uint16_t 数组，每个元素是一个寄存器的数据（2字节）
// 返回帧长度
uint16_t build_modbus_write_cmd(uint8_t device_addr, uint8_t func_code,
																uint16_t reg_addr, uint16_t reg_count,
                                uint16_t *data, uint8_t *out_buf) 
{
    uint8_t byte_count = reg_count * 2;
    uint16_t i = 0;

    out_buf[i++] = device_addr;                    // 设备地址
    out_buf[i++] = func_code;                      // 功能码（0x10）
    out_buf[i++] = (reg_addr >> 8) & 0xFF;         // 起始寄存器地址高8位
    out_buf[i++] = reg_addr & 0xFF;                // 起始寄存器地址低8位
    out_buf[i++] = (reg_count >> 8) & 0xFF;        // 寄存器数量高8位
    out_buf[i++] = reg_count & 0xFF;               // 寄存器数量低8位
    out_buf[i++] = byte_count;                     // 数据字节数

    // 写入数据（每个寄存器2字节）
    for (uint16_t j = 0; j < reg_count; j++) {
        out_buf[i++] = (data[j] >> 8) & 0xFF;
        out_buf[i++] = data[j] & 0xFF;
    }

    // 计算 CRC
    uint16_t crc = modbus_crc16(out_buf, i);
    out_buf[i++] = crc & 0xFF;    // CRC低位
    out_buf[i++] = crc >> 8;      // CRC高位

    return i; // 返回命令总长度
}


