#include "bl_usart.h" #include "parameter.h" #include "chargControlTypes.h" #include "configParameter.h" #include "string.h" #include "pDebug.h" 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寄存器状态 */ } 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_MsgFunctionCode; #define gw485RxBufferSize 256 /* 计时参数,一秒后没解析出数据,丢掉当前数据 */ 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 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 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); /** * @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 状态机函数 * @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(); } } void gw485DataAnalysis(device_handle device) { /* 1S未解析出来一帧数据,将数据清零 */ gw485RxTime++; if (gw485RxTime == 10) { gw485RxTime = 0; gw485RxBufferIndex = 0; state = wait; } while (uart_dev_char_present(device) == 1) { gw485RxBuffer[gw485RxBufferIndex++] = uart_dev_in_char(device); stateMachine(device); } stateMachine(device); } /** * @brief 状态 wait * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisWait(void) { static uint16_t maxLen = 2; /* 解析SL协议的包头 */ if (gw485RxBufferIndex >= 2) { if (gw485RxBuffer[0] == 'S' && gw485RxBuffer[1] == 'L') { state = startFlagSL; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 StartFlagSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisStartFlagSL(void) { static uint16_t maxLen = 9; /* 解析SL协议设备地址 */ if (gw485RxBufferIndex >= 9) { if (gw485RxBuffer[2] == g_cfgParameter.address[0] && gw485RxBuffer[3] == g_cfgParameter.address[1] && gw485RxBuffer[4] == g_cfgParameter.address[2] && gw485RxBuffer[5] == g_cfgParameter.address[3] && gw485RxBuffer[6] == g_cfgParameter.address[4] && gw485RxBuffer[7] == g_cfgParameter.address[5] && gw485RxBuffer[8] == g_cfgParameter.address[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; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 addressSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisAddressSL(void) { static 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 ) { state = functionCodeSL; return TRUE; } } else { if (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan) { state = functionCodeSL; frameLength = 13; return TRUE; } } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 functionCodeSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisFunctionCodeSL(void) { static 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; } log_info("tempCrc:%d", tempCrc); log_info("checkModebusCrc:%d", checkModebusCrc(gw485RxBuffer, frameLength - 3)); } /* 解析注册回复帧寄存器长度 */ 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 < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 readRegStartAddressSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisReadRegStartAddressSL(void) { static uint16_t maxLen = 12; /* 解析读取寄存器长度 */ 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; } 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; } /** * @brief 状态 crcCheckBitSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisCrcCheckBitSL(void) { /* 结束标志校验校验 */ if (gw485RxBufferIndex == frameLength) { if (gw485RxBuffer[frameLength - 1] == 0x16) { state = endFlagSL; return TRUE; } } 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); } state = wait; gw485RxBufferIndex = 0; // memcpy(gw485RxBuffer, gw485RxBuffer + gw485RxBufferIndex, ); } /** * @brief 状态 writeRegStartAddressSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisWriteRegStartAddressSL(void) { static 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 = 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; } /** * @brief 状态 regLengthSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisRegLengthSL(void) { static 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; } /** * @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"); } /** * @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"); } /** * @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"); } /** * @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"); } /** * @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"); }