
#include "bl_usart.h"
#include "parameter.h"
#include "chargControlTypes.h"
#include "configParameter.h"
#include "string.h"
#include "pDebug.h"
#include "bl_chargControl.h"
#include "interruptSend.h"
#include "inFlash.h"
#include "SOE.h"
#include "FM_RTC.h"
#include "SOE.h"
#include "abnormalManage.h"
#include "timeSliceOffset.h"

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE

#define HY_hardWordIDStartAddr         8192
#define HY_hardWordIDSize              6
#define HY_communicationIDStartAddr    (HY_hardWordIDStartAddr + HY_hardWordIDSize)
#define HY_communicationIDSize         4
static uint8_t HY_hardWordID[HY_hardWordIDSize] = {0x48, 0x59, 0x30, 0x30, 0x30, 0x31};
static uint8_t HY_communicationID[HY_communicationIDSize] = {0x00, 0x00, 0x00, 0x02};
static uint8_t HY_startFlag = 0x68;
static uint8_t HY_endFlag = 0x16;

/* 帧序号 */
uint8_t HY_frameNumber[4] = {0};

#define HY_device g_gw485_uart2_handle

static void HY_writeHardWordID_Flash(void);
static void HY_readHardWordID_Flash(void);
static void HY_writeCommunicationID_Flash(void);
static void HY_readCommunicationID_Flash(void);


/* HY进入配置模式延迟后退出 */
#define HY_configurationModeDelayedExit_reloadVal 1000         /* 任务执行间隔  */
#define HY_configurationModeDelayedExit_offset 0               /* 任务执行偏移量  */
STR_TimeSliceOffset m_HY_configurationModeDelayedExit;
/* 计时 */
static uint8_t HY_configurationModeDelay = 0;
/* 是否进入配置模式标志 */
static uint8_t HY_configurationModeFlag = 0;
void Task_HY_configurationModeDelayedExit(void)
{
    if (120 == ++HY_configurationModeDelay) {
        HY_configurationModeDelay = 0;
        HY_configurationModeFlag = 0;
        TimeSliceOffset_Unregister(&m_HY_configurationModeDelayedExit);
        m_HY_configurationModeDelayedExit.runFlag = 0;
    }
}

/**
  * @brief  启动HY进入配置模式
  * @param 
  * @retval 
  */
void HY_configurationMode_start(void)
{
    HY_configurationModeFlag = 1;
    HY_configurationModeDelay = 0;
    TimeSliceOffset_Register(&m_HY_configurationModeDelayedExit, Task_HY_configurationModeDelayedExit
                , HY_configurationModeDelayedExit_reloadVal, HY_configurationModeDelayedExit_offset);
}

/**
  * @brief  HY退出配置模式
  * @param 
  * @retval 
  */
void HY_configurationMode_stop(void)
{
    HY_configurationModeFlag = 0;
    TimeSliceOffset_Unregister(&m_HY_configurationModeDelayedExit);
    m_HY_configurationModeDelayedExit.runFlag = 0;
    HY_configurationModeDelay = 0;
}

#endif


/* 状态机 */
typedef enum {
    wait                        = 0,    /* 串口状态机初始状态 */
    startFlagSL,                        /* 接收到SL帧头 */
    addressSL,                          /* 接收到设备地址 */
    functionCodeSL,                     /* 接收到SL功能码 */
    readRegStartAddressSL,              /* 接收到SL读取寄存器起始地址 */
    readRegStartNumberSL,               /* 接收到SL读取寄存器个数 */
    crcCheckBitSL,                      /* 接收到SL校验位 */
    endFlagSL,                          /* 接收到SL帧尾 */
    writeRegStartAddressSL,             /* 接收到SL写入寄存器起始地址 */
    writeRegStartNumberSL,              /* 接收到SL写入寄存器个数 */
    regLengthSL,                        /* 接收到SL寄存器长度 */
    regStatusSL,                        /* 接收到SL寄存器状态 */
    cfgFramesNumSL,                     /* 接收到SL配置文件帧数 */
    cfgLengthSL,                        /* 接收到SL配置文件长度 */
    readCfgLengthSL,                    /* 接收到SL读取配置文件长度 */
    readSOEStartAddr,                   /* 接收到SOE起始读取位 */
    readSOELength,                      /* 接收到SOE读取长度 */

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE    
    startFlagHY,                        /* 接收到HY帧头 */
    hardWordIDHY,                       /* 接收到HY硬件ID */
    communicationIDHY,                  /* 接收到HY通信ID */
    controlWordHY,                      /* 接收到HY控制字 */
    dataLengthHY,                       /* 接收到HY数据长度 */
    
    batteryStatusHY,                    /* 接收到HY电池数据 */
    electricityStatisticsHY,            /* 接收到HY电量统计 */
    sensorNumberConfigurationHY,        /* 接收到HY传感器号码配置 */
    sensorNumberInquiryHY,              /* 接收到HY传感器号码查询 */
    resetInstructionHY,                 /* 接收到HY复位指令 */
    chargeControlConfigurationHY,       /* 接收到HY充电控制配置 */
    chargeControlQueryHY,               /* 接收到HY充电控制查询 */
    configureTimeHY,                    /* 接收到HY时间配置 */
    queryTimeHY,                        /* 接收到HY时间查询 */
    configureProtocolTypeHY,            /* 接收到HY配置协议类型 */
    // responseProtocolTypeHY,             /* 接收到HY响应协议类型 */
    queryControlBoxConfigurationHY,     /* 接收到HY查询电池控制盒当前配置 */
    querySoftwareVersionHY,             /* 接收到HY查询电池控制盒软件版本 */
    enterConfigurationModeHY,           /* 接收到HY配置模式 */
    configureHardwareIDHY,              /* 接收到HY配置控制盒硬件ID号 */
    hardwareID_communicationIDQueryHY,  /* 接收到HY控制盒硬件ID号及通信ID号（原传感器号）查询 */
    modifyCommunicationIDHY,            /* 接收到HY修改通信ID号（原传感器号） */
    checkMotherboardTemperatureHY,      /* 接收到HY查询主板温度值 */

    // checkCodeHY,                        /* 接收到HY校验位 */
    // endFlagHY,                          /* 接收到HY帧尾 */
#endif
} uartStateMachine;

/* 功能码 */
typedef enum
{
   SL_Function_Code_Read_Register           =   0x30,   /* 读寄存器数据 */
   SL_Function_Code_Write_Register          =   0x10,   /* 写寄存器数据 */
   SL_Function_Code_Broadcast_Scan          =   0xA0,   /* 广播扫描 */
   SL_Function_Code_Registration_request    =   0xA1,   /* 注册请求 */
   SL_Function_Code_Distribution_Profile    =   0xD0,   /* 配置文件下发 */
   SL_Function_Code_Read_Profile            =   0xD1,   /* 配置文件读取 */
   SL_Function_Code_Read_SOE                =   0x05,   /* 读取SOE */
}SL_MsgFunctionCode;

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE
/* HY协议控制字 */
typedef enum
{
    HY_batteryStatus                            = 0x60, /* 电池状态数据报 */
    HY_electricityStatistics                    = 0x61, /* 电量统计数据报 */
    HY_sensorNumberConfiguration                = 0x62, /* 传感器号码配置 */
    HY_sensorNumberInquiry                      = 0x63, /* 传感器号码查询 */

    HY_resetInstruction                         = 0x66, /* 复位指令 */

    HY_chargeControlConfiguration               = 0x6C, /* 充电控制配置 */
    HY_chargeControlQuery                       = 0x6D, /* 充电控制查询 */
    HY_configureTime                            = 0x6E, /* 配置时间 */
    HY_queryTime                                = 0x6F, /* 查询时间 */

    HY_configureProtocolType                    = 0x70, /* 配置协议类型 */
    HY_responseProtocolType                     = 0x71, /* 响应配置协议类型 */

    HY_queryControlBoxConfiguration             = 0x74, /* 查询电池控制盒当前配置 */
    HY_querySoftwareVersion                     = 0x75, /* 查询电池控制盒软件版本 */ 
    HY_enterConfigurationMode                   = 0x76, /* 进入配置模式 */

    HY_configureHardwareID                      = 0x7B, /* 配置控制盒硬件ID号 */
    HY_hardwareID_communicationIDQuery          = 0x7C, /* 控制盒硬件ID号及通信ID号（原传感器号）查询 */
    HY_modifyCommunicationID                    = 0x7D, /* 修改通信ID号（原传感器号） */
    HY_checkMotherboardTemperature              = 0x7E, /* 查询主板温度值 */

}HY_MsgFunctionCode;
#endif




/* 寄存器地址 */
typedef enum
{
   SL_Register_Registration_Status          = 0x0000,  /* 注册状态  */
   SL_Register_address                      = 0x0001,  /* 地址  */
   SL_Register_Access_Node_Type             = 0x0002,  /* 接入节点类型   */
   SL_Register_Communication_Methods        = 0x0003,  /* 通信方式   */

   SL_Register_Solar_Open_Circuit_Voltage   = 0x0100,  /* 太阳能开路电压 */
   SL_Register_Solar_Input_Voltage          = 0x0101,  /* 太阳能输入电压 */
   SL_Register_Output_Voltage               = 0x0102,  /* 输出电压   */
   SL_Register_Battery_Voltage              = 0x0103,  /* 电池电压   */
   SL_Register_Charg_Current                = 0x0104,  /* 充电电流（流向电池+负载）   */
   SL_Register_Discharg_Current             = 0x0105,  /* 放电电流（流向负载）   */
   SL_Register_HighSideMos_Temperature      = 0x0106,  /* 高端mos的温度 */
   SL_Register_SOC                          = 0x0107,  /* 剩余电量 */
   SL_Register_chargState                   = 0x0108,  /* 充电状态 */
   SL_Register_totalChargCapacity           = 0x0109,  /* 总充电量 */
   SL_Register_totalElectricityConsumption  = 0x010A,  /* 总放电量 */
   SL_Register_MPPT_Mode                    = 0x010B,  /* 工作模式 */

   SL_Register_eliminateStatistical         = 0x0120,  /* 消除统计 */
   SL_Register_Charg_Control                = 0x0121,  /* 充电控制 */
   SL_Register_DisCharg_Control             = 0x0122,  /* 放电控制 */
   SL_Register_Clean_SOE                    = 0x0123,  /* 清除SOE */

   SL_Register_YearMonth                    = 0x0130,  /* rtc时钟校准-年月 */
   SL_Register_DayHour                      = 0x0131,  /* rtc时钟校准-日时 */
   SL_Register_MinuteSecond                 = 0x0132,  /* rtc时钟校准-分秒 */
}SL_Mppt_MsgRegister;

/* 配置文件数据类型表 */
typedef enum {
    unique_Device_ID                        = 0x0000,   /* (7字节)唯一设备标识码  */
    SL_Protocol_Communication_Baud_Rate_Up  = 0x0001,   /* (1字节)SL协议对上通信波特率(01H：4800;02H：9600;03H：19200;04H：38400;05H：57600;06H：115200)  */
    SL_Protocol_Communication_Baud_Rate_Down= 0x0002,   /* (1字节)SL协议对下通信波特率(01H：4800;02H：9600;03H：19200;04H：38400;05H：57600;06H：115200)  */

    power_Box_Type                          = 0x0100,   /* (1字节)电源盒类型(00H：带网关; FFH：仅充电)  */
    constant_Voltage_V                      = 0x0101,   /* (2字节)恒压充电阈值电压(*10再强转u16(V)) */
    float_I                                 = 0x0102,   /* (2字节)浮充充电阈值电流(*10再强转u16(A)) */
    start_Solar_Open_Circuit_V              = 0x0103,   /* (2字节)启动充电太阳能板开路电压(*10再强转u16(A)) */
    stop_Solar_Output_Circuit_V             = 0x0104,   /* (2字节)停止充电太阳能板输出电压(*10再强转u16(A)) */
    check_Can_Start_Time                    = 0x0105,   /* (2字节)检测能否启动间隔时间(S) */
    short_Circuit_Judgment_Delay            = 0x0106,   /* (2字节)短路判断延时(S) */
    input_Power_Low_Judgment_Delay          = 0x0107,   /* (2字节)前端输入功率不足判断延时(S) */
    input_Power_Low_Again_Output_Delay      = 0x0108,   /* (2字节)前端输入功率不足再次输出延时(S) */
    first_Stage_Protection_Delay            = 0x0109,   /* (2字节)第一段保护延时(10uS) */
    first_Stage_Protection_Curr             = 0x010A,   /* (2字节)第一段保护电流(*10再强转u16(A)) */
    second_Stage_Protection_Delay           = 0x010B,   /* (2字节)第二段保护延时(100uS) */
    second_Stage_Protection_Curr            = 0x010C,   /* (2字节)第二段保护电流(*10再强转u16(A)) */
    third_Stage_Protection_Delay            = 0x010D,   /* (4字节)第三段保护延时(100uS) */
    third_Stage_Protection_Curr             = 0x010E,   /* (2字节)第三段保护电流(*10再强转u16(A)) */
    input_Power_Low_Detection_Delay         = 0x010F,   /* (2字节)前端输入功率不足检测延时(100uS) */
    input_Power_Low_Detection_Volt          = 0x0110,   /* (2字节)前端输入功率不足检测电压(*10再强转u16(V)) */
    max_Open_Solar_Output_Circuit_V         = 0x0111,   /* (2字节)最大太阳能板输出电压(*10再强转u16(V)) */
    max_Charg_Curr                          = 0x0112,   /* (2字节)最大充电电流(*10再强转u16(A)) */
    min_Check_Loop_Impedance_Charg_Curr     = 0x0113,   /* (2字节)检测回路阻抗时的最小充电电流(*10再强转u16(A)) */
    full_Power_Output_Temperature           = 0x0114,   /* (2字节)满功率输出温度(*10再强转u16(℃)) */
    reduce_Power_Output_Temperature         = 0x0115,   /* (2字节)降功率输出温度(*10再强转u16(℃)) */
    stop_PowerOutput_Temperature            = 0x0116,   /* (2字节)停止输出温度(*10再强转u16(℃)) */
    constant_Voltage_Charge_V               = 0x0117,   /* (2字节)恒压充电时的输出电压(*10再强转u16(V)) */
    float_ChargeV                           = 0x0118,   /* (2字节)浮充充电时的输出电压(*10再强转u16(V)) */
    collect_OpenCircuit_Voltage_Time        = 0x0119,   /* (2字节)充电时采集开路电压的间隔时间(S) */
    reverse_Charge_Protection_Curr          = 0x011A,   /* (2字节)反向充电保护电流(A) */

    soft_Start_Volt                         = 0x011B,   /* (2字节)软启动电压(*10再强转u16(V)) */
    MPPT_Constant_Voltage                   = 0x011C,   /* (2字节)MPPT恒定输出电压(*10再强转u16(V)) */
    MPPT_Reduce_Constant_Voltage            = 0x011D,   /* (2字节)MPPT降功率运行时控制输入电压稳定值(*10再强转u16(V)) */
    under_Voltage_Protection                = 0x011E,   /* (2字节)欠压保护电压(*10再强转u16(V)) */
}cfgFileType;

