优化BLE断连后重连广播和温湿度广播切换的程序架构
This commit is contained in:
@@ -67,10 +67,10 @@ uint8_t app_th_is_fault(void);
|
||||
uint8_t app_th_last_sample_ok(void);
|
||||
|
||||
/**
|
||||
* @brief 取走一次「本周期采样成功」事件(供 usr_le_adv 的 500ms 任务上下文)
|
||||
* @brief 取走一次「本周期采样成功」事件(供 app_th_adv 的 500ms 任务上下文)
|
||||
* @note ⚠ 生产者是 app_th_poll(20ms 硬件定时器中断上下文),那里只置
|
||||
* volatile pending,不开关广播、不打日志、不写 flash。
|
||||
* 消费者(usr_ble_adv_updata,BLE 线程任务上下文)调本函数取走,
|
||||
* 消费者(app_th_adv_tick,由 usr_ble_adv_updata 调用)调本函数取走,
|
||||
* 内部 local_irq_disable 保护,取到即清。
|
||||
* 只在真正采样成功(last_ok 那次)时产生,失败/fault 不产生,
|
||||
* 温度、湿度都是对外值(与数码管/DP3/DP4 一致)。
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/******************************************************************************
|
||||
* @file app_th_adv.c
|
||||
* @brief CBR3 自定义温湿度广播窗实现
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.09.03
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.09.03, cyWu, 从 usr_le_adv.c 拆出
|
||||
******************************************************************************/
|
||||
|
||||
#include "app_th_adv.h"
|
||||
#include "app_th.h"
|
||||
#include "app_linkage.h"
|
||||
#include "board_pin.h"
|
||||
#include "usr_le_api.h"
|
||||
#include "system/includes.h"
|
||||
#include "app_main.h"
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[TH_ADV]"
|
||||
#define LOG_INFO_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
extern void usr_set_adv_interval(u16 val);
|
||||
extern u16 usr_get_adv_interval(void);
|
||||
|
||||
#define TH_ADV_DATA_MAX 31
|
||||
#define TH_ADV_WINDOW_TICKS 2 /**< 500ms × 2 = 1s */
|
||||
#define TH_ADV_FAST_INTERVAL 80 /**< 窗内快广播,暂停 60s 变慢 */
|
||||
#define TH_ADV_TYPE_FLAGS 0x01
|
||||
#define TH_ADV_TYPE_LOCAL_NAME 0x09
|
||||
#define TH_ADV_TYPE_MANUFACTURER 0xFF
|
||||
|
||||
typedef struct {
|
||||
uint8_t ticks; /**< >0 = 窗进行中,剩余 500ms 拍数 */
|
||||
uint16_t interval; /**< 进窗前提速前的间隔;0=进窗前已是快广播 */
|
||||
} AppThAdvCtx_t;
|
||||
|
||||
static AppThAdvCtx_t s_th_adv;
|
||||
|
||||
/**
|
||||
* @brief 配对 / OTA / 已连接 / 未配网 → 不允许发温湿度窗
|
||||
* @return 1=阻塞,0=允许
|
||||
*/
|
||||
static uint8_t th_adv_blocked(void)
|
||||
{
|
||||
if (usr_ble_is_connected()) {
|
||||
return 1;
|
||||
}
|
||||
if (usr_var.usr_goto_pair || usr_var.usr_goto_updata ||
|
||||
usr_var.usr_ota_succ_flag) {
|
||||
return 1;
|
||||
}
|
||||
if (usr_get_pair_flag() == 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 组自定义温湿度 AD(Flags + Complete Local Name + Manufacturer 0xFFFF)
|
||||
* @param tank 缸体编号(非 0)
|
||||
* @param ver 配置版本
|
||||
* @param temp_x10 对外温度 ×10
|
||||
* @param humi 对外湿度 %
|
||||
* @return 无
|
||||
*/
|
||||
static void th_adv_encode(uint16_t tank, uint8_t ver, int16_t temp_x10, uint8_t humi)
|
||||
{
|
||||
uint8_t buf[TH_ADV_DATA_MAX];
|
||||
uint8_t *p = buf;
|
||||
char dec[5];
|
||||
uint8_t digits = 0;
|
||||
uint16_t v = tank;
|
||||
int32_t t_int;
|
||||
uint8_t name_len;
|
||||
|
||||
*p++ = 0x02;
|
||||
*p++ = TH_ADV_TYPE_FLAGS;
|
||||
*p++ = 0x06;
|
||||
|
||||
while (v) {
|
||||
dec[digits++] = (char)('0' + (v % 10));
|
||||
v /= 10;
|
||||
}
|
||||
name_len = (uint8_t)(5 + digits); /* "JBao-" + tank 位数 */
|
||||
*p++ = (uint8_t)(1 + name_len);
|
||||
*p++ = TH_ADV_TYPE_LOCAL_NAME;
|
||||
*p++ = 'J';
|
||||
*p++ = 'B';
|
||||
*p++ = 'a';
|
||||
*p++ = 'o';
|
||||
*p++ = '-';
|
||||
while (digits) {
|
||||
*p++ = (uint8_t)dec[--digits];
|
||||
}
|
||||
|
||||
t_int = temp_x10 / 10;
|
||||
if (t_int < -128) {
|
||||
t_int = -128;
|
||||
}
|
||||
if (t_int > 127) {
|
||||
t_int = 127;
|
||||
}
|
||||
if (humi > 100) {
|
||||
humi = 100;
|
||||
}
|
||||
*p++ = 0x06;
|
||||
*p++ = TH_ADV_TYPE_MANUFACTURER;
|
||||
*p++ = 0xFF;
|
||||
*p++ = 0xFF;
|
||||
*p++ = ver;
|
||||
*p++ = (uint8_t)t_int;
|
||||
*p++ = humi;
|
||||
|
||||
usr_ble_adv_set_raw(buf, (uint8_t)(p - buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 结束温湿度窗:还原广播间隔,可选切回见宝回连
|
||||
* @param back_to_reconn 1=组回连包(窗自然到期);0=只清窗
|
||||
* @return 无
|
||||
*/
|
||||
static void th_adv_stop(uint8_t back_to_reconn)
|
||||
{
|
||||
if (s_th_adv.ticks == 0) {
|
||||
return;
|
||||
}
|
||||
s_th_adv.ticks = 0;
|
||||
if (s_th_adv.interval != 0) {
|
||||
usr_set_adv_interval(s_th_adv.interval);
|
||||
s_th_adv.interval = 0;
|
||||
}
|
||||
if (back_to_reconn) {
|
||||
usr_ble_adv_encode_reconn();
|
||||
log_info("th adv win end, back to reconn\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 丢掉温湿度窗(不组回连包)
|
||||
* @return 无
|
||||
*/
|
||||
void app_th_adv_reset(void)
|
||||
{
|
||||
s_th_adv.ticks = 0;
|
||||
s_th_adv.interval = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 温湿度窗是否占用广播
|
||||
* @return 1=窗进行中,0=空闲
|
||||
*/
|
||||
uint8_t app_th_adv_is_active(void)
|
||||
{
|
||||
return (s_th_adv.ticks != 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 温湿度窗状态机(500ms 一拍)
|
||||
* @return 无
|
||||
*/
|
||||
void app_th_adv_tick(void)
|
||||
{
|
||||
#if !BOARD_TH_ENABLE
|
||||
return;
|
||||
#else
|
||||
int16_t t_x10 = 0;
|
||||
uint8_t humi = 0;
|
||||
uint16_t tank;
|
||||
|
||||
if (s_th_adv.ticks) {
|
||||
if (th_adv_blocked()) {
|
||||
th_adv_stop(0);
|
||||
} else if (s_th_adv.ticks > 1) {
|
||||
s_th_adv.ticks--;
|
||||
} else {
|
||||
/* 最后一拍必须先 stop(里头要求 ticks!=0),再组回连包 */
|
||||
th_adv_stop(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (th_adv_blocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!app_th_take_sample(&t_x10, &humi)) {
|
||||
return;
|
||||
}
|
||||
|
||||
tank = app_linkage_get_tank_id();
|
||||
if (tank == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_th_adv.ticks == 0) {
|
||||
s_th_adv.interval = (usr_get_adv_interval() != TH_ADV_FAST_INTERVAL) ?
|
||||
usr_get_adv_interval() : 0;
|
||||
usr_set_adv_interval(TH_ADV_FAST_INTERVAL);
|
||||
}
|
||||
th_adv_encode(tank, app_linkage_get_cfg_ver(), t_x10, humi);
|
||||
s_th_adv.ticks = TH_ADV_WINDOW_TICKS;
|
||||
log_info("th adv: tank=%u ver=%u T=%dC H=%u%%\n",
|
||||
tank, app_linkage_get_cfg_ver(), (int)(t_x10 / 10), humi);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
* @file app_th_adv.h
|
||||
* @brief CBR3 自定义温湿度广播窗(已绑定未连接时插 1s,再切回见宝回连)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.09.03
|
||||
* @version V1.0.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.09.03, cyWu, 从 usr_le_adv.c 拆出
|
||||
*
|
||||
* @note 给 nRF / 自研扫描器看,不是见宝 TLV。GATT 0x2A00 不动。
|
||||
* 进窗条件:未连接 + 已配网 + 非配对 + 非 OTA + tank_id≠0
|
||||
* + 本周期 AHT20 采样成功。窗长 500ms × 2。
|
||||
* ⚠ 只在 usr_ble_adv_updata(500ms 任务上下文)里 tick;
|
||||
* app_th 中断侧只置 pending,本模块是唯一消费者。
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __APP_TH_ADV_H__
|
||||
#define __APP_TH_ADV_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief 丢掉温湿度窗(不组回连包)
|
||||
* @note usr_ble_adv_init 会自己组绑定/回连,进 init 前调本函数清窗即可
|
||||
* @return 无
|
||||
*/
|
||||
void app_th_adv_reset(void);
|
||||
|
||||
/**
|
||||
* @brief 温湿度窗状态机(500ms 一拍,须在写协议栈广播数据之前调用)
|
||||
* @return 无
|
||||
*/
|
||||
void app_th_adv_tick(void);
|
||||
|
||||
/**
|
||||
* @brief 温湿度窗是否占用广播
|
||||
* @return 1=窗进行中(暂停 60s 变慢广播),0=空闲
|
||||
*/
|
||||
uint8_t app_th_adv_is_active(void);
|
||||
|
||||
#endif /* __APP_TH_ADV_H__ */
|
||||
Reference in New Issue
Block a user