chargeController/APP/businessLogic/Src/bl_usart.c

679 lines
19 KiB
C
Raw Normal View History

2025-01-04 09:50:05 +00:00
#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");
}