#define gw485RxBufferSize 256
#define regLength 19

/* 计时参数，1min后没解析整个配置文件，丢掉当前数据 */
static uint32_t gw485CfgTime = 0;
static uint8_t gw485CfgFlag = 0;    //0:解析完成或未下发配置文件 1：下发配置文件中 2：上次配置文件下发时间过长

/* 计时参数，一秒后没解析出数据，丢掉当前数据 */
static uint32_t gw485RxTime = 0;

/* 储存gw485数据 */
static uint8_t gw485RxBuffer[gw485RxBufferSize];
static uint16_t gw485RxBufferIndex = 0;
/* 状态机状态机变量 */
static uartStateMachine state = wait;
static uint16_t frameLength = 0;

static void stateMachine(device_handle device);
static BOOL checkCrcSl(void);

/* 状态机函数 */
static BOOL analysisWait(void);
static BOOL analysisStartFlagSL(void);
static BOOL analysisAddressSL(void);
static BOOL analysisFunctionCodeSL(void);
static BOOL analysisReadRegStartAddressSL(void);
static BOOL analysisReadRegStartNumberSL(void);
static BOOL analysisCrcCheckBitSL(void);
static void analysisEndFlagSL(device_handle device);
static BOOL analysisWriteRegStartAddressSL(void);
static BOOL analysisWriteRegStartNumberSL(void);
static BOOL analysisRegLengthSL(void);
static BOOL analysisRegStatusSL(void);
static BOOL analysisCfgFramesNumSL(void);
static BOOL analysiscfgLengthSL(void);
static BOOL analysisReadCfgLengthSL(void);
static BOOL analysisReadSOEStartAddr(void);
static BOOL analysisReadSOELength(void);

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE
    static BOOL analysisStartFlagHY(void);
    static BOOL analysisHardWordIDHY(void);
    static BOOL analysisCommunicationIDHY(void);
    static BOOL analysisControlWordHY(void);
    static BOOL analysisDataLengthHY(void);
    static BOOL analysisBatteryStatusHY(void);
    static BOOL analysisElectricityStatisticsHY(void);
    static BOOL analysisSensorNumberConfigurationHY(void);
    static BOOL analysisSensorNumberInquiryHY(void);
    static BOOL analysisResetInstructionHY(void);
    static BOOL analysisChargeControlConfigurationHY(void);
    static BOOL analysisChargeControlQueryHY(void);
    static BOOL analysisConfigureTimeHY(void);
    static BOOL analysisQueryTimeHY(void);
    static BOOL analysisConfigureProtocolTypeHY(void);
    static BOOL analysisQueryControlBoxConfigurationHY(void);
    static BOOL analysisQuerySoftwareVersionHY(void);
    static BOOL analysisEnterConfigurationModeHY(void);
    static BOOL analysisConfigureHardwareIDHY(void);
    static BOOL analysisHardwareID_communicationIDQueryHY(void);
    static BOOL analysisModifyCommunicationIDHY(void);
    static BOOL analysisCheckMotherboardTemperatureHY(void);
    // static BOOL analysisCheckCodeHY(void);
    // static BOOL analysisEndFlagHY(void);
#endif

/* SL协议寄存器解析 */
static uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg);
static uint16_t SL_ReadRegisterSolarInputVoltage(void *pMsg);
static uint16_t SL_ReadRegisterOutputVoltage(void *pMsg);
static uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg);
static uint16_t SL_ReadRegisterChargCurrent(void *pMsg);
static uint16_t SL_ReadRegisterDischargCurrent(void *pMsg);
static uint16_t SL_ReadRegisterHighSideMosTemperature(void *pMsg);
static uint16_t SL_ReadRegisterSOC(void *pMsg);
static uint16_t SL_ReadRegisterChargState(void *pMsg);
static uint16_t SL_ReadRegisterTotalChargCapacity(void *pMsg);
static uint16_t SL_ReadRegisterTotalElectricityConsumption(void *pMsg);
static uint16_t SL_ReadRegisterMPPT_Mode(void *pMsg);
static uint16_t SL_ReadRegisterYearMonth(void *pMsg);
static uint16_t SL_ReadRegisterDayHour(void *pMsg);
static uint16_t SL_ReadRegisterMinuteSecond(void *pMsg);

static uint16_t SL_WriteRegisterEliminateStatistical(void *pMsg);
static uint16_t SL_WriteRegisterChargControl(void *pMsg);
static uint16_t SL_WriteRegisterDisChargControl(void *pMsg);
static uint16_t SL_WriteRegisterCleanSOE(void *pMsg);

static uint16_t SL_WriteRegisterYearMonth(void *pMsg);
static uint16_t SL_WriteRegisterDayHour(void *pMsg);
static uint16_t SL_WriteRegisterMinuteSecond(void *pMsg);

/* 寄存器处理表 */
typedef uint16_t (*RegProcFunc)(void*);
typedef struct _SL_RegProcTable{
    uint32_t     regId;
    RegProcFunc  pRegProc;
}SL_RegProcTable;

/* 寄存器处理表 */
SL_RegProcTable g_RegTblR[] =
{
//    {SL_Register_Registration_Status,           SL_ReadRegisterRegistrationStatus},
//    {SL_Register_address,                       SL_ReadRegisteraddress},
//    {SL_Register_Access_Node_Type,              SL_ReadRegisterAccessNodeType},
//    {SL_Register_Communication_Methods,         SL_ReadRegisterCommunicationMethods},
    {SL_Register_Solar_Open_Circuit_Voltage,    SL_ReadRegisterSolarOpenCircuitVoltage},
    {SL_Register_Solar_Input_Voltage,           SL_ReadRegisterSolarInputVoltage},
    {SL_Register_Output_Voltage,                SL_ReadRegisterOutputVoltage},
    {SL_Register_Battery_Voltage,               SL_ReadRegisterBatteryVoltage},
    {SL_Register_Charg_Current,                 SL_ReadRegisterChargCurrent},
    {SL_Register_Discharg_Current,              SL_ReadRegisterDischargCurrent},
    {SL_Register_HighSideMos_Temperature,       SL_ReadRegisterHighSideMosTemperature},
    {SL_Register_SOC,                           SL_ReadRegisterSOC},
    {SL_Register_chargState,                    SL_ReadRegisterChargState},
    {SL_Register_totalChargCapacity,            SL_ReadRegisterTotalChargCapacity},
    {SL_Register_totalElectricityConsumption,   SL_ReadRegisterTotalElectricityConsumption},
    {SL_Register_MPPT_Mode,                     SL_ReadRegisterMPPT_Mode},
    {SL_Register_YearMonth,                     SL_ReadRegisterYearMonth},
    {SL_Register_DayHour,                       SL_ReadRegisterDayHour},
    {SL_Register_MinuteSecond,                  SL_ReadRegisterMinuteSecond},
};

/* 寄存器处理表 */
SL_RegProcTable g_RegTblW[] =
{
//    {SL_Register_Registration_Status,           SL_WriteRegisterRegistrationStatus},
//    {SL_Register_address,                       SL_WriteRegisteraddress},
//    {SL_Register_Access_Node_Type,              SL_WriteRegisterAccessNodeType},
//    {SL_Register_Communication_Methods,         SL_WriteRegisterCommunicationMethods},
    {SL_Register_eliminateStatistical,          SL_WriteRegisterEliminateStatistical},
    {SL_Register_Charg_Control,                 SL_WriteRegisterChargControl},
    {SL_Register_DisCharg_Control,              SL_WriteRegisterDisChargControl},
    {SL_Register_Clean_SOE,                     SL_WriteRegisterCleanSOE},
    {SL_Register_YearMonth,                     SL_WriteRegisterYearMonth},
    {SL_Register_DayHour,                       SL_WriteRegisterDayHour},
    {SL_Register_MinuteSecond,                  SL_WriteRegisterMinuteSecond},
};

/* 配置文件解析函数 */
static uint8_t *analysisDistributionProfile(uint8_t *pMsg, config_info *temp);
static uint8_t *analysisReadProfile(uint8_t *pMsg, uint8_t **outData, uint16_t *dataLen);



/* 解析出来指令对应函数 */
static void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Read_SOE(device_handle device, void *pMsg, uint32_t MsgLen);














/**
  * @brief  modbus的crc校验
  * @param  *arr_buff   需要校验的数据
  *         len         数据长度
  * @retval crc         校验的结果
  */
uint16_t checkModebusCrc(uint8_t *arr_buff, uint8_t len)
{
    uint16_t crc = 0xFFFF;
    uint16_t i, j;
    for (j = 0; j < len; ++j) {
        crc = crc ^ (*arr_buff++);
        for (i = 0; i < 8; ++i) {
            if ((crc&0x0001) > 0) {
                crc = crc >> 1;
                crc = crc ^ 0xa001;
            }
            else {
                crc = crc >> 1;
            }
        }
    }
    return crc;
}

/**
  * @brief  SL协议的crc校验
  * @param 
  * @retval 
  */
