329 lines
9.0 KiB
C
329 lines
9.0 KiB
C
#include <string.h>
|
||
#include <stdio.h>
|
||
#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); // 延时后再检测
|
||
}
|
||
}
|
||
|