You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2171 lines
65 KiB
C

/******************************************************************************
* 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
*
* <h2><center>&copy; COPYRIGHT(c) 2022 LandPower</center></h2>
*
* 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_SLEEP_TIME 1800 // 休眠时间
/* 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_SLEEP,
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];
uint16_t interval;
uint16_t threshold_power;
uint16_t threshold_defect;
uint16_t threshold_fault;
uint16_t keepalive;
uint16_t interval_fault;
} 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 energy_mode; // 节能模式
uint8_t GB_cnt; // 北斗数量
} 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
uint8_t port; // 触发端口
uint8_t reserve[3]; // 保留位
} 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;
uint16_t interval_fault;
} wl_proto_config_t;
typedef struct
{
uint8_t server_ip[4];
uint16_t server_port;
uint8_t reserve[2];
char host[DEV_NAME_LEN];
char APN[DEV_APN_LEN];
} wl_proto_dev_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_dev_set(void);
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_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_dev_set(uint8_t *cmd, uint32_t len)
{
proto_head_t *head = (proto_head_t*)cmd;
wl_proto_dev_t *cfg = (wl_proto_dev_t*)(cmd + sizeof(proto_head_t));
memcpy(dev_info.server_ip, cfg->server_ip, 4);
dev_info.server_port = cfg->server_port;
memcpy(dev_config.host, cfg->host, DEV_NAME_LEN);
memcpy(dev_config.APN, cfg->APN, DEV_APN_LEN);
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
common_sys_set(COM_SYS_SAVE_INFO, 0);
wl_ctrl.pkt_id_recv = head->pkt_id;
_wl_4G_send_dev_set();
}
/* 设备重启 */
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 (cfg->interval_fault != dev_config.fault_interval)
{
is_cfg_save = TRUE;
dev_config.fault_interval = cfg->interval_fault;
}
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_SLEEP;
}
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_SLEEP;
}
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_SLEEP;
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_recv_sleep(void)
{
uint32_t sleep_time = WL_SLEEP_TIME;
wl_ctrl.state = WL_STATE_END;
wl_ctrl.time_send = 0;
wl_ctrl.send_cnt = 0;
flash_log_write(FLASH_LOG_TYPE_WARNING, "Energy mode system sleep %ds!\r\n", sleep_time);
common_sys_set(COM_SYS_SHUTDOWN, (void*)&sleep_time);
_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_DEV_INFO_SET:
_wl_4G_recv_dev_set(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;
case DEBUG_PRV_SLEEP:
_wl_4G_recv_sleep();
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);
data->interval = dev_config.collect_interval;
data->threshold_power = dev_config.power_threshold;
data->threshold_defect = dev_config.defect_threshold;
data->threshold_fault = dev_config.fault_threshold;
data->keepalive = dev_config.keepalive;
data->interval_fault = dev_config.fault_interval;
/* 计算校验和. */
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_dev_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_INFO_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_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_sleep(void)
{
proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf;
uint32_t *data = (uint32_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t));
uint32_t *crc = NULL;
/* 封装报文头. */
_wl_4G_head_init(sizeof(proto_head_t) + sizeof(uint32_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_SLEEP, wl_ctrl.pkt_id);
*data = WL_SLEEP_TIME;
/* 计算校验和. */
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->energy_mode = ADC_ctrl.energy_mode;
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) ? 1 : 0;
data->valid_defect = IS_MONITOR_BIT_SET(dau_ctrl.col_flag, DAU_COL_FLAG_REG_DEFECT) ? 1 : 0;
data->GB_cnt = dau_ctrl.GB_cnt;
/* 计算校验和. */
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];
}
data->port = dau_ctrl.fault_port;
/* 计算校验和. */
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 if (WL_STATE_SLEEP == wl_ctrl.state)
{
if (ADC_ENERGY_SLEEP == ADC_ctrl.energy_mode)
{
_wl_4G_send_sleep();
wl_ctrl.send_cnt++;
}
else
{
wl_ctrl.state = WL_STATE_END;
wl_ctrl.time_send = 0;
wl_ctrl.send_cnt = 0;
}
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.server_ip[0], dev_info.server_ip[1], dev_info.server_ip[2],
dev_info.server_ip[3], dev_info.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_close(uint32_t sleep_time)
{
HAL_GPIO_WritePin(POWER_4G_GPIO_Port, POWER_4G_Pin, GPIO_PIN_RESET);
if (ADC_ctrl.energy_mode != ADC_ENERGY_NORMAL
&& sleep_time < WL_SLEEP_TIME)
{
sleep_time = WL_SLEEP_TIME;
}
flash_log_write(FLASH_LOG_TYPE_WARNING, "Server is disconnect system sleep %ds!\r\n", sleep_time);
common_sys_set(COM_SYS_SHUTDOWN, (void*)&sleep_time);
while(1)
{
osDelay(portMAX_DELAY);
}
}
/* 重启 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)
{
_wl_4G_hw_close(dev_config.collect_interval * 60);
}
/* 初始化软硬件 */
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(200);
}
/* 初始化 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
&& HAL_GetTick() > wl_ctrl.time_update + 10000)
{
/* 升级超时处理 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("STA: %d\r\nErr: %d\r\n", wl_ctrl.state, wl_ctrl.send_cnt);
vty_print("CSQ: %d\r\n", wl_ctrl.CSQ);
vty_print("QID: %s\r\n\n", wl_ctrl.QCCID);
}
/******************* (C) COPYRIGHT LandPower ***** END OF FILE ****************/