Compare commits

...

3 Commits

Author SHA1 Message Date
5b4353d94f feat(ble): 使用Zephyr BAS服务替换自定义电池服务实现
- 在prj.conf中启用CONFIG_BT_BAS、CONFIG_BT_DIS和CONFIG_BT_DIS_PNP配置项
- 移除自定义的电池服务实现代码
- 改用zephyr/bluetooth/services/bas.h提供的标准BAS服务API
- 简化电池状态事件处理逻辑,直接调用bt_bas_set_battery_level设置电池级别
- 移除手动GATT通知实现,依赖系统BAS服务自动处理通知功能
2026-04-01 10:48:05 +08:00
302df0230d feat(app): 使用传感器驱动重构电池和模式切换模块
- 将电池模块从ADC直接采样改为使用sensor子系统,通过battery_sense传感器获取电压
- 将模式切换模块从ADC采样改为使用mode_sense传感器获取模式电压
- 移除GPIO控制的电池使能脚,改用传感器的PM管理机制
- 更新DTS配置,移除大量设备状态设置,添加boot-mode保留内存支持

perf(pm): 调整分区大小以支持单应用引导模式

- 将mcuboot分区从0xc000扩大到0x100,为单应用模式提供更大空间
- 相应调整app分区地址布局,确保内存分配合理
- 移除secondary镜像相关配置,优化flash使用

refactor(boot): 添加MCUBOOT单应用模式配置

- 在sysbuild中启用单应用模式支持
- 为引导加载程序添加保留内存和启动模式配置
- 配置CDC ACM串口用于引导模式通信
2026-03-31 15:09:23 +08:00
82be5cae52 docs: 添加 Nordic NCS 和 Zephyr 官方知识索引文档
添加了两个新的文档文件:
- nordic_ncs_官方知识索引.md:收录 Nordic NCS 官方文档链接,
包括 Zephyr 镜像文档、CAF 框架、Partition Manager 等相关内容
- zephyr_官方知识索引.md:收录 Zephyr 官方文档链接,
涵盖构建配置、设备树、内核并发、蓝牙、USB、外设驱动等模块

这两个索引文档基于项目实际使用的 nrf52840 芯片和 NCS 3.2.3 版本,
通过浏览器渲染验证确保链接有效性,并按功能模块进行分类整理。
2026-03-31 08:36:40 +08:00
11 changed files with 465 additions and 318 deletions

View File

@@ -2,16 +2,7 @@
/ { / {
chosen { chosen {
zephyr,display = &st7789v3; zephyr,boot-mode = &boot_mode0;
};
aliases {
backlight = &backlight;
};
zephyr,user {
vbat-en-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
io-channels = <&adc 5>, <&adc 7>;
}; };
hid_dev_0: hid_dev_0 { hid_dev_0: hid_dev_0 {
@@ -45,64 +36,12 @@
}; };
}; };
&gpio0 { &gpregret1 {
status = "okay";
};
&gpio1 {
status = "okay";
};
&gpiote {
status = "okay";
};
&led_0 {
status = "okay";
};
&led_1 {
status = "okay";
};
/* 使能 SAADCmode_switch_module 使用 channel 7 采样模式拨码电压。 */
&adc {
status = "okay";
};
&i2c1 {
status = "okay"; status = "okay";
ip5305: pmic@75 { boot_mode0: boot_mode@0 {
compatible = "zephyr,retention";
status = "okay"; status = "okay";
keepalive-interval-ms = <10000>; reg = <0x0 0x1>;
}; };
}; };
&usbd {
status = "okay";
};
qdec: &qdec {
status = "okay";
};
&spi3 {
status = "okay";
};
&mipi_dbi {
status = "okay";
};
&st7789v3 {
status = "okay";
};
&pwm_leds {
status = "okay";
};
&pwm0 {
status = "okay";
};

View File

