fix(vd960DBN): 修复无法设置 IoT 模式的 bug
This commit is contained in:
@@ -1,55 +1,55 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file iot_mqtt_srv.h
|
||||
* @author wangfq
|
||||
* @version V1.0
|
||||
* @date 2026-07-03
|
||||
* @brief IoT MQTT 客户端 — DLD960 IoT 协议 (MQTT + JSON)
|
||||
* 当 g_sub_code_enable.iot_enable=1 时启用, 替代 SSC 模式
|
||||
* 协议参考: docs/DLD960_IoT_MQTT协议.md
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __IOT_MQTT_SRV_H__
|
||||
#define __IOT_MQTT_SRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*===========================================================================
|
||||
* Protocol Constants
|
||||
*===========================================================================*/
|
||||
#define IOT_MQTT_KEEPALIVE_SEC 60 // MQTT keepalive (s)
|
||||
#define IOT_MQTT_RECONNECT_MIN_MS 5000 // 最小重连间隔
|
||||
#define IOT_MQTT_RECONNECT_MAX_MS 60000 // 最大重连间隔 (指数退避上限)
|
||||
#define IOT_MQTT_HEARTBEAT_MS 60000 // 心跳上报周期 (60s)
|
||||
#define IOT_MQTT_RECV_BUF_LEN 2048 // 接收缓冲区
|
||||
#define IOT_MQTT_SEND_BUF_LEN 2048 // 发送缓冲区
|
||||
#define IOT_MQTT_TOPIC_MAX_LEN 128 // Topic 最大长度
|
||||
|
||||
/*===========================================================================
|
||||
* MQTT 连接状态
|
||||
*===========================================================================*/
|
||||
typedef enum {
|
||||
IOT_STATE_DISCONNECTED = 0, // 未连接
|
||||
IOT_STATE_TCP_CONNECTING, // TCP 连接中
|
||||
IOT_STATE_TCP_CONNECTED, // TCP 已连接, 等待 MQTT CONNECT
|
||||
IOT_STATE_MQTT_CONNECTING, // MQTT CONNECT 已发送, 等待 CONNACK
|
||||
IOT_STATE_MQTT_CONNECTED, // MQTT 已连接, 等待 SUBACK
|
||||
IOT_STATE_READY, // 完全就绪 (已订阅)
|
||||
} IotMqttState;
|
||||
|
||||
/*===========================================================================
|
||||
* Externs
|
||||
*===========================================================================*/
|
||||
extern uint8_t g_iot_socket; // MQTT TCP socket ID
|
||||
extern IotMqttState g_iot_state; // MQTT 连接状态
|
||||
extern uint8_t g_iot_msg_id; // 递增消息 ID
|
||||
|
||||
/*===========================================================================
|
||||
* API
|
||||
*===========================================================================*/
|
||||
void iot_mqtt_init(void); // 初始化 MQTT 连接 (TCP→CONNECT→SUBSCRIBE)
|
||||
void iot_mqtt_poll(void); // 主循环轮询 (状态机 + 心跳 + 重连)
|
||||
void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat); // Socket 中断处理
|
||||
void iot_mqtt_publish_sensor(void); // 推送传感器数据到 MQTT
|
||||
|
||||
#endif /* __IOT_MQTT_SRV_H__ */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file iot_mqtt_srv.h
|
||||
* @author wangfq
|
||||
* @version V1.0
|
||||
* @date 2026-07-03
|
||||
* @brief IoT MQTT 客户端 — DLD960 IoT 协议 (MQTT + JSON)
|
||||
* 当 g_sub_code_enable.iot_enable=1 时启用, 替代 SSC 模式
|
||||
* 协议参考: docs/DLD960_IoT_MQTT协议.md
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __IOT_MQTT_SRV_H__
|
||||
#define __IOT_MQTT_SRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*===========================================================================
|
||||
* Protocol Constants
|
||||
*===========================================================================*/
|
||||
#define IOT_MQTT_KEEPALIVE_SEC 60 // MQTT keepalive (s)
|
||||
#define IOT_MQTT_RECONNECT_MIN_MS 5000 // 最小重连间隔
|
||||
#define IOT_MQTT_RECONNECT_MAX_MS 60000 // 最大重连间隔 (指数退避上限)
|
||||
#define IOT_MQTT_HEARTBEAT_MS 60000 // 心跳上报周期 (60s)
|
||||
#define IOT_MQTT_RECV_BUF_LEN 2048 // 接收缓冲区
|
||||
#define IOT_MQTT_SEND_BUF_LEN 2048 // 发送缓冲区
|
||||
#define IOT_MQTT_TOPIC_MAX_LEN 128 // Topic 最大长度
|
||||
|
||||
/*===========================================================================
|
||||
* MQTT 连接状态
|
||||
*===========================================================================*/
|
||||
typedef enum {
|
||||
IOT_STATE_DISCONNECTED = 0, // 未连接
|
||||
IOT_STATE_TCP_CONNECTING, // TCP 连接中
|
||||
IOT_STATE_TCP_CONNECTED, // TCP 已连接, 等待 MQTT CONNECT
|
||||
IOT_STATE_MQTT_CONNECTING, // MQTT CONNECT 已发送, 等待 CONNACK
|
||||
IOT_STATE_MQTT_CONNECTED, // MQTT 已连接, 等待 SUBACK
|
||||
IOT_STATE_READY, // 完全就绪 (已订阅)
|
||||
} IotMqttState;
|
||||
|
||||
/*===========================================================================
|
||||
* Externs
|
||||
*===========================================================================*/
|
||||
extern uint8_t g_iot_socket; // MQTT TCP socket ID
|
||||
extern IotMqttState g_iot_state; // MQTT 连接状态
|
||||
extern uint8_t g_iot_msg_id; // 递增消息 ID
|
||||
|
||||
/*===========================================================================
|
||||
* API
|
||||
*===========================================================================*/
|
||||
void iot_mqtt_init(void); // 初始化 MQTT 连接 (TCP→CONNECT→SUBSCRIBE)
|
||||
void iot_mqtt_poll(void); // 主循环轮询 (状态机 + 心跳 + 重连)
|
||||
void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat); // Socket 中断处理
|
||||
void iot_mqtt_publish_sensor(void); // 推送传感器数据到 MQTT
|
||||
|
||||
#endif /* __IOT_MQTT_SRV_H__ */
|
||||
|
||||
@@ -1,244 +1,244 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file loop_uart_proto.h
|
||||
* @author wangfq
|
||||
* @version V1.0
|
||||
* @date 2026-07-02
|
||||
* @brief DLD960Loop 串口通信协议 (7F) — CH32V208 ↔ DLD960Loop MCU
|
||||
*
|
||||
* 帧格式: 7F | Addr | LEN | CMD | Data... | XOR | SUM
|
||||
* UART: USART2, 115200bps, PA2(Tx)/PA3(Rx)
|
||||
*
|
||||
* 该协议是通信MCU(CH32V208)与地感MCU(DLD960Loop/AT32F421)之间的接口。
|
||||
* 网络接口(TCP JSON/5960)通过本模块向地感MCU下发命令并获取数据。
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __LOOP_UART_PROTO_H__
|
||||
#define __LOOP_UART_PROTO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*===========================================================================
|
||||
* Protocol Constants
|
||||
*===========================================================================*/
|
||||
#define LUP_MAGIC 0x7F // 配置/查询协议
|
||||
#define LUP_MAGIC_OTA 0x9F // OTA
|
||||
|
||||
#define LUP_ADDR_DEFAULT 0x00 // 默认地址
|
||||
|
||||
#define LUP_MAX_VALUE_LEN 64 // Value 字段最大长度
|
||||
#define LUP_MAX_PKG_LEN (1 + 3 + LUP_MAX_VALUE_LEN + 2) // 70 bytes 最大帧
|
||||
|
||||
/*===========================================================================
|
||||
* Command Bytes (CMD)
|
||||
*===========================================================================*/
|
||||
#define LUP_CMD_GET_VERSION 0x4A // 获取设备版本号
|
||||
#define LUP_CMD_RESET 0x6D // 设备复位(无回复)
|
||||
#define LUP_CMD_FACTORY_INIT 0x92 // 出厂初始化
|
||||
#define LUP_CMD_SENSITIVITY 0x8A // 读写线圈灵敏度列表
|
||||
#define LUP_CMD_SET_PARAM 0x63 // 设置多路参数
|
||||
#define LUP_CMD_GET_PARAM 0x64 // 读取多路参数
|
||||
#define LUP_CMD_SENSOR_REPORT 0xC0 // 设备主动上报传感信息
|
||||
|
||||
/*===========================================================================
|
||||
* Sensor Types (0xC0 SensType)
|
||||
*===========================================================================*/
|
||||
#define LUP_SENS_TYPE_MULTI_COIL 0x0C // 多路线圈传感信息(四路)
|
||||
|
||||
/*===========================================================================
|
||||
* R/W byte for sensitivity (0x8A)
|
||||
*===========================================================================*/
|
||||
#define LUP_SENS_RW_READ 0x00
|
||||
#define LUP_SENS_RW_WRITE 0x01
|
||||
|
||||
/*===========================================================================
|
||||
* 线圈数
|
||||
*===========================================================================*/
|
||||
#define LUP_COIL_COUNT 4
|
||||
|
||||
/*===========================================================================
|
||||
* Data Structures
|
||||
*===========================================================================*/
|
||||
|
||||
/* 线圈配置 (0x63 Set / 0x64 Get 中使用) */
|
||||
typedef struct {
|
||||
uint8_t sensitivity; // 低4位灵敏度(0~9), 高4位频率等级[4]=高频,[5]=低频
|
||||
uint8_t loop_delay; // 延时时间 0~200, 0.1s/级
|
||||
uint8_t output_mode; // 低3位: 0=存在,1=进入脉冲,2=离开脉冲,3=方向
|
||||
// 高5位: SafeMode 分钟数(0=关闭)
|
||||
uint8_t exist_mode; // 低4位: 0=永久, 非0=有限分钟
|
||||
uint8_t direction_mode; // 低3位: 0=触发, 1~6=方向模式
|
||||
// 高4位: Function_Mode
|
||||
} LUP_CoilParam;
|
||||
|
||||
/* 多路参数设置 (0x63) */
|
||||
typedef struct {
|
||||
uint8_t auto_mode; // 0=不启用自动调频, 默认0
|
||||
uint8_t amount; // 线圈数量
|
||||
LUP_CoilParam params[LUP_COIL_COUNT];
|
||||
} LUP_ParamSet;
|
||||
|
||||
/* 多路参数读取返回 (0x64 Response) */
|
||||
typedef struct {
|
||||
uint8_t auto_mode;
|
||||
uint8_t amount;
|
||||
LUP_CoilParam params[LUP_COIL_COUNT];
|
||||
uint32_t freq[LUP_COIL_COUNT][3]; // [ch][0]=freq1, [1]=freq2, [2]=freq3
|
||||
} LUP_ParamGet;
|
||||
|
||||
/* 单路线圈传感数据单元 (0xC0/0x0C 中的每一路线圈) */
|
||||
typedef struct {
|
||||
uint8_t freq_level : 2; // 00=高频33nF, 01=中高43nF, 10=中低66nF, 11=低频76nF
|
||||
uint8_t direction : 1; // 0=触发, 1=方向判别
|
||||
uint8_t freq_type : 1; // 0=初始频率, 1=实时频率
|
||||
uint8_t sensitivity : 4; // 灵敏度等级
|
||||
// 线圈评估条件
|
||||
uint8_t condition : 4; // 环境状态评估值(0=正常, 值越大干扰越大)
|
||||
uint8_t loop_state : 1; // 0=正常, 1=断开
|
||||
uint8_t car_state : 1; // 0=无车, 1=有车
|
||||
uint8_t misc_type : 2; // 0=时间量, 1=断开次数, 2=车流量, 3=继电器输出次数
|
||||
uint32_t freq; // 频率 (3 bytes, little-endian)
|
||||
uint16_t variation; // 变化量 (2 bytes, little-endian)
|
||||
union {
|
||||
uint32_t passtime_ms; // 通过时间/车间距, 5ms单位 (misc_type=0)
|
||||
uint32_t cut_amount; // 线圈断开次数 (misc_type=1)
|
||||
uint32_t flow_amount; // 车流量数 (misc_type=2)
|
||||
uint32_t relay_count; // 继电器输出次数 (misc_type=3)
|
||||
} misc;
|
||||
} LUP_CoilSensor;
|
||||
|
||||
/* 主动上报传感信息 (0xC0/0x0C) */
|
||||
typedef struct {
|
||||
uint8_t sens_type; // 0x0C
|
||||
uint8_t sub_amount; // 分包数量(高4位), 0=无分包
|
||||
uint8_t sub_sequence; // 当前分包序号(低4位), 1-based
|
||||
uint8_t coil_count; // 线圈数 (解析出的)
|
||||
LUP_CoilSensor coils[LUP_COIL_COUNT];
|
||||
} LUP_SensorReport;
|
||||
|
||||
/* 灵敏度读写 (0x8A) */
|
||||
typedef struct {
|
||||
uint8_t rw; // 0=Read, 1=Write
|
||||
uint8_t amount; // 灵敏度值数量
|
||||
uint16_t sens_in[LUP_COIL_COUNT]; // 触发灵敏度
|
||||
uint16_t sens_out[LUP_COIL_COUNT]; // 释放灵敏度
|
||||
} LUP_Sensitivity;
|
||||
|
||||
/* 版本信息 (0x4A Response) */
|
||||
typedef struct {
|
||||
uint8_t status; // Status byte
|
||||
uint8_t hard_main;
|
||||
uint8_t hard_sub;
|
||||
uint8_t hard_ssub;
|
||||
uint8_t soft_main;
|
||||
uint8_t soft_sub;
|
||||
uint8_t soft_ssub;
|
||||
char version_str[32]; // 格式化字符串
|
||||
} LUP_VersionInfo;
|
||||
|
||||
/* 命令状态机 */
|
||||
typedef enum {
|
||||
LUP_STATE_IDLE = 0, // 空闲
|
||||
LUP_STATE_WAIT_RESPONSE, // 等待响应
|
||||
LUP_STATE_RESPONSE_READY, // 响应已就绪
|
||||
LUP_STATE_TIMEOUT // 超时
|
||||
} LUP_CmdState;
|
||||
|
||||
/* 挂起的命令跟踪 */
|
||||
typedef struct {
|
||||
uint8_t pending_cmd; // 当前等待响应的命令字节
|
||||
uint32_t send_tick; // 发送时刻 (ms)
|
||||
uint32_t timeout_ms; // 超时时间
|
||||
LUP_CmdState state;
|
||||
// 响应数据缓冲区
|
||||
uint8_t resp_buf[LUP_MAX_PKG_LEN];
|
||||
uint16_t resp_len;
|
||||
} LUP_CmdTracker;
|
||||
|
||||
/*===========================================================================
|
||||
* Global State
|
||||
*===========================================================================*/
|
||||
extern LUP_CmdTracker g_lup_cmd;
|
||||
|
||||
/*===========================================================================
|
||||
* Public API
|
||||
*===========================================================================*/
|
||||
|
||||
/* --- Checksum --- */
|
||||
uint8_t lup_calc_xor(const uint8_t *data, uint16_t len);
|
||||
uint8_t lup_calc_sum(const uint8_t *data, uint16_t len);
|
||||
int lup_verify_checksum(const uint8_t *pkg, uint16_t len);
|
||||
void lup_append_checksum(uint8_t *pkg);
|
||||
|
||||
/* --- Packet Builders (returns total packet length) --- */
|
||||
uint16_t lup_build_get_version(uint8_t *buf);
|
||||
uint16_t lup_build_reset(uint8_t *buf);
|
||||
uint16_t lup_build_factory_init(uint8_t *buf);
|
||||
uint16_t lup_build_sensitivity_read(uint8_t *buf);
|
||||
uint16_t lup_build_sensitivity_write(uint8_t *buf, const LUP_Sensitivity *sens);
|
||||
uint16_t lup_build_set_param(uint8_t *buf, const LUP_ParamSet *ps);
|
||||
uint16_t lup_build_get_param(uint8_t *buf);
|
||||
|
||||
/* --- Packet Parsers (returns 0=success, <0=error) --- */
|
||||
int lup_parse_version(const uint8_t *pkg, uint16_t len, LUP_VersionInfo *info);
|
||||
int lup_parse_factory_init_resp(const uint8_t *pkg, uint16_t len, uint8_t *success);
|
||||
int lup_parse_sensitivity_resp(const uint8_t *pkg, uint16_t len, LUP_Sensitivity *sens);
|
||||
int lup_parse_param_get(const uint8_t *pkg, uint16_t len, LUP_ParamGet *pg);
|
||||
int lup_parse_sensor_report(const uint8_t *pkg, uint16_t len, LUP_SensorReport *report);
|
||||
int lup_parse_set_param_resp(const uint8_t *pkg, uint16_t len, uint8_t *success);
|
||||
|
||||
/* --- Command State Machine --- */
|
||||
void lup_cmd_begin(uint8_t cmd, uint32_t timeout_ms);
|
||||
void lup_cmd_done(void);
|
||||
int lup_cmd_check_timeout(void);
|
||||
void lup_cmd_on_response(const uint8_t *pkg, uint16_t len);
|
||||
|
||||
/* --- High-level Commands (send + wait handled by state machine) --- */
|
||||
void lup_send_get_version(void);
|
||||
void lup_send_reset(void);
|
||||
void lup_send_factory_init(void);
|
||||
void lup_send_sensitivity_read(void);
|
||||
void lup_send_set_param(const LUP_ParamSet *ps);
|
||||
void lup_send_get_param(void);
|
||||
|
||||
/* --- Mid-packet ACK for 0xC0 multi-packet --- */
|
||||
uint16_t lup_build_sensor_ack(uint8_t *buf, uint8_t sens_type,
|
||||
uint8_t seq, uint8_t sub_amount);
|
||||
|
||||
/* --- UART Frame Parser (called from USART2 ISR context) --- */
|
||||
typedef enum {
|
||||
LUP_FRAME_STATE_IDLE = 0, // 等待 0x7F
|
||||
LUP_FRAME_STATE_HEADER, // 接收 Header (Addr, LEN, CMD)
|
||||
LUP_FRAME_STATE_VALUE, // 接收 Value
|
||||
LUP_FRAME_STATE_CHECK, // 接收 Checksum
|
||||
LUP_FRAME_STATE_COMPLETE // 帧完成
|
||||
} LUP_FrameState;
|
||||
|
||||
typedef struct {
|
||||
LUP_FrameState state;
|
||||
uint8_t buf[LUP_MAX_PKG_LEN];
|
||||
uint16_t idx; // 当前写入位置
|
||||
uint16_t value_len; // 期望的 Value 长度 (从 LEN 字段解析)
|
||||
uint16_t value_idx; // 当前已接收的 Value 字节数
|
||||
} LUP_FrameParser;
|
||||
|
||||
extern LUP_FrameParser g_lup_parser;
|
||||
|
||||
/* 喂一个字节给帧解析器,返回 1 表示帧接收完成 */
|
||||
int lup_feed_byte(uint8_t byte);
|
||||
|
||||
/* 取完整帧的指针和数据长度 */
|
||||
const uint8_t *lup_frame_data(void);
|
||||
uint16_t lup_frame_len(void);
|
||||
|
||||
/* 重置帧解析器 */
|
||||
void lup_frame_reset(void);
|
||||
|
||||
/* --- Process a complete frame (call from main loop context) --- */
|
||||
void lup_process_frame(const uint8_t *pkg, uint16_t len);
|
||||
|
||||
/* --- Sensor report callback (called when valid 0xC0 frame received) --- */
|
||||
typedef void (*lup_sensor_cb_t)(const uint8_t *pkg, uint16_t len);
|
||||
void lup_set_sensor_callback(lup_sensor_cb_t cb);
|
||||
|
||||
#endif /* __LOOP_UART_PROTO_H__ */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file loop_uart_proto.h
|
||||
* @author wangfq
|
||||
* @version V1.0
|
||||
* @date 2026-07-02
|
||||
* @brief DLD960Loop 串口通信协议 (7F) — CH32V208 ↔ DLD960Loop MCU
|
||||
*
|
||||
* 帧格式: 7F | Addr | LEN | CMD | Data... | XOR | SUM
|
||||
* UART: USART2, 115200bps, PA2(Tx)/PA3(Rx)
|
||||
*
|
||||
* 该协议是通信MCU(CH32V208)与地感MCU(DLD960Loop/AT32F421)之间的接口。
|
||||
* 网络接口(TCP JSON/5960)通过本模块向地感MCU下发命令并获取数据。
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __LOOP_UART_PROTO_H__
|
||||
#define __LOOP_UART_PROTO_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*===========================================================================
|
||||
* Protocol Constants
|
||||
*===========================================================================*/
|
||||
#define LUP_MAGIC 0x7F // 配置/查询协议
|
||||
#define LUP_MAGIC_OTA 0x9F // OTA
|
||||
|
||||
#define LUP_ADDR_DEFAULT 0x00 // 默认地址
|
||||
|
||||
#define LUP_MAX_VALUE_LEN 64 // Value 字段最大长度
|
||||
#define LUP_MAX_PKG_LEN (1 + 3 + LUP_MAX_VALUE_LEN + 2) // 70 bytes 最大帧
|
||||
|
||||
/*===========================================================================
|
||||
* Command Bytes (CMD)
|
||||
*===========================================================================*/
|
||||
#define LUP_CMD_GET_VERSION 0x4A // 获取设备版本号
|
||||
#define LUP_CMD_RESET 0x6D // 设备复位(无回复)
|
||||
#define LUP_CMD_FACTORY_INIT 0x92 // 出厂初始化
|
||||
#define LUP_CMD_SENSITIVITY 0x8A // 读写线圈灵敏度列表
|
||||
#define LUP_CMD_SET_PARAM 0x63 // 设置多路参数
|
||||
#define LUP_CMD_GET_PARAM 0x64 // 读取多路参数
|
||||
#define LUP_CMD_SENSOR_REPORT 0xC0 // 设备主动上报传感信息
|
||||
|
||||
/*===========================================================================
|
||||
* Sensor Types (0xC0 SensType)
|
||||
*===========================================================================*/
|
||||
#define LUP_SENS_TYPE_MULTI_COIL 0x0C // 多路线圈传感信息(四路)
|
||||
|
||||
/*===========================================================================
|
||||
* R/W byte for sensitivity (0x8A)
|
||||
*===========================================================================*/
|
||||
#define LUP_SENS_RW_READ 0x00
|
||||
#define LUP_SENS_RW_WRITE 0x01
|
||||
|
||||
/*===========================================================================
|
||||
* 线圈数
|
||||
*===========================================================================*/
|
||||
#define LUP_COIL_COUNT 4
|
||||
|
||||
/*===========================================================================
|
||||
* Data Structures
|
||||
*===========================================================================*/
|
||||
|
||||
/* 线圈配置 (0x63 Set / 0x64 Get 中使用) */
|
||||
typedef struct {
|
||||
uint8_t sensitivity; // 低4位灵敏度(0~9), 高4位频率等级[4]=高频,[5]=低频
|
||||
uint8_t loop_delay; // 延时时间 0~200, 0.1s/级
|
||||
uint8_t output_mode; // 低3位: 0=存在,1=进入脉冲,2=离开脉冲,3=方向
|
||||
// 高5位: SafeMode 分钟数(0=关闭)
|
||||
uint8_t exist_mode; // 低4位: 0=永久, 非0=有限分钟
|
||||
uint8_t direction_mode; // 低3位: 0=触发, 1~6=方向模式
|
||||
// 高4位: Function_Mode
|
||||
} LUP_CoilParam;
|
||||
|
||||
/* 多路参数设置 (0x63) */
|
||||
typedef struct {
|
||||
uint8_t auto_mode; // 0=不启用自动调频, 默认0
|
||||
uint8_t amount; // 线圈数量
|
||||
LUP_CoilParam params[LUP_COIL_COUNT];
|
||||
} LUP_ParamSet;
|
||||
|
||||
/* 多路参数读取返回 (0x64 Response) */
|
||||
typedef struct {
|
||||
uint8_t auto_mode;
|
||||
uint8_t amount;
|
||||
LUP_CoilParam params[LUP_COIL_COUNT];
|
||||
uint32_t freq[LUP_COIL_COUNT][3]; // [ch][0]=freq1, [1]=freq2, [2]=freq3
|
||||
} LUP_ParamGet;
|
||||
|
||||
/* 单路线圈传感数据单元 (0xC0/0x0C 中的每一路线圈) */
|
||||
typedef struct {
|
||||
uint8_t freq_level : 2; // 00=高频33nF, 01=中高43nF, 10=中低66nF, 11=低频76nF
|
||||
uint8_t direction : 1; // 0=触发, 1=方向判别
|
||||
uint8_t freq_type : 1; // 0=初始频率, 1=实时频率
|
||||
uint8_t sensitivity : 4; // 灵敏度等级
|
||||
// 线圈评估条件
|
||||
uint8_t condition : 4; // 环境状态评估值(0=正常, 值越大干扰越大)
|
||||
uint8_t loop_state : 1; // 0=正常, 1=断开
|
||||
uint8_t car_state : 1; // 0=无车, 1=有车
|
||||
uint8_t misc_type : 2; // 0=时间量, 1=断开次数, 2=车流量, 3=继电器输出次数
|
||||
uint32_t freq; // 频率 (3 bytes, little-endian)
|
||||
uint16_t variation; // 变化量 (2 bytes, little-endian)
|
||||
union {
|
||||
uint32_t passtime_ms; // 通过时间/车间距, 5ms单位 (misc_type=0)
|
||||
uint32_t cut_amount; // 线圈断开次数 (misc_type=1)
|
||||
uint32_t flow_amount; // 车流量数 (misc_type=2)
|
||||
uint32_t relay_count; // 继电器输出次数 (misc_type=3)
|
||||
} misc;
|
||||
} LUP_CoilSensor;
|
||||
|
||||
/* 主动上报传感信息 (0xC0/0x0C) */
|
||||
typedef struct {
|
||||
uint8_t sens_type; // 0x0C
|
||||
uint8_t sub_amount; // 分包数量(高4位), 0=无分包
|
||||
uint8_t sub_sequence; // 当前分包序号(低4位), 1-based
|
||||
uint8_t coil_count; // 线圈数 (解析出的)
|
||||
LUP_CoilSensor coils[LUP_COIL_COUNT];
|
||||
} LUP_SensorReport;
|
||||
|
||||
/* 灵敏度读写 (0x8A) */
|
||||
typedef struct {
|
||||
uint8_t rw; // 0=Read, 1=Write
|
||||
uint8_t amount; // 灵敏度值数量
|
||||
uint16_t sens_in[LUP_COIL_COUNT]; // 触发灵敏度
|
||||
uint16_t sens_out[LUP_COIL_COUNT]; // 释放灵敏度
|
||||
} LUP_Sensitivity;
|
||||
|
||||
/* 版本信息 (0x4A Response) */
|
||||
typedef struct {
|
||||
uint8_t status; // Status byte
|
||||
uint8_t hard_main;
|
||||
uint8_t hard_sub;
|
||||
uint8_t hard_ssub;
|
||||
uint8_t soft_main;
|
||||
uint8_t soft_sub;
|
||||
uint8_t soft_ssub;
|
||||
char version_str[32]; // 格式化字符串
|
||||
} LUP_VersionInfo;
|
||||
|
||||
/* 命令状态机 */
|
||||
typedef enum {
|
||||
LUP_STATE_IDLE = 0, // 空闲
|
||||
LUP_STATE_WAIT_RESPONSE, // 等待响应
|
||||
LUP_STATE_RESPONSE_READY, // 响应已就绪
|
||||
LUP_STATE_TIMEOUT // 超时
|
||||
} LUP_CmdState;
|
||||
|
||||
/* 挂起的命令跟踪 */
|
||||
typedef struct {
|
||||
uint8_t pending_cmd; // 当前等待响应的命令字节
|
||||
uint32_t send_tick; // 发送时刻 (ms)
|
||||
uint32_t timeout_ms; // 超时时间
|
||||
LUP_CmdState state;
|
||||
// 响应数据缓冲区
|
||||
uint8_t resp_buf[LUP_MAX_PKG_LEN];
|
||||
uint16_t resp_len;
|
||||
} LUP_CmdTracker;
|
||||
|
||||
/*===========================================================================
|
||||
* Global State
|
||||
*===========================================================================*/
|
||||
extern LUP_CmdTracker g_lup_cmd;
|
||||
|
||||
/*===========================================================================
|
||||
* Public API
|
||||
*===========================================================================*/
|
||||
|
||||
/* --- Checksum --- */
|
||||
uint8_t lup_calc_xor(const uint8_t *data, uint16_t len);
|
||||
uint8_t lup_calc_sum(const uint8_t *data, uint16_t len);
|
||||
int lup_verify_checksum(const uint8_t *pkg, uint16_t len);
|
||||
void lup_append_checksum(uint8_t *pkg);
|
||||
|
||||
/* --- Packet Builders (returns total packet length) --- */
|
||||
uint16_t lup_build_get_version(uint8_t *buf);
|
||||
uint16_t lup_build_reset(uint8_t *buf);
|
||||
uint16_t lup_build_factory_init(uint8_t *buf);
|
||||
uint16_t lup_build_sensitivity_read(uint8_t *buf);
|
||||
uint16_t lup_build_sensitivity_write(uint8_t *buf, const LUP_Sensitivity *sens);
|
||||
uint16_t lup_build_set_param(uint8_t *buf, const LUP_ParamSet *ps);
|
||||
uint16_t lup_build_get_param(uint8_t *buf);
|
||||
|
||||
/* --- Packet Parsers (returns 0=success, <0=error) --- */
|
||||
int lup_parse_version(const uint8_t *pkg, uint16_t len, LUP_VersionInfo *info);
|
||||
int lup_parse_factory_init_resp(const uint8_t *pkg, uint16_t len, uint8_t *success);
|
||||
int lup_parse_sensitivity_resp(const uint8_t *pkg, uint16_t len, LUP_Sensitivity *sens);
|
||||
int lup_parse_param_get(const uint8_t *pkg, uint16_t len, LUP_ParamGet *pg);
|
||||
int lup_parse_sensor_report(const uint8_t *pkg, uint16_t len, LUP_SensorReport *report);
|
||||
int lup_parse_set_param_resp(const uint8_t *pkg, uint16_t len, uint8_t *success);
|
||||
|
||||
/* --- Command State Machine --- */
|
||||
void lup_cmd_begin(uint8_t cmd, uint32_t timeout_ms);
|
||||
void lup_cmd_done(void);
|
||||
int lup_cmd_check_timeout(void);
|
||||
void lup_cmd_on_response(const uint8_t *pkg, uint16_t len);
|
||||
|
||||
/* --- High-level Commands (send + wait handled by state machine) --- */
|
||||
void lup_send_get_version(void);
|
||||
void lup_send_reset(void);
|
||||
void lup_send_factory_init(void);
|
||||
void lup_send_sensitivity_read(void);
|
||||
void lup_send_set_param(const LUP_ParamSet *ps);
|
||||
void lup_send_get_param(void);
|
||||
|
||||
/* --- Mid-packet ACK for 0xC0 multi-packet --- */
|
||||
uint16_t lup_build_sensor_ack(uint8_t *buf, uint8_t sens_type,
|
||||
uint8_t seq, uint8_t sub_amount);
|
||||
|
||||
/* --- UART Frame Parser (called from USART2 ISR context) --- */
|
||||
typedef enum {
|
||||
LUP_FRAME_STATE_IDLE = 0, // 等待 0x7F
|
||||
LUP_FRAME_STATE_HEADER, // 接收 Header (Addr, LEN, CMD)
|
||||
LUP_FRAME_STATE_VALUE, // 接收 Value
|
||||
LUP_FRAME_STATE_CHECK, // 接收 Checksum
|
||||
LUP_FRAME_STATE_COMPLETE // 帧完成
|
||||
} LUP_FrameState;
|
||||
|
||||
typedef struct {
|
||||
LUP_FrameState state;
|
||||
uint8_t buf[LUP_MAX_PKG_LEN];
|
||||
uint16_t idx; // 当前写入位置
|
||||
uint16_t value_len; // 期望的 Value 长度 (从 LEN 字段解析)
|
||||
uint16_t value_idx; // 当前已接收的 Value 字节数
|
||||
} LUP_FrameParser;
|
||||
|
||||
extern LUP_FrameParser g_lup_parser;
|
||||
|
||||
/* 喂一个字节给帧解析器,返回 1 表示帧接收完成 */
|
||||
int lup_feed_byte(uint8_t byte);
|
||||
|
||||
/* 取完整帧的指针和数据长度 */
|
||||
const uint8_t *lup_frame_data(void);
|
||||
uint16_t lup_frame_len(void);
|
||||
|
||||
/* 重置帧解析器 */
|
||||
void lup_frame_reset(void);
|
||||
|
||||
/* --- Process a complete frame (call from main loop context) --- */
|
||||
void lup_process_frame(const uint8_t *pkg, uint16_t len);
|
||||
|
||||
/* --- Sensor report callback (called when valid 0xC0 frame received) --- */
|
||||
typedef void (*lup_sensor_cb_t)(const uint8_t *pkg, uint16_t len);
|
||||
void lup_set_sensor_callback(lup_sensor_cb_t cb);
|
||||
|
||||
#endif /* __LOOP_UART_PROTO_H__ */
|
||||
|
||||
@@ -28,7 +28,7 @@ extern "C" {
|
||||
* 1 UDP + 2 TCP + 1 TCP_LISTEN = 4
|
||||
*/
|
||||
#define WCHNET_NUM_UDP 1 /* SSC 模式需要 UDP */
|
||||
#define WCHNET_NUM_TCP 2 /* JSON(1) + SSC client(1) max */
|
||||
#define WCHNET_NUM_TCP 1 //2 /* JSON(1) + SSC client(1) max */
|
||||
#define WCHNET_NUM_IPRAW 0 /* Number of IPRAW connections */
|
||||
|
||||
#define WCHNET_NUM_TCP_LISTEN 1 /* Number of TCP listening (required internally) */
|
||||
|
||||
@@ -23,6 +23,8 @@ void set_ble_safe_pass(uint8_t * devpass);
|
||||
void alter_dev_serila(uint8_t *serial);
|
||||
void alter_dev_baud(uint8_t *baudbuf);
|
||||
|
||||
void update_sub_code_enable(void);
|
||||
|
||||
void factory_dev_info(void);
|
||||
void output_cfg_from_flash(void);
|
||||
void load_cfg_from_flash(void);
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tcp_json_srv.h
|
||||
* @author wangfq
|
||||
* @version V1.0
|
||||
* @date 2026-06-30
|
||||
* @brief TCP JSON protocol server — DLD960 TCP JSON protocol handler
|
||||
* Port 5960, line-delimited JSON, auth + command dispatch
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __TCP_JSON_SRV_H__
|
||||
#define __TCP_JSON_SRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*===========================================================================
|
||||
* Protocol Constants
|
||||
*===========================================================================*/
|
||||
#define TCP_JSON_PORT 5960 // TCP JSON protocol default port
|
||||
#define TCP_JSON_MAX_FRAME 4096 // Max JSON frame length
|
||||
#define TCP_JSON_AUTH_TIMEOUT_MS 60000 // 60s auth timeout (ms)
|
||||
#define TCP_JSON_RECV_BUF_LEN (TCP_JSON_MAX_FRAME * 2)
|
||||
#define TCP_JSON_MAX_PWD_RETRY 3 // Max password retries before lockout
|
||||
#define TCP_JSON_LOCKOUT_TIMEOUT_MS 60000 // 60s lockout after max retries
|
||||
#define TCP_JSON_IDLE_TIMEOUT_MS 300000 // 5min idle → restart (no connect / no comm)
|
||||
#define TCP_JSON_MAX_RESTART_COUNT 3 // Max auto-restart count
|
||||
#define TCP_JSON_RESTART_COOLDOWN_MS 600000 // 10min cooldown after max restarts
|
||||
|
||||
/*===========================================================================
|
||||
* Auth / State
|
||||
*===========================================================================*/
|
||||
typedef enum {
|
||||
JSON_STATE_WAIT_AUTH = 0, // Waiting for pwd_verify
|
||||
JSON_STATE_AUTHED, // Authenticated, commands accepted
|
||||
JSON_STATE_LOCKOUT // Locked out (max retries exceeded)
|
||||
} TcpJsonAuthState;
|
||||
|
||||
/*===========================================================================
|
||||
* Error Codes
|
||||
*===========================================================================*/
|
||||
#define JSON_CODE_SUCCESS 0
|
||||
#define JSON_CODE_PARAM_ERR 1
|
||||
#define JSON_CODE_AUTH_FAIL 2
|
||||
#define JSON_CODE_BUSY 3
|
||||
#define JSON_CODE_UNSUPPORTED 4
|
||||
#define JSON_CODE_INTERNAL_ERR 5
|
||||
#define JSON_CODE_DATA_TOO_LONG 6
|
||||
#define JSON_CODE_NOT_AUTHED 7
|
||||
|
||||
/*===========================================================================
|
||||
* Pending Loop MCU Command Response (deferred)
|
||||
*===========================================================================*/
|
||||
typedef struct {
|
||||
uint8_t active; // 1 = pending response
|
||||
uint8_t socket; // TCP socket to reply to
|
||||
uint32_t msg_id; // Original msg_id
|
||||
char cmd[32]; // Original command string
|
||||
uint32_t deadline; // ms deadline for timeout
|
||||
} TcpJsonPending;
|
||||
|
||||
/*===========================================================================
|
||||
* Externs
|
||||
*===========================================================================*/
|
||||
extern uint8_t g_json_socket_listen; // TCP socket ID (listen + data)
|
||||
extern TcpJsonAuthState g_json_auth_state;
|
||||
extern uint32_t g_json_auth_timer; // ms timer for auth timeout
|
||||
extern uint8_t g_json_pwd_retry; // password retry counter
|
||||
extern TcpJsonPending g_json_pending; // Pending Loop MCU command state
|
||||
extern uint32_t g_json_last_comm_ts; // Last communication timestamp (ms)
|
||||
extern uint32_t g_json_last_connect_ts; // Last client connect timestamp (ms)
|
||||
extern uint8_t g_json_restart_count; // Auto-restart counter
|
||||
extern uint32_t g_json_restart_cooldown; // Cooldown deadline (ms)
|
||||
extern uint8_t g_report_active; // 0=inactive 1=active report
|
||||
|
||||
/*===========================================================================
|
||||
* API
|
||||
*===========================================================================*/
|
||||
void tcp_json_srv_init(void); // Create listen socket on port 5960
|
||||
void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat); // Socket interrupt handler
|
||||
void tcp_json_poll(void); // Periodic poll (auth timeout, etc.)
|
||||
void tcp_json_push_sensor(void); // Push sensor data (0xC0) to TCP client
|
||||
void tcp_json_restart(void); // Close + reopen socket (auto-restart)
|
||||
|
||||
#endif /* __TCP_JSON_SRV_H__ */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tcp_json_srv.h
|
||||
* @author wangfq
|
||||
* @version V1.0
|
||||
* @date 2026-06-30
|
||||
* @brief TCP JSON protocol server — DLD960 TCP JSON protocol handler
|
||||
* Port 5960, line-delimited JSON, auth + command dispatch
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __TCP_JSON_SRV_H__
|
||||
#define __TCP_JSON_SRV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*===========================================================================
|
||||
* Protocol Constants
|
||||
*===========================================================================*/
|
||||
#define TCP_JSON_PORT 5960 // TCP JSON protocol default port
|
||||
#define TCP_JSON_MAX_FRAME 4096 // Max JSON frame length
|
||||
#define TCP_JSON_AUTH_TIMEOUT_MS 60000 // 60s auth timeout (ms)
|
||||
#define TCP_JSON_RECV_BUF_LEN (TCP_JSON_MAX_FRAME * 2)
|
||||
#define TCP_JSON_MAX_PWD_RETRY 3 // Max password retries before lockout
|
||||
#define TCP_JSON_LOCKOUT_TIMEOUT_MS 60000 // 60s lockout after max retries
|
||||
#define TCP_JSON_IDLE_TIMEOUT_MS 300000 // 5min idle → restart (no connect / no comm)
|
||||
#define TCP_JSON_MAX_RESTART_COUNT 3 // Max auto-restart count
|
||||
#define TCP_JSON_RESTART_COOLDOWN_MS 600000 // 10min cooldown after max restarts
|
||||
|
||||
/*===========================================================================
|
||||
* Auth / State
|
||||
*===========================================================================*/
|
||||
typedef enum {
|
||||
JSON_STATE_WAIT_AUTH = 0, // Waiting for pwd_verify
|
||||
JSON_STATE_AUTHED, // Authenticated, commands accepted
|
||||
JSON_STATE_LOCKOUT // Locked out (max retries exceeded)
|
||||
} TcpJsonAuthState;
|
||||
|
||||
/*===========================================================================
|
||||
* Error Codes
|
||||
*===========================================================================*/
|
||||
#define JSON_CODE_SUCCESS 0
|
||||
#define JSON_CODE_PARAM_ERR 1
|
||||
#define JSON_CODE_AUTH_FAIL 2
|
||||
#define JSON_CODE_BUSY 3
|
||||
#define JSON_CODE_UNSUPPORTED 4
|
||||
#define JSON_CODE_INTERNAL_ERR 5
|
||||
#define JSON_CODE_DATA_TOO_LONG 6
|
||||
#define JSON_CODE_NOT_AUTHED 7
|
||||
|
||||
/*===========================================================================
|
||||
* Pending Loop MCU Command Response (deferred)
|
||||
*===========================================================================*/
|
||||
typedef struct {
|
||||
uint8_t active; // 1 = pending response
|
||||
uint8_t socket; // TCP socket to reply to
|
||||
uint32_t msg_id; // Original msg_id
|
||||
char cmd[32]; // Original command string
|
||||
uint32_t deadline; // ms deadline for timeout
|
||||
} TcpJsonPending;
|
||||
|
||||
/*===========================================================================
|
||||
* Externs
|
||||
*===========================================================================*/
|
||||
extern uint8_t g_json_socket_listen; // TCP socket ID (listen + data)
|
||||
extern TcpJsonAuthState g_json_auth_state;
|
||||
extern uint32_t g_json_auth_timer; // ms timer for auth timeout
|
||||
extern uint8_t g_json_pwd_retry; // password retry counter
|
||||
extern TcpJsonPending g_json_pending; // Pending Loop MCU command state
|
||||
extern uint32_t g_json_last_comm_ts; // Last communication timestamp (ms)
|
||||
extern uint32_t g_json_last_connect_ts; // Last client connect timestamp (ms)
|
||||
extern uint8_t g_json_restart_count; // Auto-restart counter
|
||||
extern uint32_t g_json_restart_cooldown; // Cooldown deadline (ms)
|
||||
extern uint8_t g_report_active; // 0=inactive 1=active report
|
||||
|
||||
/*===========================================================================
|
||||
* API
|
||||
*===========================================================================*/
|
||||
void tcp_json_srv_init(void); // Create listen socket on port 5960
|
||||
void tcp_json_handle_sock_int(uint8_t socketid, uint8_t intstat); // Socket interrupt handler
|
||||
void tcp_json_poll(void); // Periodic poll (auth timeout, etc.)
|
||||
void tcp_json_push_sensor(void); // Push sensor data (0xC0) to TCP client
|
||||
void tcp_json_restart(void); // Close + reopen socket (auto-restart)
|
||||
|
||||
#endif /* __TCP_JSON_SRV_H__ */
|
||||
|
||||
Reference in New Issue
Block a user