#ifndef _MODBUSSIMPLE_H_
#define _MODBUSSIMPLE_H_

#include "main.h"

extern uint8_t Device_addr; // 从设备地址
extern uint32_t g_modbusbuffer[40] ; // 当用DMA发送的时候 帧头要四字节对齐

typedef enum {
    MODBUS_TYPE_UINT16,
    MODBUS_TYPE_UINT32_BE,   // 高字节优先，2个寄存器
    MODBUS_TYPE_FLOAT_BE,    // float 类型，按 uint32_t 方式输出，2个寄存器
		MODBUS_TYPE_OILTYPE
} ModbusDataType;

// 03读指令应答结构体
typedef struct {
    uint16_t address;     					// 寄存器地址
    uint8_t  length;      					// 寄存器数量（单位：16位）
		ModbusDataType type;     				// 数据类型
    void     *data_ptr;    					// 指向实际数据的指针
} ModbusRegister_t;
extern ModbusRegister_t modbus_map[];

// 06写指令应答结构体
typedef struct {
    uint16_t address;                              // 寄存器地址
    bool (*handler)(uint16_t value);               // 寄存器处理函数，返回是否应答
} ModbusWriteRegister_t;
extern ModbusWriteRegister_t WriteReg_map[];

// 0x10 写多寄存器映射结构体
typedef struct {
    uint16_t start_address;              // 起始寄存器地址
    uint16_t reg_count;                  // 占用寄存器数量（比如 float 占 2，字符串占 N）
    bool (*handler)(uint16_t *values, void *arg); // 通用处理函数
		void *arg;                    // 额外参数（可以是数组下标、目标变量指针等）
} ModbusWriteMultiRegister_t;
extern ModbusWriteMultiRegister_t WriteMultiReg_map[];

extern size_t REGISTER_MAP_SIZE;
extern size_t MULTI_REGISTER_MAP_SIZE;

uint16_t modbus_crc16(uint8_t *data, uint16_t length) ; // Modbus CRC16（低位在前，高位在后）
bool read_modbus_registers(uint16_t addr, uint16_t len, uint8_t *dest_buf, uint16_t *out_byte_count);
// 将 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) ;

// 功能码 0x03 响应帧（角度浮点数值float）
uint16_t modbus_03response_float(uint8_t device_addr, uint8_t num, float value, uint8_t *out_buf);
// 返回错误响应帧，例如非法功能码、非法地址等错误
uint16_t modbus_error_response(uint8_t addr, uint8_t func_code, uint8_t err_code, uint8_t *buf);

void Set_485_Baudrate(uint16_t baudrate_id);
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);// Modbus 功能码0x10的写寄存器命令
uint16_t build_modbus_read_cmd(uint8_t device_addr, uint16_t reg_addr, uint16_t reg_num, uint8_t *out_buf) ; //  Modbus 读保持寄存器命令帧（功能码 0x03）	

#endif