BOOL checkCrcSl(void)
{
   static uint16_t maxLen = 0;
   maxLen = frameLength - 1;
    /* crc校验 */
    if (gw485RxBufferIndex >= maxLen) {
        uint32_t tempCrc = 0;
        tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

        if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
            state = crcCheckBitSL;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE
/**
  * @brief  校验算法
  * @param  采用累加和取反的校验方式，将终端号码、传感器号码、控制字、数据长度和数据区的所有字节进行算术累加，抛弃高位，只保留最后单字节，将单字节取反；
  * @retval
  */
uint8_t HY_CheckFunc(uint8_t *arr_buff, uint8_t len)
{
    uint8_t temp = 0x00;
    uint32_t sum = 0x00;
    arr_buff++;

    for(uint8_t i = 1; i < len; i++) {
        sum += *arr_buff++;
    }

    temp = (~sum) & 0xff;

    return temp;
}
#endif

/**
  * @brief  状态机函数
  * @param 
  * @retval 
  */
void stateMachine(device_handle device)
{
    if (state == wait) {
        if (analysisWait() == TRUE) {
                gw485RxTime = 0;
        }
    }

    else if (state == startFlagSL) {
        analysisStartFlagSL();
    }

    else if (state == addressSL) {
        analysisAddressSL();
    }
    
    else if (state == functionCodeSL) {
        analysisFunctionCodeSL();
    }

    else if (state == readRegStartAddressSL) {
        analysisReadRegStartAddressSL();
    }

    else if (state == readRegStartNumberSL) {
        analysisReadRegStartNumberSL();
    }

    else if (state == crcCheckBitSL) {
        analysisCrcCheckBitSL();
    }

    else if (state == endFlagSL) {
        analysisEndFlagSL(device);
    }

    else if (state == writeRegStartAddressSL) {
        analysisWriteRegStartAddressSL();
    }

    else if (state == writeRegStartNumberSL) {
        analysisWriteRegStartNumberSL();
    }

    else if (state == regLengthSL) {
        analysisRegLengthSL();
    }

    else if (state == regStatusSL) {
        analysisRegStatusSL();
    }

    else if (state == cfgFramesNumSL) {
        analysisCfgFramesNumSL();
    }

    else if (state == cfgLengthSL) {
        analysiscfgLengthSL();
    }

    else if (state == readCfgLengthSL) {
        analysisReadCfgLengthSL();
    }

    else if (state == readSOEStartAddr) {
        analysisReadSOEStartAddr();
    }

    else if (state == readSOELength) {
        analysisReadSOELength();
    }

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE
    else if (g_cfgParameter.supportProtocolTypes & 0x01)
    {
        if (state == startFlagHY) {
            analysisStartFlagHY();
        }
        
        else if (state == hardWordIDHY) {
            analysisHardWordIDHY();
        }
        
        else if (state == communicationIDHY) {
            analysisCommunicationIDHY();
        }
        
        else if (state == controlWordHY) {
            analysisControlWordHY();
        }
        
        else if (state == dataLengthHY) {
            analysisDataLengthHY();
        }
        
        else if (state == batteryStatusHY) {
            analysisBatteryStatusHY();
        }
        
        else if (state == electricityStatisticsHY) {
            analysisElectricityStatisticsHY();
        }
        
        else if (state == sensorNumberConfigurationHY) {
            analysisSensorNumberConfigurationHY();
        }
        
        else if (state == sensorNumberInquiryHY) {
            analysisSensorNumberInquiryHY();
        }
        
        else if (state == resetInstructionHY) {
            analysisResetInstructionHY();
        }

        else if (state == chargeControlConfigurationHY) {
            analysisChargeControlConfigurationHY();
        }
        
        else if (state == chargeControlQueryHY) {
            analysisChargeControlQueryHY();
        }
        
        else if (state == configureTimeHY) {
            analysisConfigureTimeHY();
        }
        
        else if (state == queryTimeHY) {
            analysisQueryTimeHY();
        }
        
        else if (state == configureProtocolTypeHY) {
            analysisConfigureProtocolTypeHY();
        }
        
        else if (state == queryControlBoxConfigurationHY) {
            analysisQueryControlBoxConfigurationHY();
        }

        else if (state == querySoftwareVersionHY) {
            analysisQuerySoftwareVersionHY();
        }
        
        else if (state == enterConfigurationModeHY) {
            analysisEnterConfigurationModeHY();
        }
        
        else if (state == configureHardwareIDHY) {
            analysisConfigureHardwareIDHY();
        }
        
        else if (state == hardwareID_communicationIDQueryHY) {
            analysisHardwareID_communicationIDQueryHY();
        }
        
        else if (state == modifyCommunicationIDHY) {
            analysisModifyCommunicationIDHY();
        }
        
        else if (state == checkMotherboardTemperatureHY) {
            analysisCheckMotherboardTemperatureHY();
        }
    }
#endif
}

/* 串口通信协议的初始化 */
void uartCommonInit(void)
{
#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE
    HY_readCommunicationID_Flash();
    HY_readHardWordID_Flash();
#endif


}

void gw485DataAnalysis(device_handle device)
{
    /* 每次函数最多执行5ms */
    static uint32_t tickstart = 0U;
    tickstart = HAL_GetTick();

    /* 1S未解析出来一帧数据，将数据清零 */
    gw485RxTime++;
    if (gw485RxTime >= 100) {
        gw485RxTime = 0;
        gw485RxBufferIndex = 0;
        state = wait;
    }

    /* 60S所有配置文件未传输完成，将数据清零 */
    if (gw485CfgFlag == 1) {
        gw485CfgTime++;
        if (gw485CfgTime >= 6000) {
            gw485CfgTime = 0;
            gw485CfgFlag = 2;   
        }
    }

    while (uart_dev_char_present(device) == 1 && ((HAL_GetTick() - tickstart) < 5)) {
        gw485RxBuffer[gw485RxBufferIndex++] = uart_dev_in_char(device);
        stateMachine(device);
    }

//    tickstart = HAL_GetTick();
//    while (gw485RxBufferIndex != 0 && ((HAL_GetTick() - tickstart) < 5) ) {
//         stateMachine(device);
//    }

    if (state != wait) {        
        stateMachine(device);
    }
}

/**
 * @brief   状态 wait
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisWait(void)
{
    static const uint16_t maxLen = 2;

#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE
    /* 解析HY协议的包头 */
    if (gw485RxBuffer[0] == HY_startFlag) {
        state = startFlagHY;
        return TRUE;
    }
#endif

    /* 解析SL协议的包头 */
    if (gw485RxBufferIndex >= 2) {
        if (gw485RxBuffer[0] == 'S' && gw485RxBuffer[1] == 'L') {
            state = startFlagSL;
            return TRUE;
        }
    }


    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    log_error("analysisWait \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 StartFlagSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisStartFlagSL(void)
{
    static const uint16_t maxLen = 9;

    /* 解析SL协议设备地址 */
    if (gw485RxBufferIndex >= 9) {
        if (gw485RxBuffer[2] == g_cfgParameter.uniqueDeviceID[0]
                && gw485RxBuffer[3] == g_cfgParameter.uniqueDeviceID[1]
                && gw485RxBuffer[4] == g_cfgParameter.uniqueDeviceID[2]
                && gw485RxBuffer[5] == g_cfgParameter.uniqueDeviceID[3]
                && gw485RxBuffer[6] == g_cfgParameter.uniqueDeviceID[4]
                && gw485RxBuffer[7] == g_cfgParameter.uniqueDeviceID[5]
                && gw485RxBuffer[8] == g_cfgParameter.uniqueDeviceID[6]) {
            state = addressSL;
            return TRUE;
        }
        
        if (gw485RxBuffer[2] == 0xFF
                && gw485RxBuffer[3] == 0xFF
                && gw485RxBuffer[4] == 0xFF
                && gw485RxBuffer[5] == 0xFF
                && gw485RxBuffer[6] == 0xFF
                && gw485RxBuffer[7] == 0xFF
                && gw485RxBuffer[8] == 0xFF) {
            state = addressSL;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }

    log_error("analysisStartFlagSL \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
    return FALSE;
}

/**
 * @brief   状态 addressSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisAddressSL(void)
{
    static const uint16_t maxLen = 10;

    /* 解析SL功能码 */
    if (gw485RxBufferIndex >= 10) {
        /* 判断地址是否为广播ID */
        uint8_t temp = 0;
        if (gw485RxBuffer[2] == 0xFF
                && gw485RxBuffer[3] == 0xFF
                && gw485RxBuffer[4] == 0xFF
                && gw485RxBuffer[5] == 0xFF
                && gw485RxBuffer[6] == 0xFF
                && gw485RxBuffer[7] == 0xFF
                && gw485RxBuffer[8] == 0xFF) {
            temp = 1;
        } else {
            temp = 0;
        }

        /* 判断功能码类型 */
        if (temp == 0) {
            if (gw485RxBuffer[9] == SL_Function_Code_Read_Register
                || gw485RxBuffer[9] == SL_Function_Code_Write_Register
                || gw485RxBuffer[9] == SL_Function_Code_Registration_request
                || gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile
                || gw485RxBuffer[9] == SL_Function_Code_Read_Profile
                || gw485RxBuffer[9] == SL_Function_Code_Read_SOE){
                
                state = functionCodeSL;
                return TRUE;
            }
        }
        else {
            if (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan) {                
                state = functionCodeSL;
                frameLength = 13;
                return TRUE;
            }
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    log_error("analysisAddressSL \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 functionCodeSL
 * @param   
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisFunctionCodeSL(void)
{
    static const uint16_t maxLen = 12;

    /* 解析读取寄存器起始位置 */
    if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Read_Register)) {
        uint32_t tempAddrStart = 0;
        tempAddrStart = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11];

        if (tempAddrStart >= minReadRegAddrMacro && tempAddrStart <= maxReadRegAddrMacro) {
            state = readRegStartAddressSL;
            return TRUE;
        }
    }

    /* 解析写入寄存器起始位置 */
    if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Write_Register)) {
        uint32_t tempAddrStart = 0;
        tempAddrStart = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11];

        if (tempAddrStart >= minWriteRegAddrMacro && tempAddrStart <= maxWriteRegAddrMacro) {
            state = writeRegStartAddressSL;
            return TRUE;
        }
    }

    /* 解析扫描广播帧crc校验 */
    if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan)) {
        uint32_t tempCrc = 0;
        tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];
        if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
            state = crcCheckBitSL;
            return TRUE;
        }
    }

    
    /* 解析注册回复帧寄存器长度 */
    if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Registration_request)) {
        uint32_t tempRegLen = 0;
        tempRegLen = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11];

        if (tempRegLen < RegAddrNumMacro && tempRegLen > 0) {
            state = regLengthSL;
            frameLength = 17;
            return TRUE;
        }        
    }
    
    /* 解析配置文件下发帧数 */
    if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile)) {
        if (gw485RxBuffer[10] <= gw485RxBuffer[11]) {
            state = cfgFramesNumSL;
            return TRUE;
        }        
    }

    /* 解析配置文件读取内容的长度 */
    if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Read_Profile)) {
        uint32_t tempCfgLen = 0;
        tempCfgLen = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11];

        if (tempCfgLen < maxReadCfgLen && tempCfgLen > 0) {
            state = readCfgLengthSL;
            frameLength = 15 + tempCfgLen;
            return TRUE;
        }
    }
    
    /* 解析SOE读取的起始读取位 */
    // if ((gw485RxBufferIndex >= 11) && (gw485RxBuffer[9] == SL_Function_Code_Read_SOE)) {     
    if (gw485RxBuffer[9] == SL_Function_Code_Read_SOE) {
        // if (gw485RxBuffer[10] < 100 && gw485RxBuffer[10] >= 0) {
        if (gw485RxBuffer[10] < 100) {
            state = readSOEStartAddr;
            frameLength = 15;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    log_error("analysisFunctionCodeSL \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 readRegStartAddressSL
 * @param 
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisReadRegStartAddressSL(void)
{
    static const uint16_t maxLen = 14;

    /* 解析读取寄存器长度 */
    if (gw485RxBufferIndex >= 14) {
        uint32_t tempAddrNumber = 0;
        tempAddrNumber = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

        if (tempAddrNumber >= 1 && tempAddrNumber <= maxReadRegAddrNumMacro) {
            state = readRegStartNumberSL;
            frameLength = 17;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    log_error("analysisReadRegStartAddressSL \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 readRegStartNumberSL
 * @param 
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisReadRegStartNumberSL(void)
{
    // static uint16_t maxLen = 16;

    // /* crc校验 */
    // if (gw485RxBufferIndex >= 16) {
    //     uint32_t tempCrc = 0;
    //     tempCrc = (gw485RxBuffer[14] << 8) | gw485RxBuffer[15];

    //     if (tempCrc == checkModebusCrc(gw485RxBuffer, 14)) {
    //         state = crcCheckBitSL;
    //         return TRUE;
    //     }
    // }

    // if (gw485RxBufferIndex < maxLen) {
    //     return FALSE;
    // }
    // state = wait;
    // gw485RxBufferIndex--;
    // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    // return FALSE;

    return checkCrcSl();
}

/**
 * @brief   状态 crcCheckBitSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisCrcCheckBitSL(void)
{
    /* 结束标志校验校验 */
    if (gw485RxBufferIndex == frameLength) {
        if (gw485RxBuffer[frameLength - 1] == 0x16) {
            state = endFlagSL;
            return TRUE;
        }
    }
    else if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    log_error("analysisCrcCheckBitSL \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 endFlagSL
 * @param   device 串口设备
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
void analysisEndFlagSL(device_handle device)
{
    /* 数据为读取寄存器 */
    if (gw485RxBuffer[9] == SL_Function_Code_Read_Register) {
        SL_MsgProcFunc_Read_Register(device, gw485RxBuffer, frameLength);
    }

    /* 数据为写入寄存器 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Write_Register) {
        SL_MsgProcFunc_Write_Register(device, gw485RxBuffer, frameLength);
    }

    /* 数据为扫描广播帧 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan) {
        SL_MsgProcFunc_Broadcast_Scan(device, gw485RxBuffer, frameLength);
    }

    /* 数据为注册回复帧 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Registration_request) {
        SL_MsgProcFunc_Registration_request(device, gw485RxBuffer, frameLength);
    }

    /* 数据为下发配置文件 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile) {
        SL_MsgProcFunc_Distribution_Profile(device, gw485RxBuffer, frameLength);
    }

    /* 数据为读取配置文件 */
    else if (gw485RxBuffer[9] == SL_Function_Code_Read_Profile) {
        SL_MsgProcFunc_Read_Profile(device, gw485RxBuffer, frameLength);
    }
    
    /* 数据为读取SOE */
    else if (gw485RxBuffer[9] == SL_Function_Code_Read_SOE) {
        SL_MsgProcFunc_Read_SOE(device, gw485RxBuffer, frameLength);
    }

    // log_error("analysisEndFlagSL \n");
    state = wait;
    gw485RxBufferIndex = 0;
    // memcpy(gw485RxBuffer, gw485RxBuffer + gw485RxBufferIndex, );
}

/**
 * @brief   状态 writeRegStartAddressSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisWriteRegStartAddressSL(void)
{    
    static const uint16_t maxLen = 14;

    /* 解析写入寄存器长度 */
    if (gw485RxBufferIndex >= 14) {
        uint32_t tempAddrNumber = 0;
        tempAddrNumber = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

        if (tempAddrNumber >= 1 && tempAddrNumber <= maxWriteRegAddrNumMacro) {            
            state = writeRegStartNumberSL;
            frameLength = 17 + tempAddrNumber * 2;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 writeRegStartNumberSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisWriteRegStartNumberSL(void)
{
    // static uint16_t maxLen;
    // maxLen = frameLength - 1;

    // /* crc校验 */
    // if (gw485RxBufferIndex >= maxLen) {
    //     // log_error("crcCheckBitSL error : gw485RxBuffer[12] = 0x%x, gw485RxBuffer[13] = 0x%x"\
    //     //     , gw485RxBuffer[12], gw485RxBuffer[13]);
    //     // log_error("crcCheckBitSL error : gw485RxBuffer[14] = 0x%x, gw485RxBuffer[15] = 0x%x"\
    //     //     , gw485RxBuffer[14], gw485RxBuffer[15]);
    //     // log_error("crcCheckBitSL error : gw485RxBuffer[16] = 0x%x, gw485RxBuffer[17] = 0x%x"\
    //     //     , gw485RxBuffer[16], gw485RxBuffer[17]);
    //     uint32_t tempCrc = 0;
    //     tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];
    //     // tempCrc = (gw485RxBuffer[14] << 8) | gw485RxBuffer[15];

    //     if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
    //         state = crcCheckBitSL;
    //         return TRUE;
    //     }

    //     log_error("frameLength : %d", frameLength);
    //     log_error("crcCheckBitSL error : tempCrc = 0x%x, checkModebusCrc = 0x%x"\
    //         , tempCrc, checkModebusCrc(gw485RxBuffer, frameLength - 3));
    // }

    // if (gw485RxBufferIndex < maxLen) {
    //     return FALSE;
    // }
    // state = wait;
    // gw485RxBufferIndex--;
    // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    // return FALSE;

    return checkCrcSl();
}

/**
 * @brief   状态 regLengthSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisRegLengthSL(void)
{
    static const uint16_t maxLen = 12;
    /* crc校验 */
    if (gw485RxBufferIndex >= 12) {
        uint32_t tempRegStatus = 0;
        tempRegStatus = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

        if (tempRegStatus == UNREGISTER
            || tempRegStatus == REGISTER_FAIL
            || tempRegStatus == REGISTER_SUCCESS) {
            state = regStatusSL;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 regStatusSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisRegStatusSL(void)
{
    // static uint16_t maxLen = 16;
    // /* crc校验 */
    // if (gw485RxBufferIndex >= 16) {
    //     uint32_t tempCrc = 0;
    //     tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

    //     if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
    //         state = crcCheckBitSL;
    //         return TRUE;
    //     }
    // }

    // if (gw485RxBufferIndex < maxLen) {
    //     return FALSE;
    // }
    // state = wait;
    // gw485RxBufferIndex--;
    // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    // return FALSE;

    return checkCrcSl();
}



/**
 * @brief   状态 cfgFramesNumSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisCfgFramesNumSL(void)
{    
    static const uint16_t maxLen = 14;
    
    /* 解析下发配置文件数据内容长度 */
    if (gw485RxBufferIndex >= maxLen) {
        uint32_t tempLen = 0;
        tempLen = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

        if (tempLen > 0 && tempLen <= maxDistributionCfgLen) {
            state = cfgLengthSL;
            frameLength = 17 + tempLen;
            // log_error("cfgFramesNumSL error : tempLen = %d \n", tempLen);
            return TRUE;
        }        
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;
}

/**
 * @brief   状态 cfgLengthSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysiscfgLengthSL(void)
{
//    static uint16_t maxLen = 16;
//     /* crc校验 */
//     if (gw485RxBufferIndex >= 16) {
//         uint32_t tempCrc = 0;
//         tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2];

//         if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) {
//             state = crcCheckBitSL;
//             return TRUE;
//         }
//     }

//     if (gw485RxBufferIndex < maxLen) {
//         return FALSE;
//     }
//     state = wait;
//     gw485RxBufferIndex--;
//     memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
//     return FALSE;

    return checkCrcSl();
}

/**
 * @brief   状态 readCfgLengthSL
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisReadCfgLengthSL(void)
{
    return checkCrcSl();
}

/**
 * @brief   状态 readSOEStartAddr
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisReadSOEStartAddr(void)
{
    if (gw485RxBuffer[10] + gw485RxBuffer[11] < 100 && gw485RxBuffer[11] > 0){
        state = readSOELength;
        return TRUE;
    }
    
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
    return FALSE;    
}

/**
 * @brief   状态 readSOELength
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisReadSOELength(void)
{
    return checkCrcSl();
}

/* 读取寄存器 */
/**
 * @brief   读取太阳能开路电压
 * @param
 * @retval  太阳能开路电压(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg)
{
    return (uint16_t)(getSolarOpenCircuitVoltage() * floatMagnification + 0.5f);
}

/**
 * @brief   读取太阳能输入电压
 * @param
 * @retval  太阳能输入电压(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterSolarInputVoltage(void *pMsg)
{
    return (uint16_t)(getSolarInCircuitVoltage() * floatMagnification + 0.5f);
}

/**
 * @brief   读取输出电压
 * @param
 * @retval  电池电压(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterOutputVoltage(void *pMsg)
{
    return (uint16_t)(getOutputVoltage() * floatMagnification + 0.5f);
}

/**
 * @brief   读取电池电压
 * @param
 * @retval  电池电压(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg)
{
    return (uint16_t)(getBatteryVoltage() * floatMagnification + 0.5f);
}

/**
 * @brief   读取充电电流
 * @param
 * @retval  充电电流(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterChargCurrent(void *pMsg)
{
    return (uint16_t)(getChargCurrent() * floatMagnification + 0.5f);
}

/**
 * @brief   读取放电电流
 * @param
 * @retval  放电电流(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterDischargCurrent(void *pMsg)
{
    return (uint16_t)(getDischargCurrent() * floatMagnification + 0.5f);
}

/**
 * @brief   读取MOS管温度
 * @param
 * @retval  MOS管温度(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterHighSideMosTemperature(void *pMsg)
{
    return (uint16_t)(getHighSideMosTemperature() * floatMagnification + 0.5f);
}

/**
 * @brief   读取SOC
 * @param
 * @retval  SOC
 */
uint16_t SL_ReadRegisterSOC(void *pMsg)
{
    return (uint16_t)(getSOC() * 100);
}

/**
 * @brief   读取充放电状态
 * @param
 * @retval  充放电状态
 */
uint16_t SL_ReadRegisterChargState(void *pMsg)
{
    uint16_t temp = 0;
    if (getDutyRatio() > 0 && getChargControlFlag() == TRUE) {
        temp |= 0xFF00;
    }

    if (getDischargMosState() == TRUE) {        
        temp |= 0xFF;
    }

    return temp;    
}

/**
 * @brief   读取充电量
 * @param
 * @retval  充电量(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterTotalChargCapacity(void *pMsg)
{
    volatile uint16_t temp = 0;
    temp = (uint16_t)(getTotalChargCapacity() * floatMagnification * 1000 + 0.5f);
    totalChargCapacityInt(0);
    return temp;
}

/**
 * @brief   读取放电量
 * @param
 * @retval  放电量(* floatMagnification保留为整数)
 */
uint16_t SL_ReadRegisterTotalElectricityConsumption(void *pMsg)
{
    volatile uint16_t temp = 0;
    temp = (uint16_t)(getTotalElectricityConsumption() * floatMagnification * 1000 + 0.5f);
    totalElectricityConsumptionInt(0);
    return temp;
}

/**
 * @brief   读取控制盒工作模式
 * @param
 * @retval  控制盒工作模式
 */
uint16_t SL_ReadRegisterMPPT_Mode(void *pMsg)
{
    return getMPPT_Mode();
}

/**
 * @brief   读取年月
 * @param
 * @retval  年月
 */
uint16_t SL_ReadRegisterYearMonth(void *pMsg)
{
    timeInfo time;
    getRTC_Time(&time);

    // debug_printf("%d-%d\n", time.year, time.month);

    return (time.year << 8) | time.month;
}

/**
 * @brief   读取日时
 * @param
 * @retval  日时
 */
uint16_t SL_ReadRegisterDayHour(void *pMsg)
{
    timeInfo time;
    getRTC_Time(&time);

    // debug_printf("%d-%d\n", time.day, time.hour);

    return (time.day << 8) | time.hour;
}

/**
 * @brief   读取分秒
 * @param
 * @retval  分秒
 */
uint16_t SL_ReadRegisterMinuteSecond(void *pMsg)
{
    timeInfo time;
    getRTC_Time(&time);
    
    // debug_printf("%d-%d\n", time.minute, time.second);

    return (time.minute << 8) | time.second;
}

/* 写入寄存器 */
/**
 * @brief   清除统计电量
 * @param
 * @retval
 */
uint16_t SL_WriteRegisterEliminateStatistical(void *pMsg)
{
    // debug_printf("SL_WriteRegisterEliminateStatistical\n");
    totalChargCapacityInt(0);
    totalElectricityConsumptionInt(0);
    return 0;
}

/**
 * @brief   控制充电状态
 * @param
 * @retval
 */
uint16_t SL_WriteRegisterChargControl(void *pMsg)
{
    // debug_printf("SL_WriteRegisterChargControl\n");
    if ((*(uint16_t*)pMsg) == 0x0000) {
        stopChargWork();
    }
    
    else if ((*(uint16_t*)pMsg) == 0xFFFF) {
        beginChargWork();
        // setPowerOutput(TRUE);
    }

    return 0;
}

/**
 * @brief   控制放电开关状态
 * @param
 * @retval
 */
uint16_t SL_WriteRegisterDisChargControl(void *pMsg)
{
    // debug_printf("SL_WriteRegisterDisChargControl\n");
    if ((*(uint16_t*)pMsg) == 0x0000) {
        setPowerOutput(FALSE);
    }
    
    else if ((*(uint16_t*)pMsg) == 0xFFFF) {
        setPowerOutput(TRUE);
    }

    return 0;
}

/**
 * @brief   清除SOE
 * @param
 * @retval
 */
uint16_t SL_WriteRegisterCleanSOE(void *pMsg)
{
    // debug_printf("SL_WriteRegisterCleanSOE\n");
    cleanEventsOrderRecord();

    return 0;
}

/**
 * @brief   写入年月
 * @param
 * @retval
 */
static timeInfo writeTime;
uint16_t SL_WriteRegisterYearMonth(void *pMsg)
{
    // timeInfo time;
    // getRTC_Time(&time);

    // uint8_t tempU8 = (uint8_t)((*(uint16_t*)pMsg) >> 8);
    // time.year = tempU8;
    // tempU8 = (uint8_t)(*(uint16_t*)pMsg);
    // time.month = tempU8;
    uint8_t tempU8 = (uint8_t)((*(uint16_t*)pMsg) >> 8);
    writeTime.year = tempU8;
    tempU8 = (uint8_t)(*(uint16_t*)pMsg);
    writeTime.month = tempU8;

    // setRTC_Time(&time);
    
    return 0;
}

/**
 * @brief   写入日时
 * @param
 * @retval
 */
uint16_t SL_WriteRegisterDayHour(void *pMsg)
{
    // timeInfo time;
    // getRTC_Time(&time);

    // uint8_t tempU8 = (uint8_t)((*(uint16_t*)pMsg) >> 8);
    // time.day = tempU8;
    // tempU8 = (uint8_t)(*(uint16_t*)pMsg);
    // time.hour = tempU8;

    // setRTC_Time(&time);

    uint8_t tempU8 = (uint8_t)((*(uint16_t*)pMsg) >> 8);
    writeTime.day = tempU8;
    tempU8 = (uint8_t)(*(uint16_t*)pMsg);
    writeTime.hour = tempU8;
    
    return 0;
}

/**
 * @brief   写入分秒
 * @param
 * @retval
 */
uint16_t SL_WriteRegisterMinuteSecond(void *pMsg)
{
    // timeInfo time;
    // getRTC_Time(&time);

    // uint8_t tempU8 = (uint8_t)((*(uint16_t*)pMsg) >> 8);
    // time.minute = tempU8;
    // tempU8 = (uint8_t)(*(uint16_t*)pMsg);
    // time.second = tempU8;

    // setRTC_Time(&time);    
    
    uint8_t tempU8 = (uint8_t)((*(uint16_t*)pMsg) >> 8);
    writeTime.minute = tempU8;
    tempU8 = (uint8_t)(*(uint16_t*)pMsg);
    writeTime.second = tempU8;
    
    // debug_printf("%d-%d\n", writeTime.year, writeTime.month);
    // debug_printf("%d-%d\n", writeTime.day, writeTime.hour);
    // debug_printf("%d-%d\n", writeTime.minute, writeTime.second);

    setRTC_Time(&writeTime);  

    return 0;
}

/**
  * @brief  解析下发的配置文件
  * @param  pMsg   需要解析的内容
  * @retval NULL解析失败 其他：下次解析的位置
  */
uint8_t *analysisDistributionProfile(uint8_t *pMsg, config_info *temp)
{
    uint16_t dataType;
    dataType = (*pMsg << 8) | *(pMsg + 1);

    /* 配置 unique_Device_ID */
    if (dataType == unique_Device_ID) {
        temp->uniqueDeviceID[0] = pMsg[2];
        temp->uniqueDeviceID[1] = pMsg[3];
        temp->uniqueDeviceID[2] = pMsg[4];
        temp->uniqueDeviceID[3] = pMsg[5];
        temp->uniqueDeviceID[4] = pMsg[6];
        temp->uniqueDeviceID[5] = pMsg[7];
        temp->uniqueDeviceID[6] = pMsg[8];
        return (pMsg + 9);
    }
    
    /* 配置 对上通信波特率 */
    else if (dataType == SL_Protocol_Communication_Baud_Rate_Up) {
        switch (pMsg[2]) {
        case 0x01:
            temp->gw485_Baud = 4800;
            return (pMsg + 3);
        case 0x02:
            temp->gw485_Baud = 9600;
            return (pMsg + 3);
        case 0x03:
            temp->gw485_Baud = 19200;
            return (pMsg + 3);
        case 0x04:
            temp->gw485_Baud = 38400;
            return (pMsg + 3);
        case 0x05:
            temp->gw485_Baud = 57600;
            return (pMsg + 3);
        case 0x06:
            temp->gw485_Baud = 115200;
            return (pMsg + 3);
        default:
            return NULL;
        }
    }
    
    /* 配置 对下通信波特率 */
    else if (dataType == SL_Protocol_Communication_Baud_Rate_Down) {
        switch (pMsg[2]) {
        case 0x01:
            temp->bat485_Baud = 4800;
            return (pMsg + 3);
        case 0x02:
            temp->bat485_Baud = 9600;
            return (pMsg + 3);
        case 0x03:
            temp->bat485_Baud = 19200;
            return (pMsg + 3);
        case 0x04:
            temp->bat485_Baud = 38400;
            return (pMsg + 3);
        case 0x05:
            temp->bat485_Baud = 57600;
            return (pMsg + 3);
        case 0x06:
            temp->bat485_Baud = 115200;
            return (pMsg + 3);
        default:
            return NULL; 
        }
    }

    /* 配置 充电控制盒类型 */
    else if (dataType == power_Box_Type) {
        switch (pMsg[2]) {
        case 0x00:
            temp->powerBoxType = 0x00;
            return (pMsg + 3);
        case 0xFF:
            temp->powerBoxType = 0xFF;
            return (pMsg + 3);
        default:
            return NULL;
        }
    }
    
    /* 配置 恒压充电阈值电压 */
    else if (dataType == constant_Voltage_V) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 14.4f || tempFloat < 13.5f) {
            return NULL;
        }

        temp->constantVoltageV = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 浮充充电阈值电流 */
    else if (dataType == float_I) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 0.3f || tempFloat < 0.01f) {
            return NULL;
        }

        temp->floatI = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 启动充电太阳能板开路电压 */
    else if (dataType == start_Solar_Open_Circuit_V) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 20.0f || tempFloat < 16.5f) {
            return NULL;
        }

        temp->startSolarOpenCircuitV = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 关闭充电太阳能板输出电压 */
    else if (dataType == stop_Solar_Output_Circuit_V) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 16 || tempFloat < 15) {
            return NULL;
        }

        temp->stopSolarOutputCircuitV = tempFloat;
        return (pMsg + 4);        
    }

    /* 配置 启动时能否启动间隔 */
    else if (dataType == check_Can_Start_Time) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);
        
        if (tempU16 > 1000 || tempU16 < 5) {
            return NULL;
        }

        temp->checkCanStartTime = tempU16;
        return (pMsg + 4);      
    }

    /* 配置 短路判断延时 */
    else if (dataType == short_Circuit_Judgment_Delay) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);
        
        if (tempU16 > 100 || tempU16 < 3) {
            return NULL;
        }

        temp->inputPowerLowJudgmentDelay = tempU16;
        return (pMsg + 4);
    }

    /* 配置 前端输入功率不足判断延时 */
    else if (dataType == input_Power_Low_Judgment_Delay) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);
        
        if (tempU16 > 1000 || tempU16 < 5) {
            return NULL;
        }

        temp->inputPowerLowJudgmentDelay = tempU16;
        return (pMsg + 4);
    }

    /* 配置 前端输入功率不足再次输出延时 */
    else if (dataType == input_Power_Low_Again_Output_Delay) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);
        
        if (tempU16 > 10000 || tempU16 < 100) {
            return NULL;
        }

        temp->inputPowerLowAgainOutputDelay = tempU16;
        return (pMsg + 4);
    }

    /* 配置 软件第一段保护延时 */
    else if (dataType == first_Stage_Protection_Delay) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);
        
        if (tempU16 > 1000 || tempU16 < 1) {
            return NULL;
        }

        temp->firstStageProtectionDelay = tempU16;
        return (pMsg + 4);        
    }

    /* 配置 软件第一段保护阈值电流 */
    else if (dataType == first_Stage_Protection_Curr) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 60 || tempFloat < 1) {
            return NULL;
        }

        temp->firstStageProtectionCurr = tempFloat;
        return (pMsg + 4);        
    }

    /* 配置 软件第二段保护延时 */
    else if (dataType == second_Stage_Protection_Delay) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);
        if (tempU16 > 60000 || tempU16 < 10) {
            return NULL;
        }

        temp->secondStageProtectionDelay = tempU16;
        return (pMsg + 4);        
    }

    /* 配置 软件第二段保护阈值电流 */
    else if (dataType == second_Stage_Protection_Curr) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 50 || tempFloat < 1) {
            return NULL;
        }

        temp->secondStageProtectionCurr = tempFloat;
        return (pMsg + 4);        
    }

    
    /* 配置 软件第三段保护延时 */
    else if (dataType == third_Stage_Protection_Delay) {
        uint32_t tempU32 = (*(pMsg + 2) << 24) | (*(pMsg + 3) << 16) | (*(pMsg + 4) << 8) | *(pMsg + 5);
        if (tempU32 > 10000000 || tempU32 < 10) {
            log_info("third_Stage_Protection_Delay = %d\n", tempU32);
            return NULL;
        }

        temp->thirdStageProtectionDelay = tempU32;
        return (pMsg + 6);
    }

    /* 配置 软件第三段保护阈值电流 */
    else if (dataType == third_Stage_Protection_Curr) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 50 || tempFloat < 1) {
            log_info("third_Stage_Protection_Curr\n");
            return NULL;
        }

        temp->thirdStageProtectionCurr = tempFloat;
        return (pMsg + 4);        
    }

    /* 配置 前端输入功率不足检测延时 */
    else if (dataType == input_Power_Low_Detection_Delay) {
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);        
        if (tempU16 > 1000 || tempU16 < 2) {
            log_info("input_Power_Low_Detection_Delay\n");
            return NULL;
        }

        temp->inputPowerLowDetectionDelay = tempU16;
        return (pMsg + 4);        
    }

    /* 配置 前端输入功率不足检测电压 */
    else if (dataType == input_Power_Low_Detection_Volt) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 15 || tempFloat < 8) {
            log_info("input_Power_Low_Detection_Volt\n");
            return NULL;
        }

        temp->inputPowerLowDetectionVolt = tempFloat;
        return (pMsg + 4);        
    }
    
    /* 配置 最大太阳能板输出电压 */
    else if (dataType == max_Open_Solar_Output_Circuit_V) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 27 || tempFloat < 22) {
            log_info("max_Open_Solar_Output_Circuit_V\n");
            return NULL;
        }

        temp->maxOpenSolarOutputCircuitV = tempFloat;
        return (pMsg + 4);
    }
    
    /* 配置 最大充电电流 */
    else if (dataType == max_Charg_Curr) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 40 || tempFloat < 20) {
            log_info("max_Charg_Curr\n");
            return NULL;
        }        
        // debug_printf("max_Charg_Curr : %f\n", tempFloat);

        temp->maxChargCurr = tempFloat;
        return (pMsg + 4);
    }
            
    /* 配置 检测回路阻抗时的最小充电电流 */
    else if (dataType == min_Check_Loop_Impedance_Charg_Curr) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 20 || tempFloat < 2) {
            log_info("min_Check_Loop_Impedance_Charg_Curr\n");
            return NULL;
        }

        temp->minCheckLoopImpedanceChargCurr = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 满功率输出温度 */
    else if (dataType == full_Power_Output_Temperature) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 100 || tempFloat < 30) {
            log_info("full_Power_Output_Temperature\n");
            return NULL;
        }

        temp->fullPowerOutputTemperature = tempFloat;
        return (pMsg + 4);
    }
    
    /* 配置 降功率输出温度 */
    else if (dataType == reduce_Power_Output_Temperature) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 100 || tempFloat < 30) {
            log_info("reduce_Power_Output_Temperature\n");
            return NULL;
        }

        temp->reducePowerOutputTemperature = tempFloat;
        return (pMsg + 4);
    }
    
    /* 配置 停止输出温度 */
    else if (dataType == stop_PowerOutput_Temperature) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 100 || tempFloat < 30) {
            log_info("stop_PowerOutput_Temperature\n");
            return NULL;
        }

        temp->stopPowerOutputTemperature = tempFloat;
        return (pMsg + 4);
    }
    
    /* 配置 恒压充电输出电压 */
    else if (dataType == constant_Voltage_Charge_V) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 14.5f || tempFloat < 14) {
            log_info("constant_Voltage_Charge_V\n");
            return NULL;
        }

        temp->constantVoltageChargeV = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 浮充充电输出电压 */
    else if (dataType == float_ChargeV) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 14.5f || tempFloat < 13) {
            log_info("cfg float_ChargeV error\n");
            return NULL;
        }

        temp->FloatChargeV = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 充电时采集开路电压的间隔时间 */
    else if (dataType == collect_OpenCircuit_Voltage_Time) {        
        uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3);        
        if (tempU16 > 10000 || tempU16 < 100) {
            log_info("cfg collect_OpenCircuit_Voltage_Time error\n");
            return NULL;
        }

        temp->collectOpenCircuitVoltageTime = tempU16;
        return (pMsg + 4);   
    }
    
    /* 配置 反向充电保护电流 */
    else if (dataType == reverse_Charge_Protection_Curr) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 12.0f || tempFloat < 0.1f) {
            log_info("cfg reverse_Charge_Protection_Curr error\n");
            return NULL;
        }

        temp->reverseChargProtectionCurr = tempFloat;
        return (pMsg + 4);
    }

    /* 配置 软启动电压 */
    else if (dataType == soft_Start_Volt) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat < 18.0f || tempFloat > 22.0f) {
//            log_info("cfg soft_Start_Volt error : %f\n", tempFloat);
            return NULL;
        }

        temp->softStartVolt = tempFloat;
        return (pMsg + 4);
    }
    
    /* 读取 MPPT恒定输出电压 */
    else if (dataType == MPPT_Constant_Voltage) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat < 15.0f || tempFloat > 19.0f) {
            log_info("cfg MPPT_Constant_Voltage error\n");
            return NULL;
        }

        temp->MPPTConstantVoltage = tempFloat;
        return (pMsg + 4);
    }
    
    /* 读取 MPPT降功率运行时控制输入电压稳定值 */
    else if (dataType == MPPT_Reduce_Constant_Voltage) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat < 12.0f || tempFloat > 22.0f) {
            log_info("cfg MPPT_Reduce_Constant_Voltage error\n");
            return NULL;
        }

        temp->MPPTReduceConstantVoltage = tempFloat;
        return (pMsg + 4);
    }
    
    /* 读取 欠压保护电压 */
    else if (dataType == under_Voltage_Protection) {
        float tempFloat = (float)((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification;
        if (tempFloat > 15.0f) {
            log_info("cfg under_Voltage_Protection error\n");
            return NULL;
        }

        temp->underVoltageProtection = tempFloat;
        return (pMsg + 4);
    }

    log_info("cfg file error\n");
    return NULL; 
}


/**
  * @brief  解析下发的配置文件
  * @param  pMsg        需要解析的内容
  *         dataLen     解析得到的数据长度
  * @retval NULL解析失败 其他：下次解析的位置
  */
uint8_t *analysisReadProfile(uint8_t *pMsg, uint8_t **outData, uint16_t *dataLen)
{
    /* 数据类型 */
    *(*outData + 0) = *pMsg;
    *(*outData + 1) = *(pMsg + 1);

    uint16_t dataType;
    dataType = (*pMsg << 8) | *(pMsg + 1);
    // debug_printf("dataType:%d \n", dataType);

    /* 读取 unique_Device_ID */
    if (dataType == unique_Device_ID) {
        /* 数据 */
        *(*outData + 2) = g_cfgParameter.uniqueDeviceID[0];
        *(*outData + 3) = g_cfgParameter.uniqueDeviceID[1];
        *(*outData + 4) = g_cfgParameter.uniqueDeviceID[2];
        *(*outData + 5) = g_cfgParameter.uniqueDeviceID[3];
        *(*outData + 6) = g_cfgParameter.uniqueDeviceID[4];
        *(*outData + 7) = g_cfgParameter.uniqueDeviceID[5];
        *(*outData + 8) = g_cfgParameter.uniqueDeviceID[6];

        *outData += 9;
        *dataLen += 9;

        return (pMsg + 2);
    }

    /* 读取 对上通信波特率 */
    else if (dataType == SL_Protocol_Communication_Baud_Rate_Up) {
        switch (g_cfgParameter.gw485_Baud) {
        case 4800:
            *(*outData + 2) = 0x01;        
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 9600:
            *(*outData + 2) = 0x02;        
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 19200:
            *(*outData + 2) = 0x03;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 38400:
            *(*outData + 2) = 0x04;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 57600:
            *(*outData + 2) = 0x05;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 115200:
            *(*outData + 2) = 0x06;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        default:
            return NULL; 
        }
    }
    
    /* 读取 对下通信波特率 */
    else if (dataType == SL_Protocol_Communication_Baud_Rate_Down) {
        switch (g_cfgParameter.bat485_Baud) {
        case 4800:
            *(*outData + 2) = 0x01;        
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 9600:
            *(*outData + 2) = 0x02;        
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 19200:
            *(*outData + 2) = 0x03;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 38400:
            *(*outData + 2) = 0x04;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 57600:
            *(*outData + 2) = 0x05;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        case 115200:
            *(*outData + 2) = 0x06;
            *outData += 3;
            *dataLen += 3;
            return (pMsg + 2);
        default:
            return NULL; 
        }
    }

    /* 读取 电源盒类型 */
    else if (dataType == power_Box_Type) {
        *(*outData + 2) = g_cfgParameter.powerBoxType;
        *outData += 3;
        *dataLen += 3;
        return (pMsg + 2);        
    }

    /* 读取 恒压充电阈值电压 */
    else if (dataType == constant_Voltage_V) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.constantVoltageV * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 浮充充电阈值电流 */
    else if (dataType == float_I) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.floatI * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);      
    }

    /* 读取 启动充电太阳能板开路电压 */
    else if (dataType == start_Solar_Open_Circuit_V) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.startSolarOpenCircuitV * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 电源盒类型 */
    else if (dataType == stop_Solar_Output_Circuit_V) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.stopSolarOutputCircuitV * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 检测能否启动间隔时间 */
    else if (dataType == check_Can_Start_Time) {
        uint16_t tempU16 = g_cfgParameter.checkCanStartTime;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 短路判断延时 */
    else if (dataType == short_Circuit_Judgment_Delay) {
        uint16_t tempU16 = g_cfgParameter.shortCircuitJudgmentDelay;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 前端输入功率不足判断延时 */
    else if (dataType == input_Power_Low_Judgment_Delay) {
        uint16_t tempU16 = g_cfgParameter.inputPowerLowJudgmentDelay;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 前端输入功率不足再次输出延时 */
    else if (dataType == input_Power_Low_Again_Output_Delay) {
        uint16_t tempU16 = g_cfgParameter.inputPowerLowAgainOutputDelay;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 第一段保护延时 */
    else if (dataType == first_Stage_Protection_Delay) {
        uint16_t tempU16 = g_cfgParameter.firstStageProtectionDelay;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 第一段保护电流 */
    else if (dataType == first_Stage_Protection_Curr) {        
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.firstStageProtectionCurr * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 第二段保护延时 */
    else if (dataType == second_Stage_Protection_Delay) {
        uint16_t tempU16 = g_cfgParameter.secondStageProtectionDelay;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 第二段保护电流 */
    else if (dataType == second_Stage_Protection_Curr) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.secondStageProtectionCurr * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 第三段保护延时 */
    else if (dataType == third_Stage_Protection_Delay) {
        uint32_t tempU32 = g_cfgParameter.thirdStageProtectionDelay;
        *(*outData + 2) = (uint8_t)(tempU32 >> 24);
        *(*outData + 3) = (uint8_t)(tempU32 >> 16);
        *(*outData + 4) = (uint8_t)(tempU32 >> 8);
        *(*outData + 5) = (uint8_t)(tempU32 & 0x00FF);
        *outData += 6;
        *dataLen += 6;
        return (pMsg + 2);
    }

    /* 读取 第三段保护电流 */
    else if (dataType == third_Stage_Protection_Curr) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.thirdStageProtectionCurr * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 前端输入功率不足检测延时 */
    else if (dataType == input_Power_Low_Detection_Delay) {
        uint16_t tempU16 = g_cfgParameter.inputPowerLowDetectionDelay;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 前端输入功率不足检测电压 */
    else if (dataType == input_Power_Low_Detection_Volt) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.inputPowerLowDetectionVolt * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 最大太阳能板输出电压 */
    else if (dataType == max_Open_Solar_Output_Circuit_V) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.maxOpenSolarOutputCircuitV * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 最大充电电流 */
    else if (dataType == max_Charg_Curr) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.maxChargCurr * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 检测回路阻抗时的最小充电电流 */
    else if (dataType == min_Check_Loop_Impedance_Charg_Curr) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.minCheckLoopImpedanceChargCurr * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 满功率输出温度 */
    else if (dataType == full_Power_Output_Temperature) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.fullPowerOutputTemperature * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 停止输出温度 */
    else if (dataType == reduce_Power_Output_Temperature) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.reducePowerOutputTemperature * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);        
    }

    /* 读取 停止输出温度 */
    else if (dataType == stop_PowerOutput_Temperature) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.stopPowerOutputTemperature * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 恒压充电时的输出电压 */
    else if (dataType == constant_Voltage_Charge_V) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.constantVoltageChargeV * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 浮充充电时的输出电压 */
    else if (dataType == float_ChargeV) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.FloatChargeV * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);        
    }

    /* 读取 充电时采集开路电压的间隔时间 */
    else if (dataType == collect_OpenCircuit_Voltage_Time) {
        uint16_t tempU16 = g_cfgParameter.collectOpenCircuitVoltageTime;
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 反向充电保护电流 */
    else if (dataType == reverse_Charge_Protection_Curr) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.reverseChargProtectionCurr * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    /* 读取 软启动电压 */
    else if (dataType == soft_Start_Volt) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.softStartVolt * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }
    
    /* 读取 MPPT恒定输出电压 */
    else if (dataType == MPPT_Constant_Voltage) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.MPPTConstantVoltage * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }
    
    /* 读取 MPPT降功率运行时控制输入电压稳定值 */
    else if (dataType == MPPT_Reduce_Constant_Voltage) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.MPPTReduceConstantVoltage * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }
    
    /* 读取 欠压保护电压 */
    else if (dataType == under_Voltage_Protection) {
        uint16_t tempU16 = (uint16_t)(g_cfgParameter.underVoltageProtection * floatMagnification);
        *(*outData + 2) = (uint8_t)(tempU16 >> 8);
        *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF);
        *outData += 4;
        *dataLen += 4;
        return (pMsg + 2);
    }

    debug_printf("dataType error : %d\n", dataType);
    return NULL;
}


