mppt/App/src/sl_protocol.c

837 lines
26 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

/*
* zl_protocol.c
*
* Created on: 2024年6月20日
* Author: psx
*/
#include "sl_protocol.h"
#include <string.h>
#include "inflash.h"
#include "pdebug.h"
#include "mppt_control.h"
#include <stdlib.h>
#include "task.h"
#include "tim.h"
/* 静态函数申明 */
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_Update_Profile(device_handle device, void *pMsg, uint32_t MsgLen);
static void SL_MsgProcFunc_Remote_Upgrade(device_handle device, void *pMsg, uint32_t MsgLen);
static uint16_t SL_ReadRegisterRegistrationStatus(void *pMsg);
static uint16_t SL_ReadRegisteraddress(void *pMsg);
static uint16_t SL_ReadRegisterAccessNodeType(void *pMsg);
static uint16_t SL_ReadRegisterCommunicationMethods(void *pMsg);
static uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg);
static uint16_t SL_ReadRegisterBatterytemperature(void *pMsg);
static uint16_t SL_ReadRegisterRemainingBatteryBower(void *pMsg);
static uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg);
//static uint16_t SL_ReadRegisterSolarOpenCircuitVoltage2(void *pMsg);
//static uint16_t SL_WriteRegisterRegistrationStatus(void *pMsg);
//static uint16_t SL_WriteRegisteraddress(void *pMsg);
//static uint16_t SL_WriteRegisterAccessNodeType(void *pMsg);
//static uint16_t SL_WriteRegisterCommunicationMethods(void *pMsg);
//static uint16_t SL_WriteRegisterBatteryVoltage(void *pMsg);
//static uint16_t SL_WriteRegisterBatterytemperature(void *pMsg);
//static uint16_t SL_WriteRegisterRemainingBatteryBower(void *pMsg);
//static uint16_t SL_WriteRegisterSolarOpenCircuitVoltage1(void *pMsg);
//static uint16_t SL_WriteRegisterSolarOpenCircuitVoltage2(void *pMsg);
/* 读取串口数据时用该数组解析 */
static uint8_t rs485_buff[50]={0x00};
/* 一次最多读写的寄存器个数,由设备决定 */
#define Register_Number_Max 5
/* 寄存器个数,由设备决定 */
#define MPPT_Register_Number 5
/* 读写的寄存器的最大起始位置,由设备决定 */
#define Register_Start_Address_Max 0x0200
/* 用于解析串口包时的长度 */
#define analyzeStartFlag 2 //长度为2时解析起始标志
#define analyzeAddress 9 //长度为9时解析地址
#define analyzeFunctionCode 10 //长度为10时解析功能码
#define analyzeWritelen 14 //功能码为写入寄存器且buffer长度为14时可以解析出写入寄存器包的长度
/* 功能码处理表 */
SL_FuncionMsgProcTable g_MsgTbl[] =
{
{SL_Function_Code_Read_Register, SL_MsgProcFunc_Read_Register},
{SL_Function_Code_Write_Register, SL_MsgProcFunc_Write_Register},
{SL_Function_Code_Broadcast_Scan, SL_MsgProcFunc_Broadcast_Scan},
{SL_Function_Code_Registration_request, SL_MsgProcFunc_Registration_request},
{SL_Function_Code_Update_Profile, SL_MsgProcFunc_Update_Profile},
{SL_Function_Code_Remote_Upgrade, SL_MsgProcFunc_Remote_Upgrade},
};
/* 寄存器处理表 */
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_Battery_Voltage, SL_ReadRegisterBatteryVoltage},
{SL_Register_Battery_temperature, SL_ReadRegisterBatterytemperature},
{SL_Register_Remaining_Battery_Bower, SL_ReadRegisterRemainingBatteryBower},
{SL_Register_Solar_Open_Circuit_Voltage1, SL_ReadRegisterSolarOpenCircuitVoltage},
// {SL_Register_Solar_Open_Circuit_Voltage2, SL_ReadRegisterSolarOpenCircuitVoltage2},
};
/* 寄存器处理表 */
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_Battery_Voltage, SL_WriteRegisterBatteryVoltage},
// {SL_Register_Battery_temperature, SL_WriteRegisterBatterytemperature},
// {SL_Register_Remaining_Battery_Bower, SL_WriteRegisterRemainingBatteryBower},
// {SL_Register_Solar_Open_Circuit_Voltage1, SL_WriteRegisterSolarOpenCircuitVoltage1},
// {SL_Register_Solar_Open_Circuit_Voltage2, SL_WriteRegisterSolarOpenCircuitVoltage2},
};
/**
* @brief 校验算法
* @param
* @retval
*/
uint16_t CheckFunc(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 随机延时函数,延时区间100-2500ms分辨率10ms  
* @param
* @retval 延时时间
*/
int randomDelay()
{
int minSeconds = 10;
int maxSeconds = 250;
// srand(SystemCoreClock);//time(NULL)替换为对应操作系统时钟
srand(TIM_GetCounter(TIM4));
int delaySeconds = minSeconds + rand() % (maxSeconds - minSeconds + 1);
return delaySeconds * 10;
}
/**
* @brief 检测485总线是否繁忙
* @param
* @retval 1 繁忙
* 0 空闲
*/
uint8_t Check_485_bus_busy(device_handle device)
{
if (device == g_bat485_uart3_handle) {
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
} else {
USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
}
uint16_t num_ago = ring_queue_length(device);
Delay_Ms(2);
uint16_t num_now = ring_queue_length(device);
if (device == g_bat485_uart3_handle) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
} else {
USART_ITConfig(USART4, USART_IT_RXNE, DISABLE);
}
if (num_now == num_ago) {
return 0;
}
return 1;
}
/**
* @brief 读取
* @param
* @retval
*/
void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
SL_Mppt_Rorecv_pack *rpack = (SL_Mppt_Rorecv_pack *)pMsg;
uint16_t Register_Number_16 = chang_8_to_16(rpack->read_Register_Number_L,rpack->read_Register_Number_H);
if (Register_Number_16 > Register_Number_Max) {
log_error(" Register_Number error:%x \r\n", Register_Number_16);
return;
}
uint16_t Start_Address_16 = chang_8_to_16(rpack->read_Register_Start_Address_L,rpack->read_Register_Start_Address_H);
if (Start_Address_16 > Register_Start_Address_Max) {
log_error(" Register_Start_Address error : %x \r\n", Start_Address_16);
return;
}
/* 读取寄存器数据 */
// uint8_t reply_Data_Content[2 * 5] = {0};
uint16_t reply_Data_Content[Register_Number_Max] = {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)) {
// *(uint16_t *)&reply_Data_Content[pos * 2] = g_RegTblR[var].pRegProc(NULL);
reply_Data_Content[pos] = g_RegTblR[var].pRegProc(NULL);
}
}
}
/* 打包 */
memset(rs485_buff, 0, sizeof(rs485_buff));
uint8_t *replay_pack = rs485_buff;
// strlcpy(replay_pack, g_slConfigInfo.start_Flag, 2);
*(replay_pack) = g_slConfigInfo.start_Flag[0];
*(replay_pack + 1) = g_slConfigInfo.start_Flag[1];
replay_pack += 2;
// strlcpy(replay_pack, g_slConfigInfo.address, 7);
*(replay_pack) = g_slConfigInfo.address[0];
*(replay_pack + 1) = g_slConfigInfo.address[1];
*(replay_pack + 2) = g_slConfigInfo.address[2];
*(replay_pack + 3) = g_slConfigInfo.address[3];
*(replay_pack + 4) = g_slConfigInfo.address[4];
*(replay_pack + 5) = g_slConfigInfo.address[5];
*(replay_pack + 6) = g_slConfigInfo.address[6];
replay_pack += 7;
*replay_pack = SL_Function_Code_Read_Register;
replay_pack += 1;
// *(uint16_t *)&replay_pack = rpack->read_Register_Number;
*replay_pack = (Register_Number_16 >> 8);
*(replay_pack + 1) = (Register_Number_16);
replay_pack += 2;
for (uint8_t var = 0; var < Register_Number_16 * 2; var++) {
if (0 == (var & 0x01)) {
*(replay_pack + var) = (reply_Data_Content[var / 2] >> 8);
} else {
*(replay_pack + var) = (reply_Data_Content[var / 2]);
}
}
replay_pack += Register_Number_16 * 2;
uint16_t crc_temp = CheckFunc(rs485_buff, (2 + 7 + 1 + 2 + Register_Number_16 * 2));
// log_info("CheckFunc crc_temp: %x \r\n", crc_temp);
*replay_pack = (uint8_t)(crc_temp >> 8);
replay_pack += 1;
*replay_pack = (uint8_t)crc_temp;
replay_pack += 1;
*replay_pack = g_slConfigInfo.end_Flag;
while (1) {
Delay_Ms(randomDelay());
if (!Check_485_bus_busy(device)) {
// log_info("pack : %s", (uint8_t *)&replay_pack);
// uart_dev_write(device, (uint8_t *)&replay_pack, 16 + Register_Number_16 * 2 + 1);
uart_dev_write(device, rs485_buff, 16 + Register_Number_16 * 2);
if (device == g_bat485_uart3_handle) {
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
} else {
USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
}
break;
}
}
}
void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen)
{
SL_Mppt_Worecv_pack *wpack = (SL_Mppt_Worecv_pack *)pMsg;
uint8_t *buff = (uint8_t *)pMsg;
uint16_t Register_Number = \
chang_8_to_16(wpack->write_Register_Number_L, wpack->write_Register_Number_H);
if (Register_Number > Register_Number_Max) {
log_error(" Register_Number error:%x \r\n", Register_Number);
return;
}
uint16_t Register_Start_Address = \
chang_8_to_16(wpack->write_Register_Start_Address_L, wpack->write_Register_Start_Address_H);
if (Register_Start_Address > Register_Start_Address_Max) {
log_error(" Register_Start_Address error : %x \r\n", Register_Start_Address);
return;
}
printf("in write register \n");
uint16_t content[Register_Number_Max] = {0};
for (uint16_t var = 0; var < Register_Number; var++) {
content[var] = buff[14 + 2 * var] << 8 | buff[14 + 2 * var + 1];
}
for ( uint16_t pos = 0; pos < Register_Number; pos++) {
for (uint16_t i = 0; i < sizeof(g_RegTblW) / sizeof(SL_RegProcTable); i++) {
if (g_RegTblW[i].regId == (Register_Start_Address + pos)) {
g_RegTblW[i].pRegProc(&content[pos]);
}
}
}
}
void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen)
{
g_recvBroadcastDevice = device;
g_recvBroadcastRegisterNumber = MPPT_Register_Number;
RegistrationRequestFlag = 1;
/* 任务创立后,立即执行一次 */
TimeSliceOffset_Register(&m_recvbroadcast, Task_recvbroadcast \
, recvbroadcast_reloadVal, recvbroadcast_offset);
m_recvbroadcast.runFlag = 1;
}
void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen)
{
log_info("Registration success \r\n");
recvbroadcast_flag = 1;
RegistrationRequestFlag = 0;
TimeSliceOffset_Unregister(&m_recvbroadcast);
SL_Mppt_RegistrationReply_pack *rpack = (SL_Mppt_RegistrationReply_pack *)pMsg;
g_Mppt_Para.Registration_Status = chang_8_to_16(rpack->registration_Status_L, rpack->registration_Status_H);
/* 20s内不再接收广播帧 */
run_Broadcast = 0;
TIM2->CNT = 0;
TIM_Cmd(TIM2, ENABLE); //TIM2使能
}
void SL_MsgProcFunc_Update_Profile(device_handle device, void *pMsg, uint32_t MsgLen)
{
SL_Mppt_SOther_pack SUpdateProfile_pack = {0};
SUpdateProfile_pack.start_Flag[0] = g_slConfigInfo.start_Flag[0];
SUpdateProfile_pack.start_Flag[1] = g_slConfigInfo.start_Flag[1];
SUpdateProfile_pack.address[0] = g_slConfigInfo.address[0];
SUpdateProfile_pack.address[1] = g_slConfigInfo.address[1];
SUpdateProfile_pack.address[2] = g_slConfigInfo.address[2];
SUpdateProfile_pack.address[3] = g_slConfigInfo.address[3];
SUpdateProfile_pack.address[4] = g_slConfigInfo.address[4];
SUpdateProfile_pack.address[5] = g_slConfigInfo.address[5];
SUpdateProfile_pack.address[6] = g_slConfigInfo.address[6];
SUpdateProfile_pack.function_Code = SL_Function_Code_Update_Profile;
SUpdateProfile_pack.state = 0x01;
uint16_t crc = CheckFunc((uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE - 3);
SUpdateProfile_pack.check_Bit_H = crc >> 8;
SUpdateProfile_pack.check_Bit_L = crc;
SUpdateProfile_pack.end_Flag = g_slConfigInfo.end_Flag;
while (1) {
Delay_Ms(randomDelay());
if (!Check_485_bus_busy(device)) {
uart_dev_write(device, (uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE + 1);
if (device == g_bat485_uart3_handle) {
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
} else {
USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
}
break;
}
}
}
void SL_MsgProcFunc_Remote_Upgrade(device_handle device, void *pMsg, uint32_t MsgLen)
{
SL_Mppt_SOther_pack SUpdateProfile_pack = {0};
SUpdateProfile_pack.start_Flag[0] = g_slConfigInfo.start_Flag[0];
SUpdateProfile_pack.start_Flag[1] = g_slConfigInfo.start_Flag[1];
SUpdateProfile_pack.address[0] = g_slConfigInfo.address[0];
SUpdateProfile_pack.address[1] = g_slConfigInfo.address[1];
SUpdateProfile_pack.address[2] = g_slConfigInfo.address[2];
SUpdateProfile_pack.address[3] = g_slConfigInfo.address[3];
SUpdateProfile_pack.address[4] = g_slConfigInfo.address[4];
SUpdateProfile_pack.address[5] = g_slConfigInfo.address[5];
SUpdateProfile_pack.address[6] = g_slConfigInfo.address[6];
SUpdateProfile_pack.function_Code = SL_Function_Code_Remote_Upgrade;
SUpdateProfile_pack.state = 0x01;
uint16_t crc = CheckFunc((uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE - 3);
SUpdateProfile_pack.check_Bit_H = crc >> 8;
SUpdateProfile_pack.check_Bit_L = crc;
SUpdateProfile_pack.end_Flag = g_slConfigInfo.end_Flag;
while (1) {
Delay_Ms(randomDelay());
if (!Check_485_bus_busy(device)) {
uart_dev_write(device, (uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE + 1);
if (device == g_bat485_uart3_handle) {
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
} else {
USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
}
break;
}
}
}
/**
* @brief 读取注册状态寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterRegistrationStatus(void *pMsg)
{
log_info(" SL_ReadRegisterRegistrationStatus ");
uint16_t value = g_Mppt_Para.Registration_Status;
return value;
}
/**
* @brief 读取地址寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisteraddress(void *pMsg)
{
log_info(" SL_ReadRegisteraddress ");
return 0;
}
/**
* @brief 读取接入节点类型寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterAccessNodeType(void *pMsg)
{
log_info(" SL_ReadRegisterAccessNodeType ");
uint16_t value = g_Mppt_Para.Access_Node_Type;
return value;
}
/**
* @brief 读取通信方式寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterCommunicationMethods(void *pMsg)
{
log_info(" SL_ReadRegisterCommunicationMethods ");
uint16_t value = g_Mppt_Para.Communication_Methods;
return value;
}
/**
* @brief 读取电池电压寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg)
{
log_info(" SL_ReadRegisterBatteryVoltage ");
uint16_t value = (uint16_t)g_Mppt_Para.Battery_Voltage * 10;
return value;
}
/**
* @brief 读取电池温度寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterBatterytemperature(void *pMsg)
{
log_info(" SL_ReadRegisterBatterytemperature ");
uint16_t value = (uint16_t)g_Mppt_Para.Battery_temperature * 10;
return value;
}
/**
* @brief 读取电池剩余电量寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterRemainingBatteryBower(void *pMsg)
{
log_info(" SL_ReadRegisterRemainingBatteryBower ");
uint16_t value = (uint16_t)g_Mppt_Para.Remaining_Battery_Bower * 10;
return value;
}
/**
* @brief 读取太阳能开路电压1寄存器
* @param
* @retval
*/
uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg)
{
log_info(" SL_ReadRegisterSolarOpenCircuitVoltage1 ");
uint16_t value = (uint16_t)g_Mppt_Para.Solar_Open_Circuit_Voltage * 10;
return value;
}
//
///**
// * @brief 读取太阳能开路电压2寄存器
// * @param
// * @retval
// */
//uint16_t SL_ReadRegisterSolarOpenCircuitVoltage2(void *pMsg)
//{
// log_info(" SL_ReadRegisterSolarOpenCircuitVoltage2 ");
// uint16_t value = (uint16_t)g_Mppt_Para.Solar_Open_Circuit_Voltage2 * 10;
// return value;
//}
///**
// * @brief 写入注册状态寄存器
// * @param
// * @retval
// */
//uint16_t SL_WriteRegisterRegistrationStatus(void *pMsg)
//{
// log_info(" WriteRegisterRegistrationStatus %x", *(uint16_t *)pMsg);
//
// return 0;
//}
//
///**
// * @brief 写入地址寄存器
// * @param
// * @retval
// */
//uint16_t SL_WriteRegisteraddress(void *pMsg)
//{
// log_info(" WriteRegisteraddress %x", *(uint16_t *)pMsg);
//
// return 0;
//}
//
///**
// * @brief 写入接入节点类型寄存器
// * @param
// * @retval
// */
//uint16_t SL_WriteRegisterAccessNodeType(void *pMsg)
//{
// log_info(" WriteRegisterAccessNodeType %x", *(uint16_t *)pMsg);
//
// return 0;
//}
//
///**
// * @brief 写入通信方式寄存器
// * @param
// * @retval
// */
//uint16_t SL_WriteRegisterCommunicationMethods(void *pMsg)
//{
// log_info(" WriteRegisterCommunicationMethods %x", *(uint16_t *)pMsg);
//
// return 0;
//}
/**
* @brief 匹配起始标志"SL"
* @param start_buff 起始标志
* @retval 1 匹配成功
* 0 匹配失败
*/
static int Match_Startflag(uint8_t start_buff[2])
{
// if (!strcmp(start_buff, g_slConfigInfo.start_Flag)) {
// log_info("Match_Startflag fail \r\n");
// return 1;
// }
if ((start_buff[0] == g_slConfigInfo.start_Flag[0]) && \
(start_buff[1] == g_slConfigInfo.start_Flag[1])) {
log_info("Match_Startflag success \r\n");
return 1;
}
return 0;
}
/**
* @brief 匹配设备地址
* @param address 地址
* @retval 1 匹配成功
* 0 匹配失败
*/
static int Match_address(u_int8_t address[7])
{
// if (!strcmp(address, g_slConfigInfo.address)) {
// log_info("Match_address fail \r\n");
// return 1;
// }
if ((address[0] == g_slConfigInfo.address[0]) && \
(address[1] == g_slConfigInfo.address[1]) && \
(address[2] == g_slConfigInfo.address[2]) && \
(address[3] == g_slConfigInfo.address[3]) && \
(address[4] == g_slConfigInfo.address[4]) && \
(address[5] == g_slConfigInfo.address[5]) && \
(address[6] == g_slConfigInfo.address[6])) {
log_info("Match_address success \r\n");
return 1;
}
return 0;
}
/**
* @brief 匹配广播地址
* @param address 地址
* @retval 1 匹配成功
* 0 匹配失败
*/
static int Match_Broadcastaddress(u_int8_t address[7])
{
if (address[0] == 0xFF && \
address[1] == 0xFF && \
address[2] == 0xFF && \
address[3] == 0xFF && \
address[4] == 0xFF && \
address[5] == 0xFF && \
address[6] == 0xFF) {
log_info("Match_Broadcastaddress success\r\n");
return 1;
}
return 0;
}
/**
* @brief 读取串口数据
* @param uart_handle 串口句柄
* @param buff 缓冲区
* @param buff_size 缓冲区长度
* @retval
*/
static int uart_read_climate_pack(device_handle uart_handle,uint8_t *buff, uint32_t buff_size)
{
uint32_t offset = 0;
uint32_t len = 0;
uint8_t flag_run = 0;
char c = 0;
SL_Mppt_Recv_pack *pack = (SL_Mppt_Recv_pack *)buff;
buff_size--; //预留一个'\0'位置
for (; offset < buff_size;){
if (ring_queue_length(uart_handle) == 0) {
break;
}
c = uart_dev_in_char(uart_handle);
buff[offset++] = c;
/* 匹配起始标志位 */
if (offset == analyzeStartFlag || (flag_run > 0)) {
if (!Match_Startflag(pack->start_Flag)) {
memcpy(buff, buff+1, offset-1);
offset--;
continue;
}
}
/* 匹配地址 */
if (offset == analyzeAddress || (flag_run > 1)) {
if (!((((g_Mppt_Para.Registration_Status == 2) || RegistrationRequestFlag) && Match_address(pack->address))
|| (run_Broadcast && Match_Broadcastaddress(pack->address)))) {
if (flag_run < 1) {
flag_run = 1;
}
memcpy(buff, buff+1, offset-1);
offset--;
continue;
}
}
/* 匹配功能码 */
if (offset == analyzeFunctionCode || (flag_run > 2)) {
/* 未注册时,不处理读写和其他帧 */
if (g_Mppt_Para.Registration_Status == 2) {
/* 读寄存器数据 */
if (pack->function_Code == SL_Function_Code_Read_Register) {
log_info("Read_Register\r\n");
len = SL_MPPT_RORECV_PACK_SIZE;
}
/* 写寄存器数据 */
else if (pack->function_Code == SL_Function_Code_Write_Register) {
log_info("Write_Register\r\n");
}
/* 其他帧格式 */
else if (pack->function_Code == SL_Function_Code_Update_Profile
|| pack->function_Code == SL_Function_Code_Remote_Upgrade) {
len = SL_MPPT_ROTHER_PACK_SIZE;
log_info("Other frames\r\n");
}
else if (run_Broadcast) {
/* 广播扫描 */
if (pack->function_Code == SL_Function_Code_Broadcast_Scan) {
log_info("Broadcast_Scan\r\n");
len = SL_MPPT_SCAN_BROADCAST_PACK_SIZE;
}
/* 注册请求 */
else if (pack->function_Code == SL_Function_Code_Registration_request) {
log_info("Registration_request\r\n");
len = SL_MPPT_REGISTRATIONREPLY_PACK_SIZE;
}
else {
if (flag_run < 2) {
flag_run = 2;
}
log_info("funcode error %x\r\n", pack->function_Code);
memcpy(buff, buff+1, offset-1);
offset--;
continue;
}
}
else {
if (flag_run < 2) {
flag_run = 2;
}
log_info("funcode error %x\r\n", pack->function_Code);
memcpy(buff, buff+1, offset-1);
offset--;
continue;
}
}
/* 广播扫描 */
else if (pack->function_Code == SL_Function_Code_Broadcast_Scan) {
log_info("Broadcast_Scan\r\n");
len = SL_MPPT_SCAN_BROADCAST_PACK_SIZE;
}
/* 注册请求 */
else if (pack->function_Code == SL_Function_Code_Registration_request) {
log_info("Registration_request\r\n");
len = SL_MPPT_REGISTRATIONREPLY_PACK_SIZE;
}
else {
if (flag_run < 2) {
flag_run = 2;
}
log_info("funcode error %x\r\n", pack->function_Code);
memcpy(buff, buff+1, offset-1);
offset--;
continue;
}
}
if ((pack->function_Code == SL_Function_Code_Write_Register) && (offset >= 14)) {
SL_Mppt_Worecv_pack *wpack = (SL_Mppt_Worecv_pack *)buff;
uint8_t Register_Number = (wpack->write_Register_Number_H << 8) | wpack->write_Register_Number_L;
len = Register_Number * 2 + SL_MPPT_WORECV_PACK_SIZE - 4;
continue;
}
if (offset == len) {
uint16_t crc_16 = chang_8_to_16(buff[offset - 2], buff[offset - 3]);
if ((CheckFunc(buff, offset - 3) != crc_16) || (buff[offset - 1] != 0x16)) {
if (flag_run < 3) {
flag_run = 3;
}
memcpy(buff, buff+1, offset-1);
offset--;
} else {
return offset;
}
}
}
return 0;
}
/**
* @brief 处理一条消息
* @param
* @retval
*/
void FRT_MsgHandler(device_handle device, uint8_t *pMsg, uint32_t MsgLen)
{
SL_Mppt_Recv_pack *pack = (SL_Mppt_Recv_pack *)pMsg;
for (u_int16_t i = 0; i < sizeof(g_MsgTbl) / sizeof(SL_FuncionMsgProcTable); i++){
if (pack->function_Code == g_MsgTbl[i].msgId){
g_MsgTbl[i].pMsgProc(device, pMsg, MsgLen);
}
}
}
/**
* @brief 读取并解析串口数据
* @param
* @retval
*/
void read_and_process_uart_data(device_handle device)
{
// printf("ring_queue_length = %d \n", ring_queue_length(device));
// if (ring_queue_length(device) > 10) {uart_dev_char_present(device_handle device)
if (uart_dev_char_present(device)) {
Delay_Ms(20);
// printf("ring_queue_length = %d \n", ring_queue_length(device));
memset(rs485_buff, 0, sizeof(rs485_buff));
int ret = uart_read_climate_pack(device, rs485_buff, sizeof(rs485_buff));
if(ret > 0){
FRT_MsgHandler(device, rs485_buff, ret);
}
}
}