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.

3211 lines
94 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/******************************************************************************
* 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 "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 (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;
}
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->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)
{
_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])
{
_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 ((dev_config.normal_sleep && DEV_TYPE_CT_P != dev_info.type_s)
|| DEV_TYPE_BAT == dev_info.type_s)
{
if(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;
}
}
/* 喂狗. */
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;
}
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 ****************/