/**
  * @brief  赛联协议读取寄存器
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Read_Register\n");
    uint16_t Start_Address_16 = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11];
    uint16_t Register_Number_16 = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

   /* 读取数据 */
   uint16_t reply_Data_Content[maxReadRegAddrNumMacro] = {0};
   for ( uint16_t pos = 0;  pos < Register_Number_16; pos++) {
       for (uint16_t var = 0; var < sizeof(g_RegTblR) / sizeof(SL_RegProcTable); var++) {
           if (g_RegTblR[var].regId == (Start_Address_16 + pos)) {
               reply_Data_Content[pos] = g_RegTblR[var].pRegProc(NULL);
           }
       }
   }
   uint8_t *replay_pack = getInsertData();

    /* 起始标志 */
    *(replay_pack)      =  g_cfgParameter.startFlagSL[0];
    *(replay_pack + 1)  =  g_cfgParameter.startFlagSL[1];

    /* 地址 */
    replay_pack += 2;
    *(replay_pack)      =  g_cfgParameter.uniqueDeviceID[0];
    *(replay_pack + 1)  =  g_cfgParameter.uniqueDeviceID[1];
    *(replay_pack + 2)  =  g_cfgParameter.uniqueDeviceID[2];
    *(replay_pack + 3)  =  g_cfgParameter.uniqueDeviceID[3];
    *(replay_pack + 4)  =  g_cfgParameter.uniqueDeviceID[4];
    *(replay_pack + 5)  =  g_cfgParameter.uniqueDeviceID[5];
    *(replay_pack + 6)  =  g_cfgParameter.uniqueDeviceID[6];

    /* 功能码 */
    replay_pack += 7;
    *replay_pack = SL_Function_Code_Read_Register;

    /* 回复字节数长度 */
    replay_pack += 1;
    *replay_pack = (uint8_t)((Register_Number_16 * 2) >> 8);
    *(replay_pack + 1) = (uint8_t)(Register_Number_16 * 2);

    /* 回复数据内容 */
    replay_pack += 2;
    for (uint8_t var = 0; var < Register_Number_16 * 2; var++) {
        if (0 == (var & 0x01)) {
            *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2] >> 8);
        } else {
            *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2]);
        }
    }

    /* 校验位 */
    replay_pack += Register_Number_16 * 2;
    uint16_t packLen = 2 + 7 + 1 + 2 + Register_Number_16 * 2 + 3;
    uint16_t crc_temp = checkModebusCrc(getInsertData(), packLen - 3);
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, packLen);
}

