diff --git a/Makefile b/Makefile index 7d1c07c..95daa59 100644 --- a/Makefile +++ b/Makefile @@ -411,6 +411,7 @@ c_SRC_FILES := \ apps/usr_app/app_pair.c \ apps/usr_app/app_boot.c \ apps/usr_app/app_function.c \ + apps/usr_app/app_no_disturb.c \ apps/usr_app/app_shake_wake.c \ apps/usr_le_code/ble_proto.c \ apps/usr_le_code/bleproto.c \ diff --git a/apps/earphone/board/br28/board_jl701n_demo.c b/apps/earphone/board/br28/board_jl701n_demo.c index 885cfd4..9c8bfc6 100644 --- a/apps/earphone/board/br28/board_jl701n_demo.c +++ b/apps/earphone/board/br28/board_jl701n_demo.c @@ -735,7 +735,7 @@ struct port_wakeup port0 = { }; #if BOARD_CHG_ENABLE -/* R18 is not fitted on CBC3, so VBUS never reaches VPWR in softoff. Wake on +/* R18 is not fitted on CBC4, so VBUS never reaches VPWR in softoff. Wake on * the fitted ME4054 CHG_ON signal instead; it falls when charging starts. */ struct port_wakeup board_chg_wakeup_port = { .pullup_down_enable = ENABLE, diff --git a/apps/usr_app/app_function.c b/apps/usr_app/app_function.c index 3434f69..1231309 100644 --- a/apps/usr_app/app_function.c +++ b/apps/usr_app/app_function.c @@ -19,6 +19,7 @@ #include "app_mode.h" #include "app_led.h" #include "app_shake_wake.h" +#include "app_no_disturb.h" #include "app_time_util.h" #include "bsp_hw.h" #include "board_pin.h" @@ -46,7 +47,6 @@ typedef struct { volatile uint8_t play_write_pending; volatile uint8_t play_write_mode; uint8_t shake_wake; - uint8_t no_disturb; } AppFunctionCtx_t; static AppFunctionCtx_t s_func; @@ -71,7 +71,6 @@ void app_function_init(void) app_shake_wake_init(function_shake_wake_allowed, function_shake_wake_trigger); s_func.shake_wake = !!gDevData.shake_wake; - s_func.no_disturb = !!gDevData.no_disturb_enable[0]; app_shake_wake_set_enable(s_func.shake_wake); } @@ -89,7 +88,7 @@ void app_function_dp_play_write(uint8_t mode) /** * @brief DP2 写入钩子:仅记录第 1 字节,真正执行在 app_function_poll - * @param cmd 0=忽略,1=原地右转,2=原地左转 + * @param cmd 0=停止,1=上部电机探出,2=下部电机探出 * @return 无 */ void app_function_dp_hand_write(uint8_t cmd) @@ -105,12 +104,6 @@ void app_function_set_shake_wake(uint8_t enable) app_shake_wake_set_enable(s_func.shake_wake); } -void app_function_set_no_disturb(uint8_t enable) -{ - s_func.no_disturb = !!enable; - app_shake_wake_reset(); -} - /** * @brief 跟随 APP 下发的 DP0/DP1,并处理 DP2 手动点动 * @return 无 @@ -120,10 +113,6 @@ void app_function_poll(void) if (s_func.shake_wake != !!gDevData.shake_wake) { app_function_set_shake_wake(gDevData.shake_wake); } - if (s_func.no_disturb != !!gDevData.no_disturb_enable[0]) { - app_function_set_no_disturb(gDevData.no_disturb_enable[0]); - } - if (s_func.power_write_pending) { uint8_t enable = s_func.power_write_value; s_func.power_write_pending = 0; @@ -341,7 +330,7 @@ static void function_play_mode_timeout(uint16_t dt) } /** - * @brief DP2 手动:只看第 1 字节。0=空闲,1=顺时针,2=逆时针,3=停 + * @brief DP2 手动:只看第 1 字节。0=空闲,1=上部探出,2=下部探出 * @return 无 */ static void function_hand_poll(void) @@ -501,7 +490,7 @@ static uint8_t function_power_on(uint8_t show_hint) static uint8_t function_shake_wake_allowed(void) { return s_func.shake_wake && - !s_func.no_disturb && + !app_no_disturb_is_active() && !s_func.app_power && !app_power_usb_online() && !app_power_poweroff_pending() && diff --git a/apps/usr_app/app_function.h b/apps/usr_app/app_function.h index b2532ff..4559161 100644 --- a/apps/usr_app/app_function.h +++ b/apps/usr_app/app_function.h @@ -23,24 +23,22 @@ */ void app_function_init(void); -/** CBC3 DP0 写入:排队到业务节拍统一执行。 */ +/** CBC4 DP0 写入:排队到业务节拍统一执行。 */ void app_function_dp_power_write(uint8_t enable); -/** CBC3 DP1 写入:支持重复下发当前模式时停止。 */ +/** CBC4 DP1 写入:支持重复下发当前模式时停止。 */ void app_function_dp_play_write(uint8_t mode); /** * @brief DP2 写入钩子:仅记录第 1 字节,真正执行在 app_function_poll - * @param cmd 0=忽略,1=原地右转,2=原地左转 + * @param cmd 0=停止,1=上部电机探出,2=下部电机探出 * @return 无 */ void app_function_dp_hand_write(uint8_t cmd); -/** CBC3 DP6 震动开机开关。 */ +/** CBC4 DP6 震动开机开关。 */ void app_function_set_shake_wake(uint8_t enable); -/** 勿扰时段是否正在生效;生效时屏蔽震动开机。 */ -void app_function_set_no_disturb(uint8_t enable); /** * @brief 跟随 APP 下发的 DP0/DP1,并处理 DP2 手动点动,每个业务 tick 调用一次 diff --git a/apps/usr_app/app_led.c b/apps/usr_app/app_led.c index 7c52c9b..5950a37 100644 --- a/apps/usr_app/app_led.c +++ b/apps/usr_app/app_led.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file app_led.c - * @brief CBC2 灯效适配:充电红与待机绿可同时亮,不再 if-else 互斥 + * @brief CBC4 灯效适配:充电红与待机绿可同时亮,不再 if-else 互斥 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V2.0.0 diff --git a/apps/usr_app/app_led.h b/apps/usr_app/app_led.h index 51dcc25..71dde71 100644 --- a/apps/usr_app/app_led.h +++ b/apps/usr_app/app_led.h @@ -1,6 +1,6 @@ /****************************************************************************** * @file app_led.h - * @brief CBC2 灯效:红绿独立通道,充电红与待机绿可同时亮 + * @brief CBC4 灯效:红绿独立通道,充电红与待机绿可同时亮 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V2.0.0 diff --git a/apps/usr_app/app_no_disturb.c b/apps/usr_app/app_no_disturb.c new file mode 100644 index 0000000..7efc197 --- /dev/null +++ b/apps/usr_app/app_no_disturb.c @@ -0,0 +1,168 @@ +#include "app_no_disturb.h" +#include "usr_rtc.h" +#include "system/includes.h" + +#define APP_MINUTES_PER_DAY (24U * 60U) +#define APP_NO_DISTURB_VM_MAGIC 0x444e4431UL +#define APP_NO_DISTURB_VM_VERSION 1U + +typedef struct { + uint8_t enabled; + uint8_t weekdays_mask; + uint16_t start_minute; + uint16_t end_minute; +} AppNoDisturbCtx_t; + +typedef struct { + uint32_t magic; + uint8_t version; + uint8_t length; + uint16_t checksum; + uint8_t data[APP_NO_DISTURB_DATA_LEN]; +} AppNoDisturbVm_t; + +static AppNoDisturbCtx_t s_no_disturb; +static uint8_t s_saved_data[APP_NO_DISTURB_DATA_LEN]; +static uint8_t s_saved_valid; + +static uint16_t app_no_disturb_checksum(const uint8_t *data) +{ + uint16_t checksum = 0xa55aU; + uint8_t i; + + for (i = 0; i < APP_NO_DISTURB_DATA_LEN; i++) { + checksum = (uint16_t)((checksum << 5) | (checksum >> 11)); + checksum ^= data[i]; + } + return checksum; +} + +static uint8_t app_no_disturb_vm_valid(const AppNoDisturbVm_t *vm) +{ + return vm->magic == APP_NO_DISTURB_VM_MAGIC && + vm->version == APP_NO_DISTURB_VM_VERSION && + vm->length == APP_NO_DISTURB_DATA_LEN && + vm->checksum == app_no_disturb_checksum(vm->data); +} + +static uint8_t app_no_disturb_weekday_monday0(const struct sys_time *time) +{ + static const uint8_t month_offset[12] = { + 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 + }; + uint32_t year = time->year; + uint8_t sunday0; + + if (time->month < 3U) { + year--; + } + sunday0 = (uint8_t)((year + year / 4U - year / 100U + year / 400U + + month_offset[time->month - 1U] + time->day) % 7U); + return (uint8_t)((sunday0 + 6U) % 7U); +} + +static uint8_t app_no_disturb_day_selected(uint8_t weekday) +{ + return (uint8_t)((s_no_disturb.weekdays_mask & (1U << weekday)) != 0U); +} + +void app_no_disturb_configure(uint8_t enable, uint8_t weekdays_mask, + uint16_t start_minute, uint16_t end_minute) +{ + s_no_disturb.enabled = !!enable; + s_no_disturb.weekdays_mask = weekdays_mask & 0x7fU; + s_no_disturb.start_minute = start_minute; + s_no_disturb.end_minute = end_minute; +} + +uint8_t app_no_disturb_is_active_at(const struct sys_time *time) +{ + uint8_t weekday; + uint16_t now_minute; + + if (!time || !s_no_disturb.enabled || !s_no_disturb.weekdays_mask || + s_no_disturb.start_minute >= APP_MINUTES_PER_DAY || + s_no_disturb.end_minute >= APP_MINUTES_PER_DAY || + time->month < 1U || time->month > 12U || + time->day < 1U || time->day > 31U || + time->hour > 23U || time->min > 59U) { + return 0; + } + + weekday = app_no_disturb_weekday_monday0(time); + now_minute = (uint16_t)(time->hour * 60U + time->min); + + if (s_no_disturb.start_minute == s_no_disturb.end_minute) { + return app_no_disturb_day_selected(weekday); + } + if (s_no_disturb.start_minute < s_no_disturb.end_minute) { + return app_no_disturb_day_selected(weekday) && + now_minute >= s_no_disturb.start_minute && + now_minute < s_no_disturb.end_minute; + } + if (now_minute >= s_no_disturb.start_minute) { + return app_no_disturb_day_selected(weekday); + } + if (now_minute < s_no_disturb.end_minute) { + return app_no_disturb_day_selected((uint8_t)((weekday + 6U) % 7U)); + } + return 0; +} + +uint8_t app_no_disturb_is_active(void) +{ + struct sys_time time; + + if (!usr_rtc_get_time(&time)) { + return 0; + } + return app_no_disturb_is_active_at(&time); +} + +uint8_t app_no_disturb_storage_load(uint8_t data[APP_NO_DISTURB_DATA_LEN]) +{ + AppNoDisturbVm_t vm; + int ret; + + if (!data) { + return 0; + } + memset(&vm, 0, sizeof(vm)); + ret = syscfg_read(CFG_USER_NO_DISTURB, (uint8_t *)&vm, sizeof(vm)); + if (ret != (int)sizeof(vm) || !app_no_disturb_vm_valid(&vm)) { + s_saved_valid = 0; + return 0; + } + memcpy(data, vm.data, APP_NO_DISTURB_DATA_LEN); + memcpy(s_saved_data, vm.data, APP_NO_DISTURB_DATA_LEN); + s_saved_valid = 1; + return 1; +} + +uint8_t app_no_disturb_storage_save(const uint8_t data[APP_NO_DISTURB_DATA_LEN]) +{ + AppNoDisturbVm_t vm; + int ret; + + if (!data) { + return 0; + } + if (s_saved_valid && + !memcmp(s_saved_data, data, APP_NO_DISTURB_DATA_LEN)) { + return 1; + } + + memset(&vm, 0, sizeof(vm)); + vm.magic = APP_NO_DISTURB_VM_MAGIC; + vm.version = APP_NO_DISTURB_VM_VERSION; + vm.length = APP_NO_DISTURB_DATA_LEN; + memcpy(vm.data, data, APP_NO_DISTURB_DATA_LEN); + vm.checksum = app_no_disturb_checksum(vm.data); + ret = syscfg_write(CFG_USER_NO_DISTURB, (uint8_t *)&vm, sizeof(vm)); + if (ret != (int)sizeof(vm)) { + return 0; + } + memcpy(s_saved_data, data, APP_NO_DISTURB_DATA_LEN); + s_saved_valid = 1; + return 1; +} diff --git a/apps/usr_app/app_no_disturb.h b/apps/usr_app/app_no_disturb.h new file mode 100644 index 0000000..10c7081 --- /dev/null +++ b/apps/usr_app/app_no_disturb.h @@ -0,0 +1,17 @@ +#ifndef __APP_NO_DISTURB_H__ +#define __APP_NO_DISTURB_H__ + +#include +#include "system/sys_time.h" + +#define APP_NO_DISTURB_DATA_LEN 13U + +/* weekdays_mask bit 0..6 means Monday..Sunday. */ +void app_no_disturb_configure(uint8_t enable, uint8_t weekdays_mask, + uint16_t start_minute, uint16_t end_minute); +uint8_t app_no_disturb_is_active(void); +uint8_t app_no_disturb_is_active_at(const struct sys_time *time); +uint8_t app_no_disturb_storage_load(uint8_t data[APP_NO_DISTURB_DATA_LEN]); +uint8_t app_no_disturb_storage_save(const uint8_t data[APP_NO_DISTURB_DATA_LEN]); + +#endif /* __APP_NO_DISTURB_H__ */ diff --git a/apps/usr_app/key_manager.c b/apps/usr_app/key_manager.c index 859bd0f..dc01134 100644 --- a/apps/usr_app/key_manager.c +++ b/apps/usr_app/key_manager.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file key_manager.c - * @brief CBC2 按键:读 PB1,短按/长按交给 usr_jb_main + * @brief CBC4 按键:读 PB1,短按/长按交给 usr_jb_main * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V1.0.0 diff --git a/apps/usr_app/key_manager.h b/apps/usr_app/key_manager.h index 0742b43..6c5ef2b 100644 --- a/apps/usr_app/key_manager.h +++ b/apps/usr_app/key_manager.h @@ -1,6 +1,6 @@ /****************************************************************************** * @file key_manager.h - * @brief CBC2 单按键:短按切模式,长按 3s 关机;开机 3s/5s 不走本库 + * @brief CBC4 单按键:短按切模式,长按 3s 关机;开机 3s/5s 不走本库 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V1.0.0 diff --git a/apps/usr_app/led_manager.c b/apps/usr_app/led_manager.c index 14b8db4..71fa28f 100644 --- a/apps/usr_app/led_manager.c +++ b/apps/usr_app/led_manager.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file led_manager.c - * @brief CBC2 灯事件:充电红与待机绿走不同通道,可同时亮 + * @brief CBC4 灯事件:充电红与待机绿走不同通道,可同时亮 * @author cyWu <1917507415@qq.com> * @date 2026.08.27 * @version V1.1.0 @@ -157,7 +157,7 @@ static uint8_t led_boot_reject_handler(LED_Config_t *led_config) } /** - * @brief 注册回调并装载 CBC2 事件表(GPIO 已在 bsp_hw_init) + * @brief 注册回调并装载 CBC4 事件表(GPIO 已在 bsp_hw_init) * @return 无 */ void user_led_init(void) diff --git a/apps/usr_app/led_manager.h b/apps/usr_app/led_manager.h index 9468a89..2f061aa 100644 --- a/apps/usr_app/led_manager.h +++ b/apps/usr_app/led_manager.h @@ -1,6 +1,6 @@ /****************************************************************************** * @file led_manager.h - * @brief CBC2 红绿 LED 通道与事件表 + * @brief CBC4 红绿 LED 通道与事件表 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V1.0.0 @@ -20,7 +20,7 @@ typedef enum { } LedChannel_t; /** - * @brief 注册 GPIO 回调并装载 CBC2 事件表 + * @brief 注册 GPIO 回调并装载 CBC4 事件表 * @return 无 */ void user_led_init(void); diff --git a/apps/usr_jb_proto/Protocol/jb_product.c b/apps/usr_jb_proto/Protocol/jb_product.c index be1fd69..9392822 100644 --- a/apps/usr_jb_proto/Protocol/jb_product.c +++ b/apps/usr_jb_proto/Protocol/jb_product.c @@ -1,6 +1,6 @@ /* ================================================================ * jb_product.c — 用户层实现(请填补空白处) - * 设备: 猫猫捕猎罩 | 生成时间: 2026-08-18 16:24:47 + * 设备: 弹力魔盒 | 生成时间: 2026-08-18 16:24:47 * * ══ 开发流程 ══ * 1. 实现硬件抽象: jbGetTimerCount(定时器由 SOC SDK 提供) @@ -14,7 +14,7 @@ #include "jb_product.h" #include "app_function.h" -#include "usr_rtc.h" +#include "app_no_disturb.h" /* ════════════════════════════════════════════════════════════════ * 全局变量 @@ -30,70 +30,27 @@ static volatile uint32_t timerMs; #define JB_DND_START_MIN_OFFSET 10 #define JB_DND_END_HOUR_OFFSET 11 #define JB_DND_END_MIN_OFFSET 12 -static uint8_t jbLastNoDisturbActive; -/* Return weekday with Monday=0, matching DP7 bytes 2..8. */ -static uint8_t jbWeekdayMonday0(const struct sys_time *time) -{ - static const uint8_t monthOffset[12] = { - 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 - }; - uint16_t year = time->year; - uint8_t sunday0; - - if (time->month < 3) { - year--; - } - sunday0 = (uint8_t)((year + year / 4U - year / 100U + year / 400U + - monthOffset[time->month - 1U] + time->day) % 7U); - return (uint8_t)((sunday0 + 6U) % 7U); -} - -static void jbNoDisturbNormalize(uint8_t *cfg) +static void jbNoDisturbApply(uint8_t *cfg) { uint8_t i; + uint8_t weekdays = 0; + uint16_t start_minute; + uint16_t end_minute; cfg[JB_DND_ENABLE_OFFSET] = !!cfg[JB_DND_ENABLE_OFFSET]; for (i = 0; i < 7; i++) { cfg[JB_DND_WEEK_OFFSET + i] = !!cfg[JB_DND_WEEK_OFFSET + i]; - } -} - -static uint8_t jbNoDisturbScheduleValid(const uint8_t *cfg) -{ - uint8_t i; - - if (cfg[JB_DND_START_HOUR_OFFSET] >= 24 || - cfg[JB_DND_END_HOUR_OFFSET] >= 24 || - cfg[JB_DND_START_MIN_OFFSET] >= 60 || - cfg[JB_DND_END_MIN_OFFSET] >= 60) { - return 0; - } - for (i = 0; i < 7; i++) { if (cfg[JB_DND_WEEK_OFFSET + i]) { - return 1; + weekdays |= (uint8_t)(1U << i); } } - return 0; -} - -static uint8_t jbNoDisturbActive(void) -{ - /* Match the verified product behavior: DP7 byte 0 is the global - * no-disturb switch. Schedule bytes are retained and reported, but do - * not gate the local vibration wake path. */ - return !!gDevData.no_disturb_enable[JB_DND_ENABLE_OFFSET]; -} - -static void jbNoDisturbUpdate(void) -{ - uint8_t active = jbNoDisturbActive(); - - if (active == jbLastNoDisturbActive) { - return; - } - jbLastNoDisturbActive = active; - app_function_set_no_disturb(active); + start_minute = (uint16_t)(cfg[JB_DND_START_HOUR_OFFSET] * 60U + + cfg[JB_DND_START_MIN_OFFSET]); + end_minute = (uint16_t)(cfg[JB_DND_END_HOUR_OFFSET] * 60U + + cfg[JB_DND_END_MIN_OFFSET]); + app_no_disturb_configure(cfg[JB_DND_ENABLE_OFFSET], weekdays, + start_minute, end_minute); } /* ════════════════════════════════════════════════════════════════ @@ -111,10 +68,10 @@ void userInit(void) gDevData.battery = 0; /* DP5 电量上报 */ gDevData.shake_wake = 0; /* DP6 震动触发开机 0=关 1=开 */ memset(gDevData.no_disturb_enable, 0, 13); /* DP7 勿扰模式开关 */ + app_no_disturb_storage_load(gDevData.no_disturb_enable); gDevData.charge = 0; /* CHARGE_0 (不支持充电) */ gDevData.reserva_dp3 = 0; /* DP10 预留DP3 */ - jbLastNoDisturbActive = 0xff; - jbNoDisturbUpdate(); + jbNoDisturbApply(gDevData.no_disturb_enable); } /* ════════════════════════════════════════════════════════════════ @@ -123,8 +80,6 @@ void userInit(void) * ════════════════════════════════════════════════════════════════ */ void userHandle(void) { - jbNoDisturbUpdate(); - /* ── 可上报 DP (RO / RW): 用户数据采集 ── */ // gDevData.power = read_sensor(); /* DP0 开关 */ // gDevData.play_mode = read_sensor(); /* DP1 自动模式 */ @@ -193,12 +148,19 @@ int8_t jbEventProcess(jb_event_info_t *info, jb_data_point_t *ctrl) break; /* ── DP7 勿扰模式开关 (raw) ── */ - case DP_ID_NO_DISTURB_ENABLE: + case DP_ID_NO_DISTURB_ENABLE: { + uint8_t previous[JB_DND_LEN]; + + memcpy(previous, gDevData.no_disturb_enable, JB_DND_LEN); memcpy(gDevData.no_disturb_enable, ctrl->no_disturb_enable, JB_DND_LEN); - jbNoDisturbNormalize(gDevData.no_disturb_enable); - jbNoDisturbUpdate(); + jbNoDisturbApply(gDevData.no_disturb_enable); + if (memcmp(previous, gDevData.no_disturb_enable, JB_DND_LEN) && + !app_no_disturb_storage_save(gDevData.no_disturb_enable)) { + printf("dnd vm write failed\n"); + } break; + } /* ── DP10 预留DP3 (uint32) ── */ case DP_ID_RESERVA_DP3: diff --git a/apps/usr_jb_proto/Protocol/jb_product.h b/apps/usr_jb_proto/Protocol/jb_product.h index 5b05536..6d57c7c 100644 --- a/apps/usr_jb_proto/Protocol/jb_product.h +++ b/apps/usr_jb_proto/Protocol/jb_product.h @@ -1,6 +1,6 @@ /* ================================================================ * jb_product.h — 用户层头文件(自动生成) - * 设备: 猫猫捕猎罩 | 生成时间: 2026-08-18 16:24:47 + * 设备: 弹力魔盒 | 生成时间: 2026-08-18 16:24:47 * * 声明用户需实现的函数。数据结构定义见 jb_protocol.h * ================================================================ diff --git a/apps/usr_jb_proto/Protocol/jb_protocol.c b/apps/usr_jb_proto/Protocol/jb_protocol.c index 22c875e..4292f90 100644 --- a/apps/usr_jb_proto/Protocol/jb_protocol.c +++ b/apps/usr_jb_proto/Protocol/jb_protocol.c @@ -1,6 +1,6 @@ /* ================================================================ * jb_protocol.c — 见宝 IOT 协议实现(自动生成) - * 设备: 猫猫捕猎罩 | 生成时间: 2026-08-18 16:24:47 + * 设备: 弹力魔盒 | 生成时间: 2026-08-18 16:24:47 * ================================================================ */ diff --git a/apps/usr_jb_proto/Protocol/jb_protocol.h b/apps/usr_jb_proto/Protocol/jb_protocol.h index adad1f8..41e5077 100644 --- a/apps/usr_jb_proto/Protocol/jb_protocol.h +++ b/apps/usr_jb_proto/Protocol/jb_protocol.h @@ -1,6 +1,6 @@ /* ================================================================ * jb_protocol.h — 见宝 IOT 协议层(自动生成) - * 设备: 猫猫捕猎罩 | DP 数: 10 | Bitmap: 2B + * 设备: 弹力魔盒 | DP 数: 10 | Bitmap: 2B * 协议版本: V1.0 | 生成时间: 2026-08-18 16:24:47 * * 帧格式: [55 AA] [LEN_H LEN_L] [CMD] [SN] [payload...] [CKSUM] diff --git a/apps/usr_jb_proto/usr_jb_main.c b/apps/usr_jb_proto/usr_jb_main.c index 01667d4..652e42c 100644 --- a/apps/usr_jb_proto/usr_jb_main.c +++ b/apps/usr_jb_proto/usr_jb_main.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file usr_jb_main.c - * @brief CBC1 猫猫捕猎罩业务组合根:只做调用编排,不含具体业务算法 + * @brief CBC4 弹力魔盒业务组合根:只做调用编排,不含具体业务算法 * @author cyWu <1917507415@qq.com> * @date 2026.08.27 * @version V2.3.0 diff --git a/apps/usr_periph/board_pin.h b/apps/usr_periph/board_pin.h index 78e76b1..3b5abaa 100644 --- a/apps/usr_periph/board_pin.h +++ b/apps/usr_periph/board_pin.h @@ -1,6 +1,6 @@ /****************************************************************************** * @file board_pin.h - * @brief CBC1 猫猫捕猎罩板级引脚、电平与时序(换板只改本文件) + * @brief CBC4 弹力魔盒板级引脚、电平与时序(换板只改本文件) * @author cyWu <1917507415@qq.com> * @date 2026.08.27 * @version V1.5.0 @@ -105,7 +105,7 @@ #define BOARD_MOTOR_REVERSE_MS 1 /**< 换向前先松开,防 H 桥直通 */ #define BOARD_HAND_PULSE_MS 5000 /**< 手动右转/左转单次最长 5s */ -#define BOARD_MOTOR_PWM_HZ 200 /**< 猫猫捕猎罩原项目验证过的 MCPWM 频率(Hz) */ +#define BOARD_MOTOR_PWM_HZ 200 /**< 弹力魔盒验证过的 MCPWM 频率(Hz) */ #define BOARD_MOTOR_PWM_DUTY 8000 /**< 占空比 0~10000=0%~100%,80% */ #define BOARD_MOTOR_PWM_IDLE_CLOSE 1 /**< 1=空闲/轻睡关 MCPWM;0=保持开着,方便对比待机电流 */ diff --git a/apps/usr_periph/bsp_hw.c b/apps/usr_periph/bsp_hw.c index d3e6639..48b65e1 100644 --- a/apps/usr_periph/bsp_hw.c +++ b/apps/usr_periph/bsp_hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * @file bsp_hw.c - * @brief CBC1 板级 GPIO / ADC:单电机 H 桥、震动、LED、按键、充电检测 + * @brief CBC4 板级 GPIO / ADC:上下双电机 H 桥、震动、LED、按键、充电检测 * @author cyWu <1917507415@qq.com> * @date 2026.08.24 * @version V1.5.0 diff --git a/apps/usr_periph/bsp_hw.h b/apps/usr_periph/bsp_hw.h index d6cbe1b..f290116 100644 --- a/apps/usr_periph/bsp_hw.h +++ b/apps/usr_periph/bsp_hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * @file bsp_hw.h - * @brief CBC1 板级硬件:单电机 / 震动 / LED / 按键 / 充电 / 电量 + * @brief CBC4 板级硬件:上下双电机 / 震动 / LED / 按键 / 充电 / 电量 * @author cyWu <1917507415@qq.com> * @date 2026.08.25 * @version V1.6.0 @@ -67,7 +67,8 @@ void bsp_led_all_off(void); /** * @brief 设置电机方向。STOP 时直接切断驱动,自由滑行到停(不做反接刹车) * @note 占空比用 BOARD_MOTOR_PWM_DUTY(手动点动) - * @param dir 收绳 / 放绳 / 停转 + * @param left_dir/right_dir 左右轮方向 + * @param left_duty/right_duty 左右轮占空比 * @return 无 */ void bsp_drive_set(BspMotorDir_t left_dir, uint16_t left_duty, @@ -77,7 +78,7 @@ void bsp_drive_set(BspMotorDir_t left_dir, uint16_t left_duty, void bsp_drive_stop(void); /** - * @brief 兼容旧调用;猫猫捕猎罩每个动作更新左轮对应的两路 PWM + * @brief 兼容旧调用;弹力魔盒每个动作一次性更新上下电机四路 PWM * @return 无 */ void bsp_motor_switch_tick(void); diff --git a/dp_definition.json b/dp_definition.json index 30b369e..f7bcee8 100644 --- a/dp_definition.json +++ b/dp_definition.json @@ -1,178 +1,164 @@ { - "product": { - "name": "弹力魔盒", - "code": "PICBC4", - "type": "CBC4", - "protocol": "V1.0.0" - }, - "dps": [ - { - "id": 0, - "display_name": "开关", - "key": "power", - "kind": "normal", - "type": "bool", - "len": 1, - "scale": 1.0, - "dir": "rw", - "description": "设备总开关", - "values": { - "0": "关", - "1": "开" - } - }, - { - "id": 1, - "display_name": "自动模式", - "key": "play_mode", - "kind": "normal", - "type": "enum", - "len": 1, - "scale": 1.0, - "dir": "rw", - "description": "5种玩法,按键也可切换并上报", - "values": { - "0": "停止复位", - "1": "随机躲猫猫", - "2": "洞口接力跑", - "3": "快闪+快摇组合", - "4": "慢探+随机摇摆", - "5": "终极大乱斗" - } - }, - { - "id": 2, - "display_name": "手动模式", - "key": "hand_mode", - "kind": "normal", - "type": "enum", - "len": 1, - "scale": 1.0, - "dir": "wo", - "description": "上部或下部电机单次探出,最长5秒", - "values": { - "0": "停止", - "1": "上部探出", - "2": "下部探出" - } - }, - { - "id": 3, - "display_name": "绳索校准", - "key": "calibration", - "kind": "normal", - "type": "bool", - "len": 1, - "scale": 1.0, - "dir": "wo", - "description": "用来校准绳子位置", - "values": { - "0": "停止校准", - "1": "校准" - } - }, - { - "id": 4, - "display_name": "绳索圈数", - "key": "numberturns", - "kind": "normal", - "type": "uint8", - "len": 1, - "scale": 1.0, - "dir": "wo", - "description": "根据不同的绳子设置圈数", - "values": {} - }, - { - "id": 5, - "display_name": "低电量报警", - "key": "alm_low_battery", - "kind": "alarm", - "type": "bool", - "len": 1, - "scale": 1.0, - "dir": "ro", - "description": "<3.7V上报,1分钟后休眠", - "values": { - "0": "正常", - "1": "电量<20%告警" - }, - "level": 1 - }, - { - "id": 6, - "display_name": "电量上报", - "key": "battery", - "kind": "normal", - "type": "uint8", - "len": 1, - "scale": 1.0, - "dir": "ro", - "description": "电量上报", - "values": {} - }, - { - "id": 7, - "display_name": "充电状态", - "key": "charge", - "kind": "normal", - "type": "enum", - "len": 1, - "scale": 1.0, - "dir": "ro", - "description": "充电状态上报", - "values": { - "1": "充电中", - "2": "未充电" - } - }, - { - "id": 8, - "display_name": "勿扰模式开关", - "key": "no_disturb_enable", - "kind": "normal", - "type": "raw", - "len": 13, - "scale": 1.0, - "dir": "rw", - "description": "APP控制打开或关闭勿扰模式", - "values": {} - }, - { - "id": 9, - "display_name": "预留DP1", - "key": "reserva_dp1", - "kind": "normal", - "type": "uint32", - "len": 4, - "scale": 1.0, - "dir": "rw", - "description": "预留", - "values": {} - }, - { - "id": 10, - "display_name": "预留DP2", - "key": "reserva_dp2", - "kind": "normal", - "type": "uint32", - "len": 4, - "scale": 1.0, - "dir": "rw", - "description": "预留", - "values": {} - }, - { - "id": 11, - "display_name": "预留DP3", - "key": "reserva_dp3", - "kind": "normal", - "type": "uint32", - "len": 4, - "scale": 1.0, - "dir": "rw", - "description": "预留", - "values": {} - } - ] + "product": { + "name": "弹力魔盒", + "code": "PICBC4", + "type": "CBC4", + "protocol": "V1.0.0" + }, + "dps": [ + { + "id": 0, + "display_name": "开关", + "key": "power", + "kind": "normal", + "type": "bool", + "len": 1, + "scale": 1, + "dir": "rw", + "description": "设备总开关", + "values": { + "1": "开", + "0": "关" + } + }, + { + "id": 1, + "display_name": "自动模式", + "key": "play_mode", + "kind": "normal", + "type": "enum", + "len": 1, + "scale": 1, + "dir": "rw", + "description": "5种玩法,按键也可切换并上报", + "values": { + "5": "上下电机随机组合", + "4": "上部慢探、下部随机摇摆", + "0": "停止复位", + "3": "上部间歇、下部均匀摇摆", + "2": "上部快速往复", + "1": "上部慢速往复" + } + }, + { + "id": 2, + "display_name": "手动模式", + "key": "hand_mode", + "kind": "normal", + "type": "enum", + "len": 1, + "scale": 1, + "dir": "wo", + "description": "上部或下部电机单次探出,最长5秒", + "values": { + "2": "下部探出", + "1": "上部探出", + "0": "停止" + } + }, + { + "id": 3, + "display_name": "低电量报警", + "key": "alm_low_battery", + "kind": "alarm", + "type": "bool", + "len": 1, + "scale": 1, + "dir": "ro", + "description": "低电量告警", + "values": { + "1": "告警", + "0": "正常" + }, + "level": 1 + }, + { + "id": 4, + "display_name": "声音开关", + "key": "beep_trig", + "kind": "normal", + "type": "bool", + "len": 1, + "scale": 1, + "dir": "rw", + "description": "声音触发开关", + "values": { + "1": "开", + "0": "关" + } + }, + { + "id": 5, + "display_name": "电量", + "key": "battery", + "kind": "normal", + "type": "uint8", + "len": 1, + "scale": 1, + "dir": "ro", + "description": "电量上报", + "values": { + + } + }, + { + "id": 6, + "display_name": "震动开机", + "key": "shake_wake", + "kind": "normal", + "type": "bool", + "len": 1, + "scale": 1, + "dir": "rw", + "description": "震动触发开机", + "values": { + "1": "开", + "0": "关" + } + }, + { + "id": 7, + "display_name": "勿扰模式", + "key": "no_disturb_enable", + "kind": "normal", + "type": "raw", + "len": 13, + "scale": 1, + "dir": "rw", + "description": "APP控制勿扰模式", + "values": { + + } + }, + { + "id": 8, + "display_name": "充电状态", + "key": "charge", + "kind": "normal", + "type": "enum", + "len": 1, + "scale": 1, + "dir": "ro", + "description": "充电状态上报", + "values": { + "2": "未充电", + "1": "充电中", + "0": "不支持充电" + } + }, + { + "id": 10, + "display_name": "预留DP3", + "key": "reserva_dp3", + "kind": "normal", + "type": "uint32", + "len": 4, + "scale": 1, + "dir": "rw", + "description": "预留", + "values": { + + } + } + ] } diff --git a/include_lib/system/syscfg_id.h b/include_lib/system/syscfg_id.h index 5fba4f4..d47ce4d 100644 --- a/include_lib/system/syscfg_id.h +++ b/include_lib/system/syscfg_id.h @@ -172,6 +172,7 @@ u8 *syscfg_ptr_read(u16 item_id, u16 *len); #define CFG_USER_PLAN_INFO1 25+1 #define CFG_USER_BATTERY_LEVEL 26+1 +#define CFG_USER_NO_DISTURB 28 #define CFG_USER_DEFINE_END 49