feat(gml670x4): 所有协议帧添加 CRC-8/MAXIM 校验
使用 Zephyr crc8() 对帧头之后的载荷计算 CRC,上行发送前填充、 下行接收时校验不通过则丢弃并告警。同步更新协议文档。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,19 +27,21 @@
|
|||||||
|
|
||||||
当前协议使用双帧头 `0xAA 0x55` 作为包起始标记。所有多字节字段按 Little Endian 编码。
|
当前协议使用双帧头 `0xAA 0x55` 作为包起始标记。所有多字节字段按 Little Endian 编码。
|
||||||
|
|
||||||
|
每帧末尾附加 1 字节 CRC-8/MAXIM 校验(poly=`0x31`, init=`0x00`, refin=true, refout=true, xorout=`0x00`)。校验范围为帧头之后、CRC 字节之前的所有字段(即跳过 `sync0`/`sync1`)。调用方式:`crc8(data + 2, len - 3, 0x31, 0x00, true)`。
|
||||||
|
|
||||||
| 类型名 | 值 | 方向 | 长度 | 频率 | 说明 |
|
| 类型名 | 值 | 方向 | 长度 | 频率 | 说明 |
|
||||||
|--------|----|------|------|------|------|
|
|--------|----|------|------|------|------|
|
||||||
| `PROTO_TYPE_COP` | `0x01` | 平衡板 -> 基站 | `17` | 50 Hz | 压力中心帧 |
|
| `PROTO_TYPE_COP` | `0x01` | 平衡板 -> 基站 | `18` | 50 Hz | 压力中心帧 |
|
||||||
| `PROTO_TYPE_ENCODER` | `0x02` | 平衡板 -> 基站 | `13` | TBD | 电机编码器帧(预留) |
|
| `PROTO_TYPE_ENCODER` | `0x02` | 平衡板 -> 基站 | `14` | TBD | 电机编码器帧(预留) |
|
||||||
| `PROTO_TYPE_RESISTANCE` | `0x10` | 基站 -> 平衡板 | `15` | 按需 | 阻力参数帧 |
|
| `PROTO_TYPE_RESISTANCE` | `0x10` | 基站 -> 平衡板 | `16` | 按需 | 阻力参数帧 |
|
||||||
| `PROTO_TYPE_SPOTTER` | `0x11` | 基站 -> 平衡板 | `8` | 按需 | 保护模式帧 |
|
| `PROTO_TYPE_SPOTTER` | `0x11` | 基站 -> 平衡板 | `9` | 按需 | 保护模式帧 |
|
||||||
| `PROTO_TYPE_HEARTBEAT` | `0x20` | 基站 -> 平衡板 | `4` | ~1 Hz | 心跳帧 |
|
| `PROTO_TYPE_HEARTBEAT` | `0x20` | 基站 -> 平衡板 | `5` | ~1 Hz | 心跳帧 |
|
||||||
|
|
||||||
## 3. 上行数据包
|
## 3. 上行数据包
|
||||||
|
|
||||||
### 3.1 压力中心帧 (CoP)
|
### 3.1 压力中心帧 (CoP)
|
||||||
|
|
||||||
CoP 帧固定 17 字节,结构如下:
|
CoP 帧固定 18 字节,结构如下:
|
||||||
|
|
||||||
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
||||||
|----------|------|------|---------|------|
|
|----------|------|------|---------|------|
|
||||||
@@ -51,6 +53,7 @@ CoP 帧固定 17 字节,结构如下:
|
|||||||
| `5-8` | `cop_x` | `float32 LE` | - | 压力中心 X 坐标 (mm) |
|
| `5-8` | `cop_x` | `float32 LE` | - | 压力中心 X 坐标 (mm) |
|
||||||
| `9-12` | `cop_y` | `float32 LE` | - | 压力中心 Y 坐标 (mm) |
|
| `9-12` | `cop_y` | `float32 LE` | - | 压力中心 Y 坐标 (mm) |
|
||||||
| `13-16` | `force` | `float32 LE` | - | 总压力 (N) |
|
| `13-16` | `force` | `float32 LE` | - | 总压力 (N) |
|
||||||
|
| `17` | `crc` | `uint8` | - | CRC-8/MAXIM 校验 |
|
||||||
|
|
||||||
#### flags 位定义
|
#### flags 位定义
|
||||||
|
|
||||||
@@ -94,7 +97,7 @@ CoP_Y = (F0 * y0 + F1 * y1 + F2 * y2 + F3 * y3) / F_total
|
|||||||
下面是一个 CoP 帧示例(CoP 有效):
|
下面是一个 CoP 帧示例(CoP 有效):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44
|
AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44 XX
|
||||||
```
|
```
|
||||||
|
|
||||||
含义如下:
|
含义如下:
|
||||||
@@ -106,10 +109,11 @@ AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44
|
|||||||
- `00 00 F0 41`:`cop_x = 30.0` mm(LE float32)
|
- `00 00 F0 41`:`cop_x = 30.0` mm(LE float32)
|
||||||
- `00 00 48 42`:`cop_y = 50.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)
|
- `00 80 BB 44`:`force = 1500.0` N(LE float32)
|
||||||
|
- `XX`:CRC-8/MAXIM(对字节 `[2..16]` 计算)
|
||||||
|
|
||||||
### 3.2 电机编码器帧(预留)
|
### 3.2 电机编码器帧(预留)
|
||||||
|
|
||||||
编码器帧固定 13 字节,结构如下。该帧目前仅在协议中预留定义,固件暂不实现。
|
编码器帧固定 14 字节,结构如下。该帧目前仅在协议中预留定义,固件暂不实现。
|
||||||
|
|
||||||
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
||||||
|----------|------|------|---------|------|
|
|----------|------|------|---------|------|
|
||||||
@@ -120,12 +124,13 @@ AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44
|
|||||||
| `4` | `flags` | `uint8` | `0` | 预留 |
|
| `4` | `flags` | `uint8` | `0` | 预留 |
|
||||||
| `5-8` | `cable_length` | `float32 LE` | - | 拉索长度 (mm) |
|
| `5-8` | `cable_length` | `float32 LE` | - | 拉索长度 (mm) |
|
||||||
| `9-12` | `velocity` | `float32 LE` | - | 拉索速度 (mm/s) |
|
| `9-12` | `velocity` | `float32 LE` | - | 拉索速度 (mm/s) |
|
||||||
|
| `13` | `crc` | `uint8` | - | CRC-8/MAXIM 校验 |
|
||||||
|
|
||||||
## 4. 下行数据包
|
## 4. 下行数据包
|
||||||
|
|
||||||
### 4.1 阻力参数帧
|
### 4.1 阻力参数帧
|
||||||
|
|
||||||
阻力参数帧固定 15 字节,用于基站向平衡板下发电机阻力控制参数。
|
阻力参数帧固定 16 字节,用于基站向平衡板下发电机阻力控制参数。
|
||||||
|
|
||||||
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
||||||
|----------|------|------|---------|------|
|
|----------|------|------|---------|------|
|
||||||
@@ -135,11 +140,12 @@ AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44
|
|||||||
| `3-6` | `K` | `float32 LE` | - | 刚度 (N/m) |
|
| `3-6` | `K` | `float32 LE` | - | 刚度 (N/m) |
|
||||||
| `7-10` | `B` | `float32 LE` | - | 阻尼 (Ns/m) |
|
| `7-10` | `B` | `float32 LE` | - | 阻尼 (Ns/m) |
|
||||||
| `11-14` | `Tau` | `float32 LE` | - | 时间常数 (s) |
|
| `11-14` | `Tau` | `float32 LE` | - | 时间常数 (s) |
|
||||||
|
| `15` | `crc` | `uint8` | - | CRC-8/MAXIM 校验 |
|
||||||
|
|
||||||
#### 示例
|
#### 示例
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AA 55 10 00 00 C8 42 00 00 48 41 CD CC 4C 3E
|
AA 55 10 00 00 C8 42 00 00 48 41 CD CC 4C 3E XX
|
||||||
```
|
```
|
||||||
|
|
||||||
含义如下:
|
含义如下:
|
||||||
@@ -148,10 +154,11 @@ AA 55 10 00 00 C8 42 00 00 48 41 CD CC 4C 3E
|
|||||||
- `00 00 C8 42`:`K = 100.0` N/m
|
- `00 00 C8 42`:`K = 100.0` N/m
|
||||||
- `00 00 48 41`:`B = 12.5` Ns/m
|
- `00 00 48 41`:`B = 12.5` Ns/m
|
||||||
- `CD CC 4C 3E`:`Tau = 0.2` s
|
- `CD CC 4C 3E`:`Tau = 0.2` s
|
||||||
|
- `XX`:CRC-8/MAXIM
|
||||||
|
|
||||||
### 4.2 Spotter Mode 帧
|
### 4.2 Spotter Mode 帧
|
||||||
|
|
||||||
Spotter 帧固定 8 字节,用于启用或关闭保护模式。
|
Spotter 帧固定 9 字节,用于启用或关闭保护模式。
|
||||||
|
|
||||||
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
||||||
|----------|------|------|---------|------|
|
|----------|------|------|---------|------|
|
||||||
@@ -160,18 +167,19 @@ Spotter 帧固定 8 字节,用于启用或关闭保护模式。
|
|||||||
| `2` | `type` | `uint8` | `0x11` | Spotter 包类型 |
|
| `2` | `type` | `uint8` | `0x11` | Spotter 包类型 |
|
||||||
| `3-6` | `threshold` | `float32 LE` | - | 保护力阈值 (N) |
|
| `3-6` | `threshold` | `float32 LE` | - | 保护力阈值 (N) |
|
||||||
| `7` | `enable` | `uint8` | `0` 或 `1` | `0` = 关闭, `1` = 启用 |
|
| `7` | `enable` | `uint8` | `0` 或 `1` | `0` = 关闭, `1` = 启用 |
|
||||||
|
| `8` | `crc` | `uint8` | - | CRC-8/MAXIM 校验 |
|
||||||
|
|
||||||
#### 示例
|
#### 示例
|
||||||
|
|
||||||
启用 Spotter Mode,阈值 500 N:
|
启用 Spotter Mode,阈值 500 N:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AA 55 11 00 00 FA 43 01
|
AA 55 11 00 00 FA 43 01 XX
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.3 心跳帧
|
### 4.3 心跳帧
|
||||||
|
|
||||||
心跳帧固定 4 字节,基站以约 1 Hz 频率发送,用于活性检测。
|
心跳帧固定 5 字节,基站以约 1 Hz 频率发送,用于活性检测。
|
||||||
|
|
||||||
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|
||||||
|----------|------|------|---------|------|
|
|----------|------|------|---------|------|
|
||||||
@@ -179,18 +187,19 @@ AA 55 11 00 00 FA 43 01
|
|||||||
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
|
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
|
||||||
| `2` | `type` | `uint8` | `0x20` | 心跳包类型 |
|
| `2` | `type` | `uint8` | `0x20` | 心跳包类型 |
|
||||||
| `3` | `counter` | `uint8` | `0-255` | 滚动计数 |
|
| `3` | `counter` | `uint8` | `0-255` | 滚动计数 |
|
||||||
|
| `4` | `crc` | `uint8` | - | CRC-8/MAXIM 校验 |
|
||||||
|
|
||||||
#### 示例
|
#### 示例
|
||||||
|
|
||||||
```text
|
```text
|
||||||
AA 55 20 05
|
AA 55 20 05 XX
|
||||||
```
|
```
|
||||||
|
|
||||||
含义:心跳包,计数 `5`。
|
含义:心跳包,计数 `5`,`XX` 为 CRC。
|
||||||
|
|
||||||
## 5. 当前实现约束
|
## 5. 当前实现约束
|
||||||
|
|
||||||
- CoP 帧固定 17 字节,可在最小 ATT MTU 23(NUS 有效负载 20 字节)下传输。
|
- CoP 帧固定 18 字节,可在最小 ATT MTU 23(NUS 有效负载 20 字节)下传输。
|
||||||
- 50 Hz CoP 上行流隐式充当平衡板到基站的活性检测,因此心跳仅为下行。
|
- 50 Hz CoP 上行流隐式充当平衡板到基站的活性检测,因此心跳仅为下行。
|
||||||
- 传感器通道到物理位置的映射:MUX `{0x01, 0x23, 0x45, 0x67}` → FL/FR/BR/BL。
|
- 传感器通道到物理位置的映射:MUX `{0x01, 0x23, 0x45, 0x67}` → FL/FR/BR/BL。
|
||||||
- `BOARD_HALF_WIDTH_MM = 200`,`BOARD_HALF_LENGTH_MM = 200`(后续可能调整)。
|
- `BOARD_HALF_WIDTH_MM = 200`,`BOARD_HALF_LENGTH_MM = 200`(后续可能调整)。
|
||||||
|
|||||||
+16
-10
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <zephyr/sys/crc.h>
|
||||||
|
|
||||||
/* ─── 帧常量 ─── */
|
/* ─── 帧常量 ─── */
|
||||||
/* 双帧头比单字节魔数更容易在连续字节流里完成包起始判定。 */
|
/* 双帧头比单字节魔数更容易在连续字节流里完成包起始判定。 */
|
||||||
@@ -41,9 +42,9 @@
|
|||||||
/* 总重低于此值时 CoP 无意义(除零保护),单位 kg */
|
/* 总重低于此值时 CoP 无意义(除零保护),单位 kg */
|
||||||
#define COP_MIN_FORCE_THRESHOLD 0.5f
|
#define COP_MIN_FORCE_THRESHOLD 0.5f
|
||||||
|
|
||||||
/* ─── 上行: CoP 帧 (17 bytes, 50 Hz) ───
|
/* ─── 上行: CoP 帧 (18 bytes, 50 Hz) ───
|
||||||
*
|
*
|
||||||
* [AA 55 01 seq flags cop_x(4) cop_y(4) force(4)]
|
* [AA 55 01 seq flags cop_x(4) cop_y(4) force(4) crc]
|
||||||
*/
|
*/
|
||||||
struct cop_frame_t {
|
struct cop_frame_t {
|
||||||
uint8_t sync0; /* = PROTO_SYNC0 */
|
uint8_t sync0; /* = PROTO_SYNC0 */
|
||||||
@@ -54,6 +55,7 @@ struct cop_frame_t {
|
|||||||
float cop_x; /* 压力中心 X (mm),板面坐标系 */
|
float cop_x; /* 压力中心 X (mm),板面坐标系 */
|
||||||
float cop_y; /* 压力中心 Y (mm),板面坐标系 */
|
float cop_y; /* 压力中心 Y (mm),板面坐标系 */
|
||||||
float force; /* 总重量 (kg) */
|
float force; /* 总重量 (kg) */
|
||||||
|
uint8_t crc; /* CRC-8/MAXIM, 校验 type~force */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
union cop_pkt_t {
|
union cop_pkt_t {
|
||||||
@@ -61,9 +63,9 @@ union cop_pkt_t {
|
|||||||
uint8_t bytes[sizeof(struct cop_frame_t)];
|
uint8_t bytes[sizeof(struct cop_frame_t)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ─── 上行: 电机编码器帧 (13 bytes, 预留) ───
|
/* ─── 上行: 电机编码器帧 (14 bytes, 预留) ───
|
||||||
*
|
*
|
||||||
* [AA 55 02 seq flags cable_length(4) velocity(4)]
|
* [AA 55 02 seq flags cable_length(4) velocity(4) crc]
|
||||||
*/
|
*/
|
||||||
struct encoder_frame_t {
|
struct encoder_frame_t {
|
||||||
uint8_t sync0; /* = PROTO_SYNC0 */
|
uint8_t sync0; /* = PROTO_SYNC0 */
|
||||||
@@ -73,6 +75,7 @@ struct encoder_frame_t {
|
|||||||
uint8_t flags; /* 预留,填 0 */
|
uint8_t flags; /* 预留,填 0 */
|
||||||
float cable_length; /* 拉索长度 (mm) */
|
float cable_length; /* 拉索长度 (mm) */
|
||||||
float velocity; /* 拉索速度 (mm/s) */
|
float velocity; /* 拉索速度 (mm/s) */
|
||||||
|
uint8_t crc; /* CRC-8/MAXIM */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
union encoder_pkt_t {
|
union encoder_pkt_t {
|
||||||
@@ -80,9 +83,9 @@ union encoder_pkt_t {
|
|||||||
uint8_t bytes[sizeof(struct encoder_frame_t)];
|
uint8_t bytes[sizeof(struct encoder_frame_t)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ─── 下行: 阻力参数帧 (15 bytes) ───
|
/* ─── 下行: 阻力参数帧 (16 bytes) ───
|
||||||
*
|
*
|
||||||
* [AA 55 10 K(4) B(4) Tau(4)]
|
* [AA 55 10 K(4) B(4) Tau(4) crc]
|
||||||
*/
|
*/
|
||||||
struct resistance_frame_t {
|
struct resistance_frame_t {
|
||||||
uint8_t sync0; /* = PROTO_SYNC0 */
|
uint8_t sync0; /* = PROTO_SYNC0 */
|
||||||
@@ -91,6 +94,7 @@ struct resistance_frame_t {
|
|||||||
float K; /* 刚度 (N/m) */
|
float K; /* 刚度 (N/m) */
|
||||||
float B; /* 阻尼 (Ns/m) */
|
float B; /* 阻尼 (Ns/m) */
|
||||||
float Tau; /* 时间常数 (s) */
|
float Tau; /* 时间常数 (s) */
|
||||||
|
uint8_t crc; /* CRC-8/MAXIM */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
union resistance_pkt_t {
|
union resistance_pkt_t {
|
||||||
@@ -98,9 +102,9 @@ union resistance_pkt_t {
|
|||||||
uint8_t bytes[sizeof(struct resistance_frame_t)];
|
uint8_t bytes[sizeof(struct resistance_frame_t)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ─── 下行: Spotter Mode 帧 (8 bytes) ───
|
/* ─── 下行: Spotter Mode 帧 (9 bytes) ───
|
||||||
*
|
*
|
||||||
* [AA 55 11 threshold(4) enable]
|
* [AA 55 11 threshold(4) enable crc]
|
||||||
*/
|
*/
|
||||||
struct spotter_frame_t {
|
struct spotter_frame_t {
|
||||||
uint8_t sync0; /* = PROTO_SYNC0 */
|
uint8_t sync0; /* = PROTO_SYNC0 */
|
||||||
@@ -108,6 +112,7 @@ struct spotter_frame_t {
|
|||||||
uint8_t type; /* = PROTO_TYPE_SPOTTER */
|
uint8_t type; /* = PROTO_TYPE_SPOTTER */
|
||||||
float threshold; /* 保护力阈值 (N) */
|
float threshold; /* 保护力阈值 (N) */
|
||||||
uint8_t enable; /* 0 = 关闭, 1 = 启用 */
|
uint8_t enable; /* 0 = 关闭, 1 = 启用 */
|
||||||
|
uint8_t crc; /* CRC-8/MAXIM */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
union spotter_pkt_t {
|
union spotter_pkt_t {
|
||||||
@@ -115,15 +120,16 @@ union spotter_pkt_t {
|
|||||||
uint8_t bytes[sizeof(struct spotter_frame_t)];
|
uint8_t bytes[sizeof(struct spotter_frame_t)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ─── 下行: 心跳帧 (4 bytes, ~1 Hz) ───
|
/* ─── 下行: 心跳帧 (5 bytes, ~1 Hz) ───
|
||||||
*
|
*
|
||||||
* [AA 55 20 counter]
|
* [AA 55 20 counter crc]
|
||||||
*/
|
*/
|
||||||
struct heartbeat_frame_t {
|
struct heartbeat_frame_t {
|
||||||
uint8_t sync0; /* = PROTO_SYNC0 */
|
uint8_t sync0; /* = PROTO_SYNC0 */
|
||||||
uint8_t sync1; /* = PROTO_SYNC1 */
|
uint8_t sync1; /* = PROTO_SYNC1 */
|
||||||
uint8_t type; /* = PROTO_TYPE_HEARTBEAT */
|
uint8_t type; /* = PROTO_TYPE_HEARTBEAT */
|
||||||
uint8_t counter; /* 滚动计数,用于活性检测 */
|
uint8_t counter; /* 滚动计数,用于活性检测 */
|
||||||
|
uint8_t crc; /* CRC-8/MAXIM */
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
union heartbeat_pkt_t {
|
union heartbeat_pkt_t {
|
||||||
|
|||||||
@@ -27,3 +27,5 @@ CONFIG_LOG_BACKEND_RTT=y
|
|||||||
CONFIG_LOG_BACKEND_UART=n
|
CONFIG_LOG_BACKEND_UART=n
|
||||||
CONFIG_LOG_MODE_IMMEDIATE=y
|
CONFIG_LOG_MODE_IMMEDIATE=y
|
||||||
CONFIG_MAIN_STACK_SIZE=4096
|
CONFIG_MAIN_STACK_SIZE=4096
|
||||||
|
|
||||||
|
CONFIG_CRC=y
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ static void nus_received_cb(struct bt_conn *conn, const uint8_t *data, uint16_t
|
|||||||
switch (data[2]) {
|
switch (data[2]) {
|
||||||
case PROTO_TYPE_RESISTANCE:
|
case PROTO_TYPE_RESISTANCE:
|
||||||
if (len >= sizeof(struct resistance_frame_t)) {
|
if (len >= sizeof(struct resistance_frame_t)) {
|
||||||
|
uint8_t crc = crc8(data + 2, sizeof(struct resistance_frame_t) - 3, 0x31, 0x00, true);
|
||||||
|
if (data[sizeof(struct resistance_frame_t) - 1] != crc) {
|
||||||
|
LOG_WRN("Resistance frame CRC mismatch");
|
||||||
|
break;
|
||||||
|
}
|
||||||
union resistance_pkt_t pkt;
|
union resistance_pkt_t pkt;
|
||||||
memcpy(pkt.bytes, data, sizeof(struct resistance_frame_t));
|
memcpy(pkt.bytes, data, sizeof(struct resistance_frame_t));
|
||||||
resistance_K = pkt.frame.K;
|
resistance_K = pkt.frame.K;
|
||||||
@@ -90,6 +95,11 @@ static void nus_received_cb(struct bt_conn *conn, const uint8_t *data, uint16_t
|
|||||||
break;
|
break;
|
||||||
case PROTO_TYPE_SPOTTER:
|
case PROTO_TYPE_SPOTTER:
|
||||||
if (len >= sizeof(struct spotter_frame_t)) {
|
if (len >= sizeof(struct spotter_frame_t)) {
|
||||||
|
uint8_t crc = crc8(data + 2, sizeof(struct spotter_frame_t) - 3, 0x31, 0x00, true);
|
||||||
|
if (data[sizeof(struct spotter_frame_t) - 1] != crc) {
|
||||||
|
LOG_WRN("Spotter frame CRC mismatch");
|
||||||
|
break;
|
||||||
|
}
|
||||||
union spotter_pkt_t pkt;
|
union spotter_pkt_t pkt;
|
||||||
memcpy(pkt.bytes, data, sizeof(struct spotter_frame_t));
|
memcpy(pkt.bytes, data, sizeof(struct spotter_frame_t));
|
||||||
spotter_threshold = pkt.frame.threshold;
|
spotter_threshold = pkt.frame.threshold;
|
||||||
@@ -99,6 +109,11 @@ static void nus_received_cb(struct bt_conn *conn, const uint8_t *data, uint16_t
|
|||||||
break;
|
break;
|
||||||
case PROTO_TYPE_HEARTBEAT:
|
case PROTO_TYPE_HEARTBEAT:
|
||||||
if (len >= sizeof(struct heartbeat_frame_t)) {
|
if (len >= sizeof(struct heartbeat_frame_t)) {
|
||||||
|
uint8_t crc = crc8(data + 2, sizeof(struct heartbeat_frame_t) - 3, 0x31, 0x00, true);
|
||||||
|
if (data[sizeof(struct heartbeat_frame_t) - 1] != crc) {
|
||||||
|
LOG_WRN("Heartbeat frame CRC mismatch");
|
||||||
|
break;
|
||||||
|
}
|
||||||
last_heartbeat_ms = k_uptime_get();
|
last_heartbeat_ms = k_uptime_get();
|
||||||
LOG_DBG("RX Heartbeat");
|
LOG_DBG("RX Heartbeat");
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -23,9 +23,8 @@ int main(void) {
|
|||||||
ble_transport_adv_start();
|
ble_transport_adv_start();
|
||||||
|
|
||||||
if (sensor_init()) return 0;
|
if (sensor_init()) return 0;
|
||||||
while (1) {
|
|
||||||
k_sleep(K_SECONDS(1));
|
k_sleep(K_FOREVER);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ static void sensor_thread_fn(void *p1, void *p2, void *p3) {
|
|||||||
pkt.frame.cop_x = cop_x;
|
pkt.frame.cop_x = cop_x;
|
||||||
pkt.frame.cop_y = cop_y;
|
pkt.frame.cop_y = cop_y;
|
||||||
pkt.frame.force = force;
|
pkt.frame.force = force;
|
||||||
|
pkt.frame.crc = crc8(pkt.bytes + 2, sizeof(pkt.bytes) - 3, 0x31, 0x00, true);
|
||||||
|
|
||||||
/* 发送 */
|
/* 发送 */
|
||||||
ble_transport_send(pkt.bytes, sizeof(pkt.bytes));
|
ble_transport_send(pkt.bytes, sizeof(pkt.bytes));
|
||||||
|
|||||||
Reference in New Issue
Block a user