/****************************************************************************** * file Core/Src/wireless.c * author YuLiang * version 1.0.0 * date 14-Jun-2022 * brief This file provides all the wireless related operation functions. ****************************************************************************** * Attention * *

© COPYRIGHT(c) 2022 LandPower

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of WTOE nor the names of its contributors may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "stdio.h" #include "string.h" #include "time.h" #include "usart.h" #include "adc.h" #include "tim.h" #include "rtc.h" #include "common.h" #include "wireless.h" #include "dev_config.h" #include "ADC_collect.h" #include "flash_if.h" #include "RS485_debug.h" #include "flash_log.h" #include "dau.h" /* Private define ------------------------------------------------------------*/ #define WL_RX_TIMEOUT 500 // 每 500ms 检查一次收包数据. #define WL_USART_ERR_TIMEOUT 1000 // 串口发送错误延迟时间. #define WL_SOFT_INIT_ERR 5 // 软件初始化错误最大次数. #define WL_DATA_ERR 3 // 数据发送错误最大次数. #define WL_PWR_FRE_CH_NUM 4 // 工频录波通道数. #define WL_FLASH_BUF_SIZE 1024 #define WIR_RX_TIMEOUT 10000 // 有线模式每 10s 检查一次收包数据. /* Private typedef -----------------------------------------------------------*/ /* 状态机状态. */ typedef enum { WL_STATE_SOFT = 0, WL_STATE_AT_ATE, WL_STATE_AT_IPR, WL_STATE_AT_QICSGP, WL_STATE_AT_QIACT, WL_STATE_AT_CSQ, WL_STATE_AT_QCCID, WL_STATE_AT_QICFGTS, WL_STATE_AT_QICFGWT, WL_STATE_AT_QIOPEN, WL_STATE_AT_COMP, WL_STATE_CONTACT = 128, WL_STATE_REALDATA, WL_STATE_POWER, WL_STATE_DEFECT, WL_STATE_REALDATA_FAULT, WL_STATE_POWER_FAULT, WL_STATE_FAULT, WL_STATE_UPDATE, WL_STATE_UPDATE_RT, WL_STATE_UPDATE_FPGA_RT, WL_STATE_KEEPALIVE, WL_STATE_END = 255 } WL_STATE_E; /* RS485调试通讯协议器件信息. */ typedef struct { /* 设备信息. 36byte */ uint8_t type_m; uint8_t type_s; uint8_t mac[6]; uint32_t id; uint8_t ip[4]; uint8_t ip_mask[4]; uint8_t ip_gw[4]; uint8_t server_ip[4]; uint8_t wireless_server_ip[4]; uint16_t server_port; uint16_t wireless_server_port; /* 版本信息. 224byte */ uint8_t boot_version[DEV_VERSION_STR_LEN]; uint8_t boot_compile_time[DEV_COMPILE_TIME_LEN]; uint8_t img_version[DEV_VERSION_STR_LEN]; uint8_t img_compile_time[DEV_COMPILE_TIME_LEN]; uint8_t hardware_version[DEV_VERSION_STR_LEN]; uint8_t FPGA_version[DEV_VERSION_STR_LEN]; uint8_t factory_time[DEV_COMPILE_TIME_LEN]; /* 设备其他信息. 160byte */ char name[DEV_NAME_LEN]; char QCCID[WL_QCCID_LEN]; char APN[DEV_APN_LEN]; } wl_proto_wakeup_t; /* 实时数据传输结构体 */ typedef struct { uint16_t vbat; // 电池电压, 单位: mv uint16_t vin; // 工作电压, 单位: mv int16_t temperature; // 设备温度, 单位: 0.1℃ int16_t CSQ; // 4G 信号质量 > -51dBm 统一显示 -51dBm, < -113 dBm 为无信号 uint32_t utc; // 时间 uint32_t run_time; // 设备运行时长, 单位 s uint32_t elec[DAU_PORT_POWER_CNT]; // 工频电流有效值 mA uint16_t elec_defect_max[DAU_PORT_FAULT_MAX]; // 缺陷电流最大值 mA uint8_t valid_power; // 工频波形有效 uint8_t valid_defect; // 缺陷波形有效 uint8_t reserve[2]; // 保留位 } wl_proto_realdata_t; /* 实时数据传输结构体. */ typedef struct { uint32_t utc; // 故障时间 uint32_t ns; // 故障时间纳秒 uint16_t fault_trig[DAU_PORT_FAULT_MAX];// 故障电流触发值 A uint32_t elec[DAU_PORT_POWER_CNT]; // 工频电流有效值 mA } wl_proto_realdata_fault_t; typedef struct { uint16_t interval; uint16_t threshold_power; uint16_t threshold_defect; uint16_t threshold_fault; uint16_t keepalive; uint8_t reserve[2]; } wl_proto_config_t; typedef struct { uint8_t is_utc_valid; // gps 对时是否有效 uint8_t reserve[3]; // 保留位 uint32_t utc; // gps 对时时间 } wl_proto_state_t; /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ const osThreadAttr_t WL_attributes = { .name = "WIRELESS", .stack_size = 160 * 2 * 4, .priority = (osPriority_t) osPriorityBelowNormal, }; wl_buf_list_t wl_buf_list_rx; wl_ctrl_t wl_ctrl; static RTC_DateTypeDef wl_date; static RTC_TimeTypeDef wl_time; static struct tm wl_tm; /* Private function prototypes -----------------------------------------------*/ static void _wl_4G_send_reset(void); static void _wl_4G_send_update(void); static void _wl_4G_send_cfg_set(void); static void _wl_4G_send_time(void); static void _wl_4G_send_wave_force(void); static void _wl_4G_send_update_fpga(void); /* Internal functions --------------------------------------------------------*/ /* 4G 模块发送数据. */ static int32_t _wl_4G_transmit(uint8_t *data, uint16_t len) { int32_t rv = HAL_ERROR; if (wl_ctrl.state < WL_STATE_CONTACT) { DBG(DBG_M_4G, "Send: %s", data); } else { proto_head_t *head = (proto_head_t*)data; mul_head_t *m_head = (mul_head_t*)(data + sizeof(proto_head_t)); DBG(DBG_M_4G, "Send(%d): %d %d %d %d\r\n", len, HAL_GetTick(), head->cmd_type, head->cmd, m_head->index); if (dbg_stat_get(DBG_M_4G)) { buf_print(data, len > 32 ? 32 : len); vty_print("\r\n"); } } /* 发送数据, 可能会出现上一帧报文还没有发送完的情况, 这时候等待 100ms 再尝试发送 */ HAL_GPIO_WritePin(RS485_B_DE_GPIO_Port, RS485_B_DE_Pin, GPIO_PIN_SET); rv = HAL_UART_Transmit_DMA(wl_ctrl.uart, data, len); if (rv != HAL_OK) { osDelay(200); rv = HAL_UART_Transmit_DMA(wl_ctrl.uart, data, len); } return rv; } /* AT 命令 CSQ 返回数据处理. */ static void _wl_4G_AT_CSQ_process(uint8_t *cmd) { int32_t rssi = 99; int32_t ber = 99; sscanf((char*)cmd, "+CSQ: %d,%d\r\n", &rssi, &ber); if (rssi != 99) { wl_ctrl.CSQ = -113 + (2 * rssi); } else { wl_ctrl.CSQ = -115; } } /* AT 命令 QCCID 返回数据处理 "+QCCID: 898604F2102381008969" */ static void _wl_4G_AT_QCCID_process(uint8_t *cmd) { uint8_t i = 0; uint8_t j = 0; while(cmd[i] != ' ') { if (0 == cmd[i]) { return; } i++; } i++; while(cmd[i] != 0 && cmd[i] != '\r' && cmd[i] != '\n') { wl_ctrl.QCCID[j++] = cmd[i++]; if (j >= WL_QCCID_LEN - 1) { wl_ctrl.QCCID[WL_QCCID_LEN - 1] = 0; return; } } wl_ctrl.QCCID[j] = 0; } /* AT 命令回复处理. */ static void _wl_4G_AT_process(uint8_t *cmd) { if (0 == strncmp((char*)cmd, "RDY", 3)) { /* 芯片启动后会发送. */ wl_ctrl.state++; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; } else if (0 == strncmp((char*)cmd, "OK", 2)) { /* 命令执行成功. */ if (WL_STATE_AT_IPR == wl_ctrl.state) { HAL_UART_Abort(wl_ctrl.uart); HAL_UART_DeInit(wl_ctrl.uart); memset(&wl_buf_list_rx, 0, sizeof(wl_buf_list_t)); MX_USART3_UART_Init_WL(); HAL_UARTEx_ReceiveToIdle_DMA(wl_ctrl.uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN); osDelay(1000); } if (wl_ctrl.state < WL_STATE_AT_QIOPEN) { wl_ctrl.state++; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; } } else if (0 == strncmp((char*)cmd, "CONNECT", 7)) { /* 软件初始化完成. */ wl_ctrl.state++; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; } else if (0 == strncmp((char*)cmd, "+CSQ", 4)) { /* 获取信号质量. */ _wl_4G_AT_CSQ_process(cmd); } else if (0 == strncmp((char*)cmd, "+QCCID", 6)) { /* 获取信号质量. */ _wl_4G_AT_QCCID_process(cmd); } else if (0 == strncmp((char*)cmd, "ERROR", 5)) { /* 命令执行失败. */ wl_ctrl.time_send = HAL_GetTick() + 1000; } } /* 处理接收到的 AT 指令. */ void _wl_4G_AT_recv(void) { wl_buf_list_t *buf_l = &wl_buf_list_rx; uint8_t *buf = NULL; uint16_t i = 0; /* 遍历所有有效的 buf. */ while(buf_l->current != buf_l->valid) { buf = buf_l->buf[buf_l->current]; /* 将 buf 中的数据解析成命令. */ for(i = 0; i < buf_l->buf_cnt[buf_l->current]; i++) { wl_ctrl.cmd_buf[wl_ctrl.cmd_buf_index] = buf[i]; wl_ctrl.cmd_buf_index++; if (wl_ctrl.cmd_buf_index >= WL_DMA_RX_BUF_LEN) { wl_ctrl.cmd_buf[0] = 0; wl_ctrl.cmd_buf_index = 0; break; } if (buf[i] != 0x0a) { /* 不是回车继续读取数据. */ continue; } /* 命令长度小于 2 为无效命令. */ if (wl_ctrl.cmd_buf_index <= 2) { wl_ctrl.cmd_buf_index = 0; continue; } /* 添加结束位, 更新 cmd buf index, 执行命令解析. */ wl_ctrl.cmd_buf[wl_ctrl.cmd_buf_index] = 0; wl_ctrl.cmd_buf_index = 0; DBG(DBG_M_4G, "Recv: %s\r\n", wl_ctrl.cmd_buf); _wl_4G_AT_process(wl_ctrl.cmd_buf); } /* 更新 buf index. */ buf_l->current++; if (WL_BUF_LIST_LEN == buf_l->current) { buf_l->current = 0; } } } static void _wl_4G_pkt_id_update(void) { wl_ctrl.pkt_id++; wl_ctrl.pkt_id = wl_ctrl.pkt_id >= 0x8000 ? 0 : wl_ctrl.pkt_id; } static int32_t _wl_4G_pkt_check(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; /* 设备进入复位状态后不再处理报文. */ if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_RESET)) { DBG(DBG_M_4G, "@0\r\n"); /* 这里挂住线程是因为重启时如果有收包, 会导致收包出错, 从而让设备进入休眠状态. */ osDelay(portMAX_DELAY); return HAL_ERROR; } /* 对主次设备号进行识别, 次设备号可以是广播. */ if ((head->dev_type_m != dev_info.type_m) || (head->dev_type_s != dev_info.type_s && head->dev_type_s != 0xFF)) { DBG(DBG_M_4G, "@1\r\n"); return HAL_ERROR; } /* 对设备 id 进行识别, 可以是广播. */ if (head->dev_id != (*(uint32_t*)dev_info.id) && head->dev_id != 0xFFFFFFFF) { DBG(DBG_M_4G, "@2\r\n"); return HAL_ERROR; } /* 验证 CRC32. */ if (crc32(cmd, head->len) != (*(uint32_t*)(cmd + head->len))) { DBG(DBG_M_4G, "@3: %x %x\r\n", crc32(cmd, head->len), *(uint32_t*)(cmd + head->len)); return HAL_ERROR; } /* pkt_id 验证 */ if (head->pkt_id != wl_ctrl.pkt_id && head->pkt_id < 0x8000) { DBG(DBG_M_4G, "@4: %d %d\r\n", head->pkt_id, wl_ctrl.pkt_id); return HAL_ERROR; } return HAL_OK; } /* 连接报文回复 */ static void _wl_4G_recv_contect(uint8_t *cmd, uint32_t len) { wl_proto_config_t *cfg = (wl_proto_config_t*)(cmd + sizeof(proto_head_t)); uint8_t is_cfg_save = FALSE; if (cfg->interval != dev_config.collect_interval) { is_cfg_save = TRUE; dev_config_collect_interval_set(cfg->interval); } if (cfg->threshold_power != dev_config.power_threshold) { is_cfg_save = TRUE; dev_config.power_threshold = cfg->threshold_power; } if (cfg->threshold_defect != dev_config.defect_threshold) { is_cfg_save = TRUE; dev_config.defect_threshold = cfg->threshold_defect; } if (cfg->threshold_fault != dev_config.fault_threshold) { is_cfg_save = TRUE; dev_config.fault_threshold = cfg->threshold_fault; } if (cfg->keepalive != dev_config.keepalive) { is_cfg_save = TRUE; dev_config.keepalive = cfg->keepalive; } if (is_cfg_save) { common_sys_set(COM_SYS_SAVE_CONFIG, 0); } wl_ctrl.state = WL_STATE_END; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 设备重启 */ static void _wl_4G_recv_reset(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; uint32_t reset_delay = 2; wl_ctrl.pkt_id_recv = head->pkt_id; _wl_4G_send_reset(); /* 延迟 2s 等待串口回复报文发送完成. */ flash_log_write(FLASH_LOG_TYPE_INFO, "Server system reset!\r\n"); common_sys_set(COM_SYS_RESET, (void*)&reset_delay); } /* 设备 APP 升级回复. */ static void _wl_4G_recv_update(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t)); uint8_t *data = (uint8_t*)(cmd + sizeof(proto_head_t) + sizeof(mul_head_t)); uint32_t addr = TFTP_APP_ADDRESS; uint32_t app_len = 0; /* index 为 0 表示是首保, 需要擦除 FLASH. */ if (0 == m_head->index) { /* 开始时置升级结果为错误. */ wl_ctrl.update_rt = HAL_ERROR; while(addr != TFTP_APP_ADDRESS_END) { if (spi_flash_erase(addr, SPI_CMD_BLOCK64_ERASE) != HAL_OK) { return; } addr += SPI_FLASH_BLOCK64_SIZE; } } wl_ctrl.state = WL_STATE_UPDATE; wl_ctrl.time_update = HAL_GetTick(); /* 计算写 FLASH 地址, 并写入 FLASH. */ addr = TFTP_APP_ADDRESS + m_head->index * DEBUG_DATA_SIZE; if (m_head->len > DEBUG_DATA_SIZE || m_head->index >= 2944) { return; } else if(m_head->len > 0) { if (spi_flash_write(addr, data, m_head->len) != HAL_OK) { return; } } /* 长度小于 DEBUG_FLASH_BUF_SIZE 则认为是最后一包. */ if(m_head->len < DEBUG_DATA_SIZE) { /* 校验数据. */ app_len = addr - TFTP_APP_ADDRESS + m_head->len; if (HAL_OK == debug_app_check(TFTP_APP_ADDRESS, app_len, 2)) { /* 保存信息并重启设备进入 IAP 升级 APP. */ dev_info_fireware_size_set(app_len); dev_info_magic_set(UPDATE_MAGIC); common_sys_set(COM_SYS_SAVE_INFO, 0); wl_ctrl.update_rt = HAL_OK; } } /* 回复报文发送 */ wl_ctrl.pkt_id_recv = head->pkt_id; wl_ctrl.mul_idx = m_head->index; wl_ctrl.update_len = m_head->len; _wl_4G_send_update(); /* 初始化状态量 */ if(m_head->len < DEBUG_DATA_SIZE) { wl_ctrl.mul_idx = 0; wl_ctrl.update_len = 0; wl_ctrl.state = WL_STATE_UPDATE_RT; } } /* 配置下发报文回复 */ static void _wl_4G_recv_cfg_set(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; wl_proto_config_t *cfg = (wl_proto_config_t*)(cmd + sizeof(proto_head_t)); uint8_t is_cfg_save = FALSE; if (cfg->interval != dev_config.collect_interval) { is_cfg_save = TRUE; dev_config.collect_interval = cfg->interval; } if (cfg->threshold_power != dev_config.power_threshold) { is_cfg_save = TRUE; dev_config.power_threshold = cfg->threshold_power; } if (cfg->threshold_defect != dev_config.defect_threshold) { is_cfg_save = TRUE; dev_config.defect_threshold = cfg->threshold_defect; } if (cfg->threshold_fault != dev_config.fault_threshold) { is_cfg_save = TRUE; dev_config.fault_threshold = cfg->threshold_fault; } if (cfg->keepalive != dev_config.keepalive) { is_cfg_save = TRUE; dev_config.keepalive = cfg->keepalive; } if (is_cfg_save) { MONITOR_BITMAP_SET(dau_ctrl.reg_flag, DAU_REG_PORT_WRITE); common_sys_set(COM_SYS_SAVE_CONFIG, 0); } wl_ctrl.pkt_id_recv = head->pkt_id; _wl_4G_send_cfg_set(); } /* 升级结果报文回复 */ static void _wl_4G_recv_update_rt(uint8_t *cmd, uint32_t len) { uint32_t reset_delay = 2; /* 升级成功就重启 */ if (HAL_OK == wl_ctrl.update_rt) { /* 延迟 2s 等待串口回复报文发送完成. */ flash_log_write(FLASH_LOG_TYPE_INFO, "Update APP system sleep 0s!\r\n"); common_sys_set(COM_SYS_RESET, (void*)&reset_delay); } wl_ctrl.state = WL_STATE_END; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); return; } /* 保活报文回复. */ static void _wl_4G_recv_keepalive(void) { wl_ctrl.state = WL_STATE_END; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); return; } /* 对时报文 */ static void _wl_4G_recv_time(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; uint32_t *utc = (uint32_t*)(cmd + sizeof(proto_head_t)); if (!dau_ctrl.is_utc_ok) { rtc_time_set(*utc); } wl_ctrl.pkt_id_recv = head->pkt_id; _wl_4G_send_time(); } /* 实时数据报文回复 */ static void _wl_4G_recv_realdata(void) { /* 判断是否发送工频和缺陷波形 */ if (IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_POWER)) { wl_ctrl.state = WL_STATE_POWER; } else if(IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_DEFECT)) { wl_ctrl.state = WL_STATE_DEFECT; } else { MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_CMP); wl_ctrl.state = WL_STATE_END; } wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 工频数据回复 */ static void _wl_4G_recv_power(uint8_t *cmd, uint32_t len) { mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t)); if (m_head->len < DEBUG_DATA_SIZE) { /* 判断是否发送缺陷波形 */ if(IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_DEFECT)) { wl_ctrl.state = WL_STATE_DEFECT; } else { MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_CMP); wl_ctrl.state = WL_STATE_END; } wl_ctrl.mul_idx = 0; } else { wl_ctrl.mul_idx = m_head->index + 1; } wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 缺陷波形数据回复 */ static void _wl_4G_recv_defect(uint8_t *cmd, uint32_t len) { mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t)); if (m_head->len < DEBUG_DATA_SIZE) { /* 更新 flash 地址 */ dau_ctrl.addr_reg += 0x20000; if (WARE_REG_ADDRESS_END == dau_ctrl.addr_reg) { dau_ctrl.addr_reg = WARE_REG_ADDRESS; } st_data.addr_reg = dau_ctrl.addr_reg; MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_CMP); wl_ctrl.state = WL_STATE_END; wl_ctrl.mul_idx = 0; } else { wl_ctrl.mul_idx = m_head->index + 1; } wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 故障触发数据报文回复 */ static void _wl_4G_recv_realdata_fault(void) { wl_ctrl.state = WL_STATE_POWER_FAULT; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 故障触发工频数据回复 */ static void _wl_4G_recv_power_fault(uint8_t *cmd, uint32_t len) { mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t)); if (m_head->len < DEBUG_DATA_SIZE) { wl_ctrl.state = WL_STATE_FAULT; wl_ctrl.mul_idx = 0; } else { wl_ctrl.mul_idx = m_head->index + 1; } wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 故障触发故障波形数据回复 */ static void _wl_4G_recv_fault(uint8_t *cmd, uint32_t len) { mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t)); if (m_head->len < DEBUG_DATA_SIZE) { /* 更新 flash 地址 */ dau_ctrl.addr_fault += 0x20000; if (WARE_FAULT_ADDRESS_END == dau_ctrl.addr_fault) { dau_ctrl.addr_fault = WARE_FAULT_ADDRESS; } st_data.addr_fault = dau_ctrl.addr_fault; MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_FAULT_CMP); wl_ctrl.state = WL_STATE_END; wl_ctrl.mul_idx = 0; } else { wl_ctrl.mul_idx = m_head->index + 1; } wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; _wl_4G_pkt_id_update(); } /* 强制录波 */ static void _wl_4G_recv_wave_force(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; wl_ctrl.pkt_id_recv = head->pkt_id; MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_WAVE_FORCE); _wl_4G_send_wave_force(); } /* 设备 FPGA 升级回复 */ static void _wl_4G_recv_update_fpga(uint8_t *cmd, uint32_t len) { proto_head_t *head = (proto_head_t*)cmd; mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t)); uint8_t *data = (uint8_t*)(cmd + sizeof(proto_head_t) + sizeof(mul_head_t)); uint32_t addr = TFTP_APP_ADDRESS; /* index 为 0 表示是首包, 需要擦除 FLASH */ if (0 == m_head->index) { while(addr != TFTP_APP_ADDRESS_END) { if (spi_flash_erase(addr, SPI_CMD_BLOCK64_ERASE) != HAL_OK) { return; } addr += SPI_FLASH_BLOCK64_SIZE; } } wl_ctrl.state = WL_STATE_UPDATE; wl_ctrl.time_update = HAL_GetTick(); /* 计算写 FLASH 地址, 并写入 FLASH. */ addr = TFTP_APP_ADDRESS + m_head->index * DEBUG_DATA_SIZE; if (m_head->len > DEBUG_DATA_SIZE || m_head->index >= 2944) { return; } else if(m_head->len > 0) { if (spi_flash_write(addr, data, m_head->len) != HAL_OK) { return; } } /* 长度小于 DEBUG_FLASH_BUF_SIZE 则认为是最后一包. */ if(m_head->len < DEBUG_DATA_SIZE) { /* 校验数据. */ dau_ctrl.update_len = addr - TFTP_APP_ADDRESS + m_head->len; vty_print("dau_ctrl.update_len %d\r\n", dau_ctrl.update_len); dau_ctrl.update_flag = TRUE; } /* 回复报文发送 */ wl_ctrl.pkt_id_recv = head->pkt_id; wl_ctrl.mul_idx = m_head->index; wl_ctrl.update_len = m_head->len; _wl_4G_send_update_fpga(); /* 初始化状态量 */ if(m_head->len < DEBUG_DATA_SIZE) { wl_ctrl.mul_idx = 0; wl_ctrl.update_len = 0; wl_ctrl.state = WL_STATE_END; } } /* FPGA 升级结果报文回复. */ static void _wl_4G_recv_update_fpga_rt(void) { wl_ctrl.state = WL_STATE_END; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; dau_ctrl.update_rt = DAU_UPD_NONE; _wl_4G_pkt_id_update(); return; } /* 数据回复处理. */ static void _wl_4G_data_process(uint8_t *cmd, uint32_t len) { proto_head_t *head= (proto_head_t*)cmd; /* 报文头和 CRC 校验. */ if (_wl_4G_pkt_check(cmd, len) != HAL_OK) { wl_ctrl.time_send = 0; return; } /* 升级时不处理其他数据 */ if (WL_STATE_UPDATE == wl_ctrl.state) { if (DEBUG_CT_REQUEST == head->cmd_type) { /* 共有命令处理. */ switch (head->cmd) { case DEBUG_C_UPDATE_APP: _wl_4G_recv_update(cmd, len); break; default: break; } } if (DEBUG_CT_PRV_REQUEST == head->cmd_type) { /* 私有命令处理. */ switch (head->cmd) { case DEBUG_PRV_UPDATE_FPGA: _wl_4G_recv_update_fpga(cmd, len); break; default: break; } } } else { if (DEBUG_CT_REQUEST == head->cmd_type) { /* 共有命令处理. */ switch (head->cmd) { case DEBUG_C_CONTACT: _wl_4G_recv_contect(cmd, len); break; case DEBUG_C_RESET: _wl_4G_recv_reset(cmd, len); break; case DEBUG_C_UPDATE_APP: _wl_4G_recv_update(cmd, len); break; case DEBUG_C_DEV_CONFIG_SET: _wl_4G_recv_cfg_set(cmd, len); break; case DEBUG_C_UPDATE_APP_RT: _wl_4G_recv_update_rt(cmd, len); break; case DEBUG_C_KEEPALIVE: _wl_4G_recv_keepalive(); break; case DEBUG_C_TIME: _wl_4G_recv_time(cmd, len); break; default: break; } } else if (DEBUG_CT_PRV_REQUEST == head->cmd_type) { /* 私有命令处理. */ switch (head->cmd) { case DEBUG_PRV_REALDATA: _wl_4G_recv_realdata(); break; case DEBUG_PRV_POWER: _wl_4G_recv_power(cmd, len); break; case DEBUG_PRV_DEFECT: _wl_4G_recv_defect(cmd, len); break; case DEBUG_PRV_REALDATA_FUALT: _wl_4G_recv_realdata_fault(); break; case DEBUG_PRV_POWER_FAULT: _wl_4G_recv_power_fault(cmd, len); break; case DEBUG_PRV_FAULT: _wl_4G_recv_fault(cmd, len); break; case DEBUG_PRV_WAVE_COL: _wl_4G_recv_wave_force(cmd, len); break; case DEBUG_PRV_UPDATE_FPGA: _wl_4G_recv_update_fpga(cmd, len); break; case DEBUG_PRV_UPDATE_RT: _wl_4G_recv_update_fpga_rt(); break; default: break; } } } } /* 发送数据过程中收数据回复. */ void _wl_4G_data_recv(void) { static uint32_t time = 0; wl_buf_list_t *buf_l = &wl_buf_list_rx; proto_head_t *head = (proto_head_t*)wl_ctrl.cmd_buf; uint8_t *buf = NULL; uint16_t len = 0; uint16_t len_pkt = 0; /* 超过 3s 没有收包说明收包超时, 重新开始收包. */ if (HAL_GetTick() - time > 3000) { wl_ctrl.cmd_buf_index = 0; } time = HAL_GetTick(); /* 遍历所有有效的 buf. */ while(buf_l->current != buf_l->valid) { buf = buf_l->buf[buf_l->current]; len = buf_l->buf_cnt[buf_l->current]; /* 更新 buf index. */ buf_l->current++; if (WL_BUF_LIST_LEN == buf_l->current) { buf_l->current = 0; } /* 如果收包大于协议报文长度, 认为报文错误. */ if (wl_ctrl.cmd_buf_index + len > WL_CMD_BUF_LEN) { wl_ctrl.cmd_buf_index = 0; continue; } /* 将 buf 中的数据解析成命令. */ memcpy(&wl_ctrl.cmd_buf[wl_ctrl.cmd_buf_index], buf, len); wl_ctrl.cmd_buf_index += len; len_pkt = head->len + WL_CRC32_LEN; /* 如果收包大于 buf 长度, 认为报文错误. */ if (wl_ctrl.cmd_buf_index >= 2 && len_pkt > WL_DMA_RX_BUF_LEN) { wl_ctrl.cmd_buf_index = 0; continue; } /* 报文头长度都不够, 不进行处理 */ if (wl_ctrl.cmd_buf_index < 2) { continue; } /* 报文长度与收包长度不对称, 等待后续报文. */ if (wl_ctrl.cmd_buf_index < len_pkt) { continue; } DBG(DBG_M_4G, "Recv(%d): %d %d %d\r\n", wl_ctrl.cmd_buf_index, HAL_GetTick(), head->cmd_type, head->cmd); if (dbg_stat_get(DBG_M_4G)) { buf_print(wl_ctrl.cmd_buf, wl_ctrl.cmd_buf_index > 32 ? 32 : wl_ctrl.cmd_buf_index); vty_print("\r\n"); } _wl_4G_data_process(wl_ctrl.cmd_buf, wl_ctrl.cmd_buf_index); /* 粘包处理 */ if (wl_ctrl.cmd_buf_index > len_pkt) { memcpy(wl_ctrl.cmd_buf, &wl_ctrl.cmd_buf[len_pkt], wl_ctrl.cmd_buf_index - len_pkt); wl_ctrl.cmd_buf_index -= len_pkt; } else { wl_ctrl.cmd_buf_index = 0; } wl_ctrl.err_cnt = 0; } } /* 4G模块接收数据. */ void _wl_4G_receive(void) { if (wl_ctrl.state < WL_STATE_CONTACT) { /* 初始化过程中收 AT 指令. */ _wl_4G_AT_recv(); } else { /* 发送数据过程中收数据回复. */ _wl_4G_data_recv(); } } /* 初始化报文头. */ static void _wl_4G_head_init(uint16_t len, uint8_t cmdType, uint8_t cmd, uint16_t pkt_id) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; /* 封装报文头. */ head->len = len; head->dev_type_m = dev_info.type_m; head->dev_type_s= dev_info.type_s; head->dev_id = *(uint32_t*)dev_info.id; head->cmd_type = cmdType; head->cmd = cmd; head->pkt_id = pkt_id; } /* 初始化报文头, 后台出动发送的报文. */ static void _wl_4G_head_init_recv(uint16_t len, uint8_t cmdType, uint8_t cmd, uint16_t pkt_id) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; /* 封装报文头. */ head->len = len; head->dev_type_m = dev_info.type_m; head->dev_type_s= dev_info.type_s; head->dev_id = *(uint32_t*)dev_info.id; head->cmd_type = cmdType; head->cmd = cmd; head->pkt_id = pkt_id; } /* 设备连接请求 */ static void _wl_4G_send_contact(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; wl_proto_wakeup_t *data = (wl_proto_wakeup_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t) + sizeof(wl_proto_wakeup_t), DEBUG_CT_REPLY, DEBUG_C_CONTACT, wl_ctrl.pkt_id); /* 封装数据. */ memcpy(data, &dev_info.type_m, sizeof(wl_proto_wakeup_t) - DEV_NAME_LEN - WL_QCCID_LEN - DEV_APN_LEN); memcpy(data->name, dev_config.host, DEV_NAME_LEN); memcpy(data->QCCID, wl_ctrl.QCCID, WL_QCCID_LEN); memcpy(data->APN, dev_config.APN, DEV_APN_LEN); /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文 */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 重启报文发送 */ static void _wl_4G_send_reset(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init_recv(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_RESET, wl_ctrl.pkt_id_recv); /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf_recv + head->len); *crc = crc32(wl_ctrl.dma_tx_buf_recv, head->len); /* 发送报文 */ _wl_4G_transmit(wl_ctrl.dma_tx_buf_recv, head->len + 4); } /* 升级请求报文发送. */ static void _wl_4G_send_update(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; mul_head_t *m_head = (mul_head_t*)(wl_ctrl.dma_tx_buf_recv + sizeof(proto_head_t)); uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init_recv(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_UPDATE_APP, wl_ctrl.pkt_id_recv); head->len = sizeof(proto_head_t) + sizeof(mul_head_t); m_head->index = wl_ctrl.mul_idx; m_head->len = wl_ctrl.update_len; /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf_recv + head->len); *crc = crc32(wl_ctrl.dma_tx_buf_recv, head->len); /* 发送报文 */ _wl_4G_transmit(wl_ctrl.dma_tx_buf_recv, head->len + 4); } /* 重启报文发送 */ static void _wl_4G_send_cfg_set(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init_recv(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_DEV_CONFIG_SET, wl_ctrl.pkt_id_recv); /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf_recv + head->len); *crc = crc32(wl_ctrl.dma_tx_buf_recv, head->len); /* 发送报文 */ _wl_4G_transmit(wl_ctrl.dma_tx_buf_recv, head->len + 4); } /* 升级结果报文发送 */ static void _wl_4G_send_update_rt(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; int32_t *rt = (int32_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t) + sizeof(int32_t), DEBUG_CT_REPLY, DEBUG_C_UPDATE_APP_RT, wl_ctrl.pkt_id); *rt = wl_ctrl.update_rt; /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文 */ osDelay(100); if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 保活报文发送. */ static void _wl_4G_send_keepalive(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; wl_proto_state_t *data = (wl_proto_state_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t) + sizeof(wl_proto_state_t), DEBUG_CT_REPLY, DEBUG_C_KEEPALIVE, wl_ctrl.pkt_id); data->is_utc_valid = dau_ctrl.is_utc_ok; data->utc = dau_ctrl.utc; /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文. */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 对时报文回复 */ static void _wl_4G_send_time(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; uint32_t *crc = NULL; /* 封装报文头 */ _wl_4G_head_init_recv(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_TIME, wl_ctrl.pkt_id_recv); /* 计算校验和 */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf_recv + head->len); *crc = crc32(wl_ctrl.dma_tx_buf_recv, head->len); /* 发送报文 */ _wl_4G_transmit(wl_ctrl.dma_tx_buf_recv, head->len + 4); } /* 实时数据发送 */ static void _wl_4G_send_realdata(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; wl_proto_realdata_t *data = (wl_proto_realdata_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint32_t *crc = NULL; uint8_t i = 0; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t) + sizeof(wl_proto_realdata_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_REALDATA, wl_ctrl.pkt_id); /* 装填数据. */ data->vbat = ADC_ctrl.ADCi_vbat; data->vin = ADC_ctrl.ADCi_vin; data->temperature = ADC_ctrl.ADCi_temp; data->CSQ = wl_ctrl.CSQ; HAL_RTC_GetTime(&hrtc, &wl_time, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &wl_date, RTC_FORMAT_BIN); wl_tm.tm_year = wl_date.Year + 100; wl_tm.tm_mon = wl_date.Month - 1; wl_tm.tm_mday = wl_date.Date; wl_tm.tm_hour = wl_time.Hours; wl_tm.tm_min = wl_time.Minutes; wl_tm.tm_sec = wl_time.Seconds; data->utc = mktime(&wl_tm); data->run_time = HAL_GetTick() / 1000; for(i = 0; i < DAU_PORT_POWER_CNT; i++) { data->elec[i] = dau_ctrl.reg_elec[i]; } for(i = 0; i < DAU_PORT_DEFECT_CNT; i++) { data->elec_defect_max[i] = dau_ctrl.reg_defect_max[i]; } data->valid_power = IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_POWER); data->valid_defect = IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_DEFECT); /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文. */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 工频采样波形报文发送 */ static void _wl_4G_send_power(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; mul_head_t *m_head = (mul_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint8_t *data = (uint8_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t) + sizeof(mul_head_t)); int32_t data_len = 0; uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_POWER, wl_ctrl.pkt_id); m_head->index = wl_ctrl.mul_idx; /* 填充数据, 计算数据长度和报文长度. */ data_len = sizeof(dau_ctrl.reg_power) - m_head->index * DEBUG_DATA_SIZE; if (data_len < 0) { m_head->len = 0; } else if (data_len > DEBUG_DATA_SIZE) { m_head->len = DEBUG_DATA_SIZE; } else { m_head->len = data_len; } head->len = sizeof(proto_head_t) + sizeof(mul_head_t) + m_head->len; if (m_head->len > 0) { memcpy(data, (char*)(&dau_ctrl.reg_power[0][0]) + m_head->index * DEBUG_DATA_SIZE, m_head->len); } /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文 */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 缺陷采样波形报文发送 */ static void _wl_4G_send_defect(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; mul_head_t *m_head = (mul_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); int16_t *data = (int16_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t) + sizeof(mul_head_t)); uint32_t *crc = NULL; int32_t data_len = 0; uint32_t addr = 0; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_DEFECT, wl_ctrl.pkt_id); m_head->index = wl_ctrl.mul_idx; /* 填充数据, 计算数据长度和报文长度. */ data_len = DAU_DEFECT_BYTE_CNT - m_head->index * DEBUG_DATA_SIZE; if (data_len < 0) { m_head->len = 0; } else if (data_len > DEBUG_DATA_SIZE) { m_head->len = DEBUG_DATA_SIZE; } else { m_head->len = data_len; } head->len = sizeof(proto_head_t) + sizeof(mul_head_t) + m_head->len; if (m_head->len > 0) { addr = dau_ctrl.addr_reg + m_head->index * DEBUG_DATA_SIZE; if (spi_flash_read(addr, (uint8_t*)data, DEBUG_DATA_SIZE) != HAL_OK) { return; } } /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文 */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 故障定位数据发送 */ static void _wl_4G_send_realdata_fault(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; wl_proto_realdata_fault_t *data = (wl_proto_realdata_fault_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint32_t *crc = NULL; uint8_t i = 0; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t) + sizeof(wl_proto_realdata_fault_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_REALDATA_FUALT, wl_ctrl.pkt_id); /* 装填数据. */ data->utc = dau_ctrl.fault_utc; data->ns = dau_ctrl.fault_ns; for(i = 0; i < DAU_PORT_DEFECT_CNT; i++) { data->fault_trig[i] = dau_ctrl.fault_max[i]; } for(i = 0; i < DAU_PORT_POWER_CNT; i++) { data->elec[i] = dau_ctrl.fault_elec[i]; } /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文. */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 故障触发工频采样波形报文发送 */ static void _wl_4G_send_power_fault(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; mul_head_t *m_head = (mul_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint8_t *data = (uint8_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t) + sizeof(mul_head_t)); int32_t data_len = 0; uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_POWER_FAULT, wl_ctrl.pkt_id); m_head->index = wl_ctrl.mul_idx; /* 填充数据, 计算数据长度和报文长度. */ data_len = sizeof(dau_ctrl.fault_power) - m_head->index * DEBUG_DATA_SIZE; if (data_len < 0) { m_head->len = 0; } else if (data_len > DEBUG_DATA_SIZE) { m_head->len = DEBUG_DATA_SIZE; } else { m_head->len = data_len; } head->len = sizeof(proto_head_t) + sizeof(mul_head_t) + m_head->len; if (m_head->len > 0) { memcpy(data, (char*)(&dau_ctrl.fault_power[0][0]) + m_head->index * DEBUG_DATA_SIZE, m_head->len); } /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文 */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 故障触发故障采样波形报文发送 */ static void _wl_4G_send_fault(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; mul_head_t *m_head = (mul_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); int16_t *data = (int16_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t) + sizeof(mul_head_t)); uint32_t *crc = NULL; int32_t data_len = 0; uint32_t addr = 0; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_FAULT, wl_ctrl.pkt_id); m_head->index = wl_ctrl.mul_idx; /* 填充数据, 计算数据长度和报文长度. */ data_len = DAU_FAULT_BYTE_CNT - m_head->index * DEBUG_DATA_SIZE; if (data_len < 0) { m_head->len = 0; } else if (data_len > DEBUG_DATA_SIZE) { m_head->len = DEBUG_DATA_SIZE; } else { m_head->len = data_len; } head->len = sizeof(proto_head_t) + sizeof(mul_head_t) + m_head->len; if (m_head->len > 0) { addr = dau_ctrl.addr_fault + m_head->index * DEBUG_DATA_SIZE; if (spi_flash_read(addr, (uint8_t*)data, DEBUG_DATA_SIZE) != HAL_OK) { return; } } /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文 */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 强制录波报文回复 */ static void _wl_4G_send_wave_force(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init_recv(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_WAVE_COL, wl_ctrl.pkt_id_recv); /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf_recv + head->len); *crc = crc32(wl_ctrl.dma_tx_buf_recv, head->len); /* 发送报文 */ _wl_4G_transmit(wl_ctrl.dma_tx_buf_recv, head->len + 4); } /* 升级请求报文发送. */ static void _wl_4G_send_update_fpga(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf_recv; mul_head_t *m_head = (mul_head_t*)(wl_ctrl.dma_tx_buf_recv + sizeof(proto_head_t)); uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init_recv(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_UPDATE_FPGA, wl_ctrl.pkt_id_recv); head->len = sizeof(proto_head_t) + sizeof(mul_head_t) + 64; m_head->index = wl_ctrl.mul_idx; m_head->len = wl_ctrl.update_len; /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf_recv + head->len); *crc = crc32(wl_ctrl.dma_tx_buf_recv, head->len); /* 发送报文 */ _wl_4G_transmit(wl_ctrl.dma_tx_buf_recv, head->len + 4); } /* FPGA 升级结果报文发送. */ static void _wl_4G_send_update_fpga_rt(void) { proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf; int32_t *rt = (int32_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t)); uint32_t *crc = NULL; /* 封装报文头. */ _wl_4G_head_init(sizeof(proto_head_t) + sizeof(int32_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_UPDATE_RT, wl_ctrl.pkt_id); *rt = (dau_ctrl.update_rt != DAU_UPD_OK); /* 计算校验和. */ crc = (uint32_t*)(wl_ctrl.dma_tx_buf + head->len); *crc = crc32(wl_ctrl.dma_tx_buf, head->len); /* 发送报文. */ if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, head->len + 4)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + 5500; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + 1100; } } /* 数据发送 */ void _wl_4G_send(void) { uint8_t is_timeout = wl_ctrl.time_send < HAL_GetTick(); /* 循环内只发送一次报文, 没有报文发送的情况下要跳出循环. */ while(is_timeout) { if (WL_STATE_CONTACT == wl_ctrl.state) { _wl_4G_send_contact(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_REALDATA == wl_ctrl.state) { _wl_4G_send_realdata(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_POWER == wl_ctrl.state) { _wl_4G_send_power(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_DEFECT == wl_ctrl.state) { _wl_4G_send_defect(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_REALDATA_FAULT== wl_ctrl.state) { _wl_4G_send_realdata_fault(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_POWER_FAULT == wl_ctrl.state) { _wl_4G_send_power_fault(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_FAULT == wl_ctrl.state) { _wl_4G_send_fault(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_UPDATE_RT == wl_ctrl.state) { _wl_4G_send_update_rt(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_UPDATE_FPGA_RT == wl_ctrl.state) { _wl_4G_send_update_fpga_rt(); wl_ctrl.send_cnt++; break; } else if (WL_STATE_KEEPALIVE == wl_ctrl.state) { _wl_4G_send_keepalive(); wl_ctrl.send_cnt++; break; } else { break; } } } /* 发包状态机改变 */ void _wl_4G_state_chg(void) { if (dau_ctrl.update_rt != DAU_UPD_NONE) { /* FPGA 升级结果回复 */ wl_ctrl.state = WL_STATE_UPDATE_FPGA_RT; } else if(!IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_FAULT_CMP)) { /* 故障定位数据上送 */ wl_ctrl.state = WL_STATE_REALDATA_FAULT; } else if(!IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_CMP)) { /* 定时数据上送 */ wl_ctrl.state = WL_STATE_REALDATA; } else if(wl_ctrl.keepalive < HAL_GetTick()) { /* 保活报文上送 */ wl_ctrl.state = WL_STATE_KEEPALIVE; wl_ctrl.keepalive = HAL_GetTick() + dev_config.keepalive * 60000; } } /* 初始化 4G 模块软件 */ static void _wl_4G_init_cmd_send(uint8_t *cmd, uint32_t timeout) { uint8_t len = strlen((char*)cmd); /* 复制并发送 AT 命令. */ snprintf((char*)wl_ctrl.dma_tx_buf, WL_DMA_TX_BUF_LEN, "%s", cmd); if (HAL_OK == _wl_4G_transmit(wl_ctrl.dma_tx_buf, len)) { /* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */ wl_ctrl.time_send = HAL_GetTick() + timeout; } else { /* 发送失败, 等待 1s 重发. */ wl_ctrl.time_send = HAL_GetTick() + WL_USART_ERR_TIMEOUT; } } /* 通过 AT 命令进行模块初始化. */ void _wl_4G_init_soft(void) { uint8_t is_timeout = wl_ctrl.time_send < HAL_GetTick(); if ((WL_STATE_SOFT == wl_ctrl.state) && is_timeout) { /* 等待 RDY 字符串 */ wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; wl_ctrl.state++; } else if ((WL_STATE_AT_ATE == wl_ctrl.state) && is_timeout) { /* 关闭 AT 回显. */ _wl_4G_init_cmd_send("ATE0\r\n", 1100); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_IPR == wl_ctrl.state) && is_timeout) { /* 修改波特率. */ _wl_4G_init_cmd_send("AT+IPR=230400\r\n", 1100); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_QICSGP == wl_ctrl.state) && is_timeout) { /* 创建场景 */ snprintf((char*)wl_ctrl.dma_tx_buf, WL_DMA_TX_BUF_LEN, "AT+QICSGP=1,1,\"%s\",\"\",\"\",1\r\n", dev_config.APN); _wl_4G_init_cmd_send(wl_ctrl.dma_tx_buf, 1100); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_QIACT == wl_ctrl.state) && is_timeout) { /* 使能场景 */ _wl_4G_init_cmd_send("AT+QIACT=1\r\n", 33000); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_CSQ == wl_ctrl.state) && is_timeout) { /* 读取网络信号质量. */ osDelay(5000); _wl_4G_init_cmd_send("AT+CSQ\r\n", 1100); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_QCCID == wl_ctrl.state) && is_timeout) { /* Query ICCID of the SIM card */ _wl_4G_init_cmd_send("AT+QCCID\r\n", 1100); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_QICFGTS == wl_ctrl.state) && is_timeout) { /* 连接远程服务器. */ snprintf((char*)wl_ctrl.dma_tx_buf, WL_DMA_TX_BUF_LEN, "AT+QICFG=\"transpktsize\",1460\r\n"); _wl_4G_init_cmd_send(wl_ctrl.dma_tx_buf, 11000); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_QICFGWT == wl_ctrl.state) && is_timeout) { /* 连接远程服务器. */ snprintf((char*)wl_ctrl.dma_tx_buf, WL_DMA_TX_BUF_LEN, "AT+QICFG=\"transwaittm\",0\r\n"); _wl_4G_init_cmd_send(wl_ctrl.dma_tx_buf, 11000); wl_ctrl.send_cnt++; } else if ((WL_STATE_AT_QIOPEN == wl_ctrl.state) && is_timeout) { /* 连接远程服务器. */ //snprintf((char*)wl_ctrl.dma_tx_buf, WL_DMA_TX_BUF_LEN, "AT+QIOPEN=1,0,\"TCP\",\"%d.%d.%d.%d\",%d,19421,2\r\n", // dev_info.wireless_server_ip[0], dev_info.wireless_server_ip[1], dev_info.wireless_server_ip[2], // dev_info.wireless_server_ip[3], dev_info.wireless_server_port); _wl_4G_init_cmd_send("AT+QIOPEN=1,0,\"TCP\",\"111.47.21.142\",8809,19421,2\r\n", 10000); //_wl_4G_init_cmd_send(wl_ctrl.dma_tx_buf, 11000); wl_ctrl.send_cnt++; } else if (WL_STATE_AT_COMP == wl_ctrl.state) { /* 软件初始化完成. */ wl_ctrl.state = WL_STATE_CONTACT; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; } else if (wl_ctrl.state > WL_STATE_AT_COMP) { /* 理论上进不来 */ vty_print("#WE0 %d\r\n", wl_ctrl.state); wl_ctrl.state = WL_STATE_AT_ATE; wl_ctrl.time_send = 0; wl_ctrl.send_cnt = 0; } } /* 初始化 4G 模块硬件 */ static void _wl_4G_hw_init(void) { /* 4G 模块供电打开.*/ osDelay(1000); HAL_GPIO_WritePin(POWER_4G_GPIO_Port, POWER_4G_Pin, GPIO_PIN_SET); /* 4G 模块复位. */ osDelay(500); HAL_GPIO_WritePin(G4G_RST_GPIO_Port, G4G_RST_Pin, GPIO_PIN_SET); osDelay(100); HAL_GPIO_WritePin(G4G_RST_GPIO_Port, G4G_RST_Pin, GPIO_PIN_RESET); } /* 重启 4G 模块硬件 */ static void _wl_4G_hw_restart(void) { DBG(DBG_M_4G, "4G restart(%d)\r\n", wl_ctrl.err_cnt); /* 关闭 4G 模块硬件 */ HAL_GPIO_WritePin(POWER_4G_GPIO_Port, POWER_4G_Pin, GPIO_PIN_RESET); HAL_UART_Abort(wl_ctrl.uart); HAL_UART_DeInit(wl_ctrl.uart); if (wl_ctrl.err_cnt > 3) { osDelay(600000); } /* 初始化软硬件 */ osDelay(10000); wl_ctrl.state = 0; wl_ctrl.send_cnt = 0; wl_ctrl.mul_idx = 0; wl_ctrl.cmd_buf_index = 0; wl_ctrl.time_send = HAL_GetTick() + 20000; wl_ctrl.err_cnt++; memset(&wl_buf_list_rx, 0, sizeof(wl_buf_list_t)); MX_USART3_UART_Init(); _wl_4G_hw_init(); /* 开启串口空闲中断收包 */ HAL_UARTEx_ReceiveToIdle_DMA(wl_ctrl.uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN); #if 0 /* 4G 掉线后不能阻止波形采集, 掉线后默认上传完成 */ if (!MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_CMP)) { /* 更新 flash 地址 */ dau_ctrl.addr_reg += 0x20000; if (WARE_REG_ADDRESS_END == dau_ctrl.addr_reg) { dau_ctrl.addr_reg = WARE_REG_ADDRESS; } st_data.addr_reg = dau_ctrl.addr_reg; MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_CMP); } if (!MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_FAULT_CMP)) { /* 更新 flash 地址 */ dau_ctrl.addr_fault += 0x20000; if (WARE_FAULT_ADDRESS_END == dau_ctrl.addr_fault) { dau_ctrl.addr_fault = WARE_FAULT_ADDRESS; } st_data.addr_fault = dau_ctrl.addr_fault; MONITOR_BITMAP_SET(dau_ctrl.col_flag, DAU_COL_FLAG_FAULT_CMP); } #endif } /* 无线模块主任务循环 */ static void _wl_4G_start(void *argument) { uint32_t notify_value = 0; /* 等待完成首次 ADC 采样 */ while(1) { if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_ADC)) { break; } osDelay(1000); } /* 初始化 4G 模块硬件 */ MX_USART3_UART_Init(); _wl_4G_hw_init(); /* 开启串口空闲中断收包. */ HAL_UARTEx_ReceiveToIdle_DMA(wl_ctrl.uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN); /* 20s 内要收到 4G 模块发出的 RDY. */ wl_ctrl.time_send = HAL_GetTick() + 20000; for (;;) { /* 数据发送失败, 重启 4G 模块 */ if ((wl_ctrl.send_cnt > WL_SOFT_INIT_ERR && wl_ctrl.state < WL_STATE_CONTACT) || (wl_ctrl.send_cnt > WL_DATA_ERR && wl_ctrl.state >= WL_STATE_CONTACT)) { _wl_4G_hw_restart(); } if (wl_ctrl.state < WL_STATE_CONTACT) { /* 进入软件初始化 */ _wl_4G_init_soft(); } else { if (WL_STATE_UPDATE == wl_ctrl.state && wl_ctrl.time_update + 10000 < HAL_GetTick()) { /* 升级超时处理 10s */ wl_ctrl.mul_idx = 0; wl_ctrl.update_len = 0; wl_ctrl.state = WL_STATE_END; } else if (WL_STATE_END == wl_ctrl.state) { /* 发包状态机改变 */ _wl_4G_state_chg(); } /* 根据状态机状态发送报文 */ _wl_4G_send(); } common_watchdog_set(COM_WDG_WIR); /* 等待 DMA 收包中断 */ notify_value = ulTaskNotifyTake(pdTRUE, WL_RX_TIMEOUT); if (0 == notify_value) { continue; } /* 收包处理 */ _wl_4G_receive(); } } /* Interface functions -------------------------------------------------------*/ /* description: 无线通讯任务初始化 param: return: */ void wl_init(void) { wl_ctrl.uart = &huart3; wl_ctrl.handle = osThreadNew(_wl_4G_start, NULL, &WL_attributes); } /* description: 无线通讯调试显示接口 param: return: */ void wl_show(void) { vty_print("ST: %-03d %d\r\n\n", wl_ctrl.state, wl_ctrl.send_cnt); } /******************* (C) COPYRIGHT LandPower ***** END OF FILE ****************/