基本功能已完成,还差功耗和架构优化
This commit is contained in:
@@ -127,7 +127,11 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl)
|
||||
/* ── DP2 手动模式 (raw) ── */
|
||||
case DP_ID_HAND_MODE:
|
||||
memcpy(gDevData.hand_mode, ctrl->hand_mode, 2);
|
||||
// TODO: 根据 gDevData.hand_mode 执行动作 (长度 2 字节)
|
||||
/* 薄适配:通知业务层;03=停,00=空闲 */
|
||||
{
|
||||
extern void usr_dp_hand_write(uint8_t cmd);
|
||||
usr_dp_hand_write(ctrl->hand_mode[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
/* ── DP3 绳索校准 (bool) ── */
|
||||
|
||||
+785
-10
@@ -1,16 +1,43 @@
|
||||
/******************************************************************************
|
||||
* @file usr_jb_main.c
|
||||
* @brief CBC2 业务主循环:按键 / 充电 / 电量 / 灯 / 6 档玩法 / 手动点动
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.24
|
||||
* @version V1.3.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.21, cyWu, 首次发布
|
||||
* - V1.1.0, 2026.08.24, cyWu, 收口未接线模块;DP2 仅第 1 字节点动 1s
|
||||
* - V1.2.0, 2026.08.24, cyWu, 按键:深睡 3s 开机、5s 开机+配对;开机中 3s 深睡
|
||||
* - V1.3.0, 2026.08.24, cyWu, DP2:00=空闲,01/02 转,03 停
|
||||
*
|
||||
* @note 协议生成文件 jb_product.c 不要填业务。APP 下行写 gDevData,
|
||||
* 本文件 1ms 轮询执行。usr_timer_loop 由 BLE 库回调,勿再注册第二份。
|
||||
******************************************************************************/
|
||||
|
||||
#include "system/includes.h"
|
||||
#include "app_config.h"
|
||||
#include "app_main.h"
|
||||
#include "app_task.h"
|
||||
#include "user_cfg.h"
|
||||
#include "vm.h"
|
||||
#include "sys_time.h"
|
||||
|
||||
#include "jb_protocol.h"
|
||||
#include "jb_product.h"
|
||||
#include "jb_ringbuffer.h"
|
||||
#include "jb_common.h"
|
||||
#include "usr_le_product.h"
|
||||
#include "usr_le_api.h"
|
||||
#include "bsp_hw.h"
|
||||
#include "app_led.h"
|
||||
#include "app_mode.h"
|
||||
#include "ui_manage.h"
|
||||
#include "asm/power/power_api.h"
|
||||
#include "asm/power/power_reset.h"
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_TAG_CONST APP
|
||||
#define LOG_TAG "[USR_JB]"
|
||||
#define LOG_INFO_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
/* 向 usr_le_code 库提供产品身份(换产品只改 jb_protocol.h 宏即可) */
|
||||
const uint8_t g_usr_le_prodcode[USR_LE_PRODCODE_LEN] = {
|
||||
@@ -22,27 +49,775 @@ const uint8_t g_usr_le_pcode[USR_LE_PCODE_LEN] = {
|
||||
JB_PRODUCT_CODE[3], JB_PRODUCT_CODE[4], JB_PRODUCT_CODE[5]
|
||||
};
|
||||
|
||||
void usr_timer_1_ms();
|
||||
static int jb_timer_id=0;
|
||||
static void usr_timer_1_ms(void *priv);
|
||||
void usr_timer_loop(void);
|
||||
extern void clr_wdt(void);
|
||||
extern u32 timer_get_ms(void);
|
||||
|
||||
void usr_jb_init()
|
||||
static int jb_timer_id;
|
||||
static uint8_t s_pairing; /**< 1=深睡 5s 进入配对中 */
|
||||
static uint8_t s_play_mode; /**< 当前自动模式 0~6 */
|
||||
static uint8_t s_key_raw;
|
||||
static uint8_t s_key_cnt;
|
||||
static uint8_t s_key_pressed;
|
||||
static uint8_t s_boot_key_lock; /**< 上电按着键,松开前不当短按 */
|
||||
static uint16_t s_key_hold_ms;
|
||||
static uint16_t s_key_led_override_ms; /**< 切模式闪灯期间不显示配对快闪 */
|
||||
static uint8_t s_req_poweroff;
|
||||
static uint8_t s_usb_online;
|
||||
static uint8_t s_charge_led; /**< 0=无 1=充电红 2=充满绿 */
|
||||
static uint8_t s_charge_led_last;
|
||||
static uint16_t s_full_ms;
|
||||
static uint8_t s_app_power; /**< DP0:0=软关,电机/玩法停,BLE 仍在 */
|
||||
static uint16_t s_bat_tick;
|
||||
static uint16_t s_bat_acc;
|
||||
static uint8_t s_bat_n;
|
||||
static uint16_t s_bat_mv;
|
||||
static uint8_t s_bat_pct;
|
||||
static uint8_t s_low_bat;
|
||||
static uint32_t s_low_ms;
|
||||
static uint8_t s_empty_win;
|
||||
static uint8_t s_low_enter_win;
|
||||
static uint8_t s_low_exit_win;
|
||||
static uint16_t s_bat_boot_ms;
|
||||
static uint16_t s_bat_log_ms;
|
||||
static uint8_t s_hand_busy; /**< 手动点动进行中 */
|
||||
static uint8_t s_hand_cmd_last; /**< 边沿:同一 1/2 不重复启动 */
|
||||
static uint16_t s_hand_ms;
|
||||
static volatile uint8_t s_hand_write_pending; /**< DP2 刚写入(03 停转要靠事件) */
|
||||
static volatile uint8_t s_hand_write_cmd;
|
||||
static uint32_t s_pair_ms; /**< 配对已持续 ms,满 60s 判失败 */
|
||||
|
||||
#define BAT_SAMPLE_MS 100
|
||||
#define BAT_AVG_N 8
|
||||
#define BAT_BOOT_MS 3000 /* 上电 3s 内不因低电深睡 */
|
||||
#define BAT_LOG_MS 10000
|
||||
#define BAT_LOW_WIN 3 /* 连续约 2.4s 才进低电告警 */
|
||||
#define BAT_EMPTY_WIN 5 /* 连续约 4s 才 3.2V 深睡 */
|
||||
|
||||
/**
|
||||
* @brief 忙等若干毫秒,并喂狗
|
||||
* @param ms 等待时长
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_boot_delay_ms(uint32_t ms)
|
||||
{
|
||||
uint32_t t0 = timer_get_ms();
|
||||
|
||||
while ((timer_get_ms() - t0) < ms) {
|
||||
clr_wdt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BLE 起来前进深睡(1ms 定时器尚未启动)
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_boot_sleep(void)
|
||||
{
|
||||
log_info("boot sleep\n");
|
||||
bsp_hw_enter_sleep_io();
|
||||
power_set_soft_poweroff();
|
||||
while (1) {
|
||||
clr_wdt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 上电是否跳过 3s/5s 按键判定
|
||||
* @return 1=USB / 软复位 / LVD / 看门狗,保持开机且不进配对
|
||||
*/
|
||||
static uint8_t usr_boot_skip_key_wait(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (bsp_chg_is_low() || bsp_vpwr_is_online()) {
|
||||
log_info("boot usb, skip key wait\n");
|
||||
return 1;
|
||||
}
|
||||
usr_boot_delay_ms(5);
|
||||
}
|
||||
|
||||
if (cpu_reset_by_soft()
|
||||
|| is_reset_source(MSYS_SOFT_RST)
|
||||
|| is_reset_source(P33_SOFT_RST)
|
||||
|| is_reset_source(P33_VDDIO_LVD_RST)
|
||||
|| is_reset_source(P11_WDT_RST)) {
|
||||
log_info("boot reset-keep, skip key wait\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 深睡唤醒/上电:长按 3s 开机,长按 5s 开机并配对;不足 3s 松手再睡
|
||||
* @note 必须在 BLE 起来之前调用。配对只置 usr_goto_pair,不调用 usr_goto_pair_mode
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_boot_key_wait(void)
|
||||
{
|
||||
uint32_t t0;
|
||||
uint32_t elapsed;
|
||||
uint8_t green_on = 0;
|
||||
|
||||
usr_var.usr_goto_pair = 0;
|
||||
s_pairing = 0;
|
||||
s_pair_ms = 0;
|
||||
|
||||
if (usr_boot_skip_key_wait()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bsp_key_is_pressed()) {
|
||||
log_info("boot no key, sleep\n");
|
||||
usr_boot_sleep();
|
||||
}
|
||||
|
||||
t0 = timer_get_ms();
|
||||
bsp_led_all_off();
|
||||
log_info("boot key hold, wait 3s on / 5s pair\n");
|
||||
|
||||
while (bsp_key_is_pressed()) {
|
||||
elapsed = timer_get_ms() - t0;
|
||||
clr_wdt();
|
||||
|
||||
if (elapsed >= BOARD_KEY_PAIR_MS) {
|
||||
usr_var.usr_goto_pair = 1;
|
||||
usr_clear_pair_info_noreset();
|
||||
s_pairing = 1;
|
||||
s_pair_ms = 0;
|
||||
log_info("boot hold %ums, power on + pair\n", (unsigned)elapsed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!green_on && (elapsed >= BOARD_KEY_POWER_MS)) {
|
||||
green_on = 1;
|
||||
bsp_led_green_set(1);
|
||||
log_info("boot hold 3s, will power on\n");
|
||||
}
|
||||
}
|
||||
|
||||
elapsed = timer_get_ms() - t0;
|
||||
if (elapsed < BOARD_KEY_POWER_MS) {
|
||||
log_info("boot hold %ums < 3s, sleep\n", (unsigned)elapsed);
|
||||
usr_boot_sleep();
|
||||
}
|
||||
|
||||
log_info("boot hold %ums, power on\n", (unsigned)elapsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 停手动点动(走电机反转刹车)
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_hand_stop(void)
|
||||
{
|
||||
s_hand_busy = 0;
|
||||
s_hand_ms = 0;
|
||||
bsp_motor_set(BSP_MOTOR_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 停手动 + 自动模式,并清 DP1
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_motor_all_stop(void)
|
||||
{
|
||||
s_play_mode = 0;
|
||||
gDevData.play_mode = 0;
|
||||
app_mode_stop();
|
||||
usr_hand_stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DP2 写入钩子(jb_product 薄适配调用,不在此驱电机)
|
||||
* @param cmd 第 1 字节:0=空闲,1=顺时针,2=逆时针,3=停
|
||||
* @return 无
|
||||
*/
|
||||
void usr_dp_hand_write(uint8_t cmd)
|
||||
{
|
||||
s_hand_write_cmd = cmd;
|
||||
s_hand_write_pending = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 软关:电机停、DP0=0,等 APP/短按再开。不断 BLE
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_app_soft_off(void)
|
||||
{
|
||||
s_app_power = 0;
|
||||
gDevData.power = 0;
|
||||
s_play_mode = 0;
|
||||
gDevData.play_mode = 0;
|
||||
app_mode_stop();
|
||||
usr_hand_stop();
|
||||
log_info("soft off, wait APP power on\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 切换自动模式 0~6
|
||||
* @param mode 0=停转,1~6=对应玩法
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_play_mode_apply(uint8_t mode)
|
||||
{
|
||||
if (mode > 6) {
|
||||
mode = 0;
|
||||
}
|
||||
if (s_usb_online || !s_app_power || s_req_poweroff || s_hand_busy || s_pairing) {
|
||||
mode = 0;
|
||||
}
|
||||
s_play_mode = mode;
|
||||
gDevData.play_mode = mode;
|
||||
if (mode == 0) {
|
||||
app_mode_stop();
|
||||
} else {
|
||||
app_mode_start(mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 跟随 APP 下发的 DP1 自动模式
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_play_mode_poll(void)
|
||||
{
|
||||
uint8_t mode;
|
||||
|
||||
if (s_usb_online || !s_app_power || s_req_poweroff || s_hand_busy || s_pairing) {
|
||||
return;
|
||||
}
|
||||
mode = gDevData.play_mode;
|
||||
if (mode > 6) {
|
||||
mode = 0;
|
||||
gDevData.play_mode = 0;
|
||||
}
|
||||
if (mode == s_play_mode) {
|
||||
return;
|
||||
}
|
||||
usr_play_mode_apply(mode);
|
||||
log_info("APP play_mode=%d\n", mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 跟随 APP 下发的 DP0 开关
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_app_power_poll(void)
|
||||
{
|
||||
if (s_usb_online || s_req_poweroff) {
|
||||
return;
|
||||
}
|
||||
if (gDevData.power && !s_app_power) {
|
||||
s_app_power = 1;
|
||||
log_info("APP power on\n");
|
||||
} else if (!gDevData.power && s_app_power) {
|
||||
usr_app_soft_off();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DP2 手动:只看第 1 字节。0=空闲,1=顺时针,2=逆时针,3=停
|
||||
* @note 00 00 是 DP 默认值,不当停止。百分比/力度、DP3、DP4 预留不接。
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_hand_poll(void)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint8_t got_write = s_hand_write_pending;
|
||||
|
||||
if (got_write) {
|
||||
s_hand_write_pending = 0;
|
||||
cmd = s_hand_write_cmd;
|
||||
} else {
|
||||
cmd = gDevData.hand_mode[0];
|
||||
}
|
||||
|
||||
if (s_usb_online || !s_app_power || s_req_poweroff || s_pairing) {
|
||||
if (s_hand_busy || (got_write && (cmd == 3))) {
|
||||
usr_motor_all_stop();
|
||||
}
|
||||
s_hand_cmd_last = cmd;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 0) {
|
||||
s_hand_cmd_last = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == 3) {
|
||||
if (got_write || s_hand_busy || app_mode_get_active()) {
|
||||
usr_motor_all_stop();
|
||||
log_info("hand stop cmd=3\n");
|
||||
}
|
||||
s_hand_cmd_last = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cmd == 1 || cmd == 2) && (got_write || (cmd != s_hand_cmd_last))) {
|
||||
s_play_mode = 0;
|
||||
gDevData.play_mode = 0;
|
||||
app_mode_stop();
|
||||
s_hand_busy = 1;
|
||||
s_hand_ms = 0;
|
||||
/* 1=顺时针收绳,2=逆时针放绳(BOARD_MOTOR_IN_INA_HIGH=1) */
|
||||
bsp_motor_set((cmd == 1) ? BSP_MOTOR_IN : BSP_MOTOR_OUT);
|
||||
log_info("hand cmd=%d %s until 03\n", cmd,
|
||||
(cmd == 1) ? "cw" : "ccw");
|
||||
}
|
||||
s_hand_cmd_last = cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 手动运行时推进刹车;停转改由 DP2 写 03
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_hand_tick_1ms(void)
|
||||
{
|
||||
if (!s_hand_busy) {
|
||||
return;
|
||||
}
|
||||
bsp_motor_brake_tick();
|
||||
if (s_hand_ms < 0xffff) {
|
||||
s_hand_ms++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 深睡入口(须在 1ms 高优定时器之外调用)
|
||||
* @param priv 未使用
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_do_poweroff(void *priv)
|
||||
{
|
||||
(void)priv;
|
||||
log_info("enter deep off\n");
|
||||
app_mode_stop();
|
||||
usr_hand_stop();
|
||||
bsp_hw_enter_sleep_io();
|
||||
sys_enter_soft_poweroff(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 请求深睡:先停电机,50ms 后真正关机
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_key_request_poweroff(void)
|
||||
{
|
||||
if (s_req_poweroff) {
|
||||
return;
|
||||
}
|
||||
s_req_poweroff = 1;
|
||||
log_info("request deep off\n");
|
||||
app_mode_stop();
|
||||
usr_hand_stop();
|
||||
bsp_led_all_off();
|
||||
sys_timeout_add(NULL, usr_do_poweroff, 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 电压换算电量:4.2V=100%,3.2V=0%
|
||||
* @param mv 电池电压,单位 mV
|
||||
* @return 电量百分比,范围 0~100
|
||||
*/
|
||||
static uint8_t usr_bat_percent(uint16_t mv)
|
||||
{
|
||||
int32_t span = (int32_t)BOARD_VBAT_FULL_MV - (int32_t)BOARD_VBAT_EMPTY_MV;
|
||||
int32_t pct;
|
||||
|
||||
if (mv <= BOARD_VBAT_EMPTY_MV) {
|
||||
return 0;
|
||||
}
|
||||
if (mv >= BOARD_VBAT_FULL_MV) {
|
||||
return 100;
|
||||
}
|
||||
pct = ((int32_t)mv - BOARD_VBAT_EMPTY_MV) * 100 / span;
|
||||
if (pct < 0) {
|
||||
pct = 0;
|
||||
}
|
||||
if (pct > 100) {
|
||||
pct = 100;
|
||||
}
|
||||
return (uint8_t)pct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 电量采样与低电策略
|
||||
* @note 电机运转时只记电压、不改百分比/告警,避免电流拉垮 VBAT 误报
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_bat_tick_1ms(void)
|
||||
{
|
||||
uint16_t mv;
|
||||
uint8_t pct;
|
||||
uint8_t motor_busy;
|
||||
|
||||
if (s_bat_boot_ms < BAT_BOOT_MS) {
|
||||
s_bat_boot_ms++;
|
||||
}
|
||||
|
||||
if (++s_bat_tick >= BAT_SAMPLE_MS) {
|
||||
s_bat_tick = 0;
|
||||
s_bat_acc += bsp_vbat_mv();
|
||||
s_bat_n++;
|
||||
if (s_bat_n >= BAT_AVG_N) {
|
||||
mv = (uint16_t)(s_bat_acc / s_bat_n);
|
||||
s_bat_acc = 0;
|
||||
s_bat_n = 0;
|
||||
s_bat_mv = mv;
|
||||
motor_busy = (uint8_t)(app_mode_get_active() != 0 || s_hand_busy);
|
||||
|
||||
if (!motor_busy) {
|
||||
pct = usr_bat_percent(mv);
|
||||
if (pct != s_bat_pct) {
|
||||
s_bat_pct = pct;
|
||||
gDevData.battery = pct;
|
||||
}
|
||||
|
||||
if (s_bat_boot_ms >= BAT_BOOT_MS) {
|
||||
if (!s_usb_online && mv <= BOARD_VBAT_EMPTY_MV) {
|
||||
if (s_empty_win < 0xFF) {
|
||||
s_empty_win++;
|
||||
}
|
||||
if (s_empty_win >= BAT_EMPTY_WIN) {
|
||||
s_low_bat = 1;
|
||||
gDevData.alm_low_battery = 1;
|
||||
if (!s_req_poweroff) {
|
||||
log_info("vbat %dmV empty, deep off\n", mv);
|
||||
usr_key_request_poweroff();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_empty_win = 0;
|
||||
}
|
||||
|
||||
if (mv < BOARD_VBAT_LOW_MV) {
|
||||
s_low_exit_win = 0;
|
||||
if (!s_low_bat && s_low_enter_win < 0xFF) {
|
||||
s_low_enter_win++;
|
||||
if (s_low_enter_win >= BAT_LOW_WIN) {
|
||||
s_low_bat = 1;
|
||||
s_low_ms = 0;
|
||||
gDevData.alm_low_battery = 1;
|
||||
log_info("low battery %dmV %d%%\n", mv, s_bat_pct);
|
||||
}
|
||||
}
|
||||
} else if (mv > (BOARD_VBAT_LOW_MV + BOARD_VBAT_LOW_HYST_MV)) {
|
||||
s_low_enter_win = 0;
|
||||
if (s_low_bat) {
|
||||
if (s_low_exit_win < 0xFF) {
|
||||
s_low_exit_win++;
|
||||
}
|
||||
if (s_low_exit_win >= BAT_LOW_WIN) {
|
||||
s_low_bat = 0;
|
||||
s_low_ms = 0;
|
||||
gDevData.alm_low_battery = 0;
|
||||
log_info("battery recover %dmV %d%%\n", mv, s_bat_pct);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_low_enter_win = 0;
|
||||
s_low_exit_win = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s_usb_online || s_req_poweroff || (s_bat_boot_ms < BAT_BOOT_MS)) {
|
||||
s_low_ms = 0;
|
||||
} else if (s_low_bat && (s_low_ms < BOARD_LOWBAT_SLEEP_MS)) {
|
||||
s_low_ms++;
|
||||
if (s_low_ms == BOARD_LOWBAT_SLEEP_MS) {
|
||||
log_info("low battery 1min, deep off\n");
|
||||
usr_key_request_poweroff();
|
||||
}
|
||||
}
|
||||
|
||||
if (++s_bat_log_ms >= BAT_LOG_MS) {
|
||||
s_bat_log_ms = 0;
|
||||
log_info("bat %d%% %dmV alm=%d\n", s_bat_pct, s_bat_mv, s_low_bat);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 短按:自动模式 0→1→…→6→0
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_key_on_click(void)
|
||||
{
|
||||
if (s_hand_busy) {
|
||||
log_info("key click ignored, hand busy\n");
|
||||
return;
|
||||
}
|
||||
usr_play_mode_apply((uint8_t)((s_play_mode + 1) % 7));
|
||||
app_led_request_mode_blink();
|
||||
s_key_led_override_ms = (uint16_t)((BOARD_LED_MODE_OFF_MS + BOARD_LED_MODE_ON_MS)
|
||||
* BOARD_LED_MODE_BLINK_N + 50);
|
||||
log_info("key click play_mode=%d\n", s_play_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按键状态初值
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_key_init(void)
|
||||
{
|
||||
s_play_mode = 0;
|
||||
s_boot_key_lock = bsp_key_is_pressed() ? 1 : 0;
|
||||
s_key_pressed = s_boot_key_lock;
|
||||
s_key_raw = s_key_pressed;
|
||||
s_key_cnt = BOARD_KEY_DEBOUNCE_MS;
|
||||
s_key_hold_ms = 0;
|
||||
if (s_boot_key_lock) {
|
||||
log_info("boot key held, wait release\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按键消抖:开机后 1s 内短按切模式,按住 3s 深睡;充电时忽略
|
||||
* @note 开机中即使按满 5s 也不进配对。配对只在深睡长按 5s、BLE 起来前判定
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_key_tick_1ms(void)
|
||||
{
|
||||
uint8_t raw;
|
||||
|
||||
if (s_req_poweroff) {
|
||||
return;
|
||||
}
|
||||
|
||||
raw = bsp_key_is_pressed();
|
||||
|
||||
if (raw == s_key_raw) {
|
||||
if (s_key_cnt < BOARD_KEY_DEBOUNCE_MS) {
|
||||
s_key_cnt++;
|
||||
}
|
||||
} else {
|
||||
s_key_raw = raw;
|
||||
s_key_cnt = 0;
|
||||
}
|
||||
|
||||
if (s_key_cnt != BOARD_KEY_DEBOUNCE_MS) {
|
||||
if (s_key_pressed && !s_boot_key_lock) {
|
||||
s_key_hold_ms++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (raw && !s_key_pressed) {
|
||||
s_key_pressed = 1;
|
||||
s_key_hold_ms = 0;
|
||||
} else if (!raw && s_key_pressed) {
|
||||
if (s_boot_key_lock) {
|
||||
s_boot_key_lock = 0;
|
||||
log_info("boot key released\n");
|
||||
} else if (s_key_hold_ms < BOARD_KEY_CLICK_MS && s_key_hold_ms >= 10) {
|
||||
if (s_usb_online) {
|
||||
log_info("key click ignored, charging\n");
|
||||
} else if (s_pairing) {
|
||||
log_info("key click ignored, pairing\n");
|
||||
} else if (!s_app_power) {
|
||||
s_app_power = 1;
|
||||
gDevData.power = 1;
|
||||
log_info("key click cancel soft off\n");
|
||||
} else {
|
||||
usr_key_on_click();
|
||||
}
|
||||
}
|
||||
s_key_pressed = 0;
|
||||
s_key_hold_ms = 0;
|
||||
}
|
||||
|
||||
if (s_key_pressed && !s_boot_key_lock) {
|
||||
s_key_hold_ms++;
|
||||
if (s_key_hold_ms == BOARD_KEY_POWER_MS) {
|
||||
if (s_usb_online) {
|
||||
log_info("key hold 3s ignored, charging\n");
|
||||
} else if (s_pairing) {
|
||||
log_info("key hold 3s ignored, pairing\n");
|
||||
} else {
|
||||
log_info("key hold 3s, poweroff\n");
|
||||
usr_key_request_poweroff();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 充电检测:CHG 低=充电中;VPWR 在且 CHG 高满 1s=充满;拔电软关
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_chg_tick_1ms(void)
|
||||
{
|
||||
uint8_t chg_low = bsp_chg_is_low();
|
||||
uint8_t vpwr = bsp_vpwr_is_online();
|
||||
uint8_t usb;
|
||||
|
||||
if (chg_low) {
|
||||
s_full_ms = 0;
|
||||
s_charge_led = 1;
|
||||
gDevData.charge = CHARGE_1;
|
||||
usb = 1;
|
||||
} else if (vpwr) {
|
||||
/* 拔电时 CHG 先变高、VPWR 还没掉,不能立刻当充满 */
|
||||
if (s_full_ms < 0xFFFF) {
|
||||
s_full_ms++;
|
||||
}
|
||||
if (s_full_ms >= BOARD_CHG_FULL_MS) {
|
||||
s_charge_led = 2;
|
||||
}
|
||||
gDevData.charge = (s_charge_led == 1) ? CHARGE_1 : CHARGE_2;
|
||||
usb = 1;
|
||||
} else {
|
||||
s_full_ms = 0;
|
||||
s_charge_led = 0;
|
||||
gDevData.charge = CHARGE_2;
|
||||
usb = 0;
|
||||
}
|
||||
|
||||
if (usb != s_usb_online) {
|
||||
s_usb_online = usb;
|
||||
log_info("usb %s vpwr=%d chg=%d mv=%d pair=%d goto=%d\n",
|
||||
usb ? "in" : "out", vpwr, chg_low, bsp_vpwr_mv(),
|
||||
usr_get_pair_flag(), usr_var.usr_goto_pair);
|
||||
if (usb) {
|
||||
app_mode_stop();
|
||||
usr_hand_stop();
|
||||
s_play_mode = 0;
|
||||
gDevData.play_mode = 0;
|
||||
log_info("usb in, motor stop\n");
|
||||
} else {
|
||||
ui_update_status(STATUS_NORMAL_POWER);
|
||||
usr_app_soft_off();
|
||||
}
|
||||
}
|
||||
|
||||
usr_var.usr_power_charge_flag = s_usb_online ? 1 : 2;
|
||||
|
||||
if (s_charge_led != s_charge_led_last) {
|
||||
s_charge_led_last = s_charge_led;
|
||||
log_info("charge_led=%d chg=%d vpwr=%d mv=%d\n",
|
||||
s_charge_led, chg_low, vpwr, bsp_vpwr_mv());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 组装灯效上下文:充电 > 配对 > 软关灭灯 > 低电 > 切模式闪 > 绿灯
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_led_tick_1ms(void)
|
||||
{
|
||||
AppLedCtx_t led;
|
||||
uint8_t paired;
|
||||
|
||||
if (s_req_poweroff) {
|
||||
bsp_led_all_off();
|
||||
return;
|
||||
}
|
||||
|
||||
paired = usr_get_pair_flag();
|
||||
|
||||
if (s_pairing) {
|
||||
if (paired) {
|
||||
app_led_start_pair_result(1);
|
||||
s_pairing = 0;
|
||||
s_pair_ms = 0;
|
||||
log_info("pair ok\n");
|
||||
} else if (++s_pair_ms >= BOARD_PAIR_TIMEOUT_MS) {
|
||||
s_pairing = 0;
|
||||
s_pair_ms = 0;
|
||||
app_led_start_pair_result(0);
|
||||
log_info("pair timeout 60s, stay on\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (s_key_led_override_ms) {
|
||||
s_key_led_override_ms--;
|
||||
}
|
||||
|
||||
memset(&led, 0, sizeof(led));
|
||||
led.charge_led = s_charge_led;
|
||||
led.pairing = (uint8_t)(s_pairing && s_app_power && (s_key_led_override_ms == 0));
|
||||
led.app_power = s_app_power;
|
||||
led.low_bat = s_low_bat;
|
||||
led.life_on = 1;
|
||||
app_led_tick_1ms(&led);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 业务初始化(在 BLE 栈起来之前由 app_main 调用)
|
||||
* @note 内部会等按键 3s/5s;不足 3s 直接深睡,不会启动 1ms 定时器
|
||||
* @return 无
|
||||
*/
|
||||
void usr_jb_init(void)
|
||||
{
|
||||
jbInit();
|
||||
userInit();
|
||||
if(jb_timer_id==0)jb_timer_id = sys_s_hi_timer_add(NULL, usr_timer_1_ms, TIMER_PERIOD_MS);
|
||||
bsp_hw_init();
|
||||
app_led_init();
|
||||
app_mode_init();
|
||||
|
||||
usr_boot_key_wait();
|
||||
|
||||
usr_key_init();
|
||||
s_app_power = 1;
|
||||
gDevData.power = 1;
|
||||
s_hand_busy = 0;
|
||||
s_hand_cmd_last = 0;
|
||||
s_hand_write_pending = 0;
|
||||
s_hand_write_cmd = 0;
|
||||
s_charge_led_last = 0xff;
|
||||
|
||||
if (jb_timer_id == 0) {
|
||||
jb_timer_id = sys_hi_timer_add(NULL, usr_timer_1_ms, TIMER_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void usr_timer_1_ms()
|
||||
/**
|
||||
* @brief 约 1ms 高优定时器:按键/充电/电量/DP 轮询/电机节拍/灯
|
||||
* @param priv 未使用
|
||||
* @note 用 sys_hi_timer(priority=1)避免休眠把节拍拉长。禁止在这里直接 sys_enter_soft_poweroff
|
||||
* @return 无
|
||||
*/
|
||||
static void usr_timer_1_ms(void *priv)
|
||||
{
|
||||
(void)priv;
|
||||
jbTimerIrq();
|
||||
usr_key_tick_1ms();
|
||||
usr_chg_tick_1ms();
|
||||
usr_bat_tick_1ms();
|
||||
usr_app_power_poll();
|
||||
usr_hand_poll();
|
||||
usr_play_mode_poll();
|
||||
if (s_hand_busy) {
|
||||
usr_hand_tick_1ms();
|
||||
} else {
|
||||
app_mode_run();
|
||||
}
|
||||
usr_led_tick_1ms();
|
||||
}
|
||||
|
||||
void usr_jb_le_recieve_data(u8* data,u16 len)
|
||||
/**
|
||||
* @brief BLE 收到见宝载荷,送入协议环形缓冲
|
||||
* @param data 载荷指针
|
||||
* @param len 载荷长度,单位字节
|
||||
* @return 无
|
||||
*/
|
||||
void usr_jb_le_recieve_data(u8 *data, u16 len)
|
||||
{
|
||||
jbPutData(data,len);
|
||||
jbPutData(data, len);
|
||||
}
|
||||
|
||||
void usr_timer_loop()///500ms
|
||||
/**
|
||||
* @brief 约 500ms:协议收包与 DP 上报(由 usr_le_code 库回调,不要再注册一份)
|
||||
* @return 无
|
||||
*/
|
||||
void usr_timer_loop(void)
|
||||
{
|
||||
userHandle();
|
||||
jbProtocolHandle(&gDevData);
|
||||
|
||||
Reference in New Issue
Block a user