commit 5492a98687fb3877e482d890614a9f73db03337b Author: pNexus Date: Thu Apr 30 17:36:39 2026 +0800 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) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..635a99b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# editors +*.swp +*~ + +# build +/build*/ diff --git a/BALANCE_BOARD_PROTOCOL.md b/BALANCE_BOARD_PROTOCOL.md new file mode 100644 index 0000000..616ede5 --- /dev/null +++ b/BALANCE_BOARD_PROTOCOL.md @@ -0,0 +1,198 @@ +# 平衡板协议说明 + +本文说明当前固件里的数据包格式和 BLE 通讯方式。 + +## 1. BLE 通讯方式 + +平衡板工作在 BLE `Peripheral` 角色,通过 Nordic UART Service(NUS)与基站通信。 + +- 上行方向:平衡板 -> 基站,使用 NUS `Notify` +- 下行方向:基站 -> 平衡板,使用 NUS `Write` +- 广播内容:包含设备名和 NUS 128-bit UUID + +### 1.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,下发阻力参数和控制命令 | + +### 1.2 当前连接行为 + +- 连接建立后,平衡板会请求 `7.5-15 ms` 连接区间(`min=6, max=12`)。 +- 所有数据通过 NUS 二进制帧发送,不走文本协议。 + +## 2. 数据包总览 + +当前协议使用双帧头 `0xAA 0x55` 作为包起始标记。所有多字节字段按 Little Endian 编码。 + +| 类型名 | 值 | 方向 | 长度 | 频率 | 说明 | +|--------|----|------|------|------|------| +| `PROTO_TYPE_COP` | `0x01` | 平衡板 -> 基站 | `17` | 50 Hz | 压力中心帧 | +| `PROTO_TYPE_ENCODER` | `0x02` | 平衡板 -> 基站 | `13` | TBD | 电机编码器帧(预留) | +| `PROTO_TYPE_RESISTANCE` | `0x10` | 基站 -> 平衡板 | `15` | 按需 | 阻力参数帧 | +| `PROTO_TYPE_SPOTTER` | `0x11` | 基站 -> 平衡板 | `8` | 按需 | 保护模式帧 | +| `PROTO_TYPE_HEARTBEAT` | `0x20` | 基站 -> 平衡板 | `4` | ~1 Hz | 心跳帧 | + +## 3. 上行数据包 + +### 3.1 压力中心帧 (CoP) + +CoP 帧固定 17 字节,结构如下: + +| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 | +|----------|------|------|---------|------| +| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 | +| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 | +| `2` | `type` | `uint8` | `0x01` | CoP 包类型 | +| `3` | `seq` | `uint8` | `0-255` | 包序号,循环递增 | +| `4` | `flags` | `uint8` | 见下表 | 状态标志位 | +| `5-8` | `cop_x` | `float32 LE` | - | 压力中心 X 坐标 (mm) | +| `9-12` | `cop_y` | `float32 LE` | - | 压力中心 Y 坐标 (mm) | +| `13-16` | `force` | `float32 LE` | - | 总压力 (N) | + +#### flags 位定义 + +| 位 | 名称 | 说明 | +|----|------|------| +| bit0 | `COP_FLAG_FORCE_VALID` | `1` 表示总力超过阈值,CoP 坐标有意义 | +| bit1-7 | 预留 | 填 `0` | + +#### CoP 解算公式 + +传感器布局(俯视): + +```text + S4 (FL) -------- S1 (FR) + | center | + S3 (BL) -------- S2 (BR) +``` + +传感器坐标(单位:mm,板面中心为原点): + +| 传感器 | 位置 | X | Y | +|--------|------|---|---| +| S1 | 右前 (FR) | `+200` | `+200` | +| S2 | 右后 (BR) | `+200` | `-200` | +| S3 | 左后 (BL) | `-200` | `-200` | +| S4 | 左前 (FL) | `-200` | `+200` | + +计算公式: + +```text +F_total = F0 + F1 + F2 + F3 + +CoP_X = (F0 * x0 + F1 * x1 + F2 * x2 + F3 * x3) / F_total +CoP_Y = (F0 * y0 + F1 * y1 + F2 * y2 + F3 * y3) / F_total +``` + +当 `F_total < COP_MIN_FORCE_THRESHOLD` 时,CoP 坐标无意义,`flags.bit0 = 0`,`cop_x` 和 `cop_y` 填 `0.0f`。 + +#### 示例 + +下面是一个 CoP 帧示例(CoP 有效): + +```text +AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44 +``` + +含义如下: + +- `AA 55`:双帧头 +- `01`:CoP 包 +- `2A`:序号 `0x2A` +- `01`:flags = `force_valid` +- `00 00 F0 41`:`cop_x = 30.0` mm(LE float32) +- `00 00 48 42`:`cop_y = 50.0` mm(LE float32) +- `00 80 BB 44`:`force = 1500.0` N(LE float32) + +### 3.2 电机编码器帧(预留) + +编码器帧固定 13 字节,结构如下。该帧目前仅在协议中预留定义,固件暂不实现。 + +| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 | +|----------|------|------|---------|------| +| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 | +| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 | +| `2` | `type` | `uint8` | `0x02` | 编码器包类型 | +| `3` | `seq` | `uint8` | `0-255` | 包序号 | +| `4` | `flags` | `uint8` | `0` | 预留 | +| `5-8` | `cable_length` | `float32 LE` | - | 拉索长度 (mm) | +| `9-12` | `velocity` | `float32 LE` | - | 拉索速度 (mm/s) | + +## 4. 下行数据包 + +### 4.1 阻力参数帧 + +阻力参数帧固定 15 字节,用于基站向平衡板下发电机阻力控制参数。 + +| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 | +|----------|------|------|---------|------| +| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 | +| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 | +| `2` | `type` | `uint8` | `0x10` | 阻力参数包类型 | +| `3-6` | `K` | `float32 LE` | - | 刚度 (N/m) | +| `7-10` | `B` | `float32 LE` | - | 阻尼 (Ns/m) | +| `11-14` | `Tau` | `float32 LE` | - | 时间常数 (s) | + +#### 示例 + +```text +AA 55 10 00 00 C8 42 00 00 48 41 CD CC 4C 3E +``` + +含义如下: + +- `AA 55 10`:阻力参数帧头 +- `00 00 C8 42`:`K = 100.0` N/m +- `00 00 48 41`:`B = 12.5` Ns/m +- `CD CC 4C 3E`:`Tau = 0.2` s + +### 4.2 Spotter Mode 帧 + +Spotter 帧固定 8 字节,用于启用或关闭保护模式。 + +| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 | +|----------|------|------|---------|------| +| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 | +| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 | +| `2` | `type` | `uint8` | `0x11` | Spotter 包类型 | +| `3-6` | `threshold` | `float32 LE` | - | 保护力阈值 (N) | +| `7` | `enable` | `uint8` | `0` 或 `1` | `0` = 关闭, `1` = 启用 | + +#### 示例 + +启用 Spotter Mode,阈值 500 N: + +```text +AA 55 11 00 00 FA 43 01 +``` + +### 4.3 心跳帧 + +心跳帧固定 4 字节,基站以约 1 Hz 频率发送,用于活性检测。 + +| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 | +|----------|------|------|---------|------| +| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 | +| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 | +| `2` | `type` | `uint8` | `0x20` | 心跳包类型 | +| `3` | `counter` | `uint8` | `0-255` | 滚动计数 | + +#### 示例 + +```text +AA 55 20 05 +``` + +含义:心跳包,计数 `5`。 + +## 5. 当前实现约束 + +- CoP 帧固定 17 字节,可在最小 ATT MTU 23(NUS 有效负载 20 字节)下传输。 +- 50 Hz CoP 上行流隐式充当平衡板到基站的活性检测,因此心跳仅为下行。 +- 传感器通道到物理位置的映射:MUX `{0x01, 0x23, 0x45, 0x67}` → FL/FR/BR/BL。 +- `BOARD_HALF_WIDTH_MM = 200`,`BOARD_HALF_LENGTH_MM = 200`(后续可能调整)。 +- `ADC_TO_FORCE_SCALE` 当前为占位值 `1.0f`,待 10 kg 砝码标定后修正。 +- ARM Cortex-M33 为小端架构,`float32` 在 packed struct 中天然符合 Little Endian 要求。 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7b07cf4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,32 @@ +# +# Copyright (c) 2018 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(GML670_V2) + +if(SYSBUILD) + get_filename_component(SYSBUILD_TOP_BINARY_DIR "${CMAKE_BINARY_DIR}" DIRECTORY) + add_custom_target(sync_compile_commands ALL + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_BINARY_DIR}/compile_commands.json + ${SYSBUILD_TOP_BINARY_DIR}/compile_commands.json + COMMENT "Sync ${PROJECT_NAME} compile_commands.json to sysbuild top-level build/" + VERBATIM + ) +endif() + +# NORDIC SDK APP START +target_sources(app PRIVATE + src/main.c + src/ads1256.c + src/sensor.c + src/ble_transport.c +) +target_include_directories(app PRIVATE + inc +) +# NORDIC SDK APP END diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..997add5 --- /dev/null +++ b/Kconfig @@ -0,0 +1,45 @@ +# +# Copyright (c) 2018 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +source "Kconfig.zephyr" + +menu "Nordic UART BLE GATT service sample" + +config BT_NUS_THREAD_STACK_SIZE + int "Thread stack size" + default 1024 + help + Stack size used in each of the two threads + +config BT_NUS_UART_BUFFER_SIZE + int "UART payload buffer element size" + default 40 + help + Size of the payload buffer in each RX and TX FIFO element + +config BT_NUS_SECURITY_ENABLED + bool "Security" + default y + select BT_SMP + help + Enable Bluetooth LE security for the UART service + +config BT_NUS_UART_RX_WAIT_TIME + int "Timeout for UART RX complete event" + default 50000 + help + Wait for RX complete event time in microseconds + +config SETTINGS + default y + +config ZMS + default y if (SOC_FLASH_NRF_RRAM || SOC_FLASH_NRF_MRAM) + +config NVS + default y if !(SOC_FLASH_NRF_RRAM || SOC_FLASH_NRF_MRAM) + +endmenu diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf9991b --- /dev/null +++ b/README.md @@ -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 路传感器输入 +- 在板端完成去皮、中值滤波和 CoP(Center 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 中所有频率描述都以这一实现为准 diff --git a/app.overlay b/app.overlay new file mode 100644 index 0000000..8b7a876 --- /dev/null +++ b/app.overlay @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/* + * nRF5340 DK (App Core) Overlay for ADS1256 + * 仅保留 SPI 和 GPIO 定义 + */ + +&spi1 { + compatible = "nordic,nrf-spim"; + status = "okay"; + pinctrl-0 = <&spi1_default>; + pinctrl-1 = <&spi1_sleep>; + pinctrl-names = "default", "sleep"; + + /* CS 引脚配置 */ + cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + + ads1256: ads1256@0 { + compatible = "ti,ads1256"; + reg = <0>; + spi-max-frequency = <1000000>; + }; +}; + +&pinctrl { + spi1_default: spi1_default { + group1 { + psels = , + , + ; + }; + }; + spi1_sleep: spi1_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; + +/ { + aliases { + ads-cs = &ads_cs_pin; + ads-drdy = &ads_drdy_pin; + ads-reset = &ads_reset_pin; + }; + + ads1256_control { + compatible = "gpio-keys"; + ads_cs_pin: ads_cs { + gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + }; + ads_drdy_pin: ads_drdy { + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; + ads_reset_pin: ads_reset { + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/doc/GML670.pdf b/doc/GML670.pdf new file mode 100644 index 0000000..ae8e9d8 Binary files /dev/null and b/doc/GML670.pdf differ diff --git a/doc/ads1256.pdf b/doc/ads1256.pdf new file mode 100644 index 0000000..ae84cf4 Binary files /dev/null and b/doc/ads1256.pdf differ diff --git a/prj.conf b/prj.conf new file mode 100644 index 0000000..1959d0a --- /dev/null +++ b/prj.conf @@ -0,0 +1,29 @@ +# 基础蓝牙 +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_DEVICE_NAME="GML670_System" +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_NUS=y + +# 借鉴 Kiwii: 禁用 NUS 安全限制,提高连接成功率 +CONFIG_BT_NUS_SECURITY_ENABLED=n + +# 借鉴 Kiwii: 优化缓冲区 (匹配硬件) +CONFIG_BT_BUF_ACL_TX_COUNT=3 +CONFIG_BT_L2CAP_TX_BUF_COUNT=3 + +# 硬件驱动 +CONFIG_SPI=y +CONFIG_GPIO=y +CONFIG_CBPRINTF_FP_SUPPORT=y + +# 日志 (切换到 RTT,避免日志占用 UART/Console 输出链) +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_LOG=y +CONFIG_USE_SEGGER_RTT=y +CONFIG_LOG_BACKEND_RTT=y +CONFIG_LOG_BACKEND_UART=n +CONFIG_LOG_MODE_IMMEDIATE=y +CONFIG_MAIN_STACK_SIZE=4096