#ifndef _MB_Slave_H
#define _MB_Slave_H
#include "UART.h"
#include "type_def.h"
#include "config.h"
#include "CRC_16.h"
#include "AD_DEAL.h"
// -------------------------- 宏定义【线圈改成 1000】--------------------------
#define S_COIL_NCOILS                144    // 线圈数量 1000 → 长度 125 字节
#define S_DISCRETE_INPUT_NDISCRETES  32
#define S_REG_INPUT_NREGS            36
#define S_REG_HOLDING_NREGS          1000


//寄存器首地址
#define S_COIL_START 0x0000
#define S_DISCRETE_INPUT_START 0x0000
#define S_REG_INPUT_START 0x0000
#define S_REG_HOLDING_START 0x0000


#ifndef ModBus_Slave_UART
#define ModBus_Slave_UART            UART_1
#endif
//#define MB_S_RS485_CONTROL_PIN P3_5
//#define MB_S_RS485_CONTROL_PIN_MODE {P3M1&=~0x20;P3M0&=~0x20;} //双向IO口

#define MB_S_RS485_CONTROL_PIN       P4_1
#define MB_S_RS485_CONTROL_PIN_MODE   {P4M1&=~0x02;P4M0&=~0x02;}
#define MB_S_RS485_CONTROL_SEND_MODE 1

#define MB_SLAVE                     1

// -------------------------- 串口 --------------------------
#ifndef UART_1
#define UART_1      0
#endif
#ifndef UART_2
#define UART_2      1
#endif
#ifndef UART_3
#define UART_3      2
#endif
#ifndef UART_4
#define UART_4      3
#endif

// -------------------------- 枚举 --------------------------
typedef enum
{
    MB_S_PAR_NONE,
    MB_S_PAR_ODD,
    MB_S_PAR_EVEN
} MBSlaveParity;

// -------------------------- 外部变量 --------------------------
extern volatile uint16 _ModBus_Id;
extern MBSlaveParity mb_s_Parity;

extern uint16 xdata usSRegInBuf[S_REG_INPUT_NREGS];
extern uint16 xdata usSRegHoldBuf[S_REG_HOLDING_NREGS];

// 【自动计算长度】1000线圈 = 125字节
extern  uint8 xdata ucSCoilBuf[(S_COIL_NCOILS % 8) ? ((S_COIL_NCOILS / 8) + 1) : (S_COIL_NCOILS / 8)];
extern  uint8 xdata ucSDiscInBuf[(S_DISCRETE_INPUT_NDISCRETES % 8) ? ((S_DISCRETE_INPUT_NDISCRETES / 8) + 1) : (S_DISCRETE_INPUT_NDISCRETES / 8)];

extern uint8 xdata ModBus_temp[256];      // 串口接收临时缓冲区，存放未校验的原始数据
extern uint8 xdata ModBus_data[256];      // 校验合格后的有效Modbus指令缓冲区
extern uint8 xdata ModBus_Send_data[256]; // 组装Modbus应答报文的发送缓冲区
extern uint8 xdata data_temp[256];        // 发送数据临时拷贝区（加CRC用）



// -------------------------- 函数 --------------------------
void MBSlaveInit(uint16 id, UART_Name uart_n, UART_PIN uart_rx_pin, UART_PIN uart_tx_pin, uint32 baud, UART_TIMN tim_n, MBSlaveParity eParity);
void MBSlavePoll();
int8 MBSlaveGetCoil(uint16 addr);
int8 MBSlaveSetCoil(uint16 addr,uint8 vol);
int8 MBSlaveGetDisc(uint16 addr);
int8 MBSlaveSetDisc(uint16 addr,uint8 vol);
uint16 MBSlaveGetInputReg(uint16 addr);
int8 MBSlaveSetInputReg(uint16 addr,uint16 vol);
uint16 MBSlaveGetHoldReg(uint16 addr);
int8 MBSlaveSetHoldReg(uint16 addr,uint16 vol);
void MBSlaveTimerCallback();

void MBSlaveSerialInit(UART_Name uart_n, UART_PIN uart_rx_pin, UART_PIN uart_tx_pin, uint32 baud, UART_TIMN tim_n, MBSlaveParity eParity);
void MBSlaveSerialPutBuff(UART_Name uart_n, uint8* p, uint16 len);
uint8 MBSlaveSerialGetBuff();
uint16 CRC16(uint8* pucFrame, uint16 usLen);

int8 MBMasterGetResult(uint8 MB_id, uint16 uslen, uint8 *databuf);

void MBSlaveClearRecvBuf(void);    // 手动清空接收缓存&状态
void MBSlaveProcessFault(void);

#endif // _MB_Slave_H