/**
  * @brief  赛联协议写入寄存器
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Write_Register\n");
    uint16_t Register_Start_Address = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11];
    uint16_t Register_Number = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

    /* 将指令中的数据读取出来 */
    uint16_t content[maxWriteRegAddrNumMacro] = {0};
    for (uint16_t var = 0; var < Register_Number; var++) {
        content[var] = gw485RxBuffer[14 + 2 * var] << 8 | gw485RxBuffer[14 + 2 * var + 1];
    }

    // debug_printf("Register_Start_Address : %x \n", Register_Start_Address);
    // debug_printf("Register_Number : %x \n", Register_Number);
    // debug_printf("content : %x \n", content[0]);

    /* 将数据写入到寄存器中 */
    for ( uint16_t pos = 0;  pos < Register_Number; pos++) {
        for (uint16_t i = 0; i < sizeof(g_RegTblW) / sizeof(SL_RegProcTable); i++) {
            // debug_printf("g_RegTblW[i].regId : %x \n", g_RegTblW[i].regId);
            // debug_printf("Register_Start_Address : %x \n", (Register_Start_Address + pos));
            if (g_RegTblW[i].regId == (Register_Start_Address + pos)) {
                g_RegTblW[i].pRegProc(&content[pos]);
            }
        }
    }
}

