stm32l431_xl_current/App/Src/frt_protocol.c

521 lines
14 KiB
C
Raw Permalink Normal View History

2024-07-15 09:07:44 +00:00
#include "frt_protocol.h"
#include "assertions.h"
#include "inflash.h"
#include "e22.h"
2024-07-15 09:07:44 +00:00
extern u_int8_t lora_out_buff[50];
extern uart_device_info uart_devices[];
/* 静态函数申明 */
static void send_uart_pack(device_handle device,FRT_MsgFunctionCode_e cmd_type, const void *data, u_int16_t len);
static void FRT_MsgProc_ReadRegister(device_handle device, void *pMsg);
static void FRT_MsgProc_WriteRegister(device_handle device, void *pMsg);
static u_int16_t FRT_ReadReg(unsigned char regId);
static u_int16_t FRT_ReadRegCurrent(void *pMsg);
static u_int16_t FRT_ReadRegMaxCurrent(void *pMsg);
static u_int16_t FRT_ReadRegPulseCount(void *pMsg);
static u_int16_t FRT_ReadRegBat_V(void *pMsg);
static u_int16_t FRT_ReadRegBat_Charge(void *pMsg);
static u_int16_t FRT_ReadRegMACINFO(void *pMsg);
static u_int16_t FRT_WriteRegDeviceAddr(void *pMsg);
static u_int16_t FRT_WriteRegNetId(void *pMsg);
static u_int16_t FRT_WriteRegMaxCurrent(void *pMsg);
static u_int16_t FRT_WriteRegPulseCount(void *pMsg);
static u_int16_t FRT_WriteRegReboot(void *pMsg);
static void pdebug_mcs_info();
mcs_para g_stMcs_Para = {0};
2024-07-15 09:07:44 +00:00
/* 功能码处理表 */
FRT_FuncionMsgProcTable_s g_MsgTbl[] =
{
{ FRT_FUNCTION_CODE_READ_REGISTER, FRT_MsgProc_ReadRegister },
{ FRT_FUNCTION_CODE_WRITE_REGISTER, FRT_MsgProc_WriteRegister },
};
/* 读寄存器处理表 */
FRT_RegProcTable_s g_RegTbl[] =
{
{ FRT_REGISTER_CURRENT, FRT_ReadRegCurrent }, /* 泄漏电流 */
{ FRT_REGISTER_MAX_CURRENT, FRT_ReadRegMaxCurrent }, /* 最大电流 */
{ FRT_REGISTER_PULSE_COUNT, FRT_ReadRegPulseCount }, /* 脉冲次数 */
{ FRT_REGISTER_BAT_V, FRT_ReadRegBat_V }, /* 电池电压 */
{ FRT_REGISTER_BAT_CHARGE, FRT_ReadRegBat_Charge }, /* 充电状态 */
{ FRT_REGISTER_MAC_INFO, FRT_ReadRegMACINFO }, /* MAC信息 */
};
/* 写寄存器处理表 */
FRT_RegProcTable_s g_Write_RegTbl[] =
{
{ FRT_REGISTER_DEVICE_ADDR, FRT_WriteRegDeviceAddr }, /* 写设备地址 */
{ FRT_REGISTER_NET_ID, FRT_WriteRegNetId }, /* 写网络ID */
{ FRT_REGISTER_CLEAR_MAX_CURRENT, FRT_WriteRegMaxCurrent }, /* 清空最大泄漏电流统计值 */
{ FRT_REGISTER_CLEAR_PULSE_COUNT, FRT_WriteRegPulseCount }, /* 清空脉冲次数 */
{ FRT_REGISTER_REBOOT, FRT_WriteRegReboot }, /* 重启 */
};
/**
* @brief modbus crc16算法
* @param
* @retval
*/
unsigned short CRC16(unsigned char *arr_buff, unsigned char len)
{
unsigned short crc=0xFFFF;
unsigned char 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 << 8 | crc >> 8;
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_swap_endian_16(u_int16_t value)
{
return ((value << 8) | (value >> 8));
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_ReadRegCurrent(void *pMsg)
{
u_int16_t value = (u_int16_t)(g_stMcs_Para.current * 100);
return FRT_swap_endian_16(value);//百倍泄漏电流
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_ReadRegMaxCurrent(void *pMsg)
{
u_int16_t value = (u_int16_t)(g_stMcs_Para.max_current * 100);
return FRT_swap_endian_16(value);//百倍最大泄漏电流
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_ReadRegPulseCount(void *pMsg)
{
u_int16_t value = (u_int16_t)(g_stMcs_Para.pulse_count);
return FRT_swap_endian_16(value);
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_ReadRegBat_V(void *pMsg)
{
u_int16_t value = (u_int16_t)(g_stMcs_Para.bat_v * 1000);
return FRT_swap_endian_16(value);
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_ReadRegBat_Charge(void *pMsg)
{
g_stMcs_Para.bat_charge = HAL_GPIO_ReadPin(CN3791_CHRG_GPIO_Port, CN3791_CHRG_Pin);
u_int16_t value = (u_int16_t)(g_stMcs_Para.bat_charge);
return FRT_swap_endian_16(value);
2024-07-15 09:07:44 +00:00
}
/**
* @brief MAC信息寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegMACINFO(void *pMsg)
{
u_int16_t value = (u_int16_t)(g_stConfigInfo.mac_info_h << 8 | g_stConfigInfo.mac_info_l);
return FRT_swap_endian_16(value);
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_WriteRegDeviceAddr(void *pMsg)
{
//改传感器地址
uint16_t *pMsgAddr = (uint16_t *)pMsg;
uint16_t data = *pMsgAddr;
g_stConfigInfo.addr = data;
save_config_info(g_stConfigInfo);
//改无线模块地址
e22_init();
return 0;
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_WriteRegNetId(void *pMsg)
{
//改传感器网址
uint16_t *pMsgAddr = (uint16_t *)pMsg;
uint16_t data = *pMsgAddr;
g_stConfigInfo.net_id = data;
save_config_info(g_stConfigInfo);
//改无线模块网址
e22_init();
return 0;
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_WriteRegMaxCurrent(void *pMsg)
{
uint16_t *pMsgAddr = (uint16_t *)pMsg;
uint16_t data = *pMsgAddr;
if(data == 0x0001){
g_stMcs_Para.max_current = 0;
max_rms_mA = 0;
}
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_WriteRegPulseCount(void *pMsg)
{
uint16_t *pMsgAddr = (uint16_t *)pMsg;
uint16_t data = *pMsgAddr;
if(data == 0x0001){
g_stMcs_Para.pulse_count = 0;
Pulse_Count = 0;
}
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
static u_int16_t FRT_WriteRegReboot(void *pMsg)
{
uint16_t *pMsgAddr = (uint16_t *)pMsg;
uint16_t data = *pMsgAddr;
if(data == 0x0001)
{
__iar_builtin_set_FAULTMASK(1);
NVIC_SystemReset();
}
return 0;
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval TRUEFALSE
*/
static void send_uart_pack(device_handle device,FRT_MsgFunctionCode_e cmd_type, const void *data, u_int16_t len)
{
memset(lora_out_buff,0,sizeof(lora_out_buff));
frt_climate_pack_resp *pack = (frt_climate_pack_resp*)lora_out_buff;
pack->up_addr_h = 0x00;
pack->up_addr_l = 0x00;
pack->chanel = g_stConfigInfo.net_id % 27 + 10;
2024-07-15 09:07:44 +00:00
pack->addr = g_stConfigInfo.addr;
pack->func = FRT_FUNCTION_CODE_READ_REGISTER;
pack->data_len = len;
memcpy(pack->data, data, len);
*(u_int16_t*)&pack->data[len] = CRC16((u_int8_t *)&pack->addr,pack->data_len+3);//加数据之前的字节
2024-07-15 09:07:44 +00:00
uart_dev_write(device,(u_int8_t*)pack,pack->data_len+3+2+3); // 加数据之前的字节+校验位+E22地址信道
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
u_int16_t FRT_ReadReg(unsigned char regId)
{
for(u_int16_t i = 0; i < sizeof(g_RegTbl) / sizeof(FRT_RegProcTable_s); i++){
//term_printf("regId:%d, g_RegTbl.regId :%d\r\n",regId,g_RegTbl[i].regId);
if (regId == g_RegTbl[i].regId){
return g_RegTbl[i].pRegProc(NULL);
}
}
return 0;
}
/**
* @brief
* @param
* @retval
*/
void FRT_MsgProc_ReadRegister(device_handle device, void *pMsg)
{
uint8_t *data = (uint8_t *)pMsg;
u_int16_t start_reg_addr = (data[2] << 8)| data[3];
u_int16_t reg_num= (data[4] << 8)| data[5];
if (start_reg_addr < 0x00 || start_reg_addr > 0x05)
2024-07-15 09:07:44 +00:00
{
term_printf("start_reg_addr error:%d", start_reg_addr);
return;
}
if (reg_num < 0x01 || ((reg_num + start_reg_addr - 1) < 0x00) || ((reg_num + start_reg_addr -1) > 0x05))
2024-07-15 09:07:44 +00:00
{
term_printf("reg_num error:%d", reg_num);
return;
}
static u_int8_t reg_value_buff[2*100]={0x00};
memset(reg_value_buff,0,sizeof(reg_value_buff));
for(u_int16_t pos=0; pos <reg_num; pos++){
*(u_int16_t*)&reg_value_buff[pos*2] = FRT_ReadReg((start_reg_addr+pos));
}
send_uart_pack(device, FRT_FUNCTION_CODE_READ_REGISTER, (u_int8_t*)&reg_value_buff, reg_num*2);
2024-07-15 09:07:44 +00:00
}
/**
* @brief
* @param
* @retval
*/
void FRT_MsgProc_WriteRegister(device_handle device, void *pMsg)
{
uint8_t *data = (uint8_t *)pMsg;
u_int16_t start_reg_addr = (data[2] << 8)| data[3];
u_int16_t reg_num= (data[4] << 8)| data[5];
u_int16_t byte_num= data[6];
unsigned short return_crc_value;
// 校验
if (start_reg_addr < 0x31 || start_reg_addr > 0x35 )
2024-07-15 09:07:44 +00:00
{
term_printf("start_reg_addr error:%d", start_reg_addr);
return;
}
if (reg_num < 0x01 || ((reg_num + start_reg_addr - 1) < 0x31) || ((reg_num + start_reg_addr -1) > 0x35))
2024-07-15 09:07:44 +00:00
{
term_printf("reg_num error:%d", reg_num);
return;
}
//发回数据
uint8_t Trans_data[11];
Trans_data[0] = 0x00;
Trans_data[1] = 0x00;
Trans_data[2] = g_stConfigInfo.net_id % 27 + 10;
Trans_data[3] = g_stConfigInfo.addr;
Trans_data[4] = FRT_FUNCTION_CODE_WRITE_REGISTER;
Trans_data[5] = data[2] << 8;
Trans_data[6] = data[3];
Trans_data[7] = data[4] << 8;
Trans_data[8] = data[5];
return_crc_value = CRC16(&Trans_data[3], 6);
Trans_data[9] = return_crc_value;
Trans_data[10] = return_crc_value >> 8;
uart_dev_write(g_lora_uart_handle, Trans_data, sizeof(Trans_data)/sizeof(uint8_t));
2024-07-15 09:07:44 +00:00
// 取出数据
uint16_t content[50] = {0};
for (uint16_t var = 0; var < reg_num; var++)
{
content[var] = data[7 + 2 * var] << 8 | data[7 + 2 * var + 1];
}
for(u_int16_t pos=0; pos <reg_num; pos++)
{
for (uint16_t i = 0; i < sizeof(g_Write_RegTbl) / sizeof(FRT_RegProcTable_s); i++)
{
if (g_Write_RegTbl[i].regId == (start_reg_addr + pos))
{
g_Write_RegTbl[i].pRegProc(&content[pos]);
}
}
}
}
/**
* @brief
* @param
* @retval
*/
static int uart_read_frt_climate_pack(device_handle uart_handle,u_int8_t *buff, u_int32_t buff_size)
{
u_int32_t offset = 0;
char c = 0;
// frt_climate_pack *pack = (frt_climate_pack *)buff;
unsigned char new_buff[50];
buff_size--; //预留一个'\0'位置
2024-07-15 09:07:44 +00:00
for (int offset = 0; offset < buff_size;)
2024-07-15 09:07:44 +00:00
{
// 逐字符读取
2024-07-15 09:07:44 +00:00
c = uart_dev_in_char(uart_handle);
buff[offset++] = c;
// 判断首字符是否是地址,是地址再开始读取,不是则将索引退一步
if(offset == sizeof(unsigned char))
{
if(buff[0] != g_stConfigInfo.addr)
{
memcpy(buff, buff + 1, offset - 1);
offset--;
buff_size--;
}
}
// 读寄存器
else if (buff[1] == FRT_FUNCTION_CODE_READ_REGISTER & offset == 8)
{
return offset;
}
// 写寄存器
else if (buff[1] == FRT_FUNCTION_CODE_WRITE_REGISTER & offset == 7 + buff[6] + 2)
{
return offset;
}
2024-07-15 09:07:44 +00:00
}
return 0;
}
/**
* @brief
* @param
* @retval
*/
void FRT_MsgHandler(device_handle device, u_int8_t *pMsg, u_int32_t MsgLen)
{
if(CRC16(pMsg, MsgLen-2) != FRT_CLIMATE_BUFF_CRC16(pMsg))
{
// term_printf("CRC不过");
2024-07-15 09:07:44 +00:00
return;
}
if((pMsg[1] != FRT_FUNCTION_CODE_READ_REGISTER) && (pMsg[1] != FRT_FUNCTION_CODE_WRITE_REGISTER))
{
// term_printf("功能码不过");
return;
}
for (u_int16_t i = 0; i < sizeof(g_MsgTbl) / sizeof(FRT_FuncionMsgProcTable_s); i++){
if (pMsg[1] == g_MsgTbl[i].msgId){
g_MsgTbl[i].pMsgProc(device, pMsg);
}
}
}
/**
* @brief
* @param
* @retval
*/
static u_int8_t rs485_buff[50]={0x00};
void read_and_process_uart_data(device_handle device)
{
if(uart_dev_char_present(device)){
//进入NORMAL模式以便发送数据
lora_set_mode(NORMAL);
2024-07-15 09:07:44 +00:00
memset(rs485_buff,0,sizeof(rs485_buff));
int ret = uart_read_frt_climate_pack(device, rs485_buff, sizeof(rs485_buff));
if(ret > 0){
FRT_MsgHandler(device, rs485_buff, ret);
}
HAL_Delay(E22_DELAY_MS);
HAL_Delay(E22_DELAY_MS);
//进入WOR模式
lora_set_mode(WOR);
2024-07-15 09:07:44 +00:00
}
}
/* 打印寄存器数据 */
static void pdebug_mcs_info()
{
term_printf("current: %.2f\r\n", g_stMcs_Para.current);
term_printf("max_current: %.2f\r\n", g_stMcs_Para.max_current);
term_printf("pulse_count: %.2f\r\n", g_stMcs_Para.pulse_count);
term_printf("bat_v: %.2f\r\n", g_stMcs_Para.bat_v);
term_printf("bat_charge: %.2f\r\n", g_stMcs_Para.bat_charge);
term_printf("mac_info: %.2f\r\n", g_stConfigInfo.mac_info_h);
term_printf("mac_info: %.2f\r\n", g_stConfigInfo.mac_info_l);
2024-07-15 09:07:44 +00:00
term_printf("address: %.2f\r\n", g_stConfigInfo.addr);
term_printf("NetId: %.2f\r\n", g_stConfigInfo.net_id);
// term_printf("precipitation_intensity: %.2f\r\n", g_stMcs_Para.precipitation_intensity);
}
// 30 03 00 00 00 0B 00 2C