Files
portable_modules/nfc/README.md
2026-07-20 10:48:38 +08:00

212 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NFC Module
这个模块从当前 `custom_app` 中抽取 DP1312EA + NTAG213 UID 读取功能,目标是后续可以直接移植到别的业务项目。
核心原则:
- NFC 模块不依赖业务层。
- 业务层通过回调接入 NFC 事件。
- I2C/GPIO/中断/RTOS/sleep/log 全部走平台适配层。
- Quectel SDK 调用只允许出现在 `platform/quectel/`
## 目录结构
```text
portable_modules/nfc/
include/
nfc_service.h
nfc_platform.h
src/
nfc_service.c
nfc_dp1312ea.c
nfc_ntag213.c
platform/quectel/
nfc_platform_ql.c
vendor/dp1312ea/
TypeA.c
LPCD.c
reg.h
...
examples/
banban_adapter.c
module.mk
```
## 分层说明
- `include/nfc_service.h`: 业务层接口。业务只需要关心初始化、启动、UID 回调。
- `include/nfc_platform.h`: 平台适配接口。移植到新 SDK 时实现这里的函数。
- `src/nfc_service.c`: NFC 服务状态机,包含 LPCD 等待、中断唤醒、轮询读卡、失败回退。
- `src/nfc_dp1312ea.c`: DP1312EA 寄存器、reset、transceive 等芯片封装。
- `src/nfc_ntag213.c`: NTAG213 兼容 UID 读取。
- `platform/quectel/nfc_platform_ql.c`: 当前移远 SDK 适配。
- `vendor/dp1312ea/`: 原 DP1312EA TypeA/LPCD/寄存器等底层代码。
- `examples/banban_adapter.c`: 当前 Banban 业务接入示例。
## 当前能力
- 初始化 DP1312EA。
- 进入 LPCD 低功耗检卡。
- IRQ 唤醒后轮询读卡。
- 读取 NTAG213/Ultralight 兼容标签 UID。
- 将 UID 以二进制和十六进制字符串形式回调给业务层。
暂未实现完整写 NFC 标签功能。`vendor` 中保留了 MIFARE 风格的 16 字节块写底层函数,但 NTAG213 页写入和 NDEF 写入需要后续单独补。
## 业务层怎么使用
业务层只包含:
```c
#include "nfc_service.h"
```
然后实现两个核心回调:
```c
static int app_can_poll(void *ctx)
{
// 返回 1 表示当前允许读卡,返回 0 表示暂时不读。
return 1;
}
static void app_on_uid(const nfc_uid_t *uid, void *ctx)
{
// uid->value 是十六进制字符串,例如 "04A1B2C3D4E5F6"。
// 业务层在这里决定绑定、触发 MQTT、播放提示音等。
}
```
启动 NFC
```c
nfc_service_config_t config;
nfc_service_callbacks_t callbacks = {
.can_poll = app_can_poll,
.on_uid = app_on_uid,
.on_error = 0,
.ctx = 0,
};
nfc_service_default_config(&config);
nfc_service_init(&config, &callbacks);
nfc_service_start();
```
`can_poll` 可以为空;为空时模块默认一直允许读卡。`on_uid` 必须提供。
## 当前 Banban 项目接入方式
参考:
```text
examples/banban_adapter.c
```
这个示例把原项目中的业务判断放回业务层:
- FOTA 中不读卡。
- 休眠中不读卡。
- MQTT 未连接不读卡。
- 录音/TTS/播放队列忙时不读卡。
- 测试模式允许读卡。
- 读到 UID 后,根据 `g_nfc_bind_status` 决定调用绑定还是触发上报。
在当前项目中正式切换时,应用层可以把原来的:
```c
DP1312EA_Init();
```
替换为:
```c
banban_nfc_start();
```
并把 `examples/banban_adapter.c` 加入业务工程源码。
## Quectel SDK 工程怎么接入
如果工程的 Makefile 支持 include 片段,可以引入:
```make
include ../portable_modules/nfc/module.mk
```
或者手动加入这些源码:
```make
SRC_FILES += \
../portable_modules/nfc/src/nfc_service.c \
../portable_modules/nfc/src/nfc_dp1312ea.c \
../portable_modules/nfc/src/nfc_ntag213.c \
../portable_modules/nfc/platform/quectel/nfc_platform_ql.c \
../portable_modules/nfc/vendor/dp1312ea/LPCD.c \
../portable_modules/nfc/vendor/dp1312ea/TypeA.c
INC_DIRS += \
-I../portable_modules/nfc/include \
-I../portable_modules/nfc/src \
-I../portable_modules/nfc/vendor/dp1312ea
```
如果要使用 Banban 示例,还需要加入:
```make
SRC_FILES += ../portable_modules/nfc/examples/banban_adapter.c
```
## 默认硬件配置
- I2C bus: `1`
- DP1312EA I2C slave address: `0x50 >> 1`
- Reset pin: `86`
- IRQ pin: `87`
如硬件不同,在初始化前修改 `nfc_service_config_t`
```c
nfc_service_default_config(&config);
config.i2c_bus = 1;
config.reset_pin = 86;
config.irq_pin = 87;
nfc_service_init(&config, &callbacks);
```
## 移植到其他平台
移植新平台时,不需要改 `src/``vendor/`。只需要新增一个平台实现,例如:
```text
platform/my_sdk/nfc_platform_my_sdk.c
```
实现 `include/nfc_platform.h` 中的函数:
- `nfc_platform_i2c_init`
- `nfc_platform_i2c_read`
- `nfc_platform_i2c_write`
- `nfc_platform_gpio_init`
- `nfc_platform_gpio_set_level`
- `nfc_platform_gpio_get_level`
- `nfc_platform_irq_register`
- `nfc_platform_irq_enable_wakeup`
- `nfc_platform_irq_disable_wakeup`
- `nfc_platform_sem_create`
- `nfc_platform_sem_wait`
- `nfc_platform_sem_release`
- `nfc_platform_task_create`
- `nfc_platform_sleep_ms`
- `nfc_platform_log`
## 分层约束
维护时请保持这些边界:
- `src/``vendor/` 不能 include `ql_*.h`
- `src/``vendor/` 不能 include `app_inc.h`
- `src/``vendor/` 不能调用 MQTT、绑定、播放、录音、FOTA 等业务函数。
- 业务判断必须放在 `can_poll` 回调。
- UID 后续动作必须放在 `on_uid` 回调。