chargeController/APP/businessLogic/Src/bl_usart.c

679 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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");
}