/**
  * @brief  赛联协议扫描广播帧
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Broadcast_Scan\n");
    uint8_t *replay_pack = getInsertData();

    /* 起始标志 */
    *(replay_pack)      =  g_cfgParameter.startFlagSL[0];
    *(replay_pack + 1)  =  g_cfgParameter.startFlagSL[1];

    /* 地址 */
    replay_pack += 2;
    *(replay_pack)      =  0xFF;
    *(replay_pack + 1)  =  0xFF;
    *(replay_pack + 2)  =  0xFF;
    *(replay_pack + 3)  =  0xFF;
    *(replay_pack + 4)  =  0xFF;
    *(replay_pack + 5)  =  0xFF;
    *(replay_pack + 6)  =  0xFF;

    /* 功能码 */
    replay_pack += 7;
    *replay_pack = SL_Function_Code_Registration_request;

    /* 寄存器长度 */
    replay_pack += 1;
    *replay_pack = (regLength >> 8) & 0xFF;
    *replay_pack += 1;
    *replay_pack = regLength & 0xFF;

    /* 注册状态 */
    replay_pack += 3;
    
    /* 接入节点ID */
    *(replay_pack)      =  g_cfgParameter.uniqueDeviceID[0];
    *(replay_pack + 1)  =  g_cfgParameter.uniqueDeviceID[1];
    *(replay_pack + 2)  =  g_cfgParameter.uniqueDeviceID[2];
    *(replay_pack + 3)  =  g_cfgParameter.uniqueDeviceID[3];
    *(replay_pack + 4)  =  g_cfgParameter.uniqueDeviceID[4];
    *(replay_pack + 5)  =  g_cfgParameter.uniqueDeviceID[5];
    *(replay_pack + 6)  =  g_cfgParameter.uniqueDeviceID[6];

    /* 接入节点类型 */
    replay_pack += 8;
    *replay_pack = 1;

    /* 校验位 */
    replay_pack += 1;
    uint16_t crc_temp = checkModebusCrc(getInsertData(), 23);
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 26);
}

/**
  * @brief  赛联协议注册回复帧
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Registration_request\n");
}

/**
  * @brief  赛联协议写入配置文件
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Distribution_Profile\n");
    /* 确保帧不乱序，依次发完 */
    static uint8_t flag = 0;
    static config_info cfgInfo = {0};
    // config_info cfgInfo = {0};

    uint8_t *replay_pack = getInsertData();
    if (replay_pack == NULL) {
        return;
    }

    uint16_t crc_temp;
    uint8_t *analysisData;
    uint32_t  tickstart1;

    /* 起始标志 */
    *(replay_pack)      =  g_cfgParameter.startFlagSL[0];
    *(replay_pack + 1)  =  g_cfgParameter.startFlagSL[1];

    /* 地址 */
    replay_pack += 2;
    *(replay_pack)      =  g_cfgParameter.uniqueDeviceID[0];
    *(replay_pack + 1)  =  g_cfgParameter.uniqueDeviceID[1];
    *(replay_pack + 2)  =  g_cfgParameter.uniqueDeviceID[2];
    *(replay_pack + 3)  =  g_cfgParameter.uniqueDeviceID[3];
    *(replay_pack + 4)  =  g_cfgParameter.uniqueDeviceID[4];
    *(replay_pack + 5)  =  g_cfgParameter.uniqueDeviceID[5];
    *(replay_pack + 6)  =  g_cfgParameter.uniqueDeviceID[6];

    /* 功能码 */
    replay_pack += 7;
    *replay_pack = SL_Function_Code_Distribution_Profile;

    /* 回复字节数长度 */
    replay_pack += 1;
    *replay_pack = 0x00;
    replay_pack += 1;
    *replay_pack = 0x01;

    /* 一分钟内都未接收到完整的配置文件，之前下发的配置文件都丢弃 */
    if (gw485CfgFlag == 2) {
        flag = 0;
        gw485CfgFlag = 0;
        // goto wholePackageError;
    }

    /* 传输帧的顺序不对 */
    if (*((uint8_t *)pMsg + 10) <= flag || (*((uint8_t *)pMsg + 10) > *((uint8_t *)pMsg + 11))) {
        flag = 0;
        goto wholePackageError;
    }

    /* 传输的第一帧数据 */
    if (*((uint8_t *)pMsg + 10) == 1) {
        gw485CfgTime = 0;
        gw485CfgFlag = 1;
        readFlashContent(&cfgInfo);
    }

    analysisData = pMsg;
    analysisData += 14;
    /* 解析一包的时间小于2ms */
    tickstart1 = HAL_GetTick();
    while ((analysisData != (((uint8_t *)pMsg + MsgLen) - 3)) && (analysisData != NULL) && ((HAL_GetTick() - tickstart1) < 100)) {
        analysisData = analysisDistributionProfile(analysisData, &cfgInfo);
    }
    
    if (((HAL_GetTick() - tickstart1) >= 100) || (analysisData == NULL)) {
        // if (analysisData == NULL) {
        //     debug_printf("analysisData == NULL\n");
        // }
        goto singlePackageError;
    }

    else if (*((uint8_t *)pMsg + 10) < *((uint8_t *)pMsg + 11)) {
        flag++;
        goto singlePackageCorrect;
    }

    else {
        flag = 0;
        // gw485CfgTime = 0;
        gw485CfgFlag = 0;
        goto wholePackageCorrect;
    }

/* 整个数据包正确 */
wholePackageCorrect:
    /* 回复内容 */
    replay_pack += 1;
    *replay_pack = 0xAA;

    /* 校验位 */
    replay_pack += 1;
    crc_temp = checkModebusCrc(getInsertData(), 13);
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 16);

    cfgInfo.crc = checkModebusCrc((uint8_t *)&cfgInfo, CONFIG_INFO_SIZE - 2);
    saveConfigInfo(&cfgInfo);

    // float tempF;
    // tempF = getTotalElectricityConsumption();
    // savetotalElectricityConsumption(&tempF);
    // tempF = getTotalChargCapacity();
    // savetotalChargCapacity(&tempF);
    // timeInfo time;
    // time = getLastTime();
    // saveTime(&time);

    return;

/* 整个数据包错误 */
wholePackageError:
    /* 回复内容 */
    replay_pack += 1;
    *replay_pack = 0x00;

    /* 校验位 */
    crc_temp = checkModebusCrc(getInsertData(), 13);
    replay_pack += 1;
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 16);

    return;

/* 当前数据包正确 */
singlePackageCorrect:
    /* 回复内容 */
    replay_pack += 1;
    *replay_pack = 0x55;

    /* 校验位 */
    crc_temp = checkModebusCrc(getInsertData(), 13);
    replay_pack += 1;
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 16);
    return;


/* 当前数据包错误 */
singlePackageError:
    /* 回复内容 */
    replay_pack += 1;
    *replay_pack = *((uint8_t *)pMsg + 10);

    /* 校验位 */
    crc_temp = checkModebusCrc(getInsertData(), 13);
    replay_pack += 1;
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 16);
    return;
}

/**
  * @brief  赛联协议读取配置文件
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Read_Profile\n");
    uint8_t *replay_pack = getInsertData();
    if (replay_pack == NULL) {
        return;
    }

    /* 起始标志 */
    *(replay_pack)      =  g_cfgParameter.startFlagSL[0];
    *(replay_pack + 1)  =  g_cfgParameter.startFlagSL[1];

    /* 地址 */
    replay_pack += 2;
    *(replay_pack)      =  g_cfgParameter.uniqueDeviceID[0];
    *(replay_pack + 1)  =  g_cfgParameter.uniqueDeviceID[1];
    *(replay_pack + 2)  =  g_cfgParameter.uniqueDeviceID[2];
    *(replay_pack + 3)  =  g_cfgParameter.uniqueDeviceID[3];
    *(replay_pack + 4)  =  g_cfgParameter.uniqueDeviceID[4];
    *(replay_pack + 5)  =  g_cfgParameter.uniqueDeviceID[5];
    *(replay_pack + 6)  =  g_cfgParameter.uniqueDeviceID[6];

    /* 功能码 */
    replay_pack += 7;
    *replay_pack = SL_Function_Code_Read_Profile;
    replay_pack += 1;
    replay_pack += 2;

    uint16_t replayPackDatalen = 0;

    uint8_t *analysisData = pMsg;
    analysisData += 12;

    /* 解析一包的时间小于100ms */
    uint32_t tickstart1;
    tickstart1 = HAL_GetTick();
    while ((analysisData != (((uint8_t *)pMsg + MsgLen) - 3)) && (analysisData != NULL) && ((HAL_GetTick() - tickstart1) < 100)) {
    // while ((analysisData != (((uint8_t *)pMsg + MsgLen) - 3)) && (analysisData != NULL)) {
        analysisData = analysisReadProfile(analysisData, &replay_pack, &replayPackDatalen);
    }

   if (analysisData != (((uint8_t *)pMsg + MsgLen) - 3) || (analysisData == NULL) || ((HAL_GetTick() - tickstart1) > 100)) {
    //    debug_printf("analysisData error \n");
       return;
   }
    
//    if (analysisData == NULL) {
//        debug_printf("analysisData == NULL \n");
//        return;
//    }
   
//    if (analysisData != (((uint8_t *)pMsg + MsgLen) - 3)) {
//        debug_printf("HAL_GetTick() - tickstart1 : %d \n", (HAL_GetTick() - tickstart1));
//        debug_printf("analysisData != (((uint8_t *)pMsg + MsgLen) - 3) \n");
//        return;
//    }



    uint8_t *replay_pack1 = getInsertData();
    *(replay_pack1 + 10) = (uint8_t)(replayPackDatalen >> 8);
    *(replay_pack1 + 11) = (uint8_t)(replayPackDatalen);

    /* 校验位 */
    // replay_pack += replayPackDatalen;
    uint16_t crc_temp = checkModebusCrc(getInsertData(), 12 + replayPackDatalen);
    // replay_pack += 1;
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 15 + replayPackDatalen);

    
    // debug_printf("SL_MsgProcFunc_Read_Profile end\n");
}

