#include "frt_protocol.h" #include "assertions.h" #include "inflash.h" 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 = { .mac_info = 0x9259 }; /* 功能码处理表 */ 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; j0){ crc=crc>>1; crc=crc^ 0xa001; }else{ crc=crc>>1; } } } return crc; } /** * @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); return FRT_swap_endian_16(value); } /** * @brief 读最大电流寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegMaxCurrent(void *pMsg) { u_int16_t value = (u_int16_t)(g_stMcs_Para.max_current); return FRT_swap_endian_16(value); } /** * @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); } /** * @brief 读电池电压寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegBat_V(void *pMsg) { u_int16_t value = (u_int16_t)(g_stMcs_Para.bat_v); return FRT_swap_endian_16(value); } /** * @brief 读充电状态寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegBat_Charge(void *pMsg) { u_int16_t value = (u_int16_t)(g_stMcs_Para.bat_charge); return FRT_swap_endian_16(value); } /** * @brief 读MAC信息寄存器值 * @param * @retval */ static u_int16_t FRT_ReadRegMACINFO(void *pMsg) { u_int16_t value = (u_int16_t)(g_stMcs_Para.mac_info); return FRT_swap_endian_16(value); } /** * @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); return 0; } /** * @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); return 0; } /** * @brief 清空最大电流 * @param * @retval */ static u_int16_t FRT_WriteRegMaxCurrent(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; if(data == 0x0001) { __iar_builtin_set_FAULTMASK(1); NVIC_SystemReset(); } return 0; } /** * @brief 清空脉冲次数 * @param * @retval */ static u_int16_t FRT_WriteRegPulseCount(void *pMsg) { uint16_t *pMsgAddr = (uint16_t *)pMsg; uint16_t data = *pMsgAddr; if(data == 0x0001) { __iar_builtin_set_FAULTMASK(1); NVIC_SystemReset(); } return 0; } /** * @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; } /** * @brief 封装协议发送 * @param * @retval 数据正确返回TRUE,数据异常返回FALSE */ 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->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); uart_dev_write(device,(u_int8_t*)pack,pack->data_len+5); } /** * @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 > 0x08 && start_reg_addr < 0x14) || start_reg_addr > 0x17) { term_printf("start_reg_addr error:%d", start_reg_addr); return; } if (reg_num < 0x01 || (((reg_num + start_reg_addr - 1) > 0x08) && ((reg_num + start_reg_addr - 1) < 0x14)) || ((reg_num + start_reg_addr -1) > 0x17)) { 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 0x1C ) { term_printf("start_reg_addr error:%d", start_reg_addr); return; } if (reg_num < 0x01 || ((reg_num + start_reg_addr - 1) < 0x14) || ((reg_num + start_reg_addr -1) > 0x1C)) { term_printf("reg_num error:%d", reg_num); return; } // 取出数据 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]; } // 发回数据 uint8_t Trans_data[6]; Trans_data[0] = g_stConfigInfo.addr; Trans_data[1] = data[1]; Trans_data[2] = start_reg_addr; Trans_data[3] = reg_num; return_crc_value = CRC16(Trans_data, 4); Trans_data[4] = return_crc_value; Trans_data[5] = return_crc_value >> 8; uart_dev_write(device, Trans_data, 6); for(u_int16_t pos=0; pos addr)){ // if (pack->addr != g_stConfigInfo.addr){ // memcpy(buff, buff+1, offset-1); // offset--; // buff_size--; // } // }else if (offset == FRT_CLIMATE_PACK_SIZE(pack)){ // return offset; // } // } 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不过"); 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)){ //BUFFER里面第一次有数据后返回,等下一次调用 if(read_uart_flag < 1) { read_uart_flag++; return; } read_uart_flag = 0; 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); } } } /* 打印寄存器数据 */ 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_stMcs_Para.mac_info); 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