@@ -0,0 +1,118 @@
# new_kbd 项目 Nordic NCS 官方知识索引
## 说明
- 生成时间2026-03-30
- 文档来源:仅收录 `docs.nordicsemi.com` 上可直接访问的 Nordic 官方文档
- 版本基线:按项目当前环境优先核对 `ncs-3.2.3`
- 项目芯片基线:`atguigu_mini_keyboard/nrf52840`
- 芯片依据:项目板级文件 [atguigu_mini_keyboard.yaml](E:/extra/boards/atguigu/atguigu_mini_keyboard/atguigu_mini_keyboard.yaml) 与 [atguigu_mini_keyboard.dts](E:/extra/boards/atguigu/atguigu_mini_keyboard/atguigu_mini_keyboard.dts) 明确基于 `nrf52840`
- 收录范围:仅收录 `E:\projects\new_kbd` 实际使用到的 NCS 官方知识,以及 Nordic 站点中同时存在的 Zephyr 镜像文档
- 不收录原则:如果没有核到 Nordic 官方页面,则不写入本索引
- 本版校验方式:使用浏览器渲染后再判定,凡标题或正文渲染为 `Error 404 - Page Not Found` / `ERROR CODE: 404` 的页面,均视为无效并移除
## NCS 托管的 Zephyr 文档镜像
### 构建与配置
- [应用开发总览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/develop/application/index.html)
- [CMake 构建系统NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/cmake/index.html)
- [Kconfig 配置系统NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/kconfig/index.html)
- [Sysbuild 系统构建NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/sysbuild/index.html)
### 设备树与设备模型
- [设备树入门NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/intro.html)
- [设备树 HOWTONCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/howtos.html)
- [设备树 C/C++ API 用法NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/api-usage.html)
- [zephyr,user 自定义节点NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/zephyr-user-node.html)
### 内核与并发
- [工作队列与延迟工作NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/kernel/services/threads/workqueue.html)
- [原子操作NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/kernel/services/other/atomic.html)
- [自旋锁 APINCS 镜像)](https://docs.nordicsemi.com/bundle/zephyr-apis-3.2.3/page/spinlock_8h.html)
- [时钟、超时与 uptimeNCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/kernel/services/timing/clocks.html)
### 日志与存储
- [日志子系统NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/services/logging/index.html)
- [Settings 设置子系统NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/services/storage/settings/index.html)
- [NVS 非易失存储NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/services/storage/nvs/nvs.html)
- [Flash Map 闪存映射NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/services/storage/flash_map/flash_map.html)
### 蓝牙 Low Energy
- [Bluetooth GAP 概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/bluetooth/api/gap.html)
- [Bluetooth 连接管理NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/bluetooth/api/connection_mgmt.html)
- [Bluetooth GATT 概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/bluetooth/api/gatt.html)
- [Bluetooth 标准服务总览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/bluetooth/api/services.html)
### USB 与 HID
- [USB 设备栈Device Stack NextNCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/usb/device_next/usb_device.html)
- [USB HID 设备 APINCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/usb/device_next/api/usbd_hid_device.html)
- [HID 通用定义与报告描述符NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/connectivity/usb/api/hid.html)
### 外设驱动
- [ADC 外设概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/hardware/peripherals/adc.html)
- [GPIO 外设概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/hardware/peripherals/gpio.html)
- [I2C 外设概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/hardware/peripherals/i2c.html)
- [传感器子系统概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/hardware/peripherals/sensor/index.html)
- [LED 外设概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/hardware/peripherals/led.html)
### 显示与 GUI
- [显示子系统概览NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/hardware/peripherals/display/index.html)
- [PWM LEDs 设备树绑定NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/api/bindings/led/pwm-leds.html)
- [GPIO LEDs 设备树绑定NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/api/bindings/led/gpio-leds.html)
- [LVGL 官方示例入口NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/samples/modules/lvgl/lvgl.html)
### 通用工具宏与字节序
- [sys/byteorder 字节序 APINCS 镜像)](https://docs.nordicsemi.com/bundle/zephyr-apis-3.2.3/page/sys_2byteorder_8h.html)
- [spinlock 文件参考NCS API 镜像)](https://docs.nordicsemi.com/bundle/zephyr-apis-3.2.3/page/spinlock_8h.html)
## Partition Manager 与存储布局
- [Partition Manager](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/scripts/partition_manager/partition_manager.html)
## CAF 总览与基础设施
- [Common Application Framework (CAF) 总览](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/caf/caf_overview.html)
- [Application Event Manager](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/others/app_event_manager.html)
- [Application Event Manager Profiler Tracer](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/others/app_event_manager_profiler_tracer.html)
## CAF 模块
- [CAF Buttons 模块](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/caf/buttons.html)
- [CAF LEDs 模块](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/caf/leds.html)
- [CAF BLE Advertising 模块](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/caf/ble_adv.html)
- [CAF BLE State 模块](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/caf/ble_state.html)
- [CAF Power Manager 模块](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/libraries/caf/power_manager.html)
- [Settings Loader](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/nrf/applications/nrf_desktop/doc/settings_loader.html)
## CAF API / 辅助定义
- [led_effect API](https://docs.nordicsemi.com/bundle/nrf-apis-3.2.3/page/group_led_effect_CAF.html)
## 芯片与 Nordic 外设相关
- [nRF52840 驱动索引](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/nrf52840_drivers.html)
- [nRF52840 DK 用户指南](https://docs.nordicsemi.com/bundle/ug_nrf52840_dk)
- [Nordic nRF USBD 设备树绑定NCS 镜像)](https://docs.nordicsemi.com/bundle/ncs-3.2.3/page/zephyr/build/dts/api/bindings/usb/nordic_nrf-usbd.html)
- [nrf_qdec HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_qdec.html)
- [nrf_saadc HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_saadc.html)
- [nrf_usbd HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_usbd.html)
- [nrf_gpio HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_gpio.html)
- [nrf_pwm HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_pwm.html)
- [nrf_spi HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_spi.html)
- [nrf_twim HAL / 寄存器 API](https://docs.nordicsemi.com/bundle/nrfx-apis-3.2.3/page/group_nrf_twim.html)
## 备注
- `pm_static.yml` 相关内容,本次仅核到 Nordic 官方的 Partition Manager 页面;未单独核到专门以 `pm_static.yml` 命名的独立官方页面,因此这里索引到 Partition Manager 官方文档
- Zephyr 侧已经收录的知识,只要在 Nordic 站点存在并通过浏览器渲染校验,本索引也一并收录
- 芯片相关知识本次按项目实际硬件基线 `nrf52840` 收录,没有扩展到未使用的其他 Nordic SoC
- 当前 Nordic 站点里,很多 `zephyr-apis-3.2.3``nrf-apis-3.2.3` 与部分 CAF 事件页虽然返回 `200`,但浏览器渲染后是 `Error 404 - Page Not Found`,因此已从本索引移除

View File

@@ -0,0 +1,96 @@
# new_kbd 项目 Zephyr 官方知识索引
## 说明
- 生成时间2026-03-30
- 扫描范围:`src/``inc/``prj.conf``sysbuild.conf``app.overlay``pm_static.yml`
- 收录原则:仅收录 `E:\projects\new_kbd` 当前实际用到、且已确认页面真实存在的 Zephyr 官方文档
- 链接范围:`https://docs.zephyrproject.org/latest/``https://docs.zephyrproject.org/apidoc/latest/``https://docs.zephyrproject.org/latest/doxygen/html/`
- 不收录范围Nordic NCS/CAF/App Event Manager/Partition Manager 文档,以及项目自定义驱动或项目私有协议说明
- Nordic NCS 官方补充索引见:[new_kbd 项目 Nordic NCS 官方知识索引](./nordic_ncs_官方知识索引.md)
## 构建与配置
- [应用开发总览](https://docs.zephyrproject.org/latest/develop/application/index.html)
- [CMake 构建系统](https://docs.zephyrproject.org/latest/build/cmake/index.html)
- [Kconfig 配置系统](https://docs.zephyrproject.org/latest/build/kconfig/index.html)
- [Sysbuild 系统构建](https://docs.zephyrproject.org/latest/build/sysbuild/index.html)
## 设备树与设备模型
- [设备树入门](https://docs.zephyrproject.org/latest/build/dts/intro.html)
- [设备树 HOWTO](https://docs.zephyrproject.org/latest/build/dts/howtos.html)
- [设备树 C/C++ API 用法](https://docs.zephyrproject.org/latest/build/dts/api-usage.html)
- [zephyr,user 自定义节点](https://docs.zephyrproject.org/latest/build/dts/zephyr-user-node.html)
- [设备模型 API](https://docs.zephyrproject.org/apidoc/latest/group__device__model.html)
- [设备树通用标识符 API](https://docs.zephyrproject.org/apidoc/latest/group__devicetree-generic-id.html)
## 内核与并发
- [工作队列与延迟工作](https://docs.zephyrproject.org/latest/kernel/services/threads/workqueue.html)
- [原子操作](https://docs.zephyrproject.org/latest/kernel/services/other/atomic.html)
- [自旋锁 API](https://docs.zephyrproject.org/apidoc/latest/spinlock_8h.html)
- [时钟、超时与 uptime](https://docs.zephyrproject.org/latest/kernel/services/timing/clocks.html)
## 日志与存储
- [日志子系统](https://docs.zephyrproject.org/latest/services/logging/index.html)
- [Settings 设置子系统](https://docs.zephyrproject.org/latest/services/storage/settings/index.html)
- [NVS 非易失存储](https://docs.zephyrproject.org/latest/services/storage/nvs/nvs.html)
- [Flash Map 闪存映射](https://docs.zephyrproject.org/latest/services/storage/flash_map/flash_map.html)
## 蓝牙 Low Energy
- [Bluetooth GAP 概览](https://docs.zephyrproject.org/latest/connectivity/bluetooth/api/gap.html)
- [Bluetooth GAP API](https://docs.zephyrproject.org/apidoc/latest/group__bt__gap.html)
- [Bluetooth 连接管理](https://docs.zephyrproject.org/latest/connectivity/bluetooth/api/connection_mgmt.html)
- [Bluetooth 连接管理 API](https://docs.zephyrproject.org/apidoc/latest/group__bt__conn.html)
- [Bluetooth GATT 概览](https://docs.zephyrproject.org/latest/connectivity/bluetooth/api/gatt.html)
- [Bluetooth GATT Server API](https://docs.zephyrproject.org/apidoc/latest/group__bt__gatt__server.html)
- [Bluetooth UUID API](https://docs.zephyrproject.org/apidoc/latest/group__bt__uuid.html)
- [Bluetooth Battery Service (BAS) API](https://docs.zephyrproject.org/apidoc/latest/group__bt__bas.html)
- [Bluetooth 标准服务总览](https://docs.zephyrproject.org/latest/connectivity/bluetooth/api/services.html)
- [BLE HID 外设官方示例](https://docs.zephyrproject.org/latest/samples/bluetooth/peripheral_hids/README.html)
## USB 与 HID
- [USB 设备栈Device Stack Next](https://docs.zephyrproject.org/latest/connectivity/usb/device_next/usb_device.html)
- [USB Device API](https://docs.zephyrproject.org/apidoc/latest/group__usbd__api.html)
- [USB HID 设备 API](https://docs.zephyrproject.org/latest/connectivity/usb/device_next/api/usbd_hid_device.html)
- [USB HID Device API 参考](https://docs.zephyrproject.org/apidoc/latest/group__usbd__hid__device.html)
- [HID 通用定义与报告描述符](https://docs.zephyrproject.org/latest/connectivity/usb/api/hid.html)
- [zephyr,hid-device 设备树绑定](https://docs.zephyrproject.org/latest/build/dts/api/bindings/usb/zephyr%2Chid-device.html)
## 外设驱动
- [ADC 外设概览](https://docs.zephyrproject.org/latest/hardware/peripherals/adc.html)
- [ADC API](https://docs.zephyrproject.org/apidoc/latest/group__adc__interface.html)
- [GPIO 外设概览](https://docs.zephyrproject.org/latest/hardware/peripherals/gpio.html)
- [GPIO API](https://docs.zephyrproject.org/apidoc/latest/group__gpio__interface.html)
- [I2C 外设概览](https://docs.zephyrproject.org/latest/hardware/peripherals/i2c.html)
- [传感器子系统概览](https://docs.zephyrproject.org/latest/hardware/peripherals/sensor/index.html)
- [传感器 API](https://docs.zephyrproject.org/apidoc/latest/group__sensor__interface.html)
- [LED 外设概览](https://docs.zephyrproject.org/latest/hardware/peripherals/led.html)
- [LED API](https://docs.zephyrproject.org/apidoc/latest/group__led__interface.html)
- [Nordic nRF QDEC 设备树绑定](https://docs.zephyrproject.org/latest/build/dts/api/bindings/sensor/nordic%2Cnrf-qdec.html)
## 显示与 GUI
- [显示子系统概览](https://docs.zephyrproject.org/latest/hardware/peripherals/display/index.html)
- [MIPI-DBI SPI 设备树绑定](https://docs.zephyrproject.org/latest/build/dts/api/bindings/mipi-dbi/zephyr%2Cmipi-dbi-spi.html)
- [ST7789V 设备树绑定](https://docs.zephyrproject.org/latest/build/dts/api/bindings/display/sitronix%2Cst7789v.html)
- [PWM LEDs 设备树绑定](https://docs.zephyrproject.org/latest/build/dts/api/bindings/led/pwm-leds.html)
- [GPIO LEDs 设备树绑定](https://docs.zephyrproject.org/latest/build/dts/api/bindings/led/gpio-leds.html)
- [LVGL 官方示例入口](https://docs.zephyrproject.org/latest/samples/modules/lvgl/lvgl.html)
## 通用工具宏与字节序
- [sys/util 通用工具宏 API](https://docs.zephyrproject.org/apidoc/latest/group__sys-util.html)
- [sys/byteorder 字节序 API](https://docs.zephyrproject.org/latest/doxygen/html/sys_2byteorder_8h.html)
## 未纳入本索引的项目项
- `zephyr/drivers/power/ip5305.h``CONFIG_IP5305`:当前项目使用的是自定义驱动/自定义绑定Zephyr 官方 latest 站点未核到对应官方页面,因此未纳入
- `pm_static.yml` 对应的 Partition Manager 规划:属于 Nordic NCS 范畴,不属于 Zephyr 官方 docs 站点范围Nordic 官方索引见 [nordic_ncs_官方知识索引.md](./nordic_ncs_官方知识索引.md)
- `CAF``App Event Manager``settings_loader``ble_state``ble_common_event``power_manager``buttons_def.h` 等:属于 Nordic NCS/CAF 文档范围,不属于本 Zephyr 官方索引Nordic 官方索引见 [nordic_ncs_官方知识索引.md](./nordic_ncs_官方知识索引.md)
- 项目私有协议与实现,如时间同步私有 GATT 服务、主机 HID 命令协议、显示主题持久化逻辑等:只索引其依赖的 Zephyr 通用能力,不索引项目私有设计本身

View File

@@ -1,37 +1,31 @@
mcuboot: mcuboot:
address: 0x0 address: 0x0
end_address: 0xc000 end_address: 0x10000
region: flash_primary region: flash_primary
size: 0xc000 size: 0x10000
mcuboot_pad: mcuboot_pad:
address: 0xc000 address: 0x10000
end_address: 0xc200 end_address: 0x10200
region: flash_primary region: flash_primary
size: 0x200 size: 0x200
app: app:
address: 0xc200 address: 0x10200
end_address: 0x82000 end_address: 0xf8000
region: flash_primary region: flash_primary
size: 0x75e00 size: 0xe7e00
mcuboot_primary: mcuboot_primary:
address: 0xc000 address: 0x10000
end_address: 0x82000 end_address: 0xf8000
orig_span: &id001 orig_span: &id001
- mcuboot_pad - mcuboot_pad
- app - app
region: flash_primary region: flash_primary
size: 0x76000 size: 0xe8000
span: *id001 span: *id001
mcuboot_secondary:
address: 0x82000
end_address: 0xf8000
region: flash_primary
size: 0x76000
settings_storage: settings_storage:
address: 0xf8000 address: 0xf8000
end_address: 0x100000 end_address: 0x100000

View File

@@ -16,6 +16,10 @@ CONFIG_MCUMGR_GRP_OS=n
CONFIG_IMG_MANAGER=n CONFIG_IMG_MANAGER=n
CONFIG_STREAM_FLASH=n CONFIG_STREAM_FLASH=n
CONFIG_RETAINED_MEM=y
CONFIG_RETENTION=y
CONFIG_RETENTION_BOOT_MODE=y
CONFIG_BT=y CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y CONFIG_BT_PERIPHERAL=y
CONFIG_BT_SMP=y CONFIG_BT_SMP=y
@@ -55,6 +59,9 @@ CONFIG_BT_HIDS_ATTR_MAX=40
CONFIG_BT_HIDS_INPUT_REP_MAX=4 CONFIG_BT_HIDS_INPUT_REP_MAX=4
CONFIG_BT_HIDS_OUTPUT_REP_MAX=3 CONFIG_BT_HIDS_OUTPUT_REP_MAX=3
CONFIG_BT_HIDS_FEATURE_REP_MAX=0 CONFIG_BT_HIDS_FEATURE_REP_MAX=0
CONFIG_BT_BAS=y
CONFIG_BT_DIS=y
CONFIG_BT_DIS_PNP=y
CONFIG_USB_DEVICE_STACK_NEXT=y CONFIG_USB_DEVICE_STACK_NEXT=y
CONFIG_USBD_HID_SUPPORT=y CONFIG_USBD_HID_SUPPORT=y

View File

@@ -2,9 +2,9 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/device.h> #include <zephyr/device.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/power/ip5305.h> #include <zephyr/drivers/power/ip5305.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/atomic.h> #include <zephyr/sys/atomic.h>
#include <zephyr/sys/util.h> #include <zephyr/sys/util.h>
@@ -20,11 +20,8 @@
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(MODULE); LOG_MODULE_REGISTER(MODULE);
#define BATTERY_USER_NODE DT_PATH(zephyr_user) #define BATTERY_SENSE_NODE DT_NODELABEL(battery_sense)
#define BATTERY_ADC_IO_CH_IDX 1
#define BATTERY_SAMPLE_INTERVAL_MS 1000 #define BATTERY_SAMPLE_INTERVAL_MS 1000
#define BATTERY_VDIV_NUM 2
#define BATTERY_VDIV_DEN 1
#define BATTERY_MV_WINDOW_SIZE 10 #define BATTERY_MV_WINDOW_SIZE 10
/* /*
@@ -35,18 +32,26 @@ LOG_MODULE_REGISTER(MODULE);
#define BATTERY_EMPTY_MV 3300 #define BATTERY_EMPTY_MV 3300
#define BATTERY_FULL_MV 4100 #define BATTERY_FULL_MV 4100
static const struct adc_dt_spec battery_adc = static const struct device *const ip5305_dev = DEVICE_DT_GET(DT_NODELABEL(ip5305));
ADC_DT_SPEC_GET_BY_IDX(BATTERY_USER_NODE, BATTERY_ADC_IO_CH_IDX); static const struct device *const battery_sensor_dev = DEVICE_DT_GET(BATTERY_SENSE_NODE);
/* /*
* 电池采样使能脚从 zephyr,user/vbat-en-gpios 读取,避免把引脚号硬编码在 C 里。 * 板级电源采样结果:
* 后续板级改脚位只需改 DTS不需要改固件代码。 * - 由 board provider 负责给出“原始但可用”的充电状态与电压值;
* - 本模块基于这些采样结果做滤波、SOC 估算和事件发布。
*/ */
static const struct gpio_dt_spec battery_en_gpio = struct board_power_sample
GPIO_DT_SPEC_GET(BATTERY_USER_NODE, vbat_en_gpios); {
int32_t voltage_mv;
static const struct device *const ip5305_dev = DEVICE_DT_GET(DT_NODELABEL(ip5305)); bool charging;
bool full;
};
/*
* 对外上报状态:
* - 保持现有 battery_status_event 语义不变;
* - 只承载业务层需要的 charging/full/soc 三元组。
*/
struct battery_status struct battery_status
{ {
bool charging; bool charging;
@@ -62,10 +67,16 @@ struct battery_filter_state
size_t index; size_t index;
}; };
/*
* 模块上下文:
* - sample_work 周期性拉取 board power sample
* - filter 负责平滑电池电压;
* - last_status 用于抑制重复事件;
* - pm_restrict_level 跟踪当前对 power manager 的限制等级。
*/
struct battery_ctx struct battery_ctx
{ {
struct k_work_delayable sample_work; struct k_work_delayable sample_work;
int16_t adc_sample_buffer;
atomic_t active; atomic_t active;
struct battery_status last_status; struct battery_status last_status;
bool has_last_status; bool has_last_status;
@@ -77,17 +88,14 @@ static struct battery_ctx battery = {
.pm_restrict_level = POWER_MANAGER_LEVEL_MAX, .pm_restrict_level = POWER_MANAGER_LEVEL_MAX,
}; };
static void battery_module_resume(void); /* 线性 SOC 估算:把平滑后的电池电压映射到 0~100%。 */
static uint8_t soc_from_mv(int32_t mv) static uint8_t soc_from_mv(int32_t mv)
{ {
if (mv <= BATTERY_EMPTY_MV) if (mv <= BATTERY_EMPTY_MV) {
{
return 0; return 0;
} }
if (mv >= BATTERY_FULL_MV) if (mv >= BATTERY_FULL_MV) {
{
return 100; return 100;
} }
@@ -95,109 +103,126 @@ static uint8_t soc_from_mv(int32_t mv)
return (uint8_t)CLAMP(soc, 0, 100); return (uint8_t)CLAMP(soc, 0, 100);
} }
static int adc_sample_once_mv(int32_t *mv) /* 初始化/恢复时清空滤波器,避免旧样本影响新一轮估算。 */
static void battery_filter_reset(void)
{ {
struct adc_sequence sequence = {0}; battery.filter.sum = 0;
int err = adc_sequence_init_dt(&battery_adc, &sequence); battery.filter.count = 0;
if (err) battery.filter.index = 0;
{
return err;
}
sequence.buffer = &battery.adc_sample_buffer;
sequence.buffer_size = sizeof(battery.adc_sample_buffer);
err = adc_read_dt(&battery_adc, &sequence);
if (err)
{
LOG_WRN("adc_read_dt failed (err=%d)", err);
return err;
}
*mv = battery.adc_sample_buffer;
err = adc_raw_to_millivolts_dt(&battery_adc, mv);
if (err)
{
LOG_WRN("adc_raw_to_millivolts_dt failed (err=%d raw=%d)",
err, battery.adc_sample_buffer);
}
return err;
}
static int read_battery_mv(int32_t *mv)
{
int err;
int32_t sensed_mv;
err = adc_sample_once_mv(&sensed_mv);
if (err)
{
return err;
} }
/* /*
* 板级电池检测存在分压ADC 读到的是分压后电压 * 将最新电压样本写入固定窗口平均滤波器
* 这里按分压比还原电池端真实电压,供 SOC 估算与事件上报使用 * 返回值始终是“窗口平均后的电池电压,供上层做 SOC 估算。
*/ */
int32_t battery_mv = (sensed_mv * BATTERY_VDIV_NUM) / BATTERY_VDIV_DEN; static int32_t battery_filter_apply(int32_t voltage_mv)
/*
* 使用固定窗口平均抑制采样抖动。
* 窗口未填满前按当前样本数求平均,填满后使用环形缓冲滚动更新。
*/
if (battery.filter.count < BATTERY_MV_WINDOW_SIZE)
{ {
battery.filter.window[battery.filter.index] = battery_mv; if (battery.filter.count < BATTERY_MV_WINDOW_SIZE) {
battery.filter.sum += battery_mv; battery.filter.window[battery.filter.index] = voltage_mv;
battery.filter.sum += voltage_mv;
battery.filter.count++; battery.filter.count++;
} } else {
else
{
battery.filter.sum -= battery.filter.window[battery.filter.index]; battery.filter.sum -= battery.filter.window[battery.filter.index];
battery.filter.window[battery.filter.index] = battery_mv; battery.filter.window[battery.filter.index] = voltage_mv;
battery.filter.sum += battery_mv; battery.filter.sum += voltage_mv;
} }
battery.filter.index = (battery.filter.index + 1U) % BATTERY_MV_WINDOW_SIZE; battery.filter.index = (battery.filter.index + 1U) % BATTERY_MV_WINDOW_SIZE;
*mv = (int32_t)(battery.filter.sum / (int64_t)battery.filter.count); return (int32_t)(battery.filter.sum / (int64_t)battery.filter.count);
}
/*
* 控制 board-provided battery_sense sensor 的供电状态。
* 这里不直接操纵 GPIO而是走 sensor 的 PM action让 power-gpios
* 与 ADC runtime PM 都由 voltage-divider 驱动统一管理。
*/
static int board_power_monitor_set_voltage_sensor_enabled(bool enable)
{
return pm_device_action_run(battery_sensor_dev,
enable ? PM_DEVICE_ACTION_RESUME :
PM_DEVICE_ACTION_SUSPEND);
}
/* 从 battery_sense 读取一次当前电池电压(单位 mV。 */
static int board_power_monitor_read_voltage_mv(int32_t *voltage_mv)
{
struct sensor_value value;
int err = sensor_sample_fetch(battery_sensor_dev);
if (err) {
LOG_WRN("sensor_sample_fetch(battery) failed (err=%d)", err);
return err;
}
err = sensor_channel_get(battery_sensor_dev, SENSOR_CHAN_VOLTAGE, &value);
if (err) {
LOG_WRN("sensor_channel_get(battery) failed (err=%d)", err);
return err;
}
*voltage_mv = (int32_t)sensor_value_to_milli(&value);
return 0;
}
/* 从 IP5305 读取一次充电态与满电态。 */
static int board_power_monitor_read_charge_state(bool *charging, bool *full)
{
int err = ip5305_is_charging(ip5305_dev, charging);
if (err) {
LOG_WRN("ip5305_is_charging failed (err=%d)", err);
return err;
}
err = ip5305_is_charge_full(ip5305_dev, full);
if (err) {
LOG_WRN("ip5305_is_charge_full failed (err=%d)", err);
return err;
}
return 0; return 0;
} }
static int read_battery_status(struct battery_status *status) /*
* 聚合一次完整的 board power sample
* 1) 先读 PMIC 状态;
* 2) 再读 battery_sense 电压;
* 3) 最后对电压做窗口平均,输出稳定值。
*/
static int board_power_monitor_collect_sample(struct board_power_sample *sample)
{ {
int err; int32_t voltage_mv;
int32_t mv; int err = board_power_monitor_read_charge_state(&sample->charging, &sample->full);
err = ip5305_is_charging(ip5305_dev, &status->charging); if (err) {
if (err)
{
return err; return err;
} }
err = ip5305_is_charge_full(ip5305_dev, &status->full); err = board_power_monitor_read_voltage_mv(&voltage_mv);
if (err) if (err) {
{
return err; return err;
} }
err = read_battery_mv(&mv); sample->voltage_mv = battery_filter_apply(voltage_mv);
if (err)
{
LOG_WRN("read_battery_mv failed (err=%d)", err);
return err;
}
status->soc = soc_from_mv(mv);
return 0; return 0;
} }
/* 将 board sample 映射成对外 battery status。 */
static void battery_status_from_sample(const struct board_power_sample *sample,
struct battery_status *status)
{
status->charging = sample->charging;
status->full = sample->full;
status->soc = soc_from_mv(sample->voltage_mv);
}
/* 统一封装 battery_status_event 发布,隔离事件总线细节。 */
static void publish_battery_status_event(const struct battery_status *status) static void publish_battery_status_event(const struct battery_status *status)
{ {
battery_status_event_submit(status->charging, status->full, status->soc); battery_status_event_submit(status->charging, status->full, status->soc);
} }
/* 判断本轮状态是否值得上报,避免重复事件淹没总线。 */
static bool battery_status_changed(const struct battery_status *lhs, static bool battery_status_changed(const struct battery_status *lhs,
const struct battery_status *rhs) const struct battery_status *rhs)
{ {
@@ -223,99 +248,79 @@ static void update_power_restrict_by_charging(bool charging)
power_manager_restrict(MODULE_IDX(MODULE), target); power_manager_restrict(MODULE_IDX(MODULE), target);
} }
/*
* 启停采样:
* - enable=true 时恢复 battery_sense等待前端稳定后开始周期采样
* - enable=false 时停止 work 并挂起 battery_sense避免持续耗电。
*/
static void battery_sampling_set_enabled(bool enable) static void battery_sampling_set_enabled(bool enable)
{ {
atomic_set(&battery.active, enable); atomic_set(&battery.active, enable);
(void)gpio_pin_set_dt(&battery_en_gpio, enable ? GPIO_OUTPUT_ACTIVE : GPIO_OUTPUT_INACTIVE); int err = board_power_monitor_set_voltage_sensor_enabled(enable);
if (enable) if (err) {
{ LOG_WRN("board_power_monitor_set_voltage_sensor_enabled(%d) failed (err=%d)",
// 延迟2s开始采样等待电池电压稳定 enable, err);
k_work_reschedule(&battery.sample_work, K_MSEC(2000));
} }
else
{ if (enable) {
/* 延迟开始采样,等待板上采样前端和分压网络稳定。 */
k_work_reschedule(&battery.sample_work, K_MSEC(2000));
} else {
(void)k_work_cancel_delayable(&battery.sample_work); (void)k_work_cancel_delayable(&battery.sample_work);
} }
} }
/* 周期性读取 board power sample并在需要时上报业务状态。 */
static void battery_sample_fn(struct k_work *work) static void battery_sample_fn(struct k_work *work)
{ {
ARG_UNUSED(work); ARG_UNUSED(work);
if (!atomic_get(&battery.active)) if (!atomic_get(&battery.active)) {
{
return; return;
} }
struct board_power_sample sample;
struct battery_status status;
int err = board_power_monitor_collect_sample(&sample);
struct battery_status sampled; if (err) {
int err = read_battery_status(&sampled);
if (err)
{
goto out_reschedule; goto out_reschedule;
} }
update_power_restrict_by_charging(sampled.charging); battery_status_from_sample(&sample, &status);
update_power_restrict_by_charging(status.charging);
/*
* 仅在状态发生变化时上报,避免重复事件淹没总线。
* 变化条件充电标志、满电标志、SOC 任意一个变化。
*/
if (!battery.has_last_status || if (!battery.has_last_status ||
battery_status_changed(&sampled, &battery.last_status)) battery_status_changed(&status, &battery.last_status)) {
{ battery.last_status = status;
battery.last_status = sampled;
battery.has_last_status = true; battery.has_last_status = true;
publish_battery_status_event(&sampled); publish_battery_status_event(&status);
} }
out_reschedule: out_reschedule:
k_work_reschedule(&battery.sample_work, K_MSEC(BATTERY_SAMPLE_INTERVAL_MS)); k_work_reschedule(&battery.sample_work, K_MSEC(BATTERY_SAMPLE_INTERVAL_MS));
} }
/* 初始化 board power monitor consumer并拉起首轮采样。 */
static int battery_module_init(void) static int battery_module_init(void)
{ {
if (!device_is_ready(ip5305_dev)) if (!device_is_ready(ip5305_dev)) {
{
LOG_ERR("IP5305 device not ready"); LOG_ERR("IP5305 device not ready");
return -ENODEV; return -ENODEV;
} }
if (!adc_is_ready_dt(&battery_adc)) if (!device_is_ready(battery_sensor_dev)) {
{ LOG_ERR("Battery sense device not ready");
LOG_ERR("Battery ADC device not ready");
return -ENODEV; return -ENODEV;
} }
if (!device_is_ready(battery_en_gpio.port))
{
LOG_ERR("Battery EN GPIO device not ready");
return -ENODEV;
}
int err = gpio_pin_configure_dt(&battery_en_gpio, GPIO_OUTPUT_INACTIVE);
if (err)
{
LOG_ERR("Battery EN GPIO configure failed (err=%d)", err);
return err;
}
err = adc_channel_setup_dt(&battery_adc);
if (err)
{
LOG_ERR("Battery ADC channel setup failed (err=%d)", err);
return err;
}
/* 默认非充电态允许进入 SUSPENDED但禁止进入 OFF。 */ /* 默认非充电态允许进入 SUSPENDED但禁止进入 OFF。 */
update_power_restrict_by_charging(false); update_power_restrict_by_charging(false);
k_work_init_delayable(&battery.sample_work, battery_sample_fn); k_work_init_delayable(&battery.sample_work, battery_sample_fn);
battery.has_last_status = false; battery.has_last_status = false;
battery.filter.sum = 0; battery_filter_reset();
battery.filter.count = 0;
battery.filter.index = 0;
atomic_set(&battery.active, false); atomic_set(&battery.active, false);
battery_sampling_set_enabled(true); battery_sampling_set_enabled(true);
@@ -323,10 +328,10 @@ static int battery_module_init(void)
return 0; return 0;
} }
/* 响应系统挂起:停止采样,并把本模块切到 STANDBY。 */
static void battery_module_suspend(void) static void battery_module_suspend(void)
{ {
if (!atomic_get(&battery.active)) if (!atomic_get(&battery.active)) {
{
/* 已经处于挂起态,避免重复上报 STANDBY 造成 power_down 循环。 */ /* 已经处于挂起态,避免重复上报 STANDBY 造成 power_down 循环。 */
return; return;
} }
@@ -335,10 +340,10 @@ static void battery_module_suspend(void)
module_set_state(MODULE_STATE_STANDBY); module_set_state(MODULE_STATE_STANDBY);
} }
/* 响应系统唤醒:恢复电压传感器并重启周期采样。 */
static void battery_module_resume(void) static void battery_module_resume(void)
{ {
if (atomic_get(&battery.active)) if (atomic_get(&battery.active)) {
{
return; return;
} }
@@ -346,21 +351,18 @@ static void battery_module_resume(void)
module_set_state(MODULE_STATE_READY); module_set_state(MODULE_STATE_READY);
} }
/* 仅处理模块 ready 和系统电源状态事件,保持模块职责单一。 */
static bool app_event_handler(const struct app_event_header *aeh) static bool app_event_handler(const struct app_event_header *aeh)
{ {
if (is_module_state_event(aeh)) if (is_module_state_event(aeh)) {
{
const struct module_state_event *event = cast_module_state_event(aeh); const struct module_state_event *event = cast_module_state_event(aeh);
if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) {
{
int err = battery_module_init(); int err = battery_module_init();
if (err)
{ if (err) {
module_set_state(MODULE_STATE_ERROR); module_set_state(MODULE_STATE_ERROR);
} } else {
else
{
module_set_state(MODULE_STATE_READY); module_set_state(MODULE_STATE_READY);
} }
} }

View File

@@ -1,7 +1,4 @@
#include <errno.h> #include <zephyr/bluetooth/services/bas.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/gatt.h>
#include <app_event_manager.h> #include <app_event_manager.h>
@@ -13,50 +10,13 @@
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
static bool notify_enabled;
static uint8_t battery_level = 100U;
static void bas_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
{
ARG_UNUSED(attr);
notify_enabled = (value == BT_GATT_CCC_NOTIFY);
}
static ssize_t read_battery_level(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
void *buf,
uint16_t len,
uint16_t offset)
{
const uint8_t *value = attr->user_data;
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
}
BT_GATT_SERVICE_DEFINE(ble_battery_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS),
BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL,
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_READ_ENCRYPT,
read_battery_level, NULL, &battery_level),
BT_GATT_CCC(bas_ccc_cfg_changed,
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
);
static bool handle_battery_status_event(const struct battery_status_event *event) static bool handle_battery_status_event(const struct battery_status_event *event)
{ {
battery_level = battery_status_event_get_soc(event); uint8_t battery_level = battery_status_event_get_soc(event);
int err = bt_bas_set_battery_level(battery_level);
if (!notify_enabled) { if (err) {
return false; LOG_ERR("bt_bas_set_battery_level failed: %d", err);
}
int err = bt_gatt_notify(NULL, &ble_battery_svc.attrs[1], &battery_level, sizeof(battery_level));
if (err == -ENOTCONN) {
LOG_WRN("BAS notify skipped: peer disconnecting");
} else if (err) {
LOG_ERR("BAS notify failed: %d", err);
} }
return false; return false;

View File

@@ -1,7 +1,6 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/device.h> #include <zephyr/device.h>
#include <zephyr/drivers/adc.h> #include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/atomic.h> #include <zephyr/sys/atomic.h>
#include <zephyr/sys/util.h> #include <zephyr/sys/util.h>
#include <stdlib.h> #include <stdlib.h>
@@ -18,35 +17,25 @@
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(MODULE); LOG_MODULE_REGISTER(MODULE);
#define MODE_USER_NODE DT_PATH(zephyr_user) #define MODE_SENSE_NODE DT_NODELABEL(mode_sense)
#define MODE_ADC_IO_CH_IDX 0
#define MODE_SAMPLE_INTERVAL_MS 50 #define MODE_SAMPLE_INTERVAL_MS 50
static const struct adc_dt_spec mode_adc = static const struct device *const mode_sensor_dev = DEVICE_DT_GET(MODE_SENSE_NODE);
ADC_DT_SPEC_GET_BY_IDX(MODE_USER_NODE, MODE_ADC_IO_CH_IDX);
static struct k_work_delayable mode_sample_work; static struct k_work_delayable mode_sample_work;
static int16_t adc_sample_buffer;
static atomic_t active; static atomic_t active;
static mode_type_t current_mode; static mode_type_t current_mode;
static uint8_t mode_stable_status; static uint8_t mode_stable_status;
static int init_adc(void) static int init_mode_sensor(void)
{ {
if (!adc_is_ready_dt(&mode_adc)) if (!device_is_ready(mode_sensor_dev))
{ {
LOG_ERR("ADC device not ready"); LOG_ERR("Mode sense device not ready");
return -ENODEV; return -ENODEV;
} }
int err = adc_channel_setup_dt(&mode_adc);
if (err)
{
LOG_ERR("ADC channel setup failed (err=%d)", err);
return err;
}
return 0; return 0;
} }
@@ -81,29 +70,22 @@ static mode_type_t classify_mode_from_mv(int32_t mv)
static int read_mode(mode_type_t *mode) static int read_mode(mode_type_t *mode)
{ {
struct adc_sequence sequence = {0}; struct sensor_value value;
int err = adc_sequence_init_dt(&mode_adc, &sequence); int err = sensor_sample_fetch(mode_sensor_dev);
if (err) if (err)
{ {
LOG_WRN("sensor_sample_fetch(mode) failed (err=%d)", err);
return err; return err;
} }
sequence.buffer = &adc_sample_buffer; err = sensor_channel_get(mode_sensor_dev, SENSOR_CHAN_VOLTAGE, &value);
sequence.buffer_size = sizeof(adc_sample_buffer);
err = adc_read_dt(&mode_adc, &sequence);
if (err)
{
return err;
}
int32_t v = adc_sample_buffer;
err = adc_raw_to_millivolts_dt(&mode_adc, &v);
if (err) if (err)
{ {
LOG_WRN("sensor_channel_get(mode) failed (err=%d)", err);
return err; return err;
} }
int32_t v = (int32_t)sensor_value_to_milli(&value);
*mode = classify_mode_from_mv(v); *mode = classify_mode_from_mv(v);
return 0; return 0;
@@ -187,7 +169,7 @@ static void init_mode_switch(void)
if (atomic_get(&active)) if (atomic_get(&active))
return; return;
if (init_adc()) if (init_mode_sensor())
{ {
module_set_state(MODULE_STATE_ERROR); module_set_state(MODULE_STATE_ERROR);
return; return;

View File

@@ -1 +1,2 @@
SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_BOOTLOADER_MCUBOOT=y
SB_CONFIG_MCUBOOT_MODE_SINGLE_APP=y

25
sysbuild/mcuboot.conf Normal file
View File

@@ -0,0 +1,25 @@
CONFIG_LOG=n
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_REMOTE_WAKEUP=n
CONFIG_USB_CDC_ACM=y
CONFIG_USB_NRFX=y
CONFIG_USB_DEVICE_PRODUCT="MCUBOOT"
CONFIG_USB_DEVICE_MANUFACTURER="new_kbd"
CONFIG_USB_DEVICE_VID=0x1209
CONFIG_USB_DEVICE_PID=0x0002
CONFIG_RETAINED_MEM=y
CONFIG_RETENTION=y
CONFIG_RETENTION_BOOT_MODE=y
CONFIG_MCUBOOT_SERIAL=y
CONFIG_BOOT_SERIAL_CDC_ACM=y
CONFIG_BOOT_SERIAL_BOOT_MODE=y
CONFIG_BOOT_SERIAL_NO_APPLICATION=y

23
sysbuild/mcuboot.overlay Normal file
View File

@@ -0,0 +1,23 @@
/ {
chosen {
zephyr,boot-mode = &boot_mode0;
};
};
&usbd {
status = "okay";
cdc_acm_uart0: cdc_acm_uart0 {
compatible = "zephyr,cdc-acm-uart";
};
};
&gpregret1 {
status = "okay";
boot_mode0: boot_mode@0 {
compatible = "zephyr,retention";
status = "okay";
reg = <0x0 0x1>;
};
};