/**
  * @brief  赛联协议读取SOE
  * @param  device   串口设备
  *         pMsg     数据内容
  *         MsgLen   数据长度
  * @retval
  */
void SL_MsgProcFunc_Read_SOE(device_handle device, void *pMsg, uint32_t MsgLen)
{
    // debug_printf("SL_MsgProcFunc_Read_SOE\n");
    uint8_t *replay_pack = getInsertData();
    if (replay_pack == NULL) {
        return;
    }

    /* 起始标志 */
    *(replay_pack)      =  g_cfgParameter.startFlagSL[0];
    *(replay_pack + 1)  =  g_cfgParameter.startFlagSL[1];

    /* 地址 */
    replay_pack += 2;
    *(replay_pack)      =  g_cfgParameter.uniqueDeviceID[0];
    *(replay_pack + 1)  =  g_cfgParameter.uniqueDeviceID[1];
    *(replay_pack + 2)  =  g_cfgParameter.uniqueDeviceID[2];
    *(replay_pack + 3)  =  g_cfgParameter.uniqueDeviceID[3];
    *(replay_pack + 4)  =  g_cfgParameter.uniqueDeviceID[4];
    *(replay_pack + 5)  =  g_cfgParameter.uniqueDeviceID[5];
    *(replay_pack + 6)  =  g_cfgParameter.uniqueDeviceID[6];

    /* 功能码 */
    replay_pack += 7;
    *replay_pack = SL_Function_Code_Read_SOE;

    /* 数据内容长度 */
    uint16_t replayPackDatalen = (*((uint8_t *)pMsg + 11)) * getSoeDataInfoSize();
    replay_pack += 1;
    *replay_pack = (uint8_t)(replayPackDatalen >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)replayPackDatalen;

    /* 数据内容 */
    replay_pack += 1;
    for (uint16_t i = 1; i <= (*((uint8_t *)pMsg + 11)); i++) {
        readEventsOrderRecord((*((uint8_t *)pMsg + 10)) + i, replay_pack);
        replay_pack += getSoeDataInfoSize();
    }

    /* 校验位 */
    uint16_t crc_temp = checkModebusCrc(getInsertData(), 12 + replayPackDatalen);
    *replay_pack = (uint8_t)(crc_temp >> 8);
    replay_pack += 1;
    *replay_pack = (uint8_t)crc_temp;

    /* 结束标志 */
    replay_pack += 1;
    *replay_pack = g_cfgParameter.endFlagSL;

    uart_insertDataSend(device, 15 + replayPackDatalen);
}


#ifdef HY_ChargeControlBox_PROTOCOL_ENABLE

/**
 * @brief   状态 startFlagHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisStartFlagHY(void)
{
    static const uint16_t maxLen = 7;

    /* 解析HY协议硬件ID */
    if (gw485RxBufferIndex >= 7) {
        if (gw485RxBuffer[1] == HY_hardWordID[0]
                && gw485RxBuffer[2] == HY_hardWordID[1]
                && gw485RxBuffer[3] == HY_hardWordID[2]
                && gw485RxBuffer[4] == HY_hardWordID[3]
                && gw485RxBuffer[5] == HY_hardWordID[4]
                && gw485RxBuffer[6] == HY_hardWordID[5]) {
            state = hardWordIDHY;
            return TRUE;
        }

        else if (gw485RxBuffer[1] == 0xFF
                && gw485RxBuffer[2] == 0xFF
                && gw485RxBuffer[3] == 0xFF
                && gw485RxBuffer[4] == 0xFF
                && gw485RxBuffer[5] == 0xFF
                && gw485RxBuffer[6] == 0xFF) {
            state = hardWordIDHY;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }

    log_error("analysisStartFlagHY \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
    return FALSE;
}

/**
 * @brief   状态 hardWordIDHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisHardWordIDHY(void)
{
    static const uint16_t maxLen = 11;

    /* 解析HY协议通信ID */
    if (gw485RxBufferIndex >= 11) {
        if (gw485RxBuffer[7] == HY_communicationID[0]
                && gw485RxBuffer[8] == HY_communicationID[1]
                && gw485RxBuffer[9] == HY_communicationID[2]
                && gw485RxBuffer[10] == HY_communicationID[3]) {
            state = communicationIDHY;
            return TRUE;
        }
        // log_info("in data: 0x%x 0x%x 0x%x 0x%x \n", gw485RxBuffer[7], gw485RxBuffer[8], gw485RxBuffer[9], gw485RxBuffer[10]);
        // log_info("HY_communicationID: 0x%x 0x%x 0x%x 0x%x \n", HY_communicationID[0], HY_communicationID[1], 
        //                                     HY_communicationID[2], HY_communicationID[3]);
        
        if (gw485RxBuffer[7] == 0xFF
                && gw485RxBuffer[8] == 0xFF
                && gw485RxBuffer[9] == 0xFF
                && gw485RxBuffer[10] == 0xFF) {
            state = communicationIDHY;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }

    log_error("analysisHardWordIDHY \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
    return FALSE;
}

/**
 * @brief   状态 communicationIDHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisCommunicationIDHY(void)
{
    /* 硬件ID、通信ID全为0xFF时，控制字只能为查询ID */
    if (gw485RxBuffer[1] == 0xFF
            && gw485RxBuffer[2] == 0xFF
            && gw485RxBuffer[3] == 0xFF
            && gw485RxBuffer[4] == 0xFF
            && gw485RxBuffer[5] == 0xFF
            && gw485RxBuffer[6] == 0xFF
            && gw485RxBuffer[7] == 0xFF
            && gw485RxBuffer[8] == 0xFF
            && gw485RxBuffer[9] == 0xFF
            && gw485RxBuffer[10] == 0xFF) {

        if (gw485RxBuffer[11] == HY_sensorNumberInquiry
                || gw485RxBuffer[11] == HY_hardwareID_communicationIDQuery) {            
            state = controlWordHY;
            return TRUE;
        }
    }

    else {        
        if (gw485RxBuffer[11] == HY_batteryStatus
                || gw485RxBuffer[11] == HY_electricityStatistics
                || gw485RxBuffer[11] == HY_sensorNumberConfiguration
                || gw485RxBuffer[11] == HY_resetInstruction
                || gw485RxBuffer[11] == HY_chargeControlConfiguration
                || gw485RxBuffer[11] == HY_chargeControlQuery
                || gw485RxBuffer[11] == HY_configureTime
                || gw485RxBuffer[11] == HY_queryTime
                || gw485RxBuffer[11] == HY_configureProtocolType
                || gw485RxBuffer[11] == HY_responseProtocolType
                || gw485RxBuffer[11] == HY_queryControlBoxConfiguration
                || gw485RxBuffer[11] == HY_querySoftwareVersion
                || gw485RxBuffer[11] == HY_enterConfigurationMode
                || gw485RxBuffer[11] == HY_configureHardwareID
                || gw485RxBuffer[11] == HY_modifyCommunicationID
                || gw485RxBuffer[11] == HY_checkMotherboardTemperature) {            
            state = controlWordHY;
            return TRUE;
        }
    }
    if (gw485RxBufferIndex < 12) {
        return FALSE;
    }

    log_error("analysisCommunicationIDHY \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
    return FALSE;
}

/**
 * @brief   状态 controlWordHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisControlWordHY(void)
{
    static const uint16_t maxLen = 14;

    /* 解析数据长度 */
    if (gw485RxBufferIndex >= 14) {
        uint32_t tempDataLen = 0;
        tempDataLen = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13];

        if (tempDataLen >= 1 && tempDataLen <= maxDataLenHY) {
            frameLength = tempDataLen + 16;
            state = dataLengthHY;
            return TRUE;
        }
    }

    if (gw485RxBufferIndex < maxLen) {
        return FALSE;
    }

    log_error("analysisControlWordHY \n");
    state = wait;
    gw485RxBufferIndex--;
    memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
    return FALSE;
}

