|
|
/******************************************************************************
|
|
|
* 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>© 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 "RS485_sensor.h"
|
|
|
#include "recording_wave.h"
|
|
|
#include "flash_if.h"
|
|
|
#include "RS485_debug.h"
|
|
|
#include "flash_log.h"
|
|
|
#include "position.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_QICSGP,
|
|
|
WL_STATE_AT_QIACT,
|
|
|
WL_STATE_AT_CSQ,
|
|
|
WL_STATE_AT_QICFGTS,
|
|
|
WL_STATE_AT_QICFGWT,
|
|
|
WL_STATE_AT_QIOPEN,
|
|
|
WL_STATE_ADC_WAIT,
|
|
|
WL_STATE_WAKEUP = 128,
|
|
|
WL_STATE_REALDATA,
|
|
|
WL_STATE_PWR_FRE,
|
|
|
WL_STATE_UPDATE,
|
|
|
WL_STATE_UPDATE_RT,
|
|
|
WL_STATE_WAVE,
|
|
|
WL_STATE_WAVE_MAX,
|
|
|
WL_STATE_POSITION,
|
|
|
WL_STATE_POSITION_WAVE,
|
|
|
WL_STATE_KEEPALIVE,
|
|
|
CSG_STATE_CONNECT,
|
|
|
CSG_STATE_TIME,
|
|
|
CSG_STATE_BEAT,
|
|
|
CSG_STATE_IDLE,
|
|
|
CSG_STATE_DATA,
|
|
|
CSG_STATE_DATA_HIS,
|
|
|
WL_STATE_END = 255
|
|
|
} WL_STATE_E;
|
|
|
|
|
|
typedef struct {
|
|
|
uint32_t start;
|
|
|
uint16_t len;
|
|
|
uint16_t type;
|
|
|
uint32_t id;
|
|
|
uint32_t life_cnt;
|
|
|
uint16_t num;
|
|
|
uint16_t num_index;
|
|
|
} wl_proto_head_t;
|
|
|
|
|
|
typedef struct {
|
|
|
uint32_t checksum;
|
|
|
uint32_t end;
|
|
|
} wl_proto_tail_t;
|
|
|
|
|
|
/* 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];
|
|
|
/* 设备其他信息. 128byte */
|
|
|
uint8_t name[DEV_NAME_LEN];
|
|
|
} wl_proto_wakeup_t;
|
|
|
|
|
|
/* 实时数据传输结构体. */
|
|
|
typedef struct
|
|
|
{
|
|
|
int16_t temperature; // 设备温度, 单位: 0.1℃.
|
|
|
uint16_t vbat; // 电池电压, 单位: mv.
|
|
|
int16_t CSQ; // 4G 信号质量 > -51dBm 统一显示 -51dBm, < -113 dBm 为无信号.
|
|
|
uint16_t vin; // 工作电压, 单位: mv.
|
|
|
uint32_t elec[CFG_ADC_CH_CNT]; // 通道电流有效值 mA.
|
|
|
uint16_t vsc; // 超级电容电压, 单位: mv.
|
|
|
uint16_t sen_temp[SENSOR_SUM]; // 传感器温度: 单位: 0.1℃.
|
|
|
uint16_t sen_x[SENSOR_SUM]; // 传感器震动 x 轴.
|
|
|
uint16_t sen_y[SENSOR_SUM]; // 传感器震动 y 轴.
|
|
|
uint16_t sen_z[SENSOR_SUM]; // 传感器震动 z 轴.
|
|
|
uint8_t energy_mode; // 当前设备工作模式.
|
|
|
uint8_t sen_short; // 传感器是否短路, 0 – 没有短路, 1 – 短路.
|
|
|
uint8_t sen_valid[SENSOR_SUM]; // 传感器数据是否有效, 0 - 无效, 1 - 有效.
|
|
|
uint32_t run_time; // 设备运行时长, 单位 s.
|
|
|
uint8_t fre_valid; // 工频数据有效, 有线协议使用.
|
|
|
uint8_t wave_valid; // 高频数据有效, 有线协议使用.
|
|
|
uint8_t reserve[2];
|
|
|
} wl_proto_realdata_t;
|
|
|
|
|
|
/* 实时数据传输结构体. */
|
|
|
typedef struct
|
|
|
{
|
|
|
int16_t wave[WAVE_SUM]; // 高频录波最大值, 0 - 无效, 1 - 有效值.
|
|
|
} wl_proto_wave_max_t;
|
|
|
|
|
|
typedef struct
|
|
|
{
|
|
|
uint32_t utc;
|
|
|
uint16_t interval;
|
|
|
uint8_t wave_force;
|
|
|
uint8_t wave_interval;
|
|
|
uint16_t threshold;
|
|
|
uint16_t wave_threshold;
|
|
|
uint8_t is_updata;
|
|
|
uint8_t main_cable;
|
|
|
uint8_t normal_sleep;
|
|
|
uint8_t is_voltage_col;
|
|
|
uint8_t is_temp_col;
|
|
|
uint8_t is_wave_col;
|
|
|
uint8_t reserve[2]; //字节对齐
|
|
|
uint32_t position_file_s;
|
|
|
uint32_t position_file_ns;
|
|
|
} wl_proto_config_t;
|
|
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
osThreadId_t WLHandle;
|
|
|
const osThreadAttr_t WL_attributes =
|
|
|
{
|
|
|
.name = "WIRELESS",
|
|
|
.stack_size = 160 * 2 * 4,
|
|
|
.priority = (osPriority_t) osPriorityNormal,
|
|
|
};
|
|
|
wl_buf_list_t wl_buf_list_rx;
|
|
|
static UART_HandleTypeDef *wl_uart = &huart3;
|
|
|
wl_ctrl_t wl_ctrl;
|
|
|
static uint8_t wl_flash[WL_FLASH_BUF_SIZE];
|
|
|
static fd_date_t csg_adc_data;
|
|
|
static position_data_t position_up_data;
|
|
|
static uint64_t csg_data_idx[CSG_PKT_DATA_SUM];
|
|
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
static void _wl_4G_wakeup_send(void);
|
|
|
static void _wl_4G_realdata_send(void);
|
|
|
static void _wl_4G_update_send(void);
|
|
|
static void _wl_4G_update_rt_send(void);
|
|
|
static void _wl_4G_power_fre_send(void);
|
|
|
static void _wl_4G_wave_send(void);
|
|
|
static void _wl_4G_wave_max_send(void);
|
|
|
static void _wl_4G_position_send(void);
|
|
|
static HAL_StatusTypeDef _wl_4G_position_wave_send(void);
|
|
|
static void _wir_data_process(uint8_t *cmd, uint32_t len);
|
|
|
static void _csg_pkt_recv(void);
|
|
|
|
|
|
/* Internal functions --------------------------------------------------------*/
|
|
|
/* 初始化 4G 模块硬件 */
|
|
|
static void _wl_4G_hw_init(void)
|
|
|
{
|
|
|
/* 4G 模块供电打开.*/
|
|
|
osDelay(1000);
|
|
|
HAL_GPIO_WritePin(POWER_EN_4G_GPIO_Port, POWER_EN_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_EN_4G_GPIO_Port, POWER_EN_4G_Pin, GPIO_PIN_RESET);
|
|
|
|
|
|
/* 故障定位版本装置不进行高频录波 */
|
|
|
if (st_data.wave_start && DEV_TYPE_CT_P != dev_info.type_s)
|
|
|
{
|
|
|
while(wave_ctrl.state.state != WAVE_STATE_COMPLETION)
|
|
|
{
|
|
|
osDelay(3000);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!st_data.wave_start && st_data.wave_up_start
|
|
|
&& st_data.wave_index != wl_ctrl.wave_index)
|
|
|
{
|
|
|
st_write(&st_data);
|
|
|
}
|
|
|
else if (DEV_TYPE_CT_P == dev_info.type_s
|
|
|
&& position_ctrl.position_wave_up
|
|
|
&& st_data.wave_index != wl_ctrl.wave_index)
|
|
|
{
|
|
|
st_data.wave_index = wl_ctrl.wave_index;
|
|
|
st_write(&st_data);
|
|
|
}
|
|
|
|
|
|
if (ADC_ctrl.energy_mode != ADC_ENERGY_NORMAL
|
|
|
&& sleep_time < 1800)
|
|
|
{
|
|
|
sleep_time = 1800;
|
|
|
}
|
|
|
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);
|
|
|
|
|
|
/* 开启串口空闲中断收包. */
|
|
|
if (wl_ctrl.err_cnt)
|
|
|
{
|
|
|
if (DEV_TYPE_CT_P != dev_info.type_s)
|
|
|
{
|
|
|
flash_log_write(FLASH_LOG_TYPE_WARNING, "Server is disconnect system sleep %ds!\r\n", dev_config.collect_interval * 60 - 30);
|
|
|
_wl_4G_hw_close(dev_config.collect_interval * 60 - 30);
|
|
|
return;
|
|
|
}
|
|
|
/* 故障定位版本设备出现问题时重启不休眠 */
|
|
|
else
|
|
|
{
|
|
|
flash_log_write(FLASH_LOG_TYPE_WARNING, "Server is disconnect system reset!\r\n");
|
|
|
_wl_4G_hw_close(0);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
HAL_UART_Abort(wl_uart);
|
|
|
memset(&wl_buf_list_rx, 0, sizeof(wl_buf_list_t));
|
|
|
osDelay(200);
|
|
|
HAL_UARTEx_ReceiveToIdle_DMA(wl_uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN);
|
|
|
|
|
|
/* 初始化 4G 模块硬件. */
|
|
|
HAL_GPIO_WritePin(POWER_EN_4G_GPIO_Port, POWER_EN_4G_Pin, GPIO_PIN_RESET);
|
|
|
_wl_4G_hw_init();
|
|
|
|
|
|
/* 20s 内要收到 4G 模块发出的 RDY. */
|
|
|
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.wave_index = dev_record.wave_index;
|
|
|
wl_ctrl.err_cnt++;
|
|
|
}
|
|
|
|
|
|
/* 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 命令回复处理. */
|
|
|
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_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, "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;
|
|
|
uint8_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 (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++;
|
|
|
}
|
|
|
|
|
|
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))
|
|
|
{
|
|
|
vty_print("@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))
|
|
|
{
|
|
|
vty_print("@1\r\n");
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
/* 对设备 id 进行识别, 可以是广播. */
|
|
|
if (head->dev_id != (*(uint32_t*)dev_info.id) && head->dev_id != 0xFFFFFFFF)
|
|
|
{
|
|
|
vty_print("@2\r\n");
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
/* 验证 CRC32. */
|
|
|
if (crc32(cmd, head->len) != (*(uint32_t*)(cmd + head->len)))
|
|
|
{
|
|
|
vty_print("@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
|
|
|
&& dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
vty_print("@4: %d %d\r\n", head->pkt_id, wl_ctrl.pkt_id);
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/* 设备信息获取报文处理. */
|
|
|
static void _wl_4G_pkt_reply(void)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_PWR_FRE;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_wl_4G_realdata_send();
|
|
|
}
|
|
|
|
|
|
if (dev_info.type_s == DEV_TYPE_CT_P)
|
|
|
{
|
|
|
position_ctrl.offline = FALSE;
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 设备信息回复. */
|
|
|
static void _wl_4G_dev_info_reply(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;
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
if (cfg->interval != dev_config.collect_interval)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config_collect_interval_set(cfg->interval);
|
|
|
}
|
|
|
|
|
|
if (cfg->wave_interval != dev_config.wave_interval)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config_wave_interval_set(cfg->wave_interval);
|
|
|
}
|
|
|
|
|
|
if (cfg->threshold != dev_config.threshold)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.threshold = cfg->threshold;
|
|
|
}
|
|
|
|
|
|
if (cfg->wave_threshold != dev_config.wave_threshold)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.wave_threshold = cfg->wave_threshold;
|
|
|
position_ctrl.cfg = TRUE;
|
|
|
}
|
|
|
|
|
|
if (cfg->main_cable != dev_config.main_cable)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.main_cable = cfg->main_cable;
|
|
|
}
|
|
|
|
|
|
if (cfg->normal_sleep != dev_config.normal_sleep)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.normal_sleep = cfg->normal_sleep;
|
|
|
}
|
|
|
|
|
|
if (cfg->is_voltage_col != dev_config.is_voltage_col)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.is_voltage_col = cfg->is_voltage_col;
|
|
|
}
|
|
|
|
|
|
if (cfg->is_temp_col != dev_config.is_temp_col)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.is_temp_col = cfg->is_temp_col;
|
|
|
}
|
|
|
|
|
|
if (cfg->is_wave_col != dev_config.is_wave_col)
|
|
|
{
|
|
|
is_cfg_save = TRUE;
|
|
|
dev_config.is_wave_col = cfg->is_wave_col;
|
|
|
}
|
|
|
|
|
|
if (is_cfg_save)
|
|
|
{
|
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
|
}
|
|
|
|
|
|
is_cfg_save = FALSE;
|
|
|
if (cfg->wave_force != st_data.wave_force)
|
|
|
{
|
|
|
st_data.wave_force = cfg->wave_force;
|
|
|
is_cfg_save = TRUE;
|
|
|
}
|
|
|
|
|
|
/* 强制录波或者间隔时间到了, 并且当前录波上传已完成. */
|
|
|
if ((cfg->wave_force || abs_cal_u(cfg->utc, st_data.wave_time) > (dev_config.wave_interval * 3600))
|
|
|
&& !st_data.wave_up_start && DEV_TYPE_CT_P != dev_info.type_s)
|
|
|
{
|
|
|
st_data.wave_time = cfg->utc;
|
|
|
st_data.wave_start = TRUE;
|
|
|
st_data.wave_up_start = TRUE;
|
|
|
st_data.wave_index = 0;
|
|
|
for(i = 0; i < WAVE_SUM; i++)
|
|
|
{
|
|
|
st_data.wave_max[i] = 0;
|
|
|
}
|
|
|
wl_ctrl.wave_index = 0;
|
|
|
is_cfg_save = TRUE;
|
|
|
}
|
|
|
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
if (cfg->wave_force && !position_ctrl.position_wave_up && cfg->position_file_s != 0)
|
|
|
{
|
|
|
position_ctrl.position_wave_up = TRUE;
|
|
|
position_ctrl.position_file_s = cfg->position_file_s;
|
|
|
position_ctrl.position_file_ns = cfg->position_file_ns;
|
|
|
}
|
|
|
else if (!cfg->wave_force && position_ctrl.position_wave_up)
|
|
|
{
|
|
|
position_ctrl.position_wave_up = FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (is_cfg_save)
|
|
|
{
|
|
|
st_write(&st_data);
|
|
|
}
|
|
|
|
|
|
/* 更新 RTC 时间. */
|
|
|
rtc_time_set(cfg->utc);
|
|
|
|
|
|
wl_ctrl.state = WL_STATE_REALDATA;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.is_update = cfg->is_updata;
|
|
|
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_wl_4G_wakeup_send();
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 设备 APP 升级回复. */
|
|
|
static void _wl_4G_update_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 计算写 FLASH 地址, 并写入 FLASH. */
|
|
|
addr = TFTP_APP_ADDRESS + m_head->index * DEBUG_DATA_SIZE;
|
|
|
if (m_head->len > DEBUG_DATA_SIZE)
|
|
|
{
|
|
|
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.state = WL_STATE_UPDATE_RT;
|
|
|
wl_ctrl.mul_idx = 0;
|
|
|
wl_ctrl.update_len = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.mul_idx = m_head->index + 1;
|
|
|
wl_ctrl.update_len = m_head->len;
|
|
|
}
|
|
|
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.mul_idx = m_head->index;
|
|
|
wl_ctrl.update_len = m_head->len;
|
|
|
wl_ctrl.state = WL_STATE_UPDATE;
|
|
|
_wl_4G_update_send();
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 设备信息获取报文处理. */
|
|
|
static void _wl_4G_update_rt_reply(void)
|
|
|
{
|
|
|
/* 有线设备需要回复报文后再休眠. */
|
|
|
if (DEV_TYPE_ACDC == dev_info.type_s)
|
|
|
{
|
|
|
_wl_4G_update_rt_send();
|
|
|
}
|
|
|
|
|
|
if (wl_ctrl.update_rt != HAL_OK)
|
|
|
{
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 延迟 1s 等待串口回复报文发送完成. */
|
|
|
osDelay(1000);
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "Update APP system sleep 0s!\r\n");
|
|
|
_wl_4G_hw_close(0);
|
|
|
}
|
|
|
|
|
|
wl_ctrl.is_update = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 工频数据回复. */
|
|
|
static void _wl_4G_power_fre_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t));
|
|
|
mul_head_t *m_head_send = (mul_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t));
|
|
|
|
|
|
if (m_head->len < DEBUG_DATA_SIZE)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_UPDATE;
|
|
|
wl_ctrl.mul_idx = 0;
|
|
|
ADC_ctrl.up_finish = TRUE;
|
|
|
ADC_ctrl.is_ADC_thr = FALSE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.mul_idx = m_head->index;
|
|
|
}
|
|
|
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_wl_4G_power_fre_send();
|
|
|
/* 发送完成需要通知 ADC继续采集. */
|
|
|
if (m_head_send->len < DEBUG_DATA_SIZE)
|
|
|
{
|
|
|
wl_ctrl.mul_idx = 0;
|
|
|
ADC_ctrl.up_finish = TRUE;
|
|
|
ADC_ctrl.is_ADC_thr = FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 高频数据回复. */
|
|
|
static void _wl_4G_wave_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
mul_head_t *m_head = (mul_head_t*)(cmd + sizeof(proto_head_t));
|
|
|
mul_head_t *m_head_send = (mul_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t));
|
|
|
|
|
|
if (m_head->len < DEBUG_DATA_SIZE)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE_MAX;
|
|
|
st_data.wave_up_start = FALSE;
|
|
|
st_data.wave_index = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
st_data.wave_index = m_head->index;
|
|
|
}
|
|
|
|
|
|
if (!ADC_ctrl.up_finish)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_wl_4G_wave_send();
|
|
|
/* 发送完成需要通知 ADC继续采集. */
|
|
|
if (m_head_send->len < DEBUG_DATA_SIZE)
|
|
|
{
|
|
|
st_data.wave_up_start = FALSE;
|
|
|
st_data.wave_index = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 高频数据回复. */
|
|
|
static void _wl_4G_wave_max_reply(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();
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
_wl_4G_pkt_id_update();
|
|
|
st_data.wave_max[0] = 0;
|
|
|
st_data.wave_max[1] = 0;
|
|
|
st_data.wave_max[2] = 0;
|
|
|
st_data.wave_max[3] = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_wl_4G_wave_max_send();
|
|
|
}
|
|
|
|
|
|
st_write(&st_data);
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 故障定位波形回复 */
|
|
|
static void _wl_4G_position_wave_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
position_head_t *p_head = (position_head_t*)(cmd + sizeof(proto_head_t));
|
|
|
|
|
|
if (p_head->len < DEBUG_DATA_SIZE)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_END;
|
|
|
position_ctrl.position_wave_up = FALSE;
|
|
|
wl_ctrl.wave_index = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.wave_index = p_head->index;
|
|
|
}
|
|
|
|
|
|
if (!ADC_ctrl.up_finish)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
_wl_4G_pkt_id_update();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 故障定位行波数据回复. */
|
|
|
static void _wl_4G_position_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
|
|
|
st_data.position_up_id++;
|
|
|
st_write(&st_data);
|
|
|
|
|
|
if (st_data.position_up_id == position_id)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION_WAVE;
|
|
|
}
|
|
|
|
|
|
if (!ADC_ctrl.up_finish)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
|
|
|
_wl_4G_pkt_id_update();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 保活报文回复. */
|
|
|
static void _wl_4G_wave_keepalive_reply(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_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 (DEBUG_CT_REQUEST == head->cmd_type)
|
|
|
{
|
|
|
/* 共有命令处理. */
|
|
|
switch (head->cmd)
|
|
|
{
|
|
|
case DEBUG_C_DEV_INFO:
|
|
|
_wl_4G_dev_info_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_C_UPDATE_APP:
|
|
|
_wl_4G_update_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_C_UPDATE_APP_RT:
|
|
|
_wl_4G_update_rt_reply();
|
|
|
break;
|
|
|
case DEBUG_C_KEEPALIVE:
|
|
|
_wl_4G_wave_keepalive_reply();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else if (DEBUG_CT_PRV_REQUEST == head->cmd_type)
|
|
|
{
|
|
|
/* 私有命令处理. */
|
|
|
switch (head->cmd)
|
|
|
{
|
|
|
case DEBUG_PRV_REAL_DATA:
|
|
|
_wl_4G_pkt_reply();
|
|
|
break;
|
|
|
case DEBUG_PRV_POWER_FRE:
|
|
|
_wl_4G_power_fre_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_PRV_WAVE:
|
|
|
_wl_4G_wave_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_PRV_WAVE_MAX:
|
|
|
_wl_4G_wave_max_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_PRV_POSITION_WAVE:
|
|
|
_wl_4G_position_wave_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_PRV_POSITION:
|
|
|
_wl_4G_position_reply(cmd, len);
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 发送数据过程中收数据回复. */
|
|
|
void _wl_4G_data_recv(void)
|
|
|
{
|
|
|
static uint8_t state = 0;
|
|
|
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;
|
|
|
mul_head_t *m_head = (mul_head_t*)(wl_ctrl.cmd_buf + sizeof(proto_head_t));
|
|
|
uint8_t *buf = NULL;
|
|
|
uint16_t len = 0;
|
|
|
|
|
|
/* 超过 3s 没有收包说明收包超时, 重新开始收包. */
|
|
|
if (HAL_GetTick() - time > 3000)
|
|
|
{
|
|
|
wl_ctrl.cmd_buf_index = 0;
|
|
|
state = 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;
|
|
|
}
|
|
|
|
|
|
/* 如果收包大于协议报文长度或者大于 buf 长度, 认为报文错误. */
|
|
|
if (wl_ctrl.cmd_buf_index + len > WL_DMA_RX_BUF_LEN
|
|
|
|| (wl_ctrl.cmd_buf_index >= 2 && (wl_ctrl.cmd_buf_index + len) > (head->len + WL_CRC32_LEN)))
|
|
|
{
|
|
|
wl_ctrl.cmd_buf_index = 0;
|
|
|
state = 0;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* 将 buf 中的数据解析成命令. */
|
|
|
memcpy(&wl_ctrl.cmd_buf[wl_ctrl.cmd_buf_index], buf, len);
|
|
|
wl_ctrl.cmd_buf_index += len;
|
|
|
|
|
|
if (!state)
|
|
|
{
|
|
|
/* 报文长度不对, 重新收包. */
|
|
|
if (head->len + WL_CRC32_LEN > WL_DMA_RX_BUF_LEN)
|
|
|
{
|
|
|
wl_ctrl.cmd_buf_index = 0;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* 报文长度与收包长度不对称, 等待后续报文. */
|
|
|
if (wl_ctrl.cmd_buf_index < head->len + WL_CRC32_LEN)
|
|
|
{
|
|
|
state = TRUE;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 报文长度与收包长度不对称, 等待后续报文. */
|
|
|
if (wl_ctrl.cmd_buf_index < head->len + WL_CRC32_LEN)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
state = FALSE;
|
|
|
}
|
|
|
|
|
|
DBG(DBG_M_4G, "Recv(%d): %d %d %d %d\r\n", wl_ctrl.cmd_buf_index, HAL_GetTick(), head->cmd_type, head->cmd, m_head->index);
|
|
|
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");
|
|
|
}
|
|
|
if (DEV_TYPE_ACDC == dev_info.type_s)
|
|
|
{
|
|
|
_wir_data_process(wl_ctrl.cmd_buf, wl_ctrl.cmd_buf_index);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_wl_4G_data_process(wl_ctrl.cmd_buf, wl_ctrl.cmd_buf_index);
|
|
|
}
|
|
|
wl_ctrl.cmd_buf_index = 0;
|
|
|
wl_ctrl.err_cnt = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 4G 模块发送数据. */
|
|
|
static HAL_StatusTypeDef _wl_4G_transmit(uint8_t *data, uint16_t len)
|
|
|
{
|
|
|
HAL_StatusTypeDef rv = HAL_ERROR;
|
|
|
|
|
|
if (wl_ctrl.state < WL_STATE_WAKEUP)
|
|
|
{
|
|
|
DBG(DBG_M_4G, "Send: %s\r\n", 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");
|
|
|
}
|
|
|
/* 每次发送数据更新保活时间. */
|
|
|
wl_ctrl.keepalive = HAL_GetTick() + 60000;
|
|
|
}
|
|
|
|
|
|
/* 开启串口空闲中断收包. */
|
|
|
HAL_UARTEx_ReceiveToIdle_DMA(wl_uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN);
|
|
|
HAL_GPIO_WritePin(RS485_B_DE_GPIO_Port, RS485_B_DE_Pin, GPIO_PIN_SET);
|
|
|
rv = HAL_UART_Transmit_DMA(wl_uart, data, len);
|
|
|
|
|
|
return rv;
|
|
|
}
|
|
|
|
|
|
/* 4G模块接收数据. */
|
|
|
void _wl_4G_receive(void)
|
|
|
{
|
|
|
if (wl_ctrl.state < WL_STATE_WAKEUP)
|
|
|
{
|
|
|
/* 初始化过程中收 AT 指令. */
|
|
|
_wl_4G_AT_recv();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (DEV_TYPE_CSG == dev_info.type_s)
|
|
|
{
|
|
|
/* 南网协议报文处理. */
|
|
|
_csg_pkt_recv();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送数据过程中收数据回复. */
|
|
|
_wl_4G_data_recv();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 初始化 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)
|
|
|
{
|
|
|
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_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_long);
|
|
|
_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_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\",9467,19421,2\r\n", 10000);
|
|
|
_wl_4G_init_cmd_send(wl_ctrl.dma_tx_buf, 11000);
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else if (WL_STATE_ADC_WAIT == wl_ctrl.state)
|
|
|
{
|
|
|
if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_ADC))
|
|
|
{
|
|
|
/* 软件初始化完成. */
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_END;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.energy_mode_old = ADC_ctrl.energy_mode;
|
|
|
}
|
|
|
else if (is_timeout)
|
|
|
{
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 10000;
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 初始化报文头. */
|
|
|
static void _wl_4G_data_head_init(uint16_t len, uint8_t cmdType, uint8_t cmd)
|
|
|
{
|
|
|
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;
|
|
|
if (dev_info.type_s != DEV_TYPE_ACDC)
|
|
|
{
|
|
|
head->pkt_id = wl_ctrl.pkt_id;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 设备唤醒, 发送配置和数据请求. */
|
|
|
static void _wl_4G_wakeup_send(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_data_head_init(sizeof(proto_head_t) + sizeof(wl_proto_wakeup_t), DEBUG_CT_REPLY, DEBUG_C_DEV_INFO);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
memcpy(data, &dev_info.type_m, sizeof(wl_proto_wakeup_t) - DEV_NAME_LEN);
|
|
|
memcpy(data->name, dev_config.host, DEV_NAME_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_realdata_send(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_data_head_init(sizeof(proto_head_t) + sizeof(wl_proto_realdata_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_REAL_DATA);
|
|
|
|
|
|
/* 装填数据. */
|
|
|
data->temperature = ADC_ctrl.ADCi_temp;
|
|
|
data->vbat = ADC_ctrl.ADCi_vbat;
|
|
|
data->vin = ADC_ctrl.ADCi_vin;
|
|
|
data->vsc = ADC_ctrl.ADCi_vsc;
|
|
|
data->CSQ = wl_ctrl.CSQ;
|
|
|
for(i = 0; i < CFG_ADC_CH_CNT; i++)
|
|
|
{
|
|
|
data->elec[i] = ADC_ctrl.ADC_elec[i];
|
|
|
}
|
|
|
for(i = 0; i < SENSOR_SUM; i++)
|
|
|
{
|
|
|
data->sen_temp[i] = sensor_value[i].temp;
|
|
|
data->sen_x[i] = sensor_value[i].joint_attitude_x;
|
|
|
data->sen_y[i] = sensor_value[i].joint_attitude_y;
|
|
|
data->sen_z[i] = sensor_value[i].joint_attitude_z;
|
|
|
data->sen_valid[i] = sensor_value[i].is_valid;
|
|
|
}
|
|
|
data->energy_mode = ADC_ctrl.energy_mode;
|
|
|
data->sen_short = sensor_short;
|
|
|
data->run_time = HAL_GetTick() / 1000;
|
|
|
data->fre_valid = !ADC_ctrl.up_finish && ADC_ctrl.is_ADC_thr;
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
/* 故障定位设备本次轮询离线 */
|
|
|
if (position_ctrl.offline)
|
|
|
{
|
|
|
/* 上次状态为在线,上送后台设备离线信息 */
|
|
|
if (position_ctrl.old_status == TRUE)
|
|
|
{
|
|
|
data->wave_valid = FALSE;
|
|
|
position_ctrl.old_status = FALSE;
|
|
|
}
|
|
|
/* 上次状态为离线,状态未改变 */
|
|
|
else
|
|
|
{
|
|
|
data->wave_valid = OTHER;
|
|
|
}
|
|
|
}
|
|
|
/* 故障定位设备本次轮询未离线 */
|
|
|
else
|
|
|
{
|
|
|
/* 上次状态为离线,上送后台设备上线信息 */
|
|
|
if (position_ctrl.old_status == FALSE)
|
|
|
{
|
|
|
data->wave_valid = TRUE;
|
|
|
position_ctrl.old_status = TRUE;
|
|
|
}
|
|
|
/* 上次状态为在线,状态未改变 */
|
|
|
else
|
|
|
{
|
|
|
data->wave_valid = OTHER;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
data->wave_valid = !st_data.wave_start && st_data.wave_up_start;
|
|
|
}
|
|
|
/* 有线设备不用发送工频时, 需要重新触发工频采样. 需要发送工频时, 在发送完成后设置该标志位. */
|
|
|
if (!data->fre_valid
|
|
|
&& DEV_TYPE_ACDC == dev_info.type_s)
|
|
|
{
|
|
|
ADC_ctrl.up_finish = TRUE;
|
|
|
}
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
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_power_fre_send(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_data_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_POWER_FRE);
|
|
|
|
|
|
m_head->index = wl_ctrl.mul_idx;
|
|
|
|
|
|
/* 填充数据, 计算数据长度和报文长度. */
|
|
|
data_len = ADC_COLLECT_CNT * 5 * 2 - 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, (uint8_t*)(&ADC_ctrl.ADC_value_elec[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;
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 高频采样数据获取报文发送. */
|
|
|
static void _wl_4G_wave_send(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));
|
|
|
int32_t data_len = 0;
|
|
|
uint32_t *crc = NULL;
|
|
|
uint32_t addr = 0;
|
|
|
int16_t *wave = NULL;
|
|
|
uint16_t i = 0;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_wl_4G_data_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_WAVE);
|
|
|
|
|
|
m_head->index = st_data.wave_index;
|
|
|
|
|
|
/* 填充数据, 计算数据长度和报文长度. */
|
|
|
//data_len = WAVE_ALL_DATA_LEN - m_head->index * DEBUG_DATA_SIZE;
|
|
|
data_len = WAVE_ALL_DATA_LEN - 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 = WARE_ADDRESS + m_head->index * DEBUG_DATA_SIZE;
|
|
|
if (spi_flash_read(addr, wl_flash, DEBUG_DATA_SIZE) != HAL_OK)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
wave = (int16_t*)wl_flash;
|
|
|
|
|
|
for(i = 0; i < 128; i++)
|
|
|
{
|
|
|
*data++ = *wave++;
|
|
|
*data++ = *wave++;
|
|
|
data += 2;
|
|
|
}
|
|
|
|
|
|
data = (int16_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t) + sizeof(mul_head_t));
|
|
|
for(i = 0; i < 128; i++)
|
|
|
{
|
|
|
data += 2;
|
|
|
*data++ = *wave++;
|
|
|
*data++ = *wave++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 故障定位行波波形文件获取报文发送 */
|
|
|
static HAL_StatusTypeDef _wl_4G_position_wave_send(void)
|
|
|
{
|
|
|
proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf;
|
|
|
position_head_t *p_head = (position_head_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t));
|
|
|
uint8_t *data = wl_ctrl.dma_tx_buf + sizeof(proto_head_t) + sizeof(position_head_t);
|
|
|
uint32_t *crc = NULL;
|
|
|
|
|
|
/* 封装报文头 */
|
|
|
_wl_4G_data_head_init(sizeof(proto_head_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_POSITION_WAVE);
|
|
|
|
|
|
p_head->index = wl_ctrl.wave_index;
|
|
|
p_head->file_s = position_ctrl.position_file_s;
|
|
|
p_head->file_ns = position_ctrl.position_file_ns;
|
|
|
if (HAL_OK != position_wave(data, p_head->index, &(p_head->len), p_head->file_s, p_head->file_ns))
|
|
|
{
|
|
|
position_ctrl.send_cnt++;
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
head->len = sizeof(proto_head_t) + sizeof(position_head_t) + p_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;
|
|
|
}
|
|
|
|
|
|
return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/* 升级请求报文发送. */
|
|
|
static void _wl_4G_update_send(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));
|
|
|
uint32_t *crc = NULL;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_wl_4G_data_head_init(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_UPDATE_APP);
|
|
|
|
|
|
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 + 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;
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 升级请求报文发送. */
|
|
|
static void _wl_4G_update_rt_send(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_data_head_init(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_UPDATE_APP_RT);
|
|
|
|
|
|
head->len = sizeof(proto_head_t) + sizeof(int32_t);
|
|
|
*rt = wl_ctrl.update_rt;
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 高频录波最大值数据发送. */
|
|
|
static void _wl_4G_wave_max_send(void)
|
|
|
{
|
|
|
proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf;
|
|
|
wl_proto_wave_max_t *data = (wl_proto_wave_max_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t));
|
|
|
uint32_t *crc = NULL;
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_wl_4G_data_head_init(sizeof(proto_head_t) + sizeof(wl_proto_wave_max_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_WAVE_MAX);
|
|
|
|
|
|
/* 装填数据. */
|
|
|
for(i = 0; i < WAVE_SUM; i ++)
|
|
|
{
|
|
|
data->wave[i] = st_data.wave_max[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_position_send(void)
|
|
|
{
|
|
|
proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf;
|
|
|
position_wave_info_t *wave_info = (position_wave_info_t*)(wl_ctrl.dma_tx_buf + sizeof(proto_head_t));
|
|
|
uint32_t *crc = NULL;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_wl_4G_data_head_init(sizeof(proto_head_t) + sizeof(position_wave_info_t), DEBUG_CT_PRV_REPLY, DEBUG_PRV_POSITION);
|
|
|
|
|
|
/* 装填数据. */
|
|
|
if (position_read(st_data.position_up_id, &position_up_data) != HAL_OK)
|
|
|
{
|
|
|
if (st_data.position_up_id > position_id)
|
|
|
{
|
|
|
st_data.position_up_id = position_id;
|
|
|
}
|
|
|
wl_ctrl.state = WL_STATE_POSITION_WAVE;
|
|
|
return;
|
|
|
}
|
|
|
memcpy(wave_info, &(position_up_data.wave_info), sizeof(position_wave_info_t));
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
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_wave_keepalive_send(void)
|
|
|
{
|
|
|
proto_head_t *head = (proto_head_t*)wl_ctrl.dma_tx_buf;
|
|
|
uint32_t *crc = NULL;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_wl_4G_data_head_init(sizeof(proto_head_t), DEBUG_CT_REPLY, DEBUG_C_KEEPALIVE);
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
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_data_send(void)
|
|
|
{
|
|
|
uint8_t is_timeout = wl_ctrl.time_send < HAL_GetTick();
|
|
|
|
|
|
/* 循环内只发送一次报文, 没有报文发送的情况下要跳出循环. */
|
|
|
while(is_timeout)
|
|
|
{
|
|
|
if (WL_STATE_WAKEUP == wl_ctrl.state)
|
|
|
{
|
|
|
/* 设备唤醒, 发送配置和数据请求. */
|
|
|
_wl_4G_wakeup_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else if (WL_STATE_REALDATA == wl_ctrl.state)
|
|
|
{
|
|
|
/* 实时数据报文. */
|
|
|
_wl_4G_realdata_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else if (WL_STATE_PWR_FRE == wl_ctrl.state)
|
|
|
{
|
|
|
/* 工频录波报文. */
|
|
|
if (!ADC_ctrl.up_finish && ADC_ctrl.is_ADC_thr)
|
|
|
{
|
|
|
_wl_4G_power_fre_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ADC_ctrl.up_finish = TRUE;
|
|
|
ADC_ctrl.is_ADC_thr = FALSE;
|
|
|
wl_ctrl.state = WL_STATE_UPDATE;
|
|
|
wl_ctrl.mul_idx = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
}
|
|
|
else if (WL_STATE_UPDATE == wl_ctrl.state)
|
|
|
{
|
|
|
if (wl_ctrl.is_update)
|
|
|
{
|
|
|
_wl_4G_update_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE;
|
|
|
}
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
}
|
|
|
else if (WL_STATE_UPDATE_RT == wl_ctrl.state)
|
|
|
{
|
|
|
if (wl_ctrl.is_update)
|
|
|
{
|
|
|
_wl_4G_update_rt_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE;
|
|
|
}
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
}
|
|
|
else if (WL_STATE_WAVE == wl_ctrl.state)
|
|
|
{
|
|
|
/* 高频录波报文. */
|
|
|
if (!st_data.wave_start && st_data.wave_up_start && ADC_ENERGY_NORMAL == ADC_ctrl.energy_mode)
|
|
|
{
|
|
|
_wl_4G_wave_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE_MAX;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
}
|
|
|
else if (WL_STATE_WAVE_MAX == wl_ctrl.state)
|
|
|
{
|
|
|
/* 高频最大值报文. */
|
|
|
if ((st_data.wave_max[0] || st_data.wave_max[1] || st_data.wave_max[2] || st_data.wave_max[3])
|
|
|
&& (ADC_ENERGY_NORMAL == ADC_ctrl.energy_mode))
|
|
|
{
|
|
|
_wl_4G_wave_max_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_END;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
else if (WL_STATE_POSITION == wl_ctrl.state)
|
|
|
{
|
|
|
if (st_data.position_up_id < position_id)
|
|
|
{
|
|
|
_wl_4G_position_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION_WAVE;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
}
|
|
|
else if (WL_STATE_POSITION_WAVE == wl_ctrl.state)
|
|
|
{
|
|
|
if (position_ctrl.position_wave_up)
|
|
|
{
|
|
|
if (HAL_OK == _wl_4G_position_wave_send())
|
|
|
{
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_END;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
if (WL_STATE_KEEPALIVE == wl_ctrl.state)
|
|
|
{
|
|
|
/* 设备保活报文发送. */
|
|
|
_wl_4G_wave_keepalive_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 无线模块主任务循环. */
|
|
|
static void _wl_4G_start(void *argument)
|
|
|
{
|
|
|
uint32_t notify_value = 0;
|
|
|
|
|
|
/* 等待完成 1 次 ADC 采样. */
|
|
|
while(1)
|
|
|
{
|
|
|
if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_ADC))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
osDelay(1000);
|
|
|
}
|
|
|
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s)
|
|
|
{
|
|
|
/* 完成 1 次 故障定位轮询 */
|
|
|
position_start();
|
|
|
}
|
|
|
|
|
|
/* 开启串口空闲中断收包. */
|
|
|
HAL_UARTEx_ReceiveToIdle_DMA(wl_uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN);
|
|
|
|
|
|
/* 初始化 4G 模块硬件. */
|
|
|
_wl_4G_hw_init();
|
|
|
|
|
|
/* 20s 内要收到 4G 模块发出的 RDY. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 20000;
|
|
|
wl_ctrl.wave_index = st_data.wave_index;
|
|
|
|
|
|
for (;;)
|
|
|
{
|
|
|
/* AT 指令发送失败, 直接退出. */
|
|
|
if (wl_ctrl.send_cnt > WL_SOFT_INIT_ERR && wl_ctrl.state < WL_STATE_WAKEUP)
|
|
|
{
|
|
|
//flash_log_write(FLASH_LOG_TYPE_INFO, "4G module is ERROR system sleep %ds!\r\n", dev_config.collect_interval * 60);
|
|
|
//_wl_4G_hw_close(dev_config.collect_interval * 60);
|
|
|
_wl_4G_hw_restart();
|
|
|
}
|
|
|
|
|
|
/* 数据发送失败, 重启 4G 模块 1 次. */
|
|
|
if (wl_ctrl.send_cnt > WL_DATA_ERR && wl_ctrl.state >= WL_STATE_WAKEUP)
|
|
|
{
|
|
|
_wl_4G_hw_restart();
|
|
|
}
|
|
|
|
|
|
if (wl_ctrl.state < WL_STATE_WAKEUP)
|
|
|
{
|
|
|
/* 进入软件初始化. */
|
|
|
_wl_4G_init_soft();
|
|
|
}
|
|
|
else if (wl_ctrl.state != WL_STATE_END)
|
|
|
{
|
|
|
/* 进入数据交互模式. */
|
|
|
_wl_4G_data_send();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 仅在4G通讯闲暇时轮询故障定位 */
|
|
|
if (DEV_TYPE_CT_P == dev_info.type_s && !wl_ctrl.send_cnt)
|
|
|
{
|
|
|
if (HAL_OK != position_start())
|
|
|
{
|
|
|
/* 将设备离线信息上送后台 */
|
|
|
if (position_ctrl.err_cnt == POSITION_ERR_MAX)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
else if (position_ctrl.err_cnt > POSITION_ERR_MAX)
|
|
|
{
|
|
|
/* 通过 4G 模块重启设备 */
|
|
|
flash_log_write(FLASH_LOG_TYPE_WARNING, "Position is disconnect system reset!\r\n");
|
|
|
_wl_4G_hw_close(0);
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/* 当状态为 WL_STATE_END 时, 先判断节能模式. */
|
|
|
if (ADC_ctrl.energy_mode != ADC_ENERGY_NORMAL
|
|
|
|| (dev_config.normal_sleep && DEV_TYPE_CT_P != dev_info.type_s)
|
|
|
|| DEV_TYPE_BAT == dev_info.type_s)
|
|
|
{
|
|
|
if (ADC_ctrl.energy_mode != wl_ctrl.energy_mode_old)
|
|
|
{
|
|
|
/* 模式发生转换并不立即休眠, 将状态发送给服务器后再休眠. */
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
else if(ADC_ENERGY_NORMAL == ADC_ctrl.energy_mode
|
|
|
&& DEV_TYPE_BAT == dev_info.type_s
|
|
|
&& st_data.wave_start
|
|
|
&& dev_config.is_wave_col != 0
|
|
|
&& ADC_ctrl.ADCi_vbat >= 3600)
|
|
|
{
|
|
|
/* 电池正常是模式下, 如果有高频采样, 等高频采样完成进行据发送, 不要休眠. */
|
|
|
while(wave_ctrl.state.state != WAVE_STATE_COMPLETION)
|
|
|
{
|
|
|
osDelay(3000);
|
|
|
}
|
|
|
|
|
|
if (wave_ctrl.rt != WAVE_RT_END)
|
|
|
{
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "System sleep %ds!\r\n", dev_config.collect_interval * 60 - 30);
|
|
|
_wl_4G_hw_close(dev_config.collect_interval * 60 - 30);
|
|
|
}
|
|
|
|
|
|
if (!st_data.wave_start && st_data.wave_up_start)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "System sleep %ds!\r\n", dev_config.collect_interval * 60 - 30);
|
|
|
_wl_4G_hw_close(dev_config.collect_interval * 60 - 30);
|
|
|
}
|
|
|
}
|
|
|
else if (!ADC_ctrl.up_finish)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAKEUP;
|
|
|
}
|
|
|
else if(!st_data.wave_start && st_data.wave_up_start)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_WAVE;
|
|
|
}
|
|
|
else if(st_data.position_up_id < position_id)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION;
|
|
|
}
|
|
|
else if(position_ctrl.position_wave_up)
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_POSITION_WAVE;
|
|
|
}
|
|
|
else if(wl_ctrl.keepalive < HAL_GetTick())
|
|
|
{
|
|
|
wl_ctrl.state = WL_STATE_KEEPALIVE;
|
|
|
/* 每次发送数据更新保活时间. */
|
|
|
wl_ctrl.keepalive = HAL_GetTick() + 60000;
|
|
|
}
|
|
|
|
|
|
/* 更新工作模式. */
|
|
|
wl_ctrl.energy_mode_old = ADC_ctrl.energy_mode;
|
|
|
}
|
|
|
|
|
|
/* 喂狗. */
|
|
|
common_watchdog_set(COM_WDG_WIR);
|
|
|
|
|
|
/* 等待 DMA 收包中断. */
|
|
|
notify_value = ulTaskNotifyTake(pdTRUE, WL_RX_TIMEOUT);
|
|
|
/* 收包超时, 返回循环头部. */
|
|
|
if (0 == notify_value)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* 收包处理. */
|
|
|
_wl_4G_receive();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 有线数据处理. */
|
|
|
static void _wir_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)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (DEBUG_CT_REQUEST == head->cmd_type)
|
|
|
{
|
|
|
/* 共有命令处理. */
|
|
|
switch (head->cmd)
|
|
|
{
|
|
|
case DEBUG_C_DEV_INFO:
|
|
|
_wl_4G_dev_info_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_C_UPDATE_APP:
|
|
|
_wl_4G_update_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_C_UPDATE_APP_RT:
|
|
|
_wl_4G_update_rt_reply();
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else if (DEBUG_CT_PRV_REQUEST == head->cmd_type)
|
|
|
{
|
|
|
/* 私有命令处理. */
|
|
|
switch (head->cmd)
|
|
|
{
|
|
|
case DEBUG_PRV_REAL_DATA:
|
|
|
_wl_4G_pkt_reply();
|
|
|
break;
|
|
|
case DEBUG_PRV_POWER_FRE:
|
|
|
_wl_4G_power_fre_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_PRV_WAVE:
|
|
|
_wl_4G_wave_reply(cmd, len);
|
|
|
break;
|
|
|
case DEBUG_PRV_WAVE_MAX:
|
|
|
_wl_4G_wave_max_reply(cmd, len);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 有线模式主任务循环. */
|
|
|
static void _wir_start(void *argument)
|
|
|
{
|
|
|
uint32_t notify_value = 0;
|
|
|
|
|
|
/* RS485 供电打开. */
|
|
|
HAL_GPIO_WritePin(POWER_EN_4G_GPIO_Port, POWER_EN_4G_Pin, GPIO_PIN_SET);
|
|
|
|
|
|
/* 开启串口空闲中断收包. */
|
|
|
HAL_UARTEx_ReceiveToIdle_DMA(wl_uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN);
|
|
|
|
|
|
for (;;)
|
|
|
{
|
|
|
/* 喂狗. */
|
|
|
common_watchdog_set(COM_WDG_WIR);
|
|
|
|
|
|
/* 等待 DMA 收包中断. */
|
|
|
notify_value = ulTaskNotifyTake(pdTRUE, WIR_RX_TIMEOUT);
|
|
|
/* 收包超时, 返回循环头部. */
|
|
|
if (0 == notify_value)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* 收包处理. */
|
|
|
_wl_4G_data_recv();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 4G 模块发送数据. */
|
|
|
static HAL_StatusTypeDef _csg_transmit(uint8_t *data, uint16_t len)
|
|
|
{
|
|
|
HAL_StatusTypeDef rv = HAL_ERROR;
|
|
|
|
|
|
if (wl_ctrl.state < WL_STATE_WAKEUP)
|
|
|
{
|
|
|
DBG(DBG_M_4G, "Send: %s\r\n", data);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)data;
|
|
|
DBG(DBG_M_4G, "Send(%d): 0x%x\r\n", len, head->cmd);
|
|
|
if (dbg_stat_get(DBG_M_4G))
|
|
|
{
|
|
|
buf_print(data, len > 32 ? 32 : len);
|
|
|
//buf_print(data, len);
|
|
|
vty_print("\r\n");
|
|
|
}
|
|
|
/* 每次发送数据更新保活时间. */
|
|
|
wl_ctrl.keepalive = HAL_GetTick() + 60000;
|
|
|
}
|
|
|
|
|
|
rv = HAL_UART_Transmit_DMA(wl_uart, data, len);
|
|
|
|
|
|
return rv;
|
|
|
}
|
|
|
|
|
|
static uint8_t _csg_crc(uint8_t *data, uint16_t len)
|
|
|
{
|
|
|
uint8_t crc = 0x00;
|
|
|
uint32_t sum = 0x0000;
|
|
|
uint16_t i = 0;
|
|
|
|
|
|
for(i = 0; i < len; i++)
|
|
|
{
|
|
|
sum += data[i];
|
|
|
}
|
|
|
|
|
|
crc = ~(uint8_t)(sum);
|
|
|
return crc;
|
|
|
}
|
|
|
|
|
|
/* 初始化报文头. */
|
|
|
static void _csg_data_head_init(uint16_t len, uint8_t cmd)
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)wl_ctrl.dma_tx_buf;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
head->flag = CSG_START_FLAG;
|
|
|
memcpy(head->dev_id, dev_info.csg_id, 6);
|
|
|
head->cmd = cmd;
|
|
|
head->len = PP_HTONS(len);
|
|
|
}
|
|
|
|
|
|
/* 错误回复报文. */
|
|
|
static void _csg_error_send(uint8_t cmd, uint16_t rt)
|
|
|
{
|
|
|
uint16_t *data = (uint16_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_ERROR_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_ERROR_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_ERROR_LEN, cmd);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
*data = PP_HTONS(rt);
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_ERROR_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
_csg_transmit(wl_ctrl.dma_tx_buf, CSG_ERROR_LEN + CSG_OTHER_LEN);
|
|
|
}
|
|
|
|
|
|
/* 开机联络报文. */
|
|
|
static void _csg_connect_send(uint8_t is_request)
|
|
|
{
|
|
|
uint16_t *data = (uint16_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_CONNECT_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_CONNECT_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_CONNECT_LEN, CSG_CONNECT);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
*data = PP_HTONS(dev_info.csg_version);
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_CONNECT_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
if (is_request)
|
|
|
{
|
|
|
_csg_transmit(wl_ctrl.dma_tx_buf, CSG_CONNECT_LEN + CSG_OTHER_LEN);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (HAL_OK == _csg_transmit(wl_ctrl.dma_tx_buf, CSG_CONNECT_LEN + CSG_OTHER_LEN))
|
|
|
{
|
|
|
/* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 5500;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送失败, 等待 1s 重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 1100;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 对时报文. */
|
|
|
static void _csg_time_send(void)
|
|
|
{
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_TIMING_LEN, CSG_TIMING);
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
if (HAL_OK == _csg_transmit(wl_ctrl.dma_tx_buf, CSG_OTHER_LEN))
|
|
|
{
|
|
|
/* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 5500;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送失败, 等待 1s 重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 1100;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 实时数据报文. */
|
|
|
static void _csg_data_send_his(void)
|
|
|
{
|
|
|
struct tm *day = NULL;
|
|
|
csg_data_t *data = (csg_data_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_DATA_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_DATA_LEN + CSG_CRC_LEN);
|
|
|
uint8_t i = 0;
|
|
|
uint16_t temp = 0;
|
|
|
uint32_t time = 0;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_DATA_LEN, CSG_DATA);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
memcpy(data->Ciphertext, dev_config.csg_ciphertext, CSG_CIPHERTEXT_LEN);
|
|
|
|
|
|
data->flag = 0;
|
|
|
data->sum = 0;
|
|
|
|
|
|
csg_adc_data.id = fd_id;
|
|
|
for(i = 0; i < CSG_PKT_DATA_SUM; i++)
|
|
|
{
|
|
|
if (fd_read(csg_adc_data.id, &csg_adc_data) != HAL_OK)
|
|
|
break;
|
|
|
|
|
|
/* 读到全F,表示结束了. */
|
|
|
if (FD_INVALID_ID == csg_adc_data.id)
|
|
|
break;
|
|
|
|
|
|
/* 只要历史数据. */
|
|
|
if (!csg_adc_data.is_not_updata)
|
|
|
{
|
|
|
csg_adc_data.id--;
|
|
|
if (0 == csg_adc_data.id)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
csg_data_idx[data->sum] = csg_adc_data.id;
|
|
|
data->sum++;
|
|
|
csg_data_idx[data->sum] = 0;
|
|
|
vty_print("%d %d\r\n", data->sum, csg_adc_data.id);
|
|
|
vty_print("%d/%d/%d %d:%d:%d\r\n", data->time[0], data->time[1], data->time[2], data->time[3], data->time[4], data->time[5]);
|
|
|
|
|
|
time = csg_adc_data.run_time + 28800;
|
|
|
day = localtime(&time);
|
|
|
data->time[0] = day->tm_year - 100;
|
|
|
data->time[1] = day->tm_mon + 1;
|
|
|
data->time[2] = day->tm_mday;
|
|
|
data->time[3] = day->tm_hour;
|
|
|
data->time[4] = day->tm_min;
|
|
|
data->time[5] = day->tm_sec;
|
|
|
|
|
|
temp = csg_adc_data.elec[0] / 100;
|
|
|
data->Ia = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[1] / 100;
|
|
|
data->Ib = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[2] / 100;
|
|
|
data->Ic = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[3] / 100;
|
|
|
data->ground = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[4] / 100;
|
|
|
data->rIa = PP_HTONS(temp);
|
|
|
data->rIb = 0;
|
|
|
data->rIc = 0;
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if (0 == data->sum)
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_IDLE;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_DATA_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
if (HAL_OK == _csg_transmit(wl_ctrl.dma_tx_buf, CSG_DATA_LEN + CSG_OTHER_LEN))
|
|
|
{
|
|
|
/* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 5500;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送失败, 等待 1s 重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 1100;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 实时数据上传. */
|
|
|
static void _csg_data_send_realtime(void)
|
|
|
{
|
|
|
struct tm *day = NULL;
|
|
|
csg_data_t *data = (csg_data_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_DATA_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_DATA_LEN + CSG_CRC_LEN);
|
|
|
uint16_t temp = 0;
|
|
|
uint32_t time = 0;
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_DATA_LEN, CSG_DATA);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
memcpy(data->Ciphertext, dev_config.csg_ciphertext, CSG_CIPHERTEXT_LEN);
|
|
|
data->flag = 0x00;
|
|
|
data->sum = 0x01;
|
|
|
|
|
|
fd_read(fd_id, &csg_adc_data);
|
|
|
csg_data_idx[0] = fd_id;
|
|
|
csg_data_idx[1] = 0;
|
|
|
time = csg_adc_data.run_time + 28800;
|
|
|
day = localtime(&time);
|
|
|
data->time[0] = day->tm_year - 100;
|
|
|
data->time[1] = day->tm_mon + 1;
|
|
|
data->time[2] = day->tm_mday;
|
|
|
data->time[3] = day->tm_hour;
|
|
|
data->time[4] = day->tm_min;
|
|
|
data->time[5] = day->tm_sec;
|
|
|
|
|
|
vty_print("%d/%d/%d %d:%d:%d\r\n", data->time[0], data->time[1], data->time[2], data->time[3], data->time[4], data->time[5]);
|
|
|
|
|
|
temp = csg_adc_data.elec[0] / 100;
|
|
|
data->Ia = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[1] / 100;
|
|
|
data->Ib = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[2] / 100;
|
|
|
data->Ic = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[3] / 100;
|
|
|
data->ground = PP_HTONS(temp);
|
|
|
temp = csg_adc_data.elec[4] / 100;
|
|
|
data->rIa = PP_HTONS(temp);
|
|
|
data->rIb = 0;
|
|
|
data->rIc = 0;
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_DATA_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
if (HAL_OK == _csg_transmit(wl_ctrl.dma_tx_buf, CSG_DATA_LEN + CSG_OTHER_LEN))
|
|
|
{
|
|
|
/* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 5500;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送失败, 等待 1s 重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 1100;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 心跳报文. */
|
|
|
static void _csg_beat_send(void)
|
|
|
{
|
|
|
csg_beat_t *data = (csg_beat_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_BEAT_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_BEAT_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_BEAT_LEN, CSG_BEAT);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
HAL_RTC_GetTime(&hrtc, &time_structure, RTC_FORMAT_BIN);
|
|
|
HAL_RTC_GetDate(&hrtc, &date_structure, RTC_FORMAT_BIN);
|
|
|
data->time[0] = date_structure.Year;
|
|
|
data->time[1] = date_structure.Month;
|
|
|
data->time[2] = date_structure.Date;
|
|
|
data->time[3] = time_structure.Hours;
|
|
|
data->time[4] = time_structure.Minutes;
|
|
|
data->time[5] = time_structure.Seconds;
|
|
|
data->CSQ = (wl_ctrl.CSQ + 115) * 100 / 64;
|
|
|
data->vbat = ADC_ctrl.ADCi_vbat / 100;
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_BEAT_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
if (HAL_OK == _csg_transmit(wl_ctrl.dma_tx_buf, CSG_BEAT_LEN + CSG_OTHER_LEN))
|
|
|
{
|
|
|
/* 发送成功, 如果指定时间内没有收到回复, 则根据 timeout 时间重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 5500;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送失败, 等待 1s 重发. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 1100;
|
|
|
}
|
|
|
wl_ctrl.time_beat = HAL_GetTick();
|
|
|
}
|
|
|
|
|
|
/* 服务器信息报文发送. */
|
|
|
static void _csg_server_send(void)
|
|
|
{
|
|
|
csg_server_get_t *data = (csg_server_get_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_SERVER_GET_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_SERVER_GET_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_SERVER_GET_LEN, CSG_SERVER_GET);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
memcpy(data->ip, dev_info.wireless_server_ip, 4);
|
|
|
data->port = PP_HTONS(dev_info.wireless_server_port);
|
|
|
memcpy(data->card, dev_info.csg_card, 6);
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_SERVER_GET_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
_csg_transmit(wl_ctrl.dma_tx_buf, CSG_SERVER_GET_LEN + CSG_OTHER_LEN);
|
|
|
}
|
|
|
|
|
|
/* 配饰获取报文发送. */
|
|
|
static void _csg_config_send(void)
|
|
|
{
|
|
|
uint8_t *data = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_CONFIG_GET_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_CONFIG_GET_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_CONFIG_GET_LEN, CSG_CONFIG_GET);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
/* 心跳间隔. */
|
|
|
*data = dev_config.csg_beat_interval;
|
|
|
data += 1;
|
|
|
/* 采集间隔. */
|
|
|
|
|
|
*(uint16_t*)data = PP_HTONS(dev_config.collect_interval);
|
|
|
data += 2;
|
|
|
|
|
|
/* 休眠时间. */
|
|
|
*(uint16_t*)data = PP_HTONS(dev_config.csg_sleep);
|
|
|
data += 2;
|
|
|
|
|
|
/* 在线时间. */
|
|
|
*(uint16_t*)data = PP_HTONS(HAL_GetTick() / 1000 / 60);
|
|
|
data += 2;
|
|
|
|
|
|
/* 重启时间. */
|
|
|
memcpy(data, dev_config.csg_reset_time, 3);
|
|
|
data += 3;
|
|
|
|
|
|
memset(data, 0, 10);
|
|
|
data += 10;
|
|
|
|
|
|
*data = 0x44;
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_CONFIG_GET_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
_csg_transmit(wl_ctrl.dma_tx_buf, CSG_CONFIG_GET_LEN + CSG_OTHER_LEN);
|
|
|
}
|
|
|
|
|
|
/* 时间获取报文. */
|
|
|
static void _csg_time_get_send(void)
|
|
|
{
|
|
|
uint8_t *data = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN);
|
|
|
uint8_t *crc = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_TIME_GET_LEN);
|
|
|
uint8_t *end_flag = (uint8_t*)(wl_ctrl.dma_tx_buf + CSG_HEAD_LEN + CSG_TIME_GET_LEN + CSG_CRC_LEN);
|
|
|
|
|
|
/* 封装报文头. */
|
|
|
_csg_data_head_init(CSG_TIME_GET_LEN, CSG_TIME_GET);
|
|
|
|
|
|
/* 封装数据. */
|
|
|
HAL_RTC_GetTime(&hrtc, &time_structure, RTC_FORMAT_BIN);
|
|
|
HAL_RTC_GetDate(&hrtc, &date_structure, RTC_FORMAT_BIN);
|
|
|
data[0] = date_structure.Year;
|
|
|
data[1] = date_structure.Month;
|
|
|
data[2] = date_structure.Date;
|
|
|
data[3] = time_structure.Hours;
|
|
|
data[4] = time_structure.Minutes;
|
|
|
data[5] = time_structure.Seconds;
|
|
|
|
|
|
/* 计算校验和. */
|
|
|
*crc = _csg_crc(wl_ctrl.dma_tx_buf + 1, CSG_TIME_GET_LEN + CSG_HEAD_LEN - 1);
|
|
|
*end_flag = CSG_END_FLAG;
|
|
|
|
|
|
/* 发送报文 */
|
|
|
_csg_transmit(wl_ctrl.dma_tx_buf, CSG_TIME_GET_LEN + CSG_OTHER_LEN);
|
|
|
}
|
|
|
|
|
|
/* 状态机改变 */
|
|
|
void _csg_state_change(void)
|
|
|
{
|
|
|
if (wl_ctrl.state != CSG_STATE_IDLE)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (wl_ctrl.data_request)
|
|
|
{
|
|
|
if (CSG_DATA_TYPE_HIS == wl_ctrl.data_request)
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_DATA_HIS;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ADC_restart_force();
|
|
|
}
|
|
|
|
|
|
wl_ctrl.data_request = CSG_DATA_TYPE_NONE;
|
|
|
}
|
|
|
else if ((HAL_GetTick() - wl_ctrl.time_beat) > (dev_config.csg_beat_interval * 60000))
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_BEAT;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
}
|
|
|
else if (!ADC_ctrl.up_finish)
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_DATA;
|
|
|
ADC_ctrl.up_finish = TRUE;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 数据发送. */
|
|
|
void _csg_pkt_send(void)
|
|
|
{
|
|
|
uint8_t is_timeout = wl_ctrl.time_send < HAL_GetTick();
|
|
|
|
|
|
_csg_state_change();
|
|
|
|
|
|
if ((CSG_STATE_CONNECT == wl_ctrl.state) && is_timeout)
|
|
|
{
|
|
|
/* 开机联络. */
|
|
|
_csg_connect_send(FALSE);
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else if ((CSG_STATE_TIME == wl_ctrl.state) && is_timeout)
|
|
|
{
|
|
|
/* 设备对时. */
|
|
|
_csg_time_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else if ((CSG_STATE_BEAT == wl_ctrl.state) && is_timeout)
|
|
|
{
|
|
|
/* 心跳. */
|
|
|
_csg_beat_send();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else if ((CSG_STATE_DATA == wl_ctrl.state) && is_timeout)
|
|
|
{
|
|
|
/* 实时数据. */
|
|
|
_csg_data_send_realtime();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else if ((CSG_STATE_DATA_HIS == wl_ctrl.state) && is_timeout)
|
|
|
{
|
|
|
/* 历史数据. */
|
|
|
_csg_data_send_his();
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static int32_t _csg_pkt_check(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)cmd;
|
|
|
|
|
|
/* 设备进入复位状态后不再处理报文. */
|
|
|
if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_RESET))
|
|
|
{
|
|
|
vty_print("@0\r\n");
|
|
|
/* 这里挂住线程是因为重启时如果有收包, 会导致收包出错, 从而让设备进入休眠状态. */
|
|
|
osDelay(portMAX_DELAY);
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
if (len < CSG_OTHER_LEN
|
|
|
|| (CSG_OTHER_LEN + PP_HTONS(head->len) != len))
|
|
|
{
|
|
|
vty_print("@1\r\n");
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
if (head->flag != CSG_START_FLAG || cmd[len - 1] != CSG_END_FLAG)
|
|
|
{
|
|
|
vty_print("@2\r\n");
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
/* 对主次设备号进行识别, 次设备号可以是广播. */
|
|
|
if (strncmp((char*)head->dev_id, (char*)dev_info.csg_id, 6))
|
|
|
{
|
|
|
vty_print("@3\r\n");
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
/* 验证 CRC32. */
|
|
|
if (_csg_crc(cmd + 1, PP_HTONS(head->len) + CSG_HEAD_LEN - 1) != cmd[len - 2])
|
|
|
{
|
|
|
vty_print("@4: %x %x\r\n", _csg_crc(cmd + 1, PP_HTONS(head->len) + CSG_HEAD_LEN - 1), cmd[len - 2]);
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/* 开机联络回复. */
|
|
|
static void _csg_connect_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)cmd;
|
|
|
|
|
|
if (PP_HTONS(head->len) == 0)
|
|
|
{
|
|
|
_csg_connect_send(TRUE);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_TIME;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 对时回复. */
|
|
|
static void _csg_time_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_time_t *data = (csg_time_t*)(cmd + CSG_HEAD_LEN);
|
|
|
time_t temp = 0;
|
|
|
|
|
|
/* 更新 RTC 时间. */
|
|
|
tm_structure.tm_year = data->year + 100;
|
|
|
tm_structure.tm_mon = data->mon - 1;
|
|
|
tm_structure.tm_mday = data->day;
|
|
|
tm_structure.tm_hour = data->hour;
|
|
|
tm_structure.tm_min = data->min;
|
|
|
tm_structure.tm_sec = data->sec;
|
|
|
temp = mktime(&tm_structure);
|
|
|
rtc_time_set(temp - 28800);
|
|
|
|
|
|
if (CSG_STATE_TIME == wl_ctrl.state)
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_BEAT;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送回复报文. */
|
|
|
_csg_transmit(cmd, len);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 对时回复. */
|
|
|
static void _csg_passwd_set_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_passwd_t *data = (csg_passwd_t*)(cmd + CSG_HEAD_LEN);
|
|
|
|
|
|
if (0 == memcmp(data->passwd_old, dev_config.csg_passwd, CSG_PASSWD_LEN))
|
|
|
{
|
|
|
memcpy(dev_config.csg_passwd, data->passwd_new, CSG_PASSWD_LEN);
|
|
|
dev_config.csg_passwd[CSG_PASSWD_LEN] = 0;
|
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
|
/* 发送回复报文. */
|
|
|
_csg_transmit(cmd, len);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_csg_error_send(CSG_PASSWD_SET, 0xffff);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 配置设置回复. */
|
|
|
static void _csg_config_set_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
uint8_t *data = (uint8_t*)(cmd + CSG_HEAD_LEN);
|
|
|
|
|
|
if (0 == memcmp(data, dev_config.csg_passwd, CSG_PASSWD_LEN))
|
|
|
{
|
|
|
/* 心跳间隔. */
|
|
|
data += 4;
|
|
|
dev_config.csg_beat_interval = *data;
|
|
|
|
|
|
/* 采集间隔. */
|
|
|
data += 1;
|
|
|
dev_config.collect_interval = *(uint16_t*)data;
|
|
|
dev_config.collect_interval = PP_HTONS(dev_config.collect_interval);
|
|
|
|
|
|
/* 休眠时间. */
|
|
|
data += 2;
|
|
|
dev_config.csg_sleep = *(uint16_t*)data;
|
|
|
dev_config.csg_sleep = PP_HTONS(dev_config.csg_sleep);
|
|
|
|
|
|
/* 在线时间. */
|
|
|
data += 2;
|
|
|
dev_config.csg_online = *(uint16_t*)data;
|
|
|
dev_config.csg_online = PP_HTONS(dev_config.csg_online);
|
|
|
|
|
|
/* 重启时间. */
|
|
|
data += 2;
|
|
|
memcpy(dev_config.csg_reset_time, data, 3);
|
|
|
|
|
|
/* 验证密文. */
|
|
|
data += 3;
|
|
|
memcpy(dev_config.csg_ciphertext, data, 4);
|
|
|
|
|
|
common_sys_set(COM_SYS_SAVE_CONFIG, 0);
|
|
|
/* 发送回复报文. */
|
|
|
_csg_transmit(cmd, len);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_csg_error_send(CSG_CONFIG_SET, 0xffff);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 心跳回复处理. */
|
|
|
static void _csg_beat_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_IDLE;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
}
|
|
|
|
|
|
/* 服务器设置回复. */
|
|
|
static void _csg_server_set_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_server_t *data = (csg_server_t*)(cmd + CSG_HEAD_LEN);
|
|
|
|
|
|
if (0 == memcmp(data->passwd, dev_config.csg_passwd, CSG_PASSWD_LEN))
|
|
|
{
|
|
|
if (0 == memcmp(data->ip1, data->ip2, CSG_PASSWD_LEN)
|
|
|
&& 0 == memcmp(data->card1, data->card2, 6)
|
|
|
&& data->port1 == data->port2)
|
|
|
{
|
|
|
memcpy(dev_info.wireless_server_ip, data->ip1, 4);
|
|
|
dev_info.wireless_server_port = PP_HTONS(data->port1);
|
|
|
memcpy(dev_info.csg_card, data->card1, 6);
|
|
|
|
|
|
common_sys_set(COM_SYS_SAVE_INFO, 0);
|
|
|
/* 发送回复报文. */
|
|
|
_csg_transmit(cmd, len);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_csg_error_send(CSG_SERVER_SET, 0);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_csg_error_send(CSG_SERVER_SET, 0xffff);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 服务器设置回复. */
|
|
|
static void _csg_server_get_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
_csg_server_send();
|
|
|
}
|
|
|
|
|
|
/* 设备重启回复. */
|
|
|
static void _csg_reset_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
uint8_t *data = (uint8_t*)(cmd + CSG_HEAD_LEN);
|
|
|
uint32_t reset_delay = 2;
|
|
|
|
|
|
if (0 == memcmp(data, dev_config.csg_passwd, CSG_PASSWD_LEN))
|
|
|
{
|
|
|
/* 发送回复报文. */
|
|
|
_csg_transmit(cmd, len);
|
|
|
|
|
|
flash_log_write(FLASH_LOG_TYPE_INFO, "CSG system reset!\r\n");
|
|
|
common_sys_set(COM_SYS_RESET, (void*)&reset_delay);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_csg_error_send(CSG_RESET, 0xffff);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 服务器设置回复. */
|
|
|
static void _csg_config_get_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
_csg_config_send();
|
|
|
}
|
|
|
|
|
|
/* 服务器设置回复. */
|
|
|
static void _csg_time_get_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
_csg_time_get_send();
|
|
|
}
|
|
|
|
|
|
/* 数据回复处理. */
|
|
|
static void _csg_data_get_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)cmd;
|
|
|
|
|
|
if (PP_HTONS(head->len) == 0)
|
|
|
{
|
|
|
/* 请求历史数据. */
|
|
|
wl_ctrl.data_request = CSG_DATA_TYPE_HIS;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 请求实时数据. */
|
|
|
wl_ctrl.data_request = CSG_DATA_TYPE_REAL;
|
|
|
}
|
|
|
|
|
|
_csg_transmit(cmd, len);
|
|
|
}
|
|
|
|
|
|
static void _csg_data_reply_id_updata(void)
|
|
|
{
|
|
|
uint8_t i = 0;
|
|
|
|
|
|
for(i = 0; i < CSG_PKT_DATA_SUM; i++)
|
|
|
{
|
|
|
if (0 == csg_data_idx[i])
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
fd_read(csg_data_idx[i], &csg_adc_data);
|
|
|
csg_adc_data.is_not_updata = FALSE;
|
|
|
fd_modify(csg_data_idx[i], &csg_adc_data);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 数据回复处理. */
|
|
|
static void _csg_data_reply(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)cmd;
|
|
|
|
|
|
if (PP_HTONS(head->len) == 0)
|
|
|
{
|
|
|
_csg_transmit(cmd, len);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wl_ctrl.state = CSG_STATE_IDLE;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
|
|
|
_csg_data_reply_id_updata();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 有线数据处理. */
|
|
|
static void _csgp_pkt_process(uint8_t *cmd, uint32_t len)
|
|
|
{
|
|
|
csg_head_t *head = (csg_head_t*)cmd;
|
|
|
|
|
|
/* 报文头和 CRC 校验. */
|
|
|
if (_csg_pkt_check(cmd, len) != HAL_OK)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* 共有命令处理. */
|
|
|
switch (head->cmd)
|
|
|
{
|
|
|
case CSG_CONNECT:
|
|
|
_csg_connect_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_TIMING:
|
|
|
_csg_time_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_PASSWD_SET:
|
|
|
_csg_passwd_set_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_CONFIG_SET:
|
|
|
_csg_config_set_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_BEAT:
|
|
|
_csg_beat_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_SERVER_SET:
|
|
|
_csg_server_set_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_SERVER_GET:
|
|
|
_csg_server_get_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_RESET:
|
|
|
_csg_reset_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_CONFIG_GET:
|
|
|
_csg_config_get_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_TIME_GET:
|
|
|
_csg_time_get_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_DATA_GET:
|
|
|
_csg_data_get_reply(cmd, len);
|
|
|
break;
|
|
|
case CSG_DATA:
|
|
|
_csg_data_reply(cmd, len);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void _csg_pkt_recv(void)
|
|
|
{
|
|
|
static uint8_t state = 0;
|
|
|
static uint32_t time = 0;
|
|
|
wl_buf_list_t *buf_l = &wl_buf_list_rx;
|
|
|
csg_head_t *head = (csg_head_t*)wl_ctrl.cmd_buf;
|
|
|
uint8_t *buf = NULL;
|
|
|
uint16_t len = 0;
|
|
|
int16_t i = 0;
|
|
|
|
|
|
/* 超过 3s 没有收包说明收包超时, 重新开始收包. */
|
|
|
if (HAL_GetTick() - time > 3000)
|
|
|
{
|
|
|
state = 0;
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
/* 如果收包大于 buf 长度, 认为报文错误. */
|
|
|
if (wl_ctrl.cmd_buf_index + len >= WL_DMA_RX_BUF_LEN)
|
|
|
{
|
|
|
wl_ctrl.cmd_buf_index = 0;
|
|
|
state = FALSE;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* 将 buf 中的数据解析成命令. */
|
|
|
memcpy(&wl_ctrl.cmd_buf[wl_ctrl.cmd_buf_index], buf, len);
|
|
|
wl_ctrl.cmd_buf_index += len;
|
|
|
|
|
|
/* 不够报文头长度的报文暂时不处理. */
|
|
|
if (wl_ctrl.cmd_buf_index < CSG_HEAD_LEN)
|
|
|
{
|
|
|
state = FALSE;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (!state)
|
|
|
{
|
|
|
/* 报文长度不对或者起始位不对, 重新收包. */
|
|
|
if (PP_HTONS(head->len) + CSG_OTHER_LEN > WL_DMA_RX_BUF_LEN
|
|
|
|| head->flag != CSG_START_FLAG)
|
|
|
{
|
|
|
wl_ctrl.cmd_buf_index = 0;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
/* 报文长度与收包长度不对称, 等待后续报文. */
|
|
|
if (wl_ctrl.cmd_buf_index < PP_HTONS(head->len) + CSG_OTHER_LEN)
|
|
|
{
|
|
|
state = TRUE;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 报文长度与收包长度不对称, 等待后续报文. */
|
|
|
if (wl_ctrl.cmd_buf_index < PP_HTONS(head->len) + CSG_OTHER_LEN)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
state = FALSE;
|
|
|
}
|
|
|
|
|
|
len = PP_HTONS(head->len) + CSG_OTHER_LEN;
|
|
|
wl_ctrl.cmd_buf_index -= len;
|
|
|
buf = wl_ctrl.cmd_buf + len;
|
|
|
memcpy(wl_ctrl.csg_buf, wl_ctrl.cmd_buf, len);
|
|
|
for(i = 0; i < wl_ctrl.cmd_buf_index; i++)
|
|
|
{
|
|
|
wl_ctrl.cmd_buf[i] = buf[i];
|
|
|
}
|
|
|
|
|
|
DBG(DBG_M_4G, "Recv(%d:%d): 0x%x\r\n", len, wl_ctrl.cmd_buf_index, wl_ctrl.csg_buf[7]);
|
|
|
if (dbg_stat_get(DBG_M_4G))
|
|
|
{
|
|
|
buf_print(wl_ctrl.csg_buf, len > 32 ? 32 : len);
|
|
|
vty_print("\r\n");
|
|
|
}
|
|
|
|
|
|
_csgp_pkt_process(wl_ctrl.csg_buf, len);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 通过 AT 命令进行模块初始化. */
|
|
|
void _csg_init_soft(void)
|
|
|
{
|
|
|
uint8_t is_timeout = wl_ctrl.time_send < HAL_GetTick();
|
|
|
|
|
|
if ((WL_STATE_SOFT == wl_ctrl.state) && is_timeout)
|
|
|
{
|
|
|
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_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_long);
|
|
|
_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_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,\"UDP\",\"%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\",9467,19421,2\r\n", 10000);
|
|
|
_wl_4G_init_cmd_send(wl_ctrl.dma_tx_buf, 11000);
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
else if (WL_STATE_ADC_WAIT == wl_ctrl.state)
|
|
|
{
|
|
|
if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_ADC))
|
|
|
{
|
|
|
/* 软件初始化完成. */
|
|
|
wl_ctrl.state = CSG_STATE_CONNECT;
|
|
|
wl_ctrl.time_send = 0;
|
|
|
wl_ctrl.send_cnt = 0;
|
|
|
wl_ctrl.energy_mode_old = ADC_ctrl.energy_mode;
|
|
|
}
|
|
|
else if (is_timeout)
|
|
|
{
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 10000;
|
|
|
wl_ctrl.send_cnt++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void _csg_start(void *argument)
|
|
|
{
|
|
|
uint32_t notify_value = 0;
|
|
|
|
|
|
/* 等待完成 1 次 ADC 采样. */
|
|
|
while(1)
|
|
|
{
|
|
|
if (IS_MONITOR_BIT_SET(system_init_flag, SYS_INIT_ADC))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
osDelay(1000);
|
|
|
}
|
|
|
|
|
|
/* 开启串口空闲中断收包. */
|
|
|
HAL_UARTEx_ReceiveToIdle_DMA(wl_uart, wl_ctrl.dma_rx_buf, WL_DMA_RX_BUF_LEN);
|
|
|
|
|
|
/* 初始化 4G 模块硬件. */
|
|
|
_wl_4G_hw_init();
|
|
|
|
|
|
/* 20s 内要收到 4G 模块发出的 RDY. */
|
|
|
wl_ctrl.time_send = HAL_GetTick() + 20000;
|
|
|
wl_ctrl.wave_index = st_data.wave_index;
|
|
|
|
|
|
for (;;)
|
|
|
{
|
|
|
/* AT 指令发送失败, 直接退出. */
|
|
|
if (wl_ctrl.send_cnt > WL_SOFT_INIT_ERR)
|
|
|
{
|
|
|
wl_ctrl.err_cnt = 0;
|
|
|
_wl_4G_hw_restart();
|
|
|
}
|
|
|
|
|
|
if (wl_ctrl.state < WL_STATE_WAKEUP)
|
|
|
{
|
|
|
/* 进入软件初始化. */
|
|
|
_csg_init_soft();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* 发送数据给 */
|
|
|
_csg_pkt_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 -------------------------------------------------------*/
|
|
|
/* 无线通讯任务初始化. */
|
|
|
void wl_init_os(void)
|
|
|
{
|
|
|
if (DEV_TYPE_CSG == dev_info.type_s)
|
|
|
{
|
|
|
WLHandle = osThreadNew(_csg_start, NULL, &WL_attributes);
|
|
|
}
|
|
|
else if (DEV_TYPE_ACDC == dev_info.type_s)
|
|
|
{
|
|
|
WLHandle = osThreadNew(_wir_start, NULL, &WL_attributes);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
WLHandle = osThreadNew(_wl_4G_start, NULL, &WL_attributes);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void wl_show(void)
|
|
|
{
|
|
|
vty_print("ST\r\n");
|
|
|
vty_print("%-03d %d\r\n\n", wl_ctrl.state, wl_ctrl.send_cnt);
|
|
|
}
|
|
|
/******************* (C) COPYRIGHT LandPower ***** END OF FILE ****************/
|