commit 4ed123f87cfbfca0be8c1c11dd1a211744c6199a Author: ChengCan Date: Mon Jul 20 10:48:38 2026 +0800 Add portable NFC module diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c2372b --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Portable Modules + +这个仓库用于存放从具体项目中抽取出来的可移植模块。 + +当前模块: + +- `nfc/`: DP1312EA + NTAG213 UID 读取模块,已按业务层、服务层、芯片驱动层、平台适配层分离。 + +## 目录约定 + +```text +portable_modules/ + README.md + nfc/ + README.md + include/ + src/ + platform/ + vendor/ + examples/ + module.mk +``` + +每个模块都应满足: + +- 业务代码只依赖模块公开头文件。 +- 模块核心代码不直接依赖具体项目业务。 +- SDK/RTOS/GPIO/I2C 等平台差异只放在 `platform/`。 +- 从原项目复制来的芯片厂商或第三方底层代码放在 `vendor/`。 + +## NFC 快速入口 + +NFC 模块文档见 [nfc/README.md](nfc/README.md)。 diff --git a/nfc/README.md b/nfc/README.md new file mode 100644 index 0000000..5355d1f --- /dev/null +++ b/nfc/README.md @@ -0,0 +1,211 @@ +# 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` 回调。 diff --git a/nfc/examples/banban_adapter.c b/nfc/examples/banban_adapter.c new file mode 100644 index 0000000..b7274dc --- /dev/null +++ b/nfc/examples/banban_adapter.c @@ -0,0 +1,96 @@ +#include "nfc_service.h" + +#include +#include +#include + +extern int fota_start; +extern int audio_packet_type; +extern volatile int tts_playing; +extern int g_testmode; +extern int g_nfc_bind_status; + +uint8_t get_sleep_mode(void); +int get_mqtt_connect_status(void); +unsigned char get_xiaoice_connected_status(void); +bool vad_audio_is_recording(void); +int xiaoice_get_play_counter(void); +void handle_nfc_trigger(const char *uuid); +void handle_nfc_bind(const char *uuid); + +static int banban_nfc_can_poll(void *ctx) +{ + (void)ctx; + + if (fota_start != 0) { + return 0; + } + if (get_sleep_mode() == 1) { + return 0; + } + if (get_mqtt_connect_status() != 1) { + return 0; + } + if (g_testmode == 1) { + return 1; + } + if (get_xiaoice_connected_status() != 2) { + return 0; + } + if (vad_audio_is_recording() == 1) { + return 0; + } + if (audio_packet_type != 0) { + return 0; + } + if (tts_playing != 0) { + return 0; + } + if (xiaoice_get_play_counter() != 0) { + return 0; + } + + return 1; +} + +static void banban_nfc_on_uid(const nfc_uid_t *uid, void *ctx) +{ + (void)ctx; + + if (uid == NULL || g_testmode != 0) { + return; + } + + if (g_nfc_bind_status == 1) { + handle_nfc_bind(uid->value); + g_nfc_bind_status = 0; + } else { + handle_nfc_trigger(uid->value); + } +} + +static void banban_nfc_on_error(int status, void *ctx) +{ + (void)status; + (void)ctx; +} + +int banban_nfc_start(void) +{ + nfc_service_config_t config; + nfc_service_callbacks_t callbacks = { + .can_poll = banban_nfc_can_poll, + .on_uid = banban_nfc_on_uid, + .on_error = banban_nfc_on_error, + .ctx = 0, + }; + int ret; + + nfc_service_default_config(&config); + ret = nfc_service_init(&config, &callbacks); + if (ret != NFC_STATUS_OK) { + return ret; + } + + return nfc_service_start(); +} diff --git a/nfc/include/nfc_platform.h b/nfc/include/nfc_platform.h new file mode 100644 index 0000000..48c11ff --- /dev/null +++ b/nfc/include/nfc_platform.h @@ -0,0 +1,85 @@ +#ifndef PORTABLE_NFC_PLATFORM_H +#define PORTABLE_NFC_PLATFORM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFC_PLATFORM_WAIT_FOREVER 0xFFFFFFFFu + +typedef void *nfc_platform_sem_t; +typedef void *nfc_platform_task_t; +typedef void (*nfc_platform_irq_handler_t)(void *arg); +typedef void (*nfc_platform_task_entry_t)(void *arg); + +typedef enum { + NFC_PLATFORM_GPIO_IN = 0, + NFC_PLATFORM_GPIO_OUT = 1, +} nfc_platform_gpio_direction_t; + +typedef enum { + NFC_PLATFORM_GPIO_PULL_DISABLE = 0, + NFC_PLATFORM_GPIO_PULL_UP = 1, + NFC_PLATFORM_GPIO_PULL_DOWN = 2, +} nfc_platform_gpio_pull_t; + +typedef enum { + NFC_PLATFORM_GPIO_LOW = 0, + NFC_PLATFORM_GPIO_HIGH = 1, +} nfc_platform_gpio_level_t; + +typedef enum { + NFC_PLATFORM_IRQ_NONE = 0, + NFC_PLATFORM_IRQ_RISING_EDGE = 1, + NFC_PLATFORM_IRQ_FALLING_EDGE = 2, + NFC_PLATFORM_IRQ_BOTH_EDGE = 3, +} nfc_platform_irq_edge_t; + +void nfc_platform_log(const char *fmt, ...); +void nfc_platform_sleep_ms(uint32_t ms); + +int nfc_platform_i2c_init(uint8_t bus, uint32_t fast_mode); +int nfc_platform_i2c_write(uint8_t bus, + uint8_t slave_addr, + uint16_t reg, + const uint8_t *data, + uint32_t len); +int nfc_platform_i2c_read(uint8_t bus, + uint8_t slave_addr, + uint16_t reg, + uint8_t *data, + uint32_t len); + +int nfc_platform_gpio_init(uint32_t pin, + nfc_platform_gpio_direction_t direction, + nfc_platform_gpio_pull_t pull, + nfc_platform_gpio_level_t initial_level); +int nfc_platform_gpio_set_level(uint32_t pin, nfc_platform_gpio_level_t level); +int nfc_platform_gpio_get_level(uint32_t pin, uint8_t *level); + +int nfc_platform_irq_register(uint32_t pin, + nfc_platform_irq_edge_t edge, + nfc_platform_gpio_pull_t pull, + void *arg, + nfc_platform_irq_handler_t handler); +int nfc_platform_irq_enable_wakeup(uint32_t pin, nfc_platform_irq_edge_t edge); +int nfc_platform_irq_disable_wakeup(uint32_t pin); + +int nfc_platform_sem_create(nfc_platform_sem_t *sem, uint32_t initial_count); +int nfc_platform_sem_wait(nfc_platform_sem_t sem, uint32_t timeout_ms); +int nfc_platform_sem_release(nfc_platform_sem_t sem); + +int nfc_platform_task_create(nfc_platform_task_t *task, + uint32_t stack_size, + uint32_t priority, + const char *name, + nfc_platform_task_entry_t entry, + void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nfc/include/nfc_service.h b/nfc/include/nfc_service.h new file mode 100644 index 0000000..d481ea5 --- /dev/null +++ b/nfc/include/nfc_service.h @@ -0,0 +1,63 @@ +#ifndef PORTABLE_NFC_SERVICE_H +#define PORTABLE_NFC_SERVICE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFC_UID_MAX_BYTES 10 +#define NFC_UID_STRING_MAX_LEN ((NFC_UID_MAX_BYTES * 2) + 1) + +typedef enum { + NFC_STATUS_OK = 0, + NFC_STATUS_ERROR = -1, + NFC_STATUS_BAD_PARAM = -2, + NFC_STATUS_NOT_INITIALIZED = -3, + NFC_STATUS_ALREADY_STARTED = -4, +} nfc_status_t; + +typedef struct { + uint8_t bytes[NFC_UID_MAX_BYTES]; + uint8_t length; + char value[NFC_UID_STRING_MAX_LEN]; +} nfc_uid_t; + +typedef int (*nfc_can_poll_fn)(void *ctx); +typedef void (*nfc_uid_fn)(const nfc_uid_t *uid, void *ctx); +typedef void (*nfc_error_fn)(int status, void *ctx); + +typedef struct { + nfc_can_poll_fn can_poll; + nfc_uid_fn on_uid; + nfc_error_fn on_error; + void *ctx; +} nfc_service_callbacks_t; + +typedef struct { + uint8_t i2c_bus; + uint8_t i2c_fast_mode; + uint8_t i2c_slave_addr; + uint32_t reset_pin; + uint32_t irq_pin; + uint32_t task_stack_size; + uint32_t task_priority; + uint32_t debounce_ms; + uint32_t disallowed_poll_delay_ms; + uint32_t retry_poll_delay_ms; + uint8_t max_fail_count; +} nfc_service_config_t; + +void nfc_service_default_config(nfc_service_config_t *config); +int nfc_service_init(const nfc_service_config_t *config, + const nfc_service_callbacks_t *callbacks); +int nfc_service_start(void); +int nfc_service_stop(void); +int nfc_service_is_started(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nfc/module.mk b/nfc/module.mk new file mode 100644 index 0000000..b75f6a1 --- /dev/null +++ b/nfc/module.mk @@ -0,0 +1,18 @@ +# Optional integration fragment for projects that use the Quectel platform +# adapter. Include this file from an application Makefile after setting +# NFC_MODULE_ROOT if the default relative path does not fit. + +NFC_MODULE_ROOT ?= ../portable_modules/nfc + +SRC_FILES += \ + $(NFC_MODULE_ROOT)/src/nfc_service.c \ + $(NFC_MODULE_ROOT)/src/nfc_dp1312ea.c \ + $(NFC_MODULE_ROOT)/src/nfc_ntag213.c \ + $(NFC_MODULE_ROOT)/platform/quectel/nfc_platform_ql.c \ + $(NFC_MODULE_ROOT)/vendor/dp1312ea/LPCD.c \ + $(NFC_MODULE_ROOT)/vendor/dp1312ea/TypeA.c + +INC_DIRS += \ + -I$(NFC_MODULE_ROOT)/include \ + -I$(NFC_MODULE_ROOT)/src \ + -I$(NFC_MODULE_ROOT)/vendor/dp1312ea diff --git a/nfc/platform/quectel/nfc_platform_ql.c b/nfc/platform/quectel/nfc_platform_ql.c new file mode 100644 index 0000000..7b9ff90 --- /dev/null +++ b/nfc/platform/quectel/nfc_platform_ql.c @@ -0,0 +1,186 @@ +#include "nfc_platform.h" + +#include + +#include "ql_gpio.h" +#include "ql_iic.h" +#include "ql_rtos.h" + +int vprintf(const char *fmt, va_list args); + +static PIN_DIRECTION_E map_direction(nfc_platform_gpio_direction_t direction) +{ + return direction == NFC_PLATFORM_GPIO_OUT ? PIN_DIRECTION_OUT : PIN_DIRECTION_IN; +} + +static PIN_PULL_E map_pull(nfc_platform_gpio_pull_t pull) +{ + switch (pull) { + case NFC_PLATFORM_GPIO_PULL_UP: + return PIN_PULL_PU; + case NFC_PLATFORM_GPIO_PULL_DOWN: + return PIN_PULL_PD; + case NFC_PLATFORM_GPIO_PULL_DISABLE: + default: + return PIN_PULL_DISABLE; + } +} + +static PIN_LEVEL_E map_level(nfc_platform_gpio_level_t level) +{ + return level == NFC_PLATFORM_GPIO_HIGH ? PIN_LEVEL_HIGH : PIN_LEVEL_LOW; +} + +static PIN_EDGE_E map_edge(nfc_platform_irq_edge_t edge) +{ + switch (edge) { + case NFC_PLATFORM_IRQ_RISING_EDGE: + return PIN_RISING_EDGE; + case NFC_PLATFORM_IRQ_FALLING_EDGE: + return PIN_FALLING_EDGE; + case NFC_PLATFORM_IRQ_BOTH_EDGE: + return PIN_BOTH_EDGE; + case NFC_PLATFORM_IRQ_NONE: + default: + return PIN_NO_EDGE; + } +} + +void nfc_platform_log(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +void nfc_platform_sleep_ms(uint32_t ms) +{ + ql_rtos_task_sleep_ms(ms); +} + +int nfc_platform_i2c_init(uint8_t bus, uint32_t fast_mode) +{ + return ql_i2c_init(bus, fast_mode); +} + +int nfc_platform_i2c_write(uint8_t bus, + uint8_t slave_addr, + uint16_t reg, + const uint8_t *data, + uint32_t len) +{ + return ql_i2c_write(bus, slave_addr, reg, (unsigned char *)data, len); +} + +int nfc_platform_i2c_read(uint8_t bus, + uint8_t slave_addr, + uint16_t reg, + uint8_t *data, + uint32_t len) +{ + return ql_i2c_read(bus, slave_addr, reg, data, len); +} + +int nfc_platform_gpio_init(uint32_t pin, + nfc_platform_gpio_direction_t direction, + nfc_platform_gpio_pull_t pull, + nfc_platform_gpio_level_t initial_level) +{ + return ql_gpio_init((GPIO_PIN_NUMBER_E)pin, + map_direction(direction), + map_pull(pull), + map_level(initial_level)); +} + +int nfc_platform_gpio_set_level(uint32_t pin, nfc_platform_gpio_level_t level) +{ + return ql_gpio_set_level((GPIO_PIN_NUMBER_E)pin, map_level(level)); +} + +int nfc_platform_gpio_get_level(uint32_t pin, uint8_t *level) +{ + PIN_LEVEL_E pin_level = PIN_LEVEL_LOW; + int ret; + + if (level == NULL) { + return -1; + } + + ret = ql_gpio_get_level((GPIO_PIN_NUMBER_E)pin, &pin_level); + *level = (pin_level == PIN_LEVEL_HIGH) ? 1 : 0; + return ret; +} + +int nfc_platform_irq_register(uint32_t pin, + nfc_platform_irq_edge_t edge, + nfc_platform_gpio_pull_t pull, + void *arg, + nfc_platform_irq_handler_t handler) +{ + (void)arg; + return ql_eint_register((GPIO_PIN_NUMBER_E)pin, + map_edge(edge), + map_pull(pull), + NULL, + (void *)handler); +} + +int nfc_platform_irq_enable_wakeup(uint32_t pin, nfc_platform_irq_edge_t edge) +{ + return ql_eint_enable_wakeup((GPIO_PIN_NUMBER_E)pin, map_edge(edge)); +} + +int nfc_platform_irq_disable_wakeup(uint32_t pin) +{ + return ql_eint_disable_wakeup((GPIO_PIN_NUMBER_E)pin); +} + +int nfc_platform_sem_create(nfc_platform_sem_t *sem, uint32_t initial_count) +{ + ql_sem_t ql_sem = NULL; + int ret; + + if (sem == NULL) { + return -1; + } + + ret = ql_rtos_semaphore_create(&ql_sem, initial_count); + *sem = ql_sem; + return ret; +} + +int nfc_platform_sem_wait(nfc_platform_sem_t sem, uint32_t timeout_ms) +{ + return ql_rtos_semaphore_wait((ql_sem_t)sem, timeout_ms); +} + +int nfc_platform_sem_release(nfc_platform_sem_t sem) +{ + return ql_rtos_semaphore_release((ql_sem_t)sem); +} + +int nfc_platform_task_create(nfc_platform_task_t *task, + uint32_t stack_size, + uint32_t priority, + const char *name, + nfc_platform_task_entry_t entry, + void *arg) +{ + ql_task_t ql_task = NULL; + int ret; + + if (task == NULL || entry == NULL) { + return -1; + } + + ret = ql_rtos_task_create(&ql_task, + stack_size, + (uint8_t)priority, + (char *)name, + entry, + arg); + *task = ql_task; + return ret; +} diff --git a/nfc/src/nfc_dp1312ea.c b/nfc/src/nfc_dp1312ea.c new file mode 100644 index 0000000..ec0f327 --- /dev/null +++ b/nfc/src/nfc_dp1312ea.c @@ -0,0 +1,257 @@ +#include "nfc_dp1312ea.h" + +#include + +#include "nfc_platform.h" +#include "DP1312EA_Config.h" +#include "DP1312EA.h" +#include "LPCD.h" + +static nfc_service_config_t g_config = { + .i2c_bus = 1, + .i2c_fast_mode = 0, + .i2c_slave_addr = 0x50 >> 1, + .reset_pin = 86, + .irq_pin = 87, + .task_stack_size = 1024 * 6, + .task_priority = 100, + .debounce_ms = 10, + .disallowed_poll_delay_ms = 300, + .retry_poll_delay_ms = 300, + .max_fail_count = 3, +}; + +int nfc_dp1312ea_configure(const nfc_service_config_t *config) +{ + if (config == NULL) { + return NFC_STATUS_BAD_PARAM; + } + + g_config = *config; + return NFC_STATUS_OK; +} + +uint32_t nfc_dp1312ea_get_reset_pin(void) +{ + return g_config.reset_pin; +} + +void DP1312EA_SetBitMask(u8 reg, u8 mask) +{ + u8 tmp = DP1312EA_ReadRawRC(reg); + DP1312EA_WriteRawRC(reg, tmp | mask); +} + +void DP1312EA_ClearBitMask(uint8_t reg, uint8_t mask) +{ + u8 tmp = DP1312EA_ReadRawRC(reg); + DP1312EA_WriteRawRC(reg, tmp & ~mask); +} + +void DP1312EA_WriteRawRC(uint8_t address, uint8_t value) +{ + (void)nfc_platform_i2c_write(g_config.i2c_bus, + g_config.i2c_slave_addr, + address, + &value, + 1); +} + +u8 DP1312EA_ReadRawRC(uint8_t address) +{ + u8 value = 0; + + (void)nfc_platform_i2c_read(g_config.i2c_bus, + g_config.i2c_slave_addr, + address, + &value, + 1); + return value; +} + +void DP1312EA_WriteFIFO(uint8_t *data, uint8_t len) +{ + uint8_t i; + + for (i = 0; i < len; i++) { + DP1312EA_WriteRawRC(FIFODataReg, data[i]); + } +} + +void DP1312EA_ReadFIFO(uint8_t *buf, uint8_t len) +{ + uint8_t i; + + for (i = 0; i < len; i++) { + buf[i] = DP1312EA_ReadRawRC(FIFODataReg); + } +} + +int nfc_dp1312ea_check_chip(void) +{ + u8 version = DP1312EA_ReadRawRC(VersionReg); + + if (version == 0x82) { + nfc_platform_log("\r\nDP1312EA is OK!"); + return NFC_STATUS_OK; + } + + nfc_platform_log("\r\nDP1312EA version error: 0x%02X", version); + return NFC_STATUS_ERROR; +} + +void Check_Chip(void) +{ + (void)nfc_dp1312ea_check_chip(); +} + +void DP1312EA_Enable(void) +{ + (void)nfc_platform_gpio_set_level(g_config.reset_pin, NFC_PLATFORM_GPIO_LOW); + nfc_platform_sleep_ms(2); +} + +void DP1312EA_Disable(void) +{ + (void)nfc_platform_gpio_set_level(g_config.reset_pin, NFC_PLATFORM_GPIO_HIGH); + nfc_platform_sleep_ms(2); +} + +void DP1312EA_Reset(void) +{ + (void)nfc_platform_gpio_init(g_config.reset_pin, + NFC_PLATFORM_GPIO_OUT, + NFC_PLATFORM_GPIO_PULL_DISABLE, + NFC_PLATFORM_GPIO_LOW); + + (void)nfc_platform_gpio_set_level(g_config.reset_pin, NFC_PLATFORM_GPIO_LOW); + nfc_platform_sleep_ms(1); + (void)nfc_platform_gpio_set_level(g_config.reset_pin, NFC_PLATFORM_GPIO_HIGH); + nfc_platform_sleep_ms(2); + (void)nfc_platform_gpio_set_level(g_config.reset_pin, NFC_PLATFORM_GPIO_LOW); + nfc_platform_sleep_ms(1); + + (void)nfc_platform_i2c_init(g_config.i2c_bus, g_config.i2c_fast_mode); +} + +void nfc_dp1312ea_reset(void) +{ + DP1312EA_Reset(); +} + +void nfc_dp1312ea_enable(void) +{ + DP1312EA_Enable(); +} + +void nfc_dp1312ea_disable(void) +{ + DP1312EA_Disable(); +} + +void nfc_dp1312ea_lpcd_start(void) +{ + DP1312EA_LPCD_Start(); +} + +void nfc_dp1312ea_clear_irq(void) +{ + (void)DP1312EA_CLEAR_IRQ(); +} + +void DP1312EA_FieldOn(void) +{ + u8 value = DP1312EA_ReadRawRC(TxControlReg); + + if ((value & 0x03) == 0) { + DP1312EA_WriteRawRC(TxControlReg, value | 0x03); + } +} + +void DP1312EA_FieldOff(void) +{ + DP1312EA_ClearBitMask(TxControlReg, 0x03); +} + +s8 DP1312EA_PcdComTransceive(struct TranSciveBuffer *pi) +{ + s8 status = MI_ERR; + u8 irqEn = 0; + u8 waitFor = 0; + u8 n = 0; + u8 lastBits; + u16 i; + + switch (pi->MfCommand) { + case DP1312EA_AUTHENT: + irqEn = 0x12; + waitFor = 0x10; + break; + case DP1312EA_TRANSCEIVE: + irqEn = 0x77; + waitFor = 0x30; + break; + default: + break; + } + + DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE); + DP1312EA_SetBitMask(FIFOLevelReg, 0x80); + DP1312EA_WriteRawRC(ComIrqReg, 0x7F); + + for (i = 0; i < pi->MfLength; i++) { + DP1312EA_WriteRawRC(FIFODataReg, pi->MfData[i]); + } + + DP1312EA_WriteRawRC(CommandReg, pi->MfCommand); + + if (pi->MfCommand == DP1312EA_TRANSCEIVE) { + DP1312EA_SetBitMask(BitFramingReg, 0x80); + } + + for (i = 500; i > 0; i--) { + n = DP1312EA_ReadRawRC(ComIrqReg); + if ((n & irqEn & 0x01) || (n & waitFor)) { + break; + } + } + + DP1312EA_ClearBitMask(BitFramingReg, 0x80); + + if (n & waitFor) { + if (DP1312EA_ReadRawRC(ErrorReg) & 0x1B) { + status = MI_ERR; + } else { + status = MI_OK; + + if (pi->MfCommand == DP1312EA_TRANSCEIVE) { + n = DP1312EA_ReadRawRC(FIFOLevelReg); + lastBits = DP1312EA_ReadRawRC(ControlReg) & 0x07; + if (lastBits) { + pi->MfLength = (n - 1) * 8 + lastBits; + } else { + pi->MfLength = n * 8; + } + + if (n == 0) { + n = 1; + } + if (n > MAXRLEN) { + n = MAXRLEN; + } + + for (i = 0; i < n; i++) { + pi->MfData[i] = DP1312EA_ReadRawRC(FIFODataReg); + } + } + } + } else if (n & irqEn & 0x01) { + status = MI_NOTAGERR; + } else if ((DP1312EA_ReadRawRC(ErrorReg) & 0x1B) == 0) { + status = MI_ACCESSTIMEOUT; + } + + DP1312EA_SetBitMask(ControlReg, 0x80); + DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE); + return status; +} diff --git a/nfc/src/nfc_dp1312ea.h b/nfc/src/nfc_dp1312ea.h new file mode 100644 index 0000000..fa965cf --- /dev/null +++ b/nfc/src/nfc_dp1312ea.h @@ -0,0 +1,15 @@ +#ifndef PORTABLE_NFC_DP1312EA_H +#define PORTABLE_NFC_DP1312EA_H + +#include +#include "nfc_service.h" + +int nfc_dp1312ea_configure(const nfc_service_config_t *config); +int nfc_dp1312ea_check_chip(void); +void nfc_dp1312ea_reset(void); +void nfc_dp1312ea_enable(void); +void nfc_dp1312ea_disable(void); +void nfc_dp1312ea_lpcd_start(void); +void nfc_dp1312ea_clear_irq(void); + +#endif diff --git a/nfc/src/nfc_ntag213.c b/nfc/src/nfc_ntag213.c new file mode 100644 index 0000000..5f98122 --- /dev/null +++ b/nfc/src/nfc_ntag213.c @@ -0,0 +1,65 @@ +#include "nfc_ntag213.h" + +#include + +#include "nfc_dp1312ea.h" +#include "nfc_platform.h" +#include "TypeA.h" + +static void nfc_bytes_to_hex(const uint8_t *bytes, uint8_t len, char *output) +{ + static const char hex[] = "0123456789ABCDEF"; + uint8_t i; + + for (i = 0; i < len; i++) { + output[i * 2] = hex[(bytes[i] >> 4) & 0x0F]; + output[(i * 2) + 1] = hex[bytes[i] & 0x0F]; + } + output[len * 2] = '\0'; +} + +int nfc_ntag213_read_uid(nfc_uid_t *out) +{ + s8 status; + u8 atqa[2]; + u8 raw_uid[12] = {0}; + u8 raw_uid_len = 0; + u8 sak = 0; + const u8 *uid_start = NULL; + uint8_t uid_len = 0; + + if (out == NULL) { + return NFC_STATUS_BAD_PARAM; + } + + memset(out, 0, sizeof(*out)); + + nfc_dp1312ea_reset(); + nfc_platform_sleep_ms(1); + + status = DP1312EA_PcdActivateA(atqa, raw_uid, &raw_uid_len, &sak); + nfc_dp1312ea_disable(); + + if (status != MI_OK) { + return status; + } + + if (raw_uid_len == 8) { + uid_start = &raw_uid[1]; + uid_len = 7; + } else if (raw_uid_len == 4) { + uid_start = raw_uid; + uid_len = 4; + nfc_platform_log("Warning: 4-byte UID, may be Ultralight C\n"); + } else { + nfc_platform_log("Unknown UID length: %d\n", raw_uid_len); + return MI_ERR; + } + + memcpy(out->bytes, uid_start, uid_len); + out->length = uid_len; + nfc_bytes_to_hex(out->bytes, out->length, out->value); + nfc_platform_log("NFC uid read:%s\r\n", out->value); + + return NFC_STATUS_OK; +} diff --git a/nfc/src/nfc_ntag213.h b/nfc/src/nfc_ntag213.h new file mode 100644 index 0000000..9929c87 --- /dev/null +++ b/nfc/src/nfc_ntag213.h @@ -0,0 +1,8 @@ +#ifndef PORTABLE_NFC_NTAG213_H +#define PORTABLE_NFC_NTAG213_H + +#include "nfc_service.h" + +int nfc_ntag213_read_uid(nfc_uid_t *uid); + +#endif diff --git a/nfc/src/nfc_service.c b/nfc/src/nfc_service.c new file mode 100644 index 0000000..6df9ab2 --- /dev/null +++ b/nfc/src/nfc_service.c @@ -0,0 +1,248 @@ +#include "nfc_service.h" + +#include + +#include "nfc_dp1312ea.h" +#include "nfc_ntag213.h" +#include "nfc_platform.h" + +typedef enum { + NFC_STATE_LPCD_WAIT = 0, + NFC_STATE_POLLING = 1, +} nfc_state_t; + +static nfc_platform_sem_t g_irq_sem = NULL; +static nfc_platform_task_t g_task = NULL; +static nfc_service_config_t g_config; +static nfc_service_callbacks_t g_callbacks; +static volatile nfc_state_t g_state = NFC_STATE_LPCD_WAIT; +static volatile uint8_t g_poll_fail_count = 0; +static volatile uint8_t g_irq_trigger = 0; +static volatile uint8_t g_initialized = 0; +static volatile uint8_t g_started = 0; + +void nfc_service_default_config(nfc_service_config_t *config) +{ + if (config == NULL) { + return; + } + + memset(config, 0, sizeof(*config)); + config->i2c_bus = 1; + config->i2c_fast_mode = 0; + config->i2c_slave_addr = 0x50 >> 1; + config->reset_pin = 86; + config->irq_pin = 87; + config->task_stack_size = 1024 * 6; + config->task_priority = 100; + config->debounce_ms = 10; + config->disallowed_poll_delay_ms = 300; + config->retry_poll_delay_ms = 300; + config->max_fail_count = 3; +} + +static void nfc_report_error(int status) +{ + if (g_callbacks.on_error != NULL) { + g_callbacks.on_error(status, g_callbacks.ctx); + } +} + +static int nfc_can_poll(void) +{ + if (g_callbacks.can_poll == NULL) { + return 1; + } + + return g_callbacks.can_poll(g_callbacks.ctx); +} + +static void nfc_irq_wake(void *arg) +{ + uint8_t level = 0; + + (void)arg; + (void)nfc_platform_irq_disable_wakeup(g_config.irq_pin); + (void)nfc_platform_gpio_get_level(g_config.irq_pin, &level); + nfc_platform_log("DP1312EA irq level:%d\n", level); + (void)nfc_platform_irq_enable_wakeup(g_config.irq_pin, NFC_PLATFORM_IRQ_RISING_EDGE); + + if (g_irq_trigger == 0) { + g_irq_trigger = 1; + (void)nfc_platform_sem_release(g_irq_sem); + } +} + +static void nfc_task_thread(void *arg) +{ + (void)arg; + + while (g_started) { + if (g_state == NFC_STATE_LPCD_WAIT) { + nfc_dp1312ea_lpcd_start(); + nfc_platform_log("NFC enter LPCD mode, waiting for IRQ...\r\n"); + + (void)nfc_platform_sem_wait(g_irq_sem, NFC_PLATFORM_WAIT_FOREVER); + + if (!g_started) { + break; + } + + nfc_dp1312ea_clear_irq(); + nfc_platform_sleep_ms(g_config.debounce_ms); + nfc_platform_log("NFC IRQ wake up, switch to polling mode\r\n"); + + g_state = NFC_STATE_POLLING; + g_poll_fail_count = 0; + continue; + } + + if (g_state == NFC_STATE_POLLING) { + nfc_uid_t uid; + int read_status; + + if (!nfc_can_poll()) { + nfc_platform_sleep_ms(g_config.disallowed_poll_delay_ms); + continue; + } + + read_status = nfc_ntag213_read_uid(&uid); + if (read_status == NFC_STATUS_OK) { + nfc_platform_log("NFC read OK, back to LPCD\r\n"); + if (g_callbacks.on_uid != NULL) { + g_callbacks.on_uid(&uid, g_callbacks.ctx); + } + + g_state = NFC_STATE_LPCD_WAIT; + g_poll_fail_count = 0; + g_irq_trigger = 0; + nfc_platform_sleep_ms(10); + continue; + } + + g_poll_fail_count++; + nfc_platform_log("NFC read failed, fail_count=%d\r\n", g_poll_fail_count); + + if (g_poll_fail_count >= g_config.max_fail_count) { + nfc_platform_log("NFC fail limit reached, back to LPCD\r\n"); + nfc_report_error(read_status); + g_state = NFC_STATE_LPCD_WAIT; + g_poll_fail_count = 0; + g_irq_trigger = 0; + nfc_platform_sleep_ms(10); + } else { + nfc_platform_sleep_ms(g_config.retry_poll_delay_ms); + } + } + } + + g_started = 0; +} + +int nfc_service_init(const nfc_service_config_t *config, + const nfc_service_callbacks_t *callbacks) +{ + nfc_service_config_t default_config; + int status; + + if (callbacks == NULL || callbacks->on_uid == NULL) { + return NFC_STATUS_BAD_PARAM; + } + + if (config == NULL) { + nfc_service_default_config(&default_config); + config = &default_config; + } + + g_config = *config; + g_callbacks = *callbacks; + + status = nfc_dp1312ea_configure(&g_config); + if (status != NFC_STATUS_OK) { + return status; + } + + status = nfc_platform_gpio_init(g_config.irq_pin, + NFC_PLATFORM_GPIO_IN, + NFC_PLATFORM_GPIO_PULL_DOWN, + NFC_PLATFORM_GPIO_LOW); + if (status != 0) { + return status; + } + + status = nfc_platform_irq_register(g_config.irq_pin, + NFC_PLATFORM_IRQ_RISING_EDGE, + NFC_PLATFORM_GPIO_PULL_DOWN, + NULL, + nfc_irq_wake); + if (status != 0) { + return status; + } + + status = nfc_platform_irq_enable_wakeup(g_config.irq_pin, + NFC_PLATFORM_IRQ_RISING_EDGE); + if (status != 0) { + return status; + } + + nfc_dp1312ea_reset(); + (void)nfc_dp1312ea_check_chip(); + + if (g_irq_sem == NULL) { + status = nfc_platform_sem_create(&g_irq_sem, 0); + if (status != 0) { + return status; + } + } + + g_state = NFC_STATE_LPCD_WAIT; + g_poll_fail_count = 0; + g_irq_trigger = 0; + g_initialized = 1; + + return NFC_STATUS_OK; +} + +int nfc_service_start(void) +{ + int status; + + if (!g_initialized) { + return NFC_STATUS_NOT_INITIALIZED; + } + if (g_started) { + return NFC_STATUS_ALREADY_STARTED; + } + + g_started = 1; + status = nfc_platform_task_create(&g_task, + g_config.task_stack_size, + g_config.task_priority, + "nfc_Task_Ref", + nfc_task_thread, + NULL); + if (status != 0) { + g_started = 0; + return status; + } + + return NFC_STATUS_OK; +} + +int nfc_service_stop(void) +{ + if (!g_initialized) { + return NFC_STATUS_NOT_INITIALIZED; + } + + g_started = 0; + if (g_irq_sem != NULL) { + (void)nfc_platform_sem_release(g_irq_sem); + } + return NFC_STATUS_OK; +} + +int nfc_service_is_started(void) +{ + return g_started; +} diff --git a/nfc/vendor/dp1312ea/Antcoll.c b/nfc/vendor/dp1312ea/Antcoll.c new file mode 100644 index 0000000..3f58ff3 --- /dev/null +++ b/nfc/vendor/dp1312ea/Antcoll.c @@ -0,0 +1,328 @@ +#include +#include +#include "DP1312EA_Config.h" +#include "DP1312EA.h" +#include "TypeA.h" +#include "nfc_platform.h" + + + +// 定义卡片状态 +typedef enum { + CARD_STATE_IDLE, + CARD_STATE_READY, + CARD_STATE_ACTIVE, + CARD_STATE_HALT +} CardState; + +// 卡片信息结构 +typedef struct { + uint8_t uid[10]; // UID (4,7或10字节) + uint8_t uid_len; // UID长度 + CardState state; // 卡片状态 +} CardInfo; + +// 系统参数 +#define MAX_CARDS 10 // 最大检测卡片数量 +CardInfo detectedCards[MAX_CARDS]; +uint8_t cardCount = 0; + + + +// 函数声明 +void DP1312EA_Config(void); +uint8_t DP1312EA_Transceive(uint8_t *send, uint8_t sendLen, uint8_t *recv, uint8_t *recvLen); +uint8_t DP1312EA_Request(uint8_t cmd, uint8_t *atq); +uint8_t DP1312EA_Anticollision(uint8_t level, uint8_t *uid, uint8_t *uid_len); +uint8_t DP1312EA_Select(uint8_t level, uint8_t *uid, uint8_t uid_len, uint8_t *sak); +uint8_t DP1312EA_Halt(void); +void DP1312EA_HandleCollision(uint8_t *uid, uint8_t uid_len, uint8_t level); +void FindAllCards(void); +int TypeA_AntiColl(void); + + +// DP1312EA初始化 +void DP1312EA_Config(void) { + + DP1312EA_Reset(); + // 配置DP1312EA寄存器 + DP1312EA_PcdConfigISOType('A'); + DP1312EA_FieldOn(); + nfc_platform_sleep_ms(10); +} + + + + +// 发送和接收数据 +uint8_t DP1312EA_Transceive(uint8_t *send, uint8_t sendLen, uint8_t *recv, uint8_t *recvLen) { + // 清除FIFO + DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); + DP1312EA_WriteRawRC(0x01, DP1312EA_MEM); + + // 写入发送数据 + DP1312EA_WriteFIFO(send, sendLen); + + // 启动传输 + DP1312EA_WriteRawRC(0x01, DP1312EA_TRANSCEIVE); + DP1312EA_WriteRawRC(0x0D, 0x30); // 启用发送和接收 + + // 等待传输完成 + uint16 timeout = 2000; // 超时时间 + while (!(DP1312EA_ReadRawRC(0x04) & 0x30) ){ // 等待TxIRq或RxIRq + if (--timeout == 0) { + DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); // 停止传输 + return 1; // 超时错误 + } + //nfc_platform_sleep_ms(1); + //Delay_us(100); + } + + // 检查错误 + if (DP1312EA_ReadRawRC(0x06) & 0x13) { // 检查错误标志 + DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); + return 2; // 通信错误 + } + + // 读取接收数据 + *recvLen = DP1312EA_ReadRawRC(0x0A); // FIFOLevel + if (*recvLen > 0) { + DP1312EA_ReadFIFO(recv, *recvLen); + } + + DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); + return 0; // 成功 +} + +// 请求阶段 +uint8_t DP1312EA_Request(uint8_t cmd, uint8_t *atq) { + uint8_t response[2]; + uint8_t resLen = 2; + uint8_t status = DP1312EA_Transceive(&cmd, 1, response, &resLen); + + if (status == 0 && resLen == 2) { + atq[0] = response[0]; + atq[1] = response[1]; + return 1; // 成功 + } + return 0; // 失败 +} + +// 防冲突函数 +uint8_t DP1312EA_Anticollision(uint8_t level, uint8_t *uid, uint8_t *uid_len) { + uint8_t anticoll_cmd; + uint8_t nvb; + + switch(level) { + case 0: + anticoll_cmd = PICC_ANTICOLL1; + nvb = 0x20; // 32位 + break; + case 1: + anticoll_cmd = PICC_ANTICOLL2; + nvb = 0x20; // 32位 + break; + case 2: + anticoll_cmd = PICC_ANTICOLL3; + nvb = 0x20; // 32位 + break; + default: + return 0; + } + + uint8_t sendBuf[2] = {anticoll_cmd, nvb}; + uint8_t recvBuf[10]; // 最大UID长度+1 + uint8_t recvLen = sizeof(recvBuf); + + uint8_t status = DP1312EA_Transceive(sendBuf, 2, recvBuf, &recvLen); + + if (status != 0 || recvLen < 5) { // 至少4字节UID+1字节BCC + return 0; // 失败 + } + + // 检查冲突 + if (DP1312EA_ReadRawRC(0x06) & 0x08) { // CollErr标志 + return 2; // 冲突 + } + + // 计算BCC + uint8_t bcc = 0; + for (uint8_t i = 0; i < recvLen - 1; i++) { + bcc ^= recvBuf[i]; + } + + if (bcc != recvBuf[recvLen-1]) { + return 0; // BCC错误 + } + + // 复制UID + *uid_len = recvLen - 1; + memcpy(uid, recvBuf, *uid_len); + return 1; // 成功 +} + +// 选择卡片 +uint8_t DP1312EA_Select(uint8_t level, uint8_t *uid, uint8_t uid_len, uint8_t *sak) { + uint8_t select_cmd; + + switch(level) { + case 0: select_cmd = SELECT_0; break; + case 1: select_cmd = SELECT_1; break; + case 2: select_cmd = SELECT_2; break; + default: return 0; + } + + uint8_t sendBuf[10]; // SEL + NVB + UID + BCC + uint8_t sendLen = 0; + + sendBuf[sendLen++] = select_cmd; + sendBuf[sendLen++] = 0x70; // NVB=64位 + + uint8_t bcc = 0; + for (uint8_t i = 0; i < uid_len; i++) { + sendBuf[sendLen++] = uid[i]; + bcc ^= uid[i]; + } + sendBuf[sendLen++] = bcc; + + uint8_t response[3]; + uint8_t resLen = sizeof(response); + + if (DP1312EA_Transceive(sendBuf, sendLen, response, &resLen) != 0 || resLen < 1) { + return 0; // 失败 + } + + *sak = response[0]; + return 1; // 成功 +} + +// 休眠卡片 +uint8_t DP1312EA_Halt(void) { + uint8_t halt_cmd[4] = {PICC_HALT, 0, 0, 0}; // CRC由DP1312EA计算 + uint8_t resLen = 0; + return (DP1312EA_Transceive(halt_cmd, 4, NULL, &resLen) == 0); +} + +// 处理冲突 +void DP1312EA_HandleCollision(uint8_t *uid, uint8_t uid_len, uint8_t level) { + uint8_t coll_pos = DP1312EA_ReadRawRC(BitFramingReg) & 0x1F; + uint8_t bit_pos = coll_pos % 8; + uint8_t byte_pos = coll_pos / 8; + + // 确定冲突位的位置 +// uint8_t collision_byte = uid[byte_pos]; + + // 尝试两种可能的值 (0和1) + for (uint8_t bit_value = 0; bit_value <= 1; bit_value++) { + // 创建新的UID分支 + uint8_t new_uid[10]; + memcpy(new_uid, uid, uid_len); + + // 设置冲突位的值 + if (bit_value) { + new_uid[byte_pos] |= (1 << bit_pos); + } else { + new_uid[byte_pos] &= ~(1 << bit_pos); + } + + // 尝试防冲突 + uint8_t status = DP1312EA_Anticollision(level, new_uid, &uid_len); + + if (status == 1) { + // 成功获取UID + uint8_t sak; + if (DP1312EA_Select(level, new_uid, uid_len, &sak)) { + // 检查SAK的UID完整标志 + if (sak & 0x04) { + // UID完整,存储卡片 + if (cardCount < MAX_CARDS) { + memcpy(detectedCards[cardCount].uid, new_uid, uid_len); + detectedCards[cardCount].uid_len = uid_len; + detectedCards[cardCount].state = CARD_STATE_ACTIVE; + cardCount++; + } + // 使卡片休眠 + DP1312EA_Halt(); + } else { + // UID不完整,进入下一级防冲突 + DP1312EA_HandleCollision(new_uid, uid_len, level + 1); + } + } + } else if (status == 2) { + // 仍有冲突,递归处理 + DP1312EA_HandleCollision(new_uid, uid_len, level); + } + } +} + +// 完整的防冲突流程 +void FindAllCards(void) { + cardCount = 0; // 重置卡片计数 + + // 1. 发送REQA唤醒卡片 + uint8_t atq[2]; + if (!DP1312EA_Request(PICC_REQIDL, atq)) { + return; // 没有卡片 + } + + // 2. 初始防冲突循环 + uint8_t uid[10]; + uint8_t uid_len; + uint8_t status; + + while (cardCount < MAX_CARDS) { + status = DP1312EA_Anticollision(0, uid, &uid_len); + + if (status == 1) { + // 成功获取UID + uint8_t sak; + if (DP1312EA_Select(0, uid, uid_len, &sak)) { + // 检查SAK的UID完整标志 + if (sak & 0x04) { + // UID完整,存储卡片 + memcpy(detectedCards[cardCount].uid, uid, uid_len); + detectedCards[cardCount].uid_len = uid_len; + detectedCards[cardCount].state = CARD_STATE_ACTIVE; + cardCount++; + + // 使卡片休眠 + DP1312EA_Halt(); + } else { + // UID不完整,进入下一级防冲突 + DP1312EA_HandleCollision(uid, uid_len, 1); + } + } + } else if (status == 2) { + // 冲突发生,处理冲突 + DP1312EA_HandleCollision(uid, uid_len, 0); + } else { + // 没有更多卡片 + break; + } + } +} + +// 主函数 +int TypeA_AntiColl(void) { + + DP1312EA_Config(); + + while (1) { + FindAllCards(); + + if (cardCount > 0) { + // 处理所有检测到的卡片 + for (uint8_t i = 0; i < cardCount; i++) { + // 打印UID + nfc_platform_log("Card %d UID: ", i); + for (uint8_t j = 0; j < detectedCards[i].uid_len; j++) { + nfc_platform_log("%02X ", detectedCards[i].uid[j]); + } + nfc_platform_log("\n"); + } + } + + //Delay_ms(500); // 延时后再检测 + } +} + diff --git a/nfc/vendor/dp1312ea/DP1312EA.h b/nfc/vendor/dp1312ea/DP1312EA.h new file mode 100644 index 0000000..fb36f65 --- /dev/null +++ b/nfc/vendor/dp1312ea/DP1312EA.h @@ -0,0 +1,26 @@ +#ifndef DP1312EA_DRIVER_H +#define DP1312EA_DRIVER_H + +#include +#include "nfc.h" +#include "reg.h" + +void DP1312EA_SetBitMask(u8 reg, u8 mask); +void DP1312EA_ClearBitMask(u8 reg, u8 mask); +void DP1312EA_WriteRawRC(u8 address, u8 value); +u8 DP1312EA_ReadRawRC(u8 address); + +void Check_Chip(void); +void DP1312EA_Reset(void); +void DP1312EA_Enable(void); +void DP1312EA_Disable(void); +s8 DP1312EA_PcdComTransceive(struct TranSciveBuffer *pi); +void DP1312EA_WriteFIFO(uint8_t *data, uint8_t len); +void DP1312EA_ReadFIFO(uint8_t *buf, uint8_t len); + +void DP1312EA_FieldOn(void); +void DP1312EA_FieldOff(void); + +uint32_t nfc_dp1312ea_get_reset_pin(void); + +#endif diff --git a/nfc/vendor/dp1312ea/DP1312EA_Config.h b/nfc/vendor/dp1312ea/DP1312EA_Config.h new file mode 100644 index 0000000..ba3371e --- /dev/null +++ b/nfc/vendor/dp1312ea/DP1312EA_Config.h @@ -0,0 +1,74 @@ +#ifndef __DP1312EA_Config_H +#define __DP1312EA_Config_H + + +//set IRQ LEVEL +#define IRQ_HIGH_LEVEL 1 //set high level irq +#define IRQ_LOW_LEVEL 2 //set low level irq + +#define IRQ_LEVEL_SET IRQ_HIGH_LEVEL //设为低电平 + + + +//set irq output mode +#define IRQ_OUT_PP 1 //set IRQ CMOS ouput +#define IRQ_OUT_OD 2 //set IRQ OPEN drain + +#define IRQ_OUT_MODE IRQ_OUT_PP //中断输出设置为CMOS + +//sensitive adjust, 0-8 +#define SENSITIVE_MIN 0 +#define SENSITIVE_SEC 2 +#define SENSITIVE_MID 4 +#define SENSITIVE_SIX 6 +#define SENSITIVE_MAX 8 + +#define LPCD_Sensitive_Value SENSITIVE_MIN //灵敏度设置 + + +/* set check cycle */ +#define CHECK_PERIOD_110MS 0x08ff //110ms +-12% +#define CHECK_PERIOD_220MS 0x10ff //220ms +-12% +#define CHECK_PERIOD_330MS 0x1aff //330ms +-12% +#define CHECK_PERIOD_430MS 0x22ff //430ms +-12% + +/*设置LPCD检测周期*/ +#define LPCD_Cycle_Time CHECK_PERIOD_220MS //430ms + + +/* set LPCD check time */ +#define CHECK_TIME_10US 0x007f //10us +#define CHECK_TIME_05US 0x003f //5us +#define CHECK_TIME_20US 0x00ff //20us + +/*选择检卡时长*/ +#define LPCD_Duration_Time CHECK_TIME_05US //5us + + +/* 读卡寄存器配置,不同的天线适配不同的配置,选择最优的定义 */ +#define REG_SET_1 1 //A卡寄存配置1 +#define REG_SET_2 2 //A卡寄存配置2 +#define REG_SET_3 3 //A卡寄存配置3 +#define REG_SET_4 4 //A卡寄存配置4 + +#define TYPEA_REG_CONFIG REG_SET_1 //选择寄存器配置1 + + +/* 通讯接口定义 */ +#define INTERFACE_SPI 1 +#define INTERFACE_I2C 2 +#define INTERFACE_UART 3 + +/* 通讯接口选择 */ +#define HOSTINTERFACE INTERFACE_I2C //SPI接口 + + +/*调试信息是否通过口口打印定义,有定义则打印,无定义则不打印*/ +//#define UART_DEBUG + + + +#endif + +/***********************************************END*******************************************************/ + diff --git a/nfc/vendor/dp1312ea/Felica.c b/nfc/vendor/dp1312ea/Felica.c new file mode 100644 index 0000000..7dd0073 --- /dev/null +++ b/nfc/vendor/dp1312ea/Felica.c @@ -0,0 +1,199 @@ +/*********************************************************************************************** +*FeliCa操作函数文件 +***********************************************************************************************/ +#include +#include +#include "DP1312EA.h" +#include "DP1312EA_Config.h" +#include "Felica.h" +#include "nfc_platform.h" + +void ReadmoniF(void) +{ + s8 status; + u8 i; + u8 IDm[10],PMm[8]; + + DP1312EA_PcdConfigISOTypeF(); + nfc_platform_sleep_ms(10); + status = DP1312EA_PcdRequestF(IDm,PMm); + +#ifdef UART_DEBUG + nfc_platform_log("ATQF: %d_",status); + if(status==MI_OK) + { + for(i=0;i<10;i++) + nfc_platform_log(" %02X ",IDm[i]); + nfc_platform_log("_"); + for(i=0;i<8;i++) + nfc_platform_log(" %02X",PMm[i]); + } + nfc_platform_log("\n"); +#endif + + if(status!=MI_OK) return; + +} + + + +/*********************************************************************************************** +*配置为FeliCa卡 +***********************************************************************************************/ +void DP1312EA_PcdConfigISOTypeF(void) +{ + DP1312EA_ClearBitMask(Status2Reg,0x08);//08h //MFCrypto1On + DP1312EA_WriteRawRC(WaterLevelReg,0x10); //0bh, + DP1312EA_WriteRawRC(ControlReg,0x10);//0ch, //Initiator + DP1312EA_WriteRawRC(BitFramingReg,0); //0dh, + DP1312EA_WriteRawRC(ModeReg,0x00);//11h, *00* + DP1312EA_WriteRawRC(TxModeReg,0x92); //12h, 212k + DP1312EA_WriteRawRC(RxModeReg,0x92); //13h, 212k + //DP1312EA_WriteRawRC(TxModeReg,0xa2); //12h 424k + //DP1312EA_WriteRawRC(RxModeReg,0xa2);//13h 424k + DP1312EA_WriteRawRC(TxControlReg,0x80);//14h, + DP1312EA_WriteRawRC(TxAutoReg,0x00); //15h, + DP1312EA_WriteRawRC(TxSelReg,0x10);//16h + DP1312EA_WriteRawRC(RxSelReg,0x83);//17h + DP1312EA_WriteRawRC(RxThresholdReg,0x55); //18h + DP1312EA_WriteRawRC(DemodReg,0x6D); //19h + DP1312EA_WriteRawRC(TypeBReg,0); //1eh, + DP1312EA_WriteRawRC(GsNOffReg,0xF2); //23h + DP1312EA_WriteRawRC(ModWidthReg,0x26); //24h, + DP1312EA_WriteRawRC(RFCfgReg,0x78); //26h + DP1312EA_WriteRawRC(GsNOnReg,0xFF); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x3f); //28h + DP1312EA_WriteRawRC(ModGsPReg,0x12); //29h + DP1312EA_WriteRawRC(TModeReg,0x8D); //2ah + DP1312EA_WriteRawRC(TPrescalerReg,0x00); //2bh + + DP1312EA_FieldOff(); + nfc_platform_sleep_ms(5); + DP1312EA_FieldOn(); + +} + +s8 DP1312EA_PcdRequestF(u8 *pIDm,u8 *pPMm) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(TPrescalerReg,0x01); //2bh, + DP1312EA_WriteRawRC(TModeReg,0x80); //2ah, + DP1312EA_WriteRawRC(TReloadRegL,0xEC);//2dh, + DP1312EA_WriteRawRC(TReloadRegH,0x5C); //2ch, + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength =6; + MfComData.MfData[0] =0x06; + MfComData.MfData[1] =0; + MfComData.MfData[2] =0xFF; + MfComData.MfData[3] =0xFF; + MfComData.MfData[4] =0; + MfComData.MfData[5] =0; + // FLAG_0; + status = DP1312EA_PcdComTransceive(pi); + // FLAG_1; + if (status == MI_OK) + { + if(MfComData.MfLength == 0x90) + { + memcpy(pIDm, &MfComData.MfData[2], 8); + memcpy(pPMm, &MfComData.MfData[10], 8); + } + else + status = MI_VALERR; + } + return status; +} + +s8 DP1312EA_PcdReadF(u8 *pIDm,u8 *pDat) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi= &MfComData; + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 16; + MfComData.MfData[0] = 0x10; //len + MfComData.MfData[1] = 0x06; + memcpy(&MfComData.MfData[2],pIDm, 8); + MfComData.MfData[10] = 1; //bNumServices + MfComData.MfData[11] = 0x0B; //pServiceList.. + MfComData.MfData[12] = 0; + MfComData.MfData[13] = 1; //read how much number of block + MfComData.MfData[14] = 0x80; //pBlockList.. + MfComData.MfData[15] = 0x01; + status = DP1312EA_PcdComTransceive(pi); + if (status == MI_OK) + { + if(MfComData.MfLength == 0xE8) + { + memcpy(pDat, &MfComData.MfData[13], 16); + } + else + status = MI_VALERR; + } + return status; +} + +/*********************************************************************************************** +*检测并读取FeliCa卡函数 +***********************************************************************************************/ +void DP1312EA_Felica(void) +{ + s8 status; + u8 i; + u8 IDm[8],PMm[8],buf[16]; + + DP1312EA_Reset(); + + DP1312EA_PcdConfigISOTypeF(); + nfc_platform_sleep_ms(10); + status = DP1312EA_PcdRequestF(IDm,PMm); + +#ifdef UART_DEBUG + nfc_platform_log("ATQF: %d_",status); + if(status==MI_OK) + { + for(i=0;i<8;i++) + nfc_platform_log(" %02X ",IDm[i]); + nfc_platform_log("_"); + for(i=0;i<8;i++) + nfc_platform_log(" %02X",PMm[i]); + } + nfc_platform_log("\n"); +#endif + + if(status!=MI_OK) return; + + status = DP1312EA_PcdReadF(IDm,buf); + +#ifdef UART_DEBUG + nfc_platform_log("Read: %d_",status); + if(status==MI_OK) + { + for(i=0;i<16;i++) + nfc_platform_log(" %02X",buf[i]); + } + nfc_platform_log("\n"); +#endif + + if(status!=MI_OK) return; + + do + { + DP1312EA_FieldOff(); + nfc_platform_sleep_ms(10); + DP1312EA_FieldOn(); + //LED_1; + nfc_platform_sleep_ms(10); + status = DP1312EA_PcdRequestF(IDm,PMm); + if(status==MI_OK){ + // LED_0; + } + else + break; + }while(status==MI_OK); +} +/***********************************************END*******************************************************/ + diff --git a/nfc/vendor/dp1312ea/Felica.h b/nfc/vendor/dp1312ea/Felica.h new file mode 100644 index 0000000..fc9b4a0 --- /dev/null +++ b/nfc/vendor/dp1312ea/Felica.h @@ -0,0 +1,15 @@ +#ifndef __FELICA_H +#define __FELICA_H + +#include "nfc.h" +#include "reg.h" + +void DP1312EA_Felica(void); +void DP1312EA_PcdConfigISOTypeF(void); +s8 DP1312EA_PcdRequestF(u8 *pIDm,u8 *pPMm); +s8 DP1312EA_PcdReadF(u8 *pIDm,u8 *pDat); +void ReadmoniF(void); +#endif + +/***********************************************END*******************************************************/ + diff --git a/nfc/vendor/dp1312ea/LPCD.c b/nfc/vendor/dp1312ea/LPCD.c new file mode 100644 index 0000000..60a19b1 --- /dev/null +++ b/nfc/vendor/dp1312ea/LPCD.c @@ -0,0 +1,227 @@ +/*********************************************************************************************** +*LPCDļ +***********************************************************************************************/ +#include +#include "DP1312EA_Config.h" +#include "DP1312EA.h" +#include "LPCD.h" +#include "nfc_platform.h" + + +extern u8 Status_INT; + +/*********************************************************************************************** +*дLPCDĴĴַҪдֵ +***********************************************************************************************/ +void write_Lpcd_reg(u8 reg,u8 value) +{ + DP1312EA_WriteRawRC(0x37,0xa0); + DP1312EA_WriteRawRC(0x0f,reg); + DP1312EA_WriteRawRC(0x37,0xa1); + DP1312EA_WriteRawRC(0x0f,value); +} +/*********************************************************************************************** +*ȡLPCDĴĴַ,ضȡֵ +***********************************************************************************************/ +u8 read_Lpcd_reg(u8 reg) +{ + u8 value; + DP1312EA_WriteRawRC(0x37,0xa0); + DP1312EA_WriteRawRC(0x0f,reg); + DP1312EA_WriteRawRC(0x37,0xa1); + value = DP1312EA_ReadRawRC(0x0f); + return value; + +} + +/*********************************************************************************************** +*ȡLPCD IͨĴֵ +***********************************************************************************************/ +u8 Read_I_Channel(void) +{ + u8 i; + DP1312EA_WriteRawRC(0x37,0xa0); + DP1312EA_WriteRawRC(0x0f,0x05); + DP1312EA_WriteRawRC(0x37,0xa1); + i = DP1312EA_ReadRawRC(0x0f); //LPCD_RI + return i; +} +/*********************************************************************************************** +*ȡLPCD QͨĴֵ +***********************************************************************************************/ +u8 Read_Q_Channel(void) +{ + u8 q; + DP1312EA_WriteRawRC(0x37,0xa0); + DP1312EA_WriteRawRC(0x0f,0x06); + DP1312EA_WriteRawRC(0x37,0xa1); + q = DP1312EA_ReadRawRC(0x0f); //LPCD_RQ + return q; +} + +/*********************************************************************************************** +*LPCD I/Qֵͨ +***********************************************************************************************/ +void set_I_Q_threshold(u8 I_value,u8 Q_value) +{ + u8 I_MIN,I_MAX; + u8 Q_MIN,Q_MAX; + if((I_value>=LPCD_Sensitive_Value)&&(Q_value>=LPCD_Sensitive_Value)) + { + I_MIN = I_value - LPCD_Sensitive_Value; + I_MAX = I_value + LPCD_Sensitive_Value; + Q_MIN = Q_value - LPCD_Sensitive_Value; + Q_MAX = Q_value + LPCD_Sensitive_Value; + } + else + { + I_MIN = 0x9c; + I_MAX = 0x9c; + Q_MIN = 0x7c; + Q_MAX = 0x7c; + } + + write_Lpcd_reg(0x01,I_MAX); + + write_Lpcd_reg(0x02,I_MIN); + + write_Lpcd_reg(0x03,Q_MAX); + + write_Lpcd_reg(0x04,Q_MIN); + +} +/*********************************************************************************************** +*ֹLPCDѺûиλоƬҪǰȽֹLPCD +***********************************************************************************************/ +void DP1312EA_LPCD_Stop(void) +{ + DP1312EA_WriteRawRC(0x37,0xa0); + DP1312EA_WriteRawRC(0x0f,0x00); + DP1312EA_WriteRawRC(0x37,0xa1); + DP1312EA_WriteRawRC(0x0f,0x00); +} + +/*********************************************************************************************** +*оƬLPCDжϱ־λ +***********************************************************************************************/ +void Clear_lpcd_irq(void) +{ + DP1312EA_WriteRawRC(DivIrqReg,0x20); //жϱ +} +/********************************************************************************************************** +*ƣvoid DP1312EA_LPCD_Enter(u16 cycle,u16 duration ) +* + òLPCDģʽв˳Ҫ󣬲ҪĶ˳ +* + cycleڣ16λĬ0x22ff380msԼ10% + durationʱ16λĬ0x001f2.5usѡ0x003f=5us,0x007f=10us +*ز + +* + IRQжϣ1)ѡCMOS©©裻2)ѡߵƽжϻ͵ƽжϣ + +**********************************************************************************************************/ +void DP1312EA_LPCD_Enter(u16 cycle,u16 duration ) +{ + u8 i,q,n; + + n = DP1312EA_ReadRawRC(0x0c); + DP1312EA_WriteRawRC(0x0c, n|0x10); + + //DP1312EA_WriteRawRC(0x28,0x02); //ӲЧ, + + /*set IRQ int level*/ +#if (IRQ_LEVEL_SET == IRQ_HIGH_LEVEL) + DP1312EA_WriteRawRC(ComIEnReg,0x00); //ComIEnRegbit7 0ߵƽж +#else + DP1312EA_WriteRawRC(ComIEnReg,0x80); //ComIEnRegbit7 1͵ƽж +#endif + + /*set IRQ Output Mode*/ +#if (IRQ_OUT_MODE == IRQ_OUT_PP) + DP1312EA_WriteRawRC(DivlEnReg,0xE0); //bit7=1ΪCMOSbit5=1 LPCDжʹ +#else + DP1312EA_WriteRawRC(DivlEnReg,0x60); //bit7=0ΪOPEN DRAINbit5=1 LPCDжʹ +#endif + + DP1312EA_WriteRawRC(DivIrqReg,0x7F); //жϱ + + //üʱ + write_Lpcd_reg(0x08,(u8)(duration>>8)); //ʱλĴ + write_Lpcd_reg(0x09,(u8)duration); //ʱλĴ + + //ü + write_Lpcd_reg(0x0a,0x00); //ڸλĴ + write_Lpcd_reg(0x0b,0xff); //ڵλĴ + + //׼1 + write_Lpcd_reg(0x01,0xf0); //LPCDĴ + write_Lpcd_reg(0x02,0x00); + write_Lpcd_reg(0x03,0xf0); //LPCDĴ + write_Lpcd_reg(0x04,0x00); + + //ʹLPCDҪֿ + write_Lpcd_reg(0x00,0x50); //enable LPCD + + //LPCD + write_Lpcd_reg(0x00,0xd0); //start LPCD + + //ȡƼĴDZģΪ˹۲ + n=read_Lpcd_reg(0x00); + +#ifdef UART_DEBUG + nfc_platform_log("lpcd_00reg = %02x \n",n); +#endif + nfc_platform_sleep_ms(5); + + //زȴһУ׼ + DP1312EA_WriteRawRC(TxControlReg,0x83); + nfc_platform_sleep_ms(20); + + //ȡI/Qֵ + i = Read_I_Channel(); + q = Read_Q_Channel(); + +#ifdef UART_DEBUG + nfc_platform_log("lpcd_: I:%02X ,Q:%02X\n",i,q); +#endif + //ûֵ + set_I_Q_threshold(i,q); + + //趨ʱ + write_Lpcd_reg(0x08,(u8)(duration>>8)); //ʱλĴ + write_Lpcd_reg(0x09,(u8)duration); //ʱλĴ + + //趨ռ + write_Lpcd_reg(0x0a,(u8)(cycle>>8)); + write_Lpcd_reg(0x0b,(u8)(cycle)); + + DP1312EA_WriteRawRC(DivIrqReg,0x7F); //жϱ + +} + + +/*********************************************************************************************** +*ȴж +***********************************************************************************************/ +u8 DP1312EA_CLEAR_IRQ(void) +{ + Clear_lpcd_irq(); + return MI_OK; +} + +/*********************************************************************************************** +*LPCDȴж +***********************************************************************************************/ +void DP1312EA_LPCD_Start(void) +{ + DP1312EA_Reset(); + nfc_platform_sleep_ms(5); + DP1312EA_LPCD_Enter(LPCD_Cycle_Time,LPCD_Duration_Time); +} + + + + +/**************************************************END*****************************************/ + diff --git a/nfc/vendor/dp1312ea/LPCD.h b/nfc/vendor/dp1312ea/LPCD.h new file mode 100644 index 0000000..e8ebdfc --- /dev/null +++ b/nfc/vendor/dp1312ea/LPCD.h @@ -0,0 +1,25 @@ +#ifndef __LPCD_H +#define __LPCD_H + +#include "reg.h" + + +void write_Lpcd_reg(u8 reg,u8 value); +u8 read_Lpcd_reg(u8 reg); +u8 Read_Q_Channel(void); +u8 Read_I_Channel(void); + +void set_I_Q_threshold(u8 I_value,u8 Q_value); +void DP1312EA_LPCD_Start(void); + +u8 DP1312EA_CLEAR_IRQ(void); + +void DP1312EA_Check_Card(void); +void Clear_lpcd_irq(void); +void DP1312EA_LPCD_Stop(void); + +#endif + + +/***********************************************END*******************************************************/ + diff --git a/nfc/vendor/dp1312ea/TypeA.c b/nfc/vendor/dp1312ea/TypeA.c new file mode 100644 index 0000000..c0ec689 --- /dev/null +++ b/nfc/vendor/dp1312ea/TypeA.c @@ -0,0 +1,1103 @@ +/*********************************************************************************************** +* A/Mifareļ +***********************************************************************************************/ +#include +#include +#include "DP1312EA_Config.h" +#include "DP1312EA.h" +#include "TypeA.h" +#include "nfc_platform.h" + +#define NRSTPD_LP_PIN nfc_dp1312ea_get_reset_pin() + + +u16 ErrFlag; + +s8 DP1312EA_JewelTransceive(struct TranSciveBuffer *pi) +{ + s8 status = MI_ERR; + u8 waitFor,n,lastBits; + u16 i; + u8 temp,irqEn; + + irqEn = 0x77; + waitFor = 0x30; + DP1312EA_WriteRawRC(CommandReg,DP1312EA_IDLE); + DP1312EA_SetBitMask(FIFOLevelReg,0x80); + DP1312EA_WriteRawRC(ComIrqReg,0x7F); + DP1312EA_WriteRawRC(DivIrqReg,0x7F); + DP1312EA_WriteRawRC(ManualRCVReg,0x10); + for (i=0; iMfLength; i++) + DP1312EA_WriteRawRC(FIFODataReg, pi->MfData [i]); + + DP1312EA_WriteRawRC(ComIEnReg,irqEn|0x80); + DP1312EA_WriteRawRC(CommandReg, pi->MfCommand); + DP1312EA_SetBitMask(BitFramingReg,0x80); + do + { + temp = DP1312EA_ReadRawRC(ComIrqReg); //wait for TxIRQ + } while((temp&0x40)==0); + + if(pi->MfCommand == DP1312EA_TRANSMIT) + { + if(DP1312EA_ReadRawRC(ErrorReg)==0) + status = MI_OK; + else + status = -1; + } + + if(pi->MfCommand == DP1312EA_TRANSCEIVE) + { + DP1312EA_WriteRawRC(ManualRCVReg,0x00); + + for(i =1000;i>0;i--) + { + n = DP1312EA_ReadRawRC(ComIrqReg); //04h + if((n&irqEn&0x01)||(n&waitFor))break; //timerirq idleirq rxirq + } + + if (n&waitFor) //IdleIRq + { + temp = DP1312EA_ReadRawRC(ErrorReg); + if(temp&0x1B) //06h + { + status = MI_ERR; + } + else + { + status = MI_OK; + if (pi->MfCommand == DP1312EA_TRANSCEIVE) + { + n = DP1312EA_ReadRawRC(FIFOLevelReg); //0ah + lastBits = DP1312EA_ReadRawRC(ControlReg) & 0x07; //0ch + if (lastBits) + pi->MfLength = (n-1)*8 + lastBits; + else + pi->MfLength = n*8; + if (n == 0) n = 1; + if (n > MAXRLEN) n = MAXRLEN; + for (i=0; iMfData[i] = DP1312EA_ReadRawRC(FIFODataReg); //09h + } + } + } + else if (n & irqEn & 0x01) //TimerIRq + { + status = MI_NOTAGERR; + } + else if (!(DP1312EA_ReadRawRC(ErrorReg)&0x1B)) + { + temp = DP1312EA_ReadRawRC(ErrorReg); + status = MI_ACCESSTIMEOUT; + } + } + return status; +} + +s8 DP1312EA_PcdConfigISOType(u8 type) +{ + if (type == 'A') //ISO14443_A + { + DP1312EA_WriteRawRC(ControlReg,0x10); + DP1312EA_WriteRawRC(TxAutoReg,0x40); + DP1312EA_WriteRawRC(TxModeReg,0x00); + DP1312EA_WriteRawRC(RxModeReg,0x00);// A + DP1312EA_WriteRawRC(ModWidthReg,0x26); //24h ABⶼУ + DP1312EA_WriteRawRC(BitFramingReg,0); //0dh, + DP1312EA_WriteRawRC(ModeReg,0x3D); //11h, + DP1312EA_WriteRawRC(TxControlReg,0x84); //14h, + DP1312EA_WriteRawRC(RxSelReg,0x88); //17h, + DP1312EA_WriteRawRC(DemodReg,0x8D); //19h, //AddIQ + + DP1312EA_WriteRawRC(TypeBReg,0); //1eh, + + DP1312EA_WriteRawRC(TModeReg,0x8D); //2ah, + + + DP1312EA_WriteRawRC(TPrescalerReg,0x3e); //2bh + DP1312EA_WriteRawRC(TReloadRegL,30);//2dh + DP1312EA_WriteRawRC(TReloadRegH,0); //2ch + DP1312EA_WriteRawRC(AutoTestReg,0); //36h + + +#if (TYPEA_REG_CONFIG==REG_SET_1) + DP1312EA_WriteRawRC(RxThresholdReg,0x64); //20201117 + DP1312EA_WriteRawRC(RFCfgReg,0x78); //26h + DP1312EA_WriteRawRC(GsNOnReg,0xF8); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x3F); //28h + +#elif (TYPEA_REG_CONFIG==REG_SET_2) + DP1312EA_WriteRawRC(RxThresholdReg,0x64); //20201117 + DP1312EA_WriteRawRC(RFCfgReg,0x44); //26h + DP1312EA_WriteRawRC(GsNOnReg,0x88); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x20); //28h + +#elif (TYPEA_REG_CONFIG==REG_SET_3) + DP1312EA_WriteRawRC(RxThresholdReg,0x84); //20201117 + DP1312EA_WriteRawRC(RFCfgReg,0x64); //26h + DP1312EA_WriteRawRC(GsNOnReg,0xF8); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x3F); //28h + +#else + DP1312EA_WriteRawRC(RxThresholdReg,0x84); //20201117 + DP1312EA_WriteRawRC(RFCfgReg,0x64); //26h + DP1312EA_WriteRawRC(GsNOnReg,0x88); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x20); //28h +#endif + + DP1312EA_FieldOff(); + nfc_platform_sleep_ms(1); + DP1312EA_FieldOn();//ֹijЩλ,ǰƵ + nfc_platform_sleep_ms(10); + } + else if(type =='K') //CARD SIMULATION + { + DP1312EA_WriteRawRC(TxModeReg,0x80); //12h, + DP1312EA_WriteRawRC(RxModeReg,0x80); //13h, + DP1312EA_WriteRawRC(RxThresholdReg,0x55); //18h, + DP1312EA_WriteRawRC(DemodReg,0x61); //19h, + DP1312EA_WriteRawRC(MifareReg,0x62); //1ch, + DP1312EA_WriteRawRC(GsNOffReg,0xf2); ///23h + DP1312EA_WriteRawRC(TxBitPhaseReg,0x87); //25h + DP1312EA_WriteRawRC(RFCfgReg,0x79); //26h + DP1312EA_WriteRawRC(GsNOnReg,0x6F); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x3f); //28h + DP1312EA_WriteRawRC(ModGsPReg,0x3A); //29h + DP1312EA_WriteRawRC(TxSelReg,0x17); //16h + DP1312EA_WriteRawRC(FIFOLevelReg,0x80); + } + else if(type == 'L') + { + + DP1312EA_WriteRawRC(TxModeReg,0x92); //12h + DP1312EA_WriteRawRC(RxModeReg,0x92); //13h + DP1312EA_WriteRawRC(TxSelReg,0x17); //16h + DP1312EA_WriteRawRC(RxThresholdReg,0x55);//18h, + DP1312EA_WriteRawRC(DemodReg,0x61);//19h + DP1312EA_WriteRawRC(RFU1A,0x00);//1Bh + DP1312EA_WriteRawRC(ManualRCVReg,0x08); + DP1312EA_WriteRawRC(RFU1B,0x80);//1Bh + DP1312EA_WriteRawRC(GsNOffReg,0xf2);//23h + DP1312EA_WriteRawRC(RFCfgReg,0x59); //26h + DP1312EA_WriteRawRC(GsNOnReg,0x6f); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x3f); //28h + DP1312EA_WriteRawRC(ModGsPReg,0x3a);//29h + DP1312EA_WriteRawRC(FIFOLevelReg,0x80); + } + else + return MI_ERR; + + return MI_OK; +} + +/********************************************************************************************************** +*ģA +**********************************************************************************************************/ +void DP1312EA_Simulate_Card(void) +{ + u8 i; + const u8 CardConfig[]={ 0x44,0x00, //SENS_RES-2ֽ--ATQA + 0xAA,0xBB,0xCC, //NFCID1-3ֽ--UID,ֽڹ̶Ϊ0x08 + 0x00, //SEL_RES-1ֽ--SAK + 0x01,0xfe,0x33,0x44,0x55,0x66,0x77,0x88, //NFCID2-8ֽ + 0x07,0x01,0x02,0x03,0x04,0x05,0x06,0x07, //Pad-8ֽ + 0xff,0xff, //ϵͳ-2ֽ + 0x88 //NFCID3-1ֽ + }; + + DP1312EA_PcdConfigISOType('K'); + nfc_platform_sleep_ms(2); + for (i=0; i<25; i++) + { + DP1312EA_WriteRawRC(FIFODataReg, CardConfig[i]); + } + nfc_platform_sleep_ms(2); + DP1312EA_WriteRawRC(CommandReg, DP1312EA_MEM); + DP1312EA_WriteRawRC(CommandReg, DP1312EA_AUTOCOLL); +} + +/********************************************************************************************************** +*ģA,λ͹,λ빤ʱ䣬ƽ⹦ +**********************************************************************************************************/ + +void DP1312EA_Simulate_Card_LP(void) +{ + nfc_platform_gpio_init(NRSTPD_LP_PIN,NFC_PLATFORM_GPIO_OUT,NFC_PLATFORM_GPIO_PULL_DISABLE,NFC_PLATFORM_GPIO_HIGH); + + DP1312EA_FieldOff(); + nfc_platform_gpio_set_level(NRSTPD_LP_PIN,NFC_PLATFORM_GPIO_LOW); + nfc_platform_sleep_ms(900); + nfc_platform_gpio_set_level(NRSTPD_LP_PIN,NFC_PLATFORM_GPIO_HIGH); + DP1312EA_FieldOn(); + DP1312EA_Simulate_Card();//ģA + nfc_platform_sleep_ms(100); + +} + +/********************************************************************************************************** +*ģF +**********************************************************************************************************/ +void DP1312EA_Simulate_CardF(void) +{ + u8 i; + const u8 CardConfig[]={ 0x10,0xfe,0x01,0x12,0x01,0x24,0x69,0x0b,0x50,0x37, + 0x2E,0x3d,0x24,0x69,0x0b,0x50,0x37,0x2E, + 0x3d,0x24,0x69,0x0b,0x50,0x37,0x0b}; + DP1312EA_PcdConfigISOType('L'); + nfc_platform_sleep_ms(10); + for (i=0; i<25; i++) + DP1312EA_WriteRawRC(FIFODataReg, CardConfig[i]); + + nfc_platform_sleep_ms(100); + DP1312EA_WriteRawRC(CommandReg, DP1312EA_MEM); + DP1312EA_WriteRawRC(CommandReg, DP1312EA_AUTOCOLL); +} + + +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdRequestA(u8 req_code,u8 *pTagType) +* + Ѱ +* + levelײ + pSnrid + pSizeȣ +*ز + MI_OKѡɹ + ѡʧܣ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdRequestA(u8 req_code,u8 *pTagType) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi= &MfComData; + + DP1312EA_ClearBitMask(TxModeReg,0x80);//12h, //TxCRCEn + DP1312EA_ClearBitMask(RxModeReg,0x80);//13h, + DP1312EA_WriteRawRC(TReloadRegL,0x59);//2dh, + DP1312EA_WriteRawRC(TReloadRegH,0x0A); //2ch, + DP1312EA_ClearBitMask(Status2Reg,0x08); //08h + DP1312EA_WriteRawRC(BitFramingReg,0x07); //0dh + DP1312EA_SetBitMask(TxControlReg,0x03); //14h 0x03 + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 1; + MfComData.MfData[0] = req_code; + //FLAG_1; + status = DP1312EA_PcdComTransceive(pi); + //FLAG_0; + if (status == MI_OK) + { + if(MfComData.MfLength == 0x10) + { + *pTagType = MfComData.MfData[0]; + *(pTagType+1) = MfComData.MfData[1]; + } + else + status = MI_VALERR; + } + return status; +} + +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdSelect(u8 level,u8 *pSnr,u8 *pSize) +* + ѡ +* + levelײ + pSnrid + pSizeȣ +*ز + MI_OKѡɹ + ѡʧܣ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdSelect(u8 level,u8 *pSnr,u8 *pSize) +{ + s8 status; + u8 i,snr_check = 0; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(TxModeReg,0x80); //12h TxCRCEn + DP1312EA_WriteRawRC(RxModeReg,0x80); //13h + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 7; + MfComData.MfData[0] = level; + MfComData.MfData[1] = 0x70; + for (i=0; i<4; i++) + { + snr_check ^= *(pSnr+i); + MfComData.MfData[i+2] = *(pSnr+i); + } + MfComData.MfData[6] = snr_check; + status = DP1312EA_PcdComTransceive(pi); + + if (status == MI_OK) + { + if (MfComData.MfLength != 0x8) + status = MI_BITCOUNTERR; + else + *pSize = MfComData.MfData[0]; + } + + return status; +} + +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdAuthState(u8 auth_mode,u8 block,u8 *pKey,u8 *pSnr) +* + Կ֤ +* + auth_mode֤ģʽ + blockҪ֤ţ + pKeyԿָ + pSnr +*ز + MI_OKдɹ + ֤ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdAuthState(u8 auth_mode,u8 block,u8 *pKey,u8 *pSnr) +{ + s8 status; + u8 reg; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + MfComData.MfCommand = DP1312EA_AUTHENT; + MfComData.MfLength = 12; + MfComData.MfData[0] = auth_mode; + MfComData.MfData[1] = block; + memcpy(&MfComData.MfData[2], pKey, 6); + memcpy(&MfComData.MfData[8], pSnr, 4); + status = DP1312EA_PcdComTransceive(pi); + if (status == MI_OK) + { + reg = DP1312EA_ReadRawRC(Status2Reg); + if(!(reg&0x08)) + status = MI_AUTHERR; + } + return status; +} +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdRead(u8 addr,u8 *pReaddata) +* + ָ +* + addrţ + pWritedataָ룻 +*ز + MI_OKдɹ + ֤ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdRead(u8 addr,u8 *pReaddata) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 2; + MfComData.MfData[0] = PICC_READ; + MfComData.MfData[1] = addr; + status = DP1312EA_PcdComTransceive(pi); + if (status == MI_OK) + { + if (MfComData.MfLength != 0x80) + status = MI_BITCOUNTERR; + else + memcpy(pReaddata, &MfComData.MfData[0], 16); + } + return status; +} + +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdWrite(u8 addr,u8 *pWritedata) +* + дָ +* + addrţ + pWritedataָ룻 +*ز + MI_OKдɹ + MI_NOTAUTHERR֤ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdWrite(u8 addr,u8 *pWritedata) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 2; + MfComData.MfData[0] = PICC_WRITE; + MfComData.MfData[1] = addr; + status = DP1312EA_PcdComTransceive(pi); + if (status != MI_NOTAGERR) + { + if(MfComData.MfLength != 4) + status=MI_BITCOUNTERR; + else + { + MfComData.MfData[0] &= 0x0F; + switch (MfComData.MfData[0]) + { + case 0x00: + status = MI_NOTAUTHERR; + break; + case 0x0A: + status = MI_OK; + break; + default: + status = MI_CODEERR; + break; + } + } + } + if (status == MI_OK) + { + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 16; + memcpy(&MfComData.MfData[0], pWritedata, 16); + status = DP1312EA_PcdComTransceive(pi); + if (status != MI_NOTAGERR) + { + MfComData.MfData[0] &= 0x0F; + switch(MfComData.MfData[0]) + { + case 0x00: + status = MI_WRITEERR; + break; + case 0x0A: + status = MI_OK; + break; + default: + status = MI_CODEERR; + break; + } + } + } + return status; +} + +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdHaltA(void) +* + ͣ +* + addrţ + pWritedataָ룻 +*ز + MI_OKɹ + ʧܣ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdHaltA(void) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 2; + MfComData.MfData[0] = PICC_HALT; + MfComData.MfData[1] = 0; + status = DP1312EA_PcdComTransceive(pi); + if (status) + { + if (status==MI_NOTAGERR || status==MI_ACCESSTIMEOUT) + status = MI_OK; + } + DP1312EA_WriteRawRC(CommandReg,DP1312EA_IDLE); + return status; +} + +/********************************************************************************************************** +*ƣs8 DP1312EA_PcdAnticoll(u8 level,u8 *pSnr) +* + ײ +* + levelײ + pSnrUIDָ룻 +*ز + MI_OKɹ + ʧܣ +* + +**********************************************************************************************************/ + +s8 DP1312EA_PcdAnticoll(u8 level,u8 *pSnr) +{ + s8 status ; + u8 i; + u8 ucBits,ucBytes; + u8 snr_check = 0; + u8 ucCollPosition = 0; + u8 ucTemp; + u8 ucSNR[5] = {0, 0, 0, 0 ,0}; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(BitFramingReg,0x00); + DP1312EA_ClearBitMask(CollReg,0x80); + DP1312EA_ClearBitMask(TxModeReg,0x80); + DP1312EA_ClearBitMask(RxModeReg,0x80); + do + { + ucBits = (ucCollPosition) % 8; + if (ucBits != 0) + { + ucBytes = ucCollPosition / 8 + 1; + DP1312EA_WriteRawRC(BitFramingReg, (ucBits << 4) + ucBits); + } + else + ucBytes = ucCollPosition / 8; + + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfData[0] = level; + MfComData.MfData[1] = 0x20 + ((ucCollPosition / 8) << 4) + (ucBits & 0x0F); + for (i=0; i> 8U) ^ ((uint16_t)bCh << 8U) ^ ((u16)bCh << 3U) ^ ((u16)bCh>>4U); +} + +void ComputeCrc_B( u8 *pData,u32 dwLength,u8 *pCrc) +{ + u8 bChBlock = 0; + u16 wCrc = 0xFFFF; + do + { + bChBlock = *pData++; + UpdateCrc_B(bChBlock, &wCrc); + } while (0u != (--dwLength)); + wCrc = ~wCrc; + pCrc[0] = (u8) (wCrc & 0xFFU); + pCrc[1] = (u8) ( (wCrc>>8U) & 0xFFU); +} + +s8 DP1312EA_PcdJewelCommand(u8* pdata,u8 len,u8* resp,u8* replen) +{ + s8 status; + struct TranSciveBuffer ComData,*pi = &ComData; + u8 i; + u8 crc[2]; + for(i=0;i +#include +#include "DP1312EA_Config.h" +#include "DP1312EA.h" +#include "TypeB.h" +#include "nfc_platform.h" + + + +void DP1312EA_PcdConfigISOTypeB(void) +{ + DP1312EA_ClearBitMask(Status2Reg,0x08);//08h + DP1312EA_WriteRawRC(WaterLevelReg,0x10); //0bh, + DP1312EA_WriteRawRC(ControlReg,0x10);//0ch, + DP1312EA_WriteRawRC(BitFramingReg,0); //0dh, + + DP1312EA_WriteRawRC(ModeReg,0x3F);//11h + DP1312EA_WriteRawRC(TxModeReg,0x03); //12h, + DP1312EA_WriteRawRC(RxModeReg,0x03); //13h, + DP1312EA_WriteRawRC(TxControlReg,0x80);//14h + DP1312EA_WriteRawRC(TxAutoReg,0x00); //15h, + DP1312EA_WriteRawRC(RxSelReg,0x88);//17h, + DP1312EA_WriteRawRC(RxThresholdReg,0x50); //18h, + DP1312EA_WriteRawRC(DemodReg,0x4D); //19h, + DP1312EA_WriteRawRC(TypeBReg,0x00); //1eh, + DP1312EA_WriteRawRC(GsNOffReg,0xF2); //23h + DP1312EA_WriteRawRC(ModWidthReg,0x68); //24h, + DP1312EA_WriteRawRC(RFCfgReg,0x59); //26h + DP1312EA_WriteRawRC(GsNOnReg,0xF8); //27h + DP1312EA_WriteRawRC(CWGsPReg,0x3f); //28h + DP1312EA_WriteRawRC(ModGsPReg,0x20); //29h, + + DP1312EA_WriteRawRC(TModeReg,0x8D); //2ah, + DP1312EA_WriteRawRC(TPrescalerReg,0x3e); //2bh + DP1312EA_WriteRawRC(TReloadRegL,30);//2dh + DP1312EA_WriteRawRC(TReloadRegH,0); //2ch + + DP1312EA_WriteRawRC(AutoTestReg,0); //36h + + DP1312EA_FieldOff(); + nfc_platform_sleep_ms(5); + DP1312EA_FieldOn(); +} + +s8 DP1312EA_PcdRequestB(u8 *atqb,u8 *pLen) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + DP1312EA_WriteRawRC(TxModeReg,0x83); //12h + DP1312EA_WriteRawRC(RxModeReg,0x83); //13h + DP1312EA_WriteRawRC(TReloadRegL,0x59);//2dh, + DP1312EA_WriteRawRC(TReloadRegH,0x0A); //2ch, + DP1312EA_ClearBitMask(Status2Reg,0x08); //08h + DP1312EA_SetBitMask(TxControlReg,0x03); //14h 0x03 + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 3; + MfComData.MfData[0] = PICC_ANTI; + MfComData.MfData[1] = 0; + MfComData.MfData[2] = 0; + status = DP1312EA_PcdComTransceive(pi); + + if (status == MI_OK) + { + if((MfComData.MfLength == 0x60) || (MfComData.MfLength == 0x10) ) + { + *pLen = MfComData.MfLength/8; + memcpy(atqb, &MfComData.MfData[0], *pLen); + } + else + status = MI_VALERR; + } + return status; +} + +s8 DP1312EA_PcdAttribB(u8 *pCid) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(TPrescalerReg,0x80); //2bh, + DP1312EA_WriteRawRC(TModeReg,0x80); //2ah, + DP1312EA_WriteRawRC(TReloadRegL,0xC9);//2dh, + DP1312EA_WriteRawRC(TReloadRegH,0xFF); //2ch, + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 9; + MfComData.MfData[0] = PICC_ATTRIB; + memset(&MfComData.MfData[1], 0x00, 4); //pupi + MfComData.MfData[5] = 0; + MfComData.MfData[6] = 0x08; + MfComData.MfData[7] = 0x01; + MfComData.MfData[8] = 0x08; + status = DP1312EA_PcdComTransceive(pi); + + if (status == MI_OK) + { + if (MfComData.MfLength != 0x8) + status = MI_BITCOUNTERR; + else + *pCid = MfComData.MfData[0]; + } + + return status; +} + +s8 DP1312EA_PcdGetUidB(u8 *puid) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + DP1312EA_WriteRawRC(TxModeReg,0x83); //12h + DP1312EA_WriteRawRC(RxModeReg,0x83); //13h + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength =5; + MfComData.MfData[0] =0x00; + MfComData.MfData[1] =0x36; + MfComData.MfData[2] =0x00; + MfComData.MfData[3] =0x00; + MfComData.MfData[4] =0x08; + status = DP1312EA_PcdComTransceive(pi); + if ((status == MI_OK)&& (MfComData.MfLength == 0x50) ) + memcpy(puid, &MfComData.MfData[0], 10); + else + status = MI_ERR; + return status; +} + +void DP1312EA_SRT512(void) +{ + s8 status; + u8 i; + u8 RD_Data[12],Len; + u8 chipID; + + DP1312EA_PcdConfigISOTypeB(); + nfc_platform_sleep_ms(10); + + status = INITIATE_PCALL16(&chipID,&Len,0); + if(status==MI_OK) + { +#ifdef UART_DEBUG + nfc_platform_log("Chip_ID1: %02X",chipID); + nfc_platform_log("\n"); +#endif + } + if(status!=MI_OK) return; + + status = SelectChipID(RD_Data,&Len,chipID); + if(status==MI_OK) + { +#ifdef UART_DEBUG + nfc_platform_log("Chip_ID2: %02X",RD_Data[0]); + nfc_platform_log("\n"); +#endif + } + if(status!=MI_OK) return; + + status = GetUid(RD_Data); + if(status==MI_OK) + { +#ifdef UART_DEBUG + for(i=0;i<8;i++) + nfc_platform_log(" %02X",RD_Data[i]); + nfc_platform_log("\n"); +#endif + } + + if(status!=MI_OK) return; + status = SRTReadBlock(0,RD_Data); + if(status==MI_OK) + { +#ifdef UART_DEBUG + for(i=0;i<4;i++) + nfc_platform_log(" %02X",RD_Data[i]); + nfc_platform_log("\n"); +#endif + } + + + if(status!=MI_OK) return; + do + { + status = GetUid(RD_Data); + if(status==MI_OK) + { + // LED_0; + } + else + { + //LED_1; + break; + } + }while(status==MI_OK); + +} +s8 Write_ReadBlock(u8 block,u8 *Data) +{ + s8 status; + u8 i; + u8 random[]={0x80,0x23,0x03,0x27}; + struct TranSciveBuffer MfComData,*pi = &MfComData; + DP1312EA_WriteRawRC(TxModeReg,0x83); //12h + DP1312EA_WriteRawRC(RxModeReg,0x83); + MfComData.MfCommand = DP1312EA_TRANSMIT; + MfComData.MfLength =6; + MfComData.MfData[0] =0x09; + MfComData.MfData[1] =block; + for (i=0;i<4;i++) + { + MfComData.MfData[2+i]=random[i]; + } + status = DP1312EA_PcdComTransceive(pi); + if(status!= MI_OK) return MI_ERR; + nfc_platform_sleep_ms(5); + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength =2; + MfComData.MfData[0] =0x08; + MfComData.MfData[1] =block; + status = DP1312EA_PcdComTransceive(pi); + if ((status == MI_OK)&& (MfComData.MfLength == 0x20) ) + memcpy(Data, &MfComData.MfData[0],4); + else + status = MI_ERR; + + return status; + +} +s8 SRTReadBlock(u8 block,u8 *Data) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength =2; + MfComData.MfData[0] =0x08; + MfComData.MfData[1] =block; + status = DP1312EA_PcdComTransceive(pi); + if ((status == MI_OK)&& (MfComData.MfLength == 0x20) ) + memcpy(Data, &MfComData.MfData[0],4); + else + status = MI_ERR; + + return status; +} +s8 GetUid(u8 *puid) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(TxModeReg,0x83); //12h + DP1312EA_WriteRawRC(RxModeReg,0x83); //13h + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength =1; + MfComData.MfData[0] =0x0B; + + status = DP1312EA_PcdComTransceive(pi); + if ((status == MI_OK)&& (MfComData.MfLength == 0x40) ) + memcpy(puid, &MfComData.MfData[0], 8); + else + status = MI_ERR; + + return status; +} +s8 SelectChipID(u8 *atqb,u8 *pLen,u8 id) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(TxModeReg,0x83); //12h + DP1312EA_WriteRawRC(RxModeReg,0x83); //13h + DP1312EA_WriteRawRC(TReloadRegL,0x59);//2dh, + DP1312EA_WriteRawRC(TReloadRegH,0x0A); //2ch, + DP1312EA_ClearBitMask(Status2Reg,0x08); //08h + DP1312EA_SetBitMask(TxControlReg,0x03); //14h + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 2; + MfComData.MfData[0] = 0x0E; + MfComData.MfData[1] = id; + + status = DP1312EA_PcdComTransceive(pi); + + if (status == MI_OK) + { + if( MfComData.MfLength == 0x08 ) + { + *pLen = MfComData.MfLength/8; + memcpy(atqb, &MfComData.MfData[0], *pLen); + } + else + status = MI_VALERR; + } + return status; +} +s8 INITIATE_PCALL16(u8 *atqb,u8 *pLen,u8 cmd) +{ + s8 status; + struct TranSciveBuffer MfComData,*pi = &MfComData; + + DP1312EA_WriteRawRC(TxModeReg,0x83); //12h + DP1312EA_WriteRawRC(RxModeReg,0x83); //13h + DP1312EA_WriteRawRC(TReloadRegL,0x59);//2dh, + DP1312EA_WriteRawRC(TReloadRegH,0x0A); //2ch, + DP1312EA_ClearBitMask(Status2Reg,0x08); //08h + DP1312EA_SetBitMask(TxControlReg,0x03);//14h + + MfComData.MfCommand = DP1312EA_TRANSCEIVE; + MfComData.MfLength = 2; + MfComData.MfData[0] = 0x06; + MfComData.MfData[1] = cmd; + + status = DP1312EA_PcdComTransceive(pi); + + if (status == MI_OK) + { + if( MfComData.MfLength == 0x08 ) + { + *pLen = MfComData.MfLength/8; + memcpy(atqb, &MfComData.MfData[0], *pLen); + } + else + status = MI_VALERR; + } + return status; + +} + +void DP1312EA_ChinaID2(u8 *UID_b) +{ + s8 status; + u8 i; + u8 RD_Data[12],Len; + + memset(UID_b,0x00,8); + + DP1312EA_Reset(); + + DP1312EA_PcdConfigISOTypeB(); + nfc_platform_sleep_ms(10); + status = DP1312EA_PcdRequestB(RD_Data,&Len); + +#ifdef UART_DEBUG + nfc_platform_log("ATQB: %d_",status); + if(status==MI_OK) + { + for(i=0;i + +typedef uint8_t u8; +typedef int8_t s8; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint32_t u32; +typedef int32_t s32; +typedef int8_t int8; +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; + +#define PICC_REQIDL 0x26 +#define PICC_REQALL 0x52 +#define PICC_ANTICOLL1 0x93 +#define PICC_ANTICOLL2 0x95 +#define PICC_ANTICOLL3 0x97 +#define PICC_AUTHENT1A 0x60 +#define PICC_AUTHENT1B 0x61 +#define PICC_READ 0x30 +#define PICC_WRITE 0xA0 +#define PICC_DECREMENT 0xC0 +#define PICC_INCREMENT 0xC1 +#define PICC_RESTORE 0xC2 +#define PICC_TRANSFER 0xB0 +#define PICC_HALT 0x50 + +#define SELECT_0 0x93 +#define SELECT_1 0x95 +#define SELECT_2 0x97 + +#define PICC_ANTI 0x05 +#define PICC_ATTRIB 0x1D + +#define MI_OK 0 +#define MI_CHK_OK 0 +#define MI_NOTAGERR (-1) +#define MI_CHK_FAILED (-1) +#define MI_CRCERR (-2) +#define MI_CHK_COMPERR (-2) +#define MI_EMPTY (-3) +#define MI_AUTHERR (-4) +#define MI_PARITYERR (-5) +#define MI_CODEERR (-6) +#define MI_SERNRERR (-8) +#define MI_KEYERR (-9) +#define MI_NOTAUTHERR (-10) +#define MI_BITCOUNTERR (-11) +#define MI_BYTECOUNTERR (-12) +#define MI_IDLE (-13) +#define MI_TRANSERR (-14) +#define MI_WRITEERR (-15) +#define MI_INCRERR (-16) +#define MI_DECRERR (-17) +#define MI_READERR (-18) +#define MI_OVFLERR (-19) +#define MI_POLLING (-20) +#define MI_FRAMINGERR (-21) +#define MI_ACCESSERR (-22) +#define MI_UNKNOWN_COMMAND (-23) +#define MI_COLLERR (-24) +#define MI_RESETERR (-25) +#define MI_INITERR (-25) +#define MI_INTERFACEERR (-26) +#define MI_ACCESSTIMEOUT (-27) +#define MI_NOBITWISEANTICOLL (-28) +#define MI_QUIT (-30) +#define MI_RECBUF_OVERFLOW (-50) +#define MI_SENDBYTENR (-51) +#define MI_SENDBUF_OVERFLOW (-53) +#define MI_BAUDRATE_NOT_SUPPORTED (-54) +#define MI_SAME_BAUDRATE_REQUIRED (-55) +#define MI_WRONG_PARAMETER_VALUE (-60) +#define MI_BREAK (-99) +#define MI_NY_IMPLEMENTED (-100) +#define MI_NO_MFRC (-101) +#define MI_MFRC_NOTAUTH (-102) +#define MI_WRONG_DES_MODE (-103) +#define MI_HOST_AUTH_FAILED (-104) +#define MI_WRONG_LOAD_MODE (-106) +#define MI_WRONG_DESKEY (-107) +#define MI_MKLOAD_FAILED (-108) +#define MI_FIFOERR (-109) +#define MI_WRONG_ADDR (-110) +#define MI_DESKEYLOAD_FAILED (-111) +#define MI_WRONG_SEL_CNT (-114) +#define MI_WRONG_TEST_MODE (-117) +#define MI_TEST_FAILED (-118) +#define MI_TOC_ERROR (-119) +#define MI_COMM_ABORT (-120) +#define MI_INVALID_BASE (-121) +#define MI_MFRC_RESET (-122) +#define MI_WRONG_VALUE (-123) +#define MI_VALERR (-124) +#define MI_COM_ERR (-125) +#define MI_ERR (-126) + +#define DEF_FIFO_LENGTH 64 +#define MAXRLEN 18 + +struct TranSciveBuffer { + u8 MfCommand; + u16 MfLength; + u8 MfData[DEF_FIFO_LENGTH]; +}; + +#endif diff --git a/nfc/vendor/dp1312ea/reg.h b/nfc/vendor/dp1312ea/reg.h new file mode 100644 index 0000000..8646914 --- /dev/null +++ b/nfc/vendor/dp1312ea/reg.h @@ -0,0 +1,95 @@ +#ifndef __REG_H +#define __REG_H + +// +///////////////////////////////////////////////////////////////////// +#define DP1312EA_IDLE 0x00 //ȡǰ +#define DP1312EA_MEM 0x01 //CONFIG +#define DP1312EA_AUTHENT 0x0E //֤Կ +#define DP1312EA_RECEIVE 0x08 // +#define DP1312EA_TRANSMIT 0x04 // +#define DP1312EA_TRANSCEIVE 0x0C //Ͳ +#define DP1312EA_RESETPHASE 0x0F //λ +#define DP1312EA_CALCCRC 0x03 //CRC +#define DP1312EA_AUTOCOLL 0x0D //MIFARE anticollision, Card Operation mode only + + +//Ĵ +///////////////////////////////////////////////////////////////////// +// PAGE 0 +#define RFU00 0x00 +#define CommandReg 0x01 +#define ComIEnReg 0x02 +#define DivlEnReg 0x03 +#define ComIrqReg 0x04 +#define DivIrqReg 0x05 +#define ErrorReg 0x06 +#define Status1Reg 0x07 +#define Status2Reg 0x08 +#define FIFODataReg 0x09 +#define FIFOLevelReg 0x0A +#define WaterLevelReg 0x0B +#define ControlReg 0x0C +#define BitFramingReg 0x0D +#define CollReg 0x0E +#define RFU0F 0x0F +// PAGE 1 +#define RFU10 0x10 +#define ModeReg 0x11 +#define TxModeReg 0x12 +#define RxModeReg 0x13 +#define TxControlReg 0x14 +#define TxAskReg 0x15 //rc523 +#define TxAutoReg 0x15 //pn512 +#define TxSelReg 0x16 +#define RxSelReg 0x17 +#define RxThresholdReg 0x18 +#define DemodReg 0x19 +#define RFU1A 0x1A +#define RFU1B 0x1B +#define MifareReg 0x1C +#define ManualRCVReg 0x1D +#define TypeBReg 0x1E +#define SerialSpeedReg 0x1F +// PAGE 2 +#define RFU20 0x20 +#define CRCResultRegM 0x21 +#define CRCResultRegL 0x22 +#define GsNOffReg 0x23 +#define ModWidthReg 0x24 +#define TxBitPhaseReg 0x25 +#define RFCfgReg 0x26 +#define GsNOnReg 0x27 +#define CWGsPReg 0x28 +#define ModGsPReg 0x29 +#define TModeReg 0x2A +#define TPrescalerReg 0x2B +#define TReloadRegH 0x2C +#define TReloadRegL 0x2D +#define TCounterValueRegH 0x2E +#define TCounterValueRegL 0x2F +// PAGE 3 +#define RFU30 0x30 +#define TestSel1Reg 0x31 +#define TestSel2Reg 0x32 +#define TestPinEnReg 0x33 +#define TestPinValueReg 0x34 +#define TestBusReg 0x35 +#define AutoTestReg 0x36 +#define VersionReg 0x37 +#define AnalogTestReg 0x38 +#define TestDAC1Reg 0x39 +#define TestDAC2Reg 0x3A +#define TestADCReg 0x3B +#define RFU3C 0x3C +#define RFU3D 0x3D +#define RFU3E 0x3E +#define RFU3F 0x3F + + +#endif + + +/***********************************************END*******************************************************/ + +