/**
 * @brief   状态 dataLengthHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisDataLengthHY(void)
{
    if (gw485RxBufferIndex < 15) {
        return FALSE;
    }

    if (gw485RxBuffer[11] == HY_batteryStatus) {        
        state = batteryStatusHY;
    }
    
    else if (gw485RxBuffer[11] == HY_electricityStatistics) {        
        state = electricityStatisticsHY;
    }

    else if (gw485RxBuffer[11] == HY_sensorNumberConfiguration) {        
        state = sensorNumberConfigurationHY;
    }
    
    else if (gw485RxBuffer[11] == HY_sensorNumberInquiry) {        
        state = sensorNumberInquiryHY;
    }
    
    else if (gw485RxBuffer[11] == HY_resetInstruction) {        
        state = resetInstructionHY;
    }
    
    else if (gw485RxBuffer[11] == HY_chargeControlConfiguration) {
        state = chargeControlConfigurationHY;
    }
    
    else if (gw485RxBuffer[11] == HY_chargeControlQuery) {        
        state = chargeControlQueryHY;
    }
    
    else if (gw485RxBuffer[11] == HY_configureTime) {        
        state = configureTimeHY;
    }
    
    else if (gw485RxBuffer[11] == HY_queryTime) {        
        state = queryTimeHY;
    }
    
    else if (gw485RxBuffer[11] == HY_configureProtocolType) {        
        state = configureProtocolTypeHY;
    }
    
    // else if (gw485RxBuffer[11] == HY_responseProtocolType) {        
    //     state = queryControlBoxConfigurationHY;
    // }
    
    else if (gw485RxBuffer[11] == HY_queryControlBoxConfiguration) {        
        state = queryControlBoxConfigurationHY;
    }
    
    else if (gw485RxBuffer[11] == HY_querySoftwareVersion) {        
        state = querySoftwareVersionHY;
    }
    
    else if (gw485RxBuffer[11] == HY_enterConfigurationMode) {        
        state = enterConfigurationModeHY;
    }
    
    else if (gw485RxBuffer[11] == HY_configureHardwareID) {        
        state = configureHardwareIDHY;
    }
    
    else if (gw485RxBuffer[11] == HY_hardwareID_communicationIDQuery) {        
        state = hardwareID_communicationIDQueryHY;
    }
    
    else if (gw485RxBuffer[11] == HY_modifyCommunicationID) {        
        state = modifyCommunicationIDHY;
    }

    else if (gw485RxBuffer[11] == HY_checkMotherboardTemperature) {
        state = checkMotherboardTemperatureHY;
    }

    return TRUE;
}

/**
 * @brief   状态 HY_batteryStatus
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisBatteryStatusHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("HY_batteryStatus \n");

        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        if (gw485RxBuffer[18] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[19] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_batteryStatus;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(38 >> 8);
        *(replay_pack + 1) = (uint8_t)38;
        replay_pack += 2;

        /* 数据域 */
        float temp;
        //电池电压
        // *(float *)(replay_pack) = getBatteryVoltage();
        temp = getBatteryVoltage();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //输出电流
        // *(float *)(replay_pack) = getDischargCurrent();
        temp = getDischargCurrent();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //充电电流1
        // *(float *)(replay_pack) = getChargCurrent();
        temp = getChargCurrent();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //剩余电量
        // *(float *)(replay_pack) = getSOC();
        temp = getSOC();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //充电开路电压1
        // *(float *)(replay_pack) = getSolarOpenCircuitVoltage();
        temp = getSolarOpenCircuitVoltage();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //充电开关状态1
        *(replay_pack) = getChargMosState();
        replay_pack += 1;
        //充电电流2
        // *(float *)(replay_pack) = getChargCurrent();
        // temp = getChargCurrent();
        temp = 0;
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //充电开路电压2
        // *(float *)(replay_pack) = getSolarOpenCircuitVoltage();
        // temp = getSolarOpenCircuitVoltage();
        temp = 0;
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //充电开关状态2
        *(replay_pack) = 0x00;
        replay_pack += 1;
        //工作温度
        // *(float *)(replay_pack) = getHighSideMosTemperature();
        temp = getHighSideMosTemperature();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;
        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 52);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;
        uart_insertDataSend(HY_device, 54);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 electricityStatisticsHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisElectricityStatisticsHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisElectricityStatisticsHY \n");

        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        //比较校验位和结束标志
        if (gw485RxBuffer[18] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[19] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_electricityStatistics;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(16 >> 8);
        *(replay_pack + 1) = (uint8_t)16;
        replay_pack += 2;

        /* 数据域 */
        //统计时长
        float tempF;
        uint32_t tempU32;
        timeInfo time1, time2;
        getRTC_Time(&time1);
        time2 = getLastTime();
        tempU32 = differTime(&time1, &time2);
        setLastTime(time1);
        memcpy(replay_pack, &tempU32, sizeof(uint32_t));
        replay_pack += 4;

        //总消耗电量
        tempF = getTotalElectricityConsumption();
        totalElectricityConsumptionInt(0);
        memcpy(replay_pack, &tempF, sizeof(float));
        replay_pack += 4;

        //总充电电量
        tempF = getTotalChargCapacity();
        totalChargCapacityInt(0);
        memcpy(replay_pack, &tempF, sizeof(float));
        replay_pack += 4;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 30);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 32);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 sensorNumberConfigurationHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisSensorNumberConfigurationHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisSensorNumberConfigurationHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 比较数据域中的硬件ID是否正确 */
        uint8_t flag = 0;
        if (gw485RxBuffer[18] != HY_hardWordID[0]
                || gw485RxBuffer[19] != HY_hardWordID[1]
                || gw485RxBuffer[20] != HY_hardWordID[2]
                || gw485RxBuffer[21] != HY_hardWordID[3]
                || gw485RxBuffer[22] != HY_hardWordID[4]
                || gw485RxBuffer[23] != HY_hardWordID[5]) {                    
            flag = 1;
            // state = wait;
            // gw485RxBufferIndex--;
            // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
            // return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        /* 保存要修改的通信ID */
        HY_communicationID[0] = gw485RxBuffer[24];
        HY_communicationID[1] = gw485RxBuffer[25];
        HY_communicationID[2] = gw485RxBuffer[26];
        HY_communicationID[3] = gw485RxBuffer[27];
        HY_writeCommunicationID_Flash();

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_sensorNumberConfiguration;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        if (flag) {
            *(replay_pack) = 0x00;
        } else {
            *(replay_pack) = 0xFF;
        }
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 sensorNumberInquiryHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisSensorNumberInquiryHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisSensorNumberInquiryHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_sensorNumberInquiry;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(14 >> 8);
        *(replay_pack + 1) = (uint8_t)14;
        replay_pack += 2;

        /* 数据域 */
        //硬件ID
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        //通信ID
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 28);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 30);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 resetInstructionHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisResetInstructionHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisResetInstructionHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_sensorNumberInquiry;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        *(replay_pack) = 0xFF;
        replay_pack++;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 chargeControlConfigurationHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisChargeControlConfigurationHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisSensorNumberInquiryHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        /* 判断打开还是关闭充电 */
        uint8_t flag = 0;
        if (gw485RxBuffer[19] == 0x00) {
            beginChargWork();
        } else if (gw485RxBuffer[19] == 0x01) {
            stopChargWork();
        } else {
            // state = wait;
            // gw485RxBufferIndex--;
            // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
            // return FALSE;
            flag = 1;
        }

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_chargeControlConfiguration;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        if (flag) {
            *(replay_pack) = 0x00;
        } else {
            *(replay_pack) = 0xFF;
        }
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 chargeControlQueryHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisChargeControlQueryHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisChargeControlQueryHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_chargeControlQuery;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(6 >> 8);
        *(replay_pack + 1) = (uint8_t)6;
        replay_pack += 2;

        /* 数据域 */
        //接口状态
        if (getChargControlFlag()
            && getDutyRatio() > 0 
            && getDutyRatio() < 1) {
            *(replay_pack) = 0x01;
            *(replay_pack + 1) = 0x01;
        } else {
            *(replay_pack) = 0x00;
            *(replay_pack + 1) = 0x00;
        }
        replay_pack += 2;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 20);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 22);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 configureTimeHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisConfigureTimeHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisChargeControlQueryHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        timeInfo timeTemp;
        timeTemp.year = gw485RxBuffer[18];
        timeTemp.month = gw485RxBuffer[19];
        timeTemp.day = gw485RxBuffer[20];
        timeTemp.hour = gw485RxBuffer[21];
        timeTemp.minute = gw485RxBuffer[22];
        timeTemp.second = gw485RxBuffer[23];
        setRTC_Time(&timeTemp);

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_configureTime;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        *(replay_pack) = 0xFF;
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 queryTimeHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisQueryTimeHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
         log_info("analysisQueryTimeHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_queryTime;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(10 >> 8);
        *(replay_pack + 1) = (uint8_t)10;
        replay_pack += 2;

        /* 数据域 */
        //时间
        timeInfo timeTemp;
        getRTC_Time(&timeTemp);
        *(replay_pack + 0) = timeTemp.year;
        *(replay_pack + 1) = timeTemp.month;
        *(replay_pack + 2) = timeTemp.day;
        *(replay_pack + 3) = timeTemp.hour;
        *(replay_pack + 4) = timeTemp.minute;
        *(replay_pack + 5) = timeTemp.second;
        replay_pack += 6;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 24);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 26);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 configureProtocolTypeHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisConfigureProtocolTypeHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisConfigureProtocolTypeHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 判断协议类型 */
        uint8_t flag = 0;
        if (gw485RxBuffer[16] == 0x01) {
            g_cfgParameter.gw485_Baud = 9600;
            Init_GW485_uart(g_cfgParameter.gw485_Baud);
        } else if (gw485RxBuffer[16] == 0x02) {
            g_cfgParameter.gw485_Baud = 115200;
            Init_GW485_uart(g_cfgParameter.gw485_Baud);
        } else {
            flag = 1;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_responseProtocolType;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        if (flag) {
            *(replay_pack) = 0x00;
        } else {
            *(replay_pack) = 0x01;
        }
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 queryControlBoxConfigurationHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisQueryControlBoxConfigurationHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisQueryControlBoxConfigurationHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_queryControlBoxConfiguration;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(8 >> 8);
        *(replay_pack + 1) = (uint8_t)8;
        replay_pack += 2;

        /* 数据域 */
        //协议类型
        if (g_cfgParameter.gw485_Baud == 9600) {
            *(replay_pack) = 0x01;
        } else if (g_cfgParameter.gw485_Baud == 115200) {
            *(replay_pack) = 0x02;
        } else {
            *(replay_pack) = 0x00;
        }
        replay_pack += 1;

        //电压等级
        *(replay_pack) = 0x00;
        replay_pack += 3;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 22);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 24);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 querySoftwareVersionHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisQuerySoftwareVersionHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisQuerySoftwareVersionHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_querySoftwareVersion;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(17 >> 8);
        *(replay_pack + 1) = (uint8_t)17;
        replay_pack += 2;

        /* 数据域 */
        //版本信息
        memcpy(replay_pack, getVersionnInformation(), 13);
        replay_pack += 13;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 31);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 33);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 enterConfigurationModeHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisEnterConfigurationModeHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisEnterConfigurationModeHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        HY_configurationMode_start();

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_enterConfigurationMode;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        *(replay_pack) = 0xFF;
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 configureHardwareIDHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisConfigureHardwareIDHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisConfigureHardwareIDHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 判断是否进入配置模式 */
        uint8_t flag = 0;
        if (HY_configurationModeFlag == 1) {
            HY_hardWordID[0] = gw485RxBuffer[18];
            HY_hardWordID[1] = gw485RxBuffer[19];
            HY_hardWordID[2] = gw485RxBuffer[20];
            HY_hardWordID[3] = gw485RxBuffer[21];
            HY_hardWordID[4] = gw485RxBuffer[22];
            HY_hardWordID[5] = gw485RxBuffer[23];
            HY_writeHardWordID_Flash();
            HY_configurationMode_stop();
        } else {
            flag = 1;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_configureHardwareID;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        if (flag) {
            *(replay_pack) = 0x00;
        } else {
            *(replay_pack) = 0xFF;
        }
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 hardwareID_communicationIDQueryHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisHardwareID_communicationIDQueryHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisHardwareID_communicationIDQueryHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_hardwareID_communicationIDQuery;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(14 >> 8);
        *(replay_pack + 1) = (uint8_t)14;
        replay_pack += 2;

        /* 数据域 */
        //硬件ID
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        //通信ID
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 28);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 30);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 modifyCommunicationIDHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisModifyCommunicationIDHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        log_info("analysisSensorNumberConfigurationHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 比较数据域中的硬件ID是否正确 */
        uint8_t flag = 0;
        if (gw485RxBuffer[18] != HY_hardWordID[0]
                || gw485RxBuffer[19] != HY_hardWordID[1]
                || gw485RxBuffer[20] != HY_hardWordID[2]
                || gw485RxBuffer[21] != HY_hardWordID[3]
                || gw485RxBuffer[22] != HY_hardWordID[4]
                || gw485RxBuffer[23] != HY_hardWordID[5]) {                    
            flag = 1;
            // state = wait;
            // gw485RxBufferIndex--;
            // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);
            // return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        /* 保存要修改的通信ID */
        HY_communicationID[0] = gw485RxBuffer[24];
        HY_communicationID[1] = gw485RxBuffer[25];
        HY_communicationID[2] = gw485RxBuffer[26];
        HY_communicationID[3] = gw485RxBuffer[27];
        HY_writeCommunicationID_Flash();

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_sensorNumberConfiguration;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(5 >> 8);
        *(replay_pack + 1) = (uint8_t)5;
        replay_pack += 2;

        /* 数据域 */
        //状态
        if (flag) {
            *(replay_pack) = 0x00;
        } else {
            *(replay_pack) = 0xFF;
        }
        replay_pack += 1;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 19);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 21);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

/**
 * @brief   状态 checkMotherboardTemperatureHY
 * @param
 * @retval  TRUE:解析成功 FALSE:解析失败
 */
BOOL analysisCheckMotherboardTemperatureHY(void)
{
    /* 解析帧 */
    if (gw485RxBufferIndex >= frameLength) {
        // log_info("analysisCheckMotherboardTemperatureHY \n");

        /* 比较校验位和结束标志 */
        if (gw485RxBuffer[frameLength - 2] != HY_CheckFunc(gw485RxBuffer, frameLength - 2)
            || gw485RxBuffer[frameLength - 1] != HY_endFlag) {
            state = wait;
            gw485RxBufferIndex--;
            memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex);    
            return FALSE;
        }

        /* 获取帧序号 */
        HY_frameNumber[0] = gw485RxBuffer[14];
        HY_frameNumber[1] = gw485RxBuffer[15];
        HY_frameNumber[2] = gw485RxBuffer[16];
        HY_frameNumber[3] = gw485RxBuffer[17];

        uint8_t *replay_pack = getInsertData();
        /* 起始标志 */
        *(replay_pack) = HY_startFlag;
        replay_pack++;

        /* 硬件ID */
        *(replay_pack + 0) = HY_hardWordID[0];
        *(replay_pack + 1) = HY_hardWordID[1];
        *(replay_pack + 2) = HY_hardWordID[2];
        *(replay_pack + 3) = HY_hardWordID[3];
        *(replay_pack + 4) = HY_hardWordID[4];
        *(replay_pack + 5) = HY_hardWordID[5];
        replay_pack += 6;

        /* 通信ID */
        *(replay_pack + 0) = HY_communicationID[0];
        *(replay_pack + 1) = HY_communicationID[1];
        *(replay_pack + 2) = HY_communicationID[2];
        *(replay_pack + 3) = HY_communicationID[3];
        replay_pack += 4;

        /* 控制字 */        
        *(replay_pack) = HY_checkMotherboardTemperature;
        replay_pack++;

        /* 数据长度 */
        *(replay_pack) = (uint8_t)(8 >> 8);
        *(replay_pack + 1) = (uint8_t)8;
        replay_pack += 2;

        /* 数据域 */
        //温度
        float temp;
        temp = getHighSideMosTemperature();
        memcpy(replay_pack, &temp, sizeof(float));
        replay_pack += 4;

        //帧序号
        *(replay_pack) = HY_frameNumber[0];
        *(replay_pack + 1) = HY_frameNumber[1];
        *(replay_pack + 2) = HY_frameNumber[2];
        *(replay_pack + 3) = HY_frameNumber[3];
        replay_pack += 4;

        /* 校验码 */
        *(replay_pack) = HY_CheckFunc(getInsertData(), 22);
        replay_pack++;

        /* 结束码 */
        *(replay_pack) = HY_endFlag;
        replay_pack++;

        uart_insertDataSend(HY_device, 24);

        gw485RxBufferIndex = 0;
        state = wait;
    }

    if (gw485RxBufferIndex < frameLength) {
        return FALSE;
    }

    return TRUE;
}

// /**
//  * @brief   状态 readSOELength
//  * @param
//  * @retval  TRUE:解析成功 FALSE:解析失败
//  */
// BOOL analysisCheckCodeHY(void)
// {
//     log_info("analysisCheckCodeHY \n");

//     return TRUE;
// }

// /**
//  * @brief   状态 readSOELength
//  * @param
//  * @retval  TRUE:解析成功 FALSE:解析失败
//  */
// BOOL analysisEndFlagHY(void)
// {
//     log_info("analysisEndFlagHY \n");

//     return TRUE;
// }

/**
 * @brief   向flash中存入硬件ID的值
 * @param
 * @retval
 */
void HY_writeHardWordID_Flash(void)
{
    write_Flash(HY_hardWordID, HY_hardWordIDStartAddr, HY_hardWordIDSize);
}

/**
 * @brief   向flash中读取硬件ID的值，当所有值都为0xFF时，该值不生效
 * @param
 * @retval
 */
void HY_readHardWordID_Flash(void)
{
    uint8_t temp[6];
    read_Flash(temp, HY_hardWordIDStartAddr, HY_hardWordIDSize);
    int i = 0;
    for (; i < HY_hardWordIDSize; i++) {
        if (temp[0] != 0xFF) {
            break;
        }
    }

    if (i != HY_hardWordIDSize) {
        i = 0;    
        for (; i < HY_hardWordIDSize; i++) {
            HY_hardWordID[i] = temp[i];
        }
    }

    // HY_hardWordID[0] = g_cfgParameter.uniqueDeviceID[0];
    // HY_hardWordID[1] = g_cfgParameter.uniqueDeviceID[1];
    // HY_hardWordID[2] = g_cfgParameter.uniqueDeviceID[2];
    // HY_hardWordID[3] = g_cfgParameter.uniqueDeviceID[3];
    // HY_hardWordID[4] = g_cfgParameter.uniqueDeviceID[4];
    // HY_hardWordID[5] = g_cfgParameter.uniqueDeviceID[5];
    
    // log_info("HY_hardWordID[0]:%x\n", HY_hardWordID[0]);
    // log_info("HY_hardWordID[1]:%x\n", HY_hardWordID[1]);
    // log_info("HY_hardWordID[2]:%x\n", HY_hardWordID[2]);
    // log_info("HY_hardWordID[3]:%x\n", HY_hardWordID[3]);
    // log_info("HY_hardWordID[4]:%x\n", HY_hardWordID[4]);
    // log_info("HY_hardWordID[5]:%x\n", HY_hardWordID[5]);
}

/**
 * @brief   向flash中存入通信ID的值
 * @param
 * @retval
 */
void HY_writeCommunicationID_Flash(void)
{
    write_Flash(HY_communicationID, HY_communicationIDStartAddr, HY_communicationIDSize);
}

/**
 * @brief   向flash中读取通信ID的值，当所有值都为0xFF时，该值不生效
 * @param
 * @retval
 */
void HY_readCommunicationID_Flash(void)
{
    uint8_t temp[HY_communicationIDSize];
    read_Flash(temp, HY_communicationIDStartAddr, HY_communicationIDSize);
    int i = 0;
    for (; i < HY_communicationIDSize; i++) {
        if (temp[0] != 0xFF) {
            break;
        }
    }

    if (i != HY_communicationIDSize) {
        i = 0;    
        for (; i < HY_communicationIDSize; i++) {
            HY_communicationID[i] = temp[i];
        }
    }

    // log_info("HY_communicationID[0]:%x\n", HY_communicationID[0]);
    // log_info("HY_communicationID[1]:%x\n", HY_communicationID[1]);
    // log_info("HY_communicationID[2]:%x\n", HY_communicationID[2]);
    // log_info("HY_communicationID[3]:%x\n", HY_communicationID[3]);
}

#endif