feat(gml670-v2): 添加工程骨架与构建配置

基于 V1 副本新建 V2 工程,包含 CMakeLists.txt、Kconfig、prj.conf、
app.overlay、README.md 及 ADS1256/GML670 参考数据手册。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-30 17:36:39 +08:00
commit 5492a98687
9 changed files with 655 additions and 0 deletions
+279
View File
@@ -0,0 +1,279 @@
# GML670 Balance Board
> 当前目录是 `GML670x4_V1`。代码内的 CMake 项目名为 `GML670_V2`BLE 设备名为 `GML670_System`。
>
> 本文档是当前工程的总入口说明,重点覆盖已落地的固件行为。更细的协议字段和示例帧见 [BALANCE_BOARD_PROTOCOL.md](./BALANCE_BOARD_PROTOCOL.md)。
---
## 目录
1. [产品概述](#1-产品概述)
2. [硬件组成](#2-硬件组成)
3. [系统架构](#3-系统架构)
4. [功能需求与当前状态](#4-功能需求与当前状态)
5. [BLE 协议规格](#5-ble-协议规格)
6. [ADS1256 / CoP 规格](#6-ads1256--cop-规格)
7. [开发环境与板级配置](#7-开发环境与板级配置)
8. [项目结构](#8-项目结构)
9. [构建与烧录](#9-构建与烧录)
10. [日志与当前约束](#10-日志与当前约束)
---
## 1. 产品概述
本工程是平衡板的 nRF5340 App Core 固件,当前版本的核心能力是:
- 通过 ADS1256 轮询 4 路传感器输入
- 在板端完成去皮、中值滤波和 CoPCenter of Pressure,压力中心)解算
- 通过 BLE NUS 以二进制帧持续上报 CoP 数据
- 接收基站下发的阻力参数、Spotter 模式和心跳帧
当前实现的上行主数据是固定 17 字节的 CoP 帧,发送频率为 50 Hz。阻力、Spotter、Heartbeat 的下行协议已经接入接收路径,但控制逻辑还没有继续向执行器或保护动作落地。
## 2. 硬件组成
当前仓库里能直接确认的硬件如下:
| 器件 | 型号 / 对象 | 接口 | 作用 | 状态 |
|------|-------------|------|------|------|
| 主控 | nRF5340 DK App Core | - | 运行 BLE、SPI 采样和 CoP 解算 | ✅ |
| ADC | ADS1256 | SPI1 | 4 路多通道采样 | ✅ |
| 传感器输入 | 4 路差分输入 | ADS1256 MUX | 用于压力类信号采样 | ✅ |
| 基站链路 | Nordic UART Service | BLE | 上报 CoP、接收控制参数 | ✅ |
| 编码器链路 | 预留 | BLE 协议 | 编码器上行帧结构已定义,固件未发送 | 🔲 |
### ADS1256 相关引脚
`app.overlay` 当前把 ADS1256 绑定到 `spi1`,连线如下:
| 信号 | nRF5340 引脚 | 说明 |
|------|--------------|------|
| SCK | `P1.15` | `spi1` 时钟 |
| MOSI | `P1.13` | `spi1` 主发从收 |
| MISO | `P1.14` | `spi1` 主收从发 |
| CS | `P1.12` | 片选,`GPIO_ACTIVE_LOW` |
| DRDY | `P1.11` | 数据就绪输入 |
| RESET | `P1.10` | ADS1256 复位控制 |
## 3. 系统架构
```text
4 路传感器输入
|
v
ADS1256
|
v
SPI1
|
v
nRF5340 App Core
|
+--> tare / 7 点中值滤波 / CoP 解算
|
+--> BLE NUS Notify --> 基站
|
+<-- BLE NUS Write <-- 基站
| | |
| | +-- Heartbeat
| +------------ Spotter 参数
+--------------------- Resistance 参数
```
当前主循环完成 4 路轮询采样、滤波、CoP 解算和上行发送。下行方向只负责解析三类控制帧并保存参数,参数接收后会记录到内存并打印日志,不会继续驱动执行机构。
## 4. 功能需求与当前状态
### 4.1 采样与解算
| 项目 | 说明 | 状态 |
|------|------|------|
| 4 路轮询采样 | 通过 ADS1256 MUX 依次读取 `0x01 / 0x23 / 0x45 / 0x67` 四组通道 | ✅ |
| tare 去皮 | 启动阶段每路取 7 个样本,中值作为零点偏移 | ✅ |
| 中值滤波 | 每路保留最近 7 个样本,排序后取中位数 | ✅ |
| 死区抑制 | 中值落在 `-80 ~ 80` 时压到 `0` | ✅ |
| CoP 解算 | 根据四角力值计算 `cop_x / cop_y / force` | ✅ |
| 力值标定 | `ADC_TO_FORCE_SCALE` 仍为占位值 `1.0f` | 🔲 |
### 4.2 BLE 通信
| 项目 | 说明 | 状态 |
|------|------|------|
| BLE 角色 | `Peripheral`,使用 NUS 私有服务 | ✅ |
| 广播 | 广播包带 NUS UUID,扫描响应带设备名 | ✅ |
| 连接参数请求 | 连接后请求 `7.5-15 ms` 区间 | ✅ |
| CoP 上行 | 固定 17 字节二进制帧,50 Hz | ✅ |
| 断线重广播 | 断开 1 秒后重新广播 | ✅ |
| NUS 下行解析 | Resistance / Spotter / Heartbeat 三类帧已接收解析 | ✅ |
| 编码器上行 | 协议已预留,主循环未发送 | 🔲 |
### 4.3 控制参数与保护逻辑
| 项目 | 说明 | 状态 |
|------|------|------|
| Resistance 参数接收 | 接收 `K / B / Tau` 并保存到内存 | ✅ |
| Spotter 参数接收 | 接收 `threshold / enable` 并保存到内存 | ✅ |
| Heartbeat 接收 | 接收后刷新时间戳 | ✅ |
| 阻力闭环控制 | 参数已接入协议层,控制逻辑未落地 | 🔲 |
| Spotter 保护动作 | 参数已接入协议层,保护动作未落地 | 🔲 |
## 5. BLE 协议规格
平衡板工作在 BLE `Peripheral` 角色,通过 Nordic UART Service 与基站交换二进制帧。
- 上行方向:平衡板 -> 基站,使用 NUS `Notify`
- 下行方向:基站 -> 平衡板,使用 NUS `Write`
- 广播行为:广播包包含 NUS 128-bit UUID,扫描响应包含设备名 `GML670_System`
### 5.1 NUS UUID
| 项目 | UUID | 方向 | 说明 |
|------|------|------|------|
| Service | `6E400001-B5A3-F393-E0A9-E50E24DCCA9E` | - | NUS 主服务 |
| TX Characteristic | `6E400003-B5A3-F393-E0A9-E50E24DCCA9E` | 平衡板 -> 基站 | Notify,上报 CoP 数据 |
| RX Characteristic | `6E400002-B5A3-F393-E0A9-E50E24DCCA9E` | 基站 -> 平衡板 | Write,下发控制参数 |
### 5.2 连接参数
| 参数 | 当前值 | 说明 |
|------|--------|------|
| 广播模式 | `BT_LE_ADV_CONN_FAST_2` | 上电和断线后通过同一入口启动 |
| 连接间隔请求 | `7.5-15 ms` | `interval_min = 6``interval_max = 12` |
| 从站延迟 | `0` | 不跳过连接事件 |
| 监督超时 | `4000 ms` | `timeout = 400` |
### 5.3 帧类型总览
| 类型名 | 值 | 方向 | 长度 | 频率 | 说明 |
|--------|----|------|------|------|------|
| `PROTO_TYPE_COP` | `0x01` | 平衡板 -> 基站 | `17` | `50 Hz` | CoP 上行帧 |
| `PROTO_TYPE_ENCODER` | `0x02` | 平衡板 -> 基站 | `13` | TBD | 编码器上行帧,预留 |
| `PROTO_TYPE_RESISTANCE` | `0x10` | 基站 -> 平衡板 | `15` | 按需 | 阻力参数帧 |
| `PROTO_TYPE_SPOTTER` | `0x11` | 基站 -> 平衡板 | `8` | 按需 | Spotter 参数帧 |
| `PROTO_TYPE_HEARTBEAT` | `0x20` | 基站 -> 平衡板 | `4` | `~1 Hz` | 心跳帧 |
### 5.4 当前上行主帧
CoP 帧固定 17 字节,结构如下:
| 字节偏移 | 字段 | 类型 | 说明 |
|----------|------|------|------|
| `0` | `sync0` | `uint8` | 固定 `0xAA` |
| `1` | `sync1` | `uint8` | 固定 `0x55` |
| `2` | `type` | `uint8` | 固定 `0x01` |
| `3` | `seq` | `uint8` | 包序号,循环递增 |
| `4` | `flags` | `uint8` | `bit0` 表示 `force_valid` |
| `5-8` | `cop_x` | `float32 LE` | 压力中心 X 坐标,单位 mm |
| `9-12` | `cop_y` | `float32 LE` | 压力中心 Y 坐标,单位 mm |
| `13-16` | `force` | `float32 LE` | 总压力,单位 N |
更完整的协议示例帧和字段说明见 [BALANCE_BOARD_PROTOCOL.md](./BALANCE_BOARD_PROTOCOL.md)。
## 6. ADS1256 / CoP 规格
### 6.1 初始化与采样流程
当前固件的 ADS1256 侧流程如下:
```text
上电
|
+-- 配置 CS / DRDY / RESET GPIO
+-- 绑定 SPI1,频率 500 kHz
+-- 关闭 ADS1256 连续输出
+-- 配置 STATUS / MUX / ADCON / DRATE
+-- 执行自校准
+-- tare 去皮
|
+-- 主循环
|
+-- 轮询 4 路 MUX
+-- 读取 ADC 原始值
+-- 扣除零点偏移
+-- 7 点中值滤波
+-- 死区抑制
+-- CoP 解算
+-- 打包 CoP 帧并发送
```
### 6.2 关键参数
| 项目 | 当前值 | 说明 |
|------|--------|------|
| SPI 频率 | `500 kHz` | `spi_cfg.frequency = 500000` |
| 中值滤波窗口 | `7` | `MEDIAN_WINDOW = 7` |
| 死区 | `±80` | `-80 < median_val < 80` 时压到 `0` |
| 主循环周期 | `20 ms` | `k_msleep(20)` |
| CoP 上行频率 | `50 Hz` | 与主循环周期一致 |
| 板面半宽 | `200 mm` | `BOARD_HALF_WIDTH_MM = 200.0f` |
| 板面半长 | `200 mm` | `BOARD_HALF_LENGTH_MM = 200.0f` |
| CoP 最小有效总力 | `50 N` | `COP_MIN_FORCE_THRESHOLD = 50.0f` |
| 力值换算系数 | `1.0f` | `ADC_TO_FORCE_SCALE` 仍是占位值 |
### 6.3 CoP 判定规则
- 四路滤波后 ADC 值先通过 `ADC_TO_FORCE_SCALE` 转成力值
- 总力小于 `50 N` 时,`cop_x``cop_y``0.0f`
- 此时 `flags.bit0 = 0`,表示 CoP 坐标没有物理意义
- 总力达到阈值后,再根据四个角点坐标做加权平均
## 7. 开发环境与板级配置
当前工程采用标准 Zephyr / NCS 应用结构,目标板为 `nrf5340dk/nrf5340/cpuapp`
`prj.conf` 当前可以直接确认的配置点包括:
- `CONFIG_BT=y`,启用 BLE
- `CONFIG_BT_PERIPHERAL=y`,工作在外设角色
- `CONFIG_BT_NUS=y`,启用 Nordic UART Service
- `CONFIG_BT_DEVICE_NAME="GML670_System"`,设置广播设备名
- 日志走 RTT`CONFIG_USE_SEGGER_RTT=y`
- 关闭 UART Console`CONFIG_CONSOLE=n``CONFIG_UART_CONSOLE=n`
- 关闭串口驱动:`CONFIG_SERIAL=n`
`app.overlay` 当前只保留了 SPI1 和 ADS1256 控制 GPIO 的定义,没有额外启用 UART 控制台复用。
## 8. 项目结构
当前阅读和维护时最关键的文件如下:
| 路径 | 说明 |
|------|------|
| `src/main.c` | 主流程,包含 BLE、ADS1256 采样、滤波、CoP 解算和发送 |
| `src/protocol.h` | 二进制协议结构、常量、几何参数和阈值 |
| `app.overlay` | SPI1、CS、DRDY、RESET 的板级连线 |
| `prj.conf` | BLE、日志和控制台相关配置 |
| `BALANCE_BOARD_PROTOCOL.md` | 协议专项说明、字段表和示例帧 |
## 9. 构建与烧录
在已经配置好 Zephyr / NCS 环境的前提下,可以直接在工程根目录执行:
```bash
west build -b nrf5340dk/nrf5340/cpuapp -p always .
west flash
```
如果只是重新编译当前应用,默认目标仍然是 `nrf5340dk/nrf5340/cpuapp`
## 10. 日志与当前约束
### 10.1 日志
当前日志走 RTT,不占用 UART Console。启动后可以看到如下类型的信息:
- 启动 banner
- tare 开始和结束
- 下行 Resistance 参数日志
- 下行 Spotter 参数日志
- Heartbeat 接收路径已接入,默认 `INF` 级别下不会单独打印
### 10.2 当前约束
- 阻力参数、Spotter 参数和 Heartbeat 当前只做到协议接收、内存保存和日志打印
- 编码器上行帧只在协议头里预留,主循环没有产生这类数据
- `ADC_TO_FORCE_SCALE = 1.0f` 仍是占位值,真实力值需要结合实物标定修正
- CoP 当前依赖四角传感器的固定几何布局,默认使用 `200 mm x 200 mm` 半尺寸
- 主循环固定为 `20 ms` 周期,当前 README 中所有频率描述都以这一实现为准