432 lines
13 KiB
C
432 lines
13 KiB
C
/***********************************************************************************************
|
||
*DP1312EAÇý¶¯Îļþ
|
||
***********************************************************************************************/
|
||
#include <stdio.h>
|
||
#include "ql_rtos.h"
|
||
#include "ql_application.h"
|
||
#include "ql_audio.h"
|
||
#include "ql_iic.h"
|
||
#include "ql_gpio.h"
|
||
#include "app_inc.h"
|
||
#include "ql_fs.h"
|
||
|
||
#include "DP1312EA_Config.h"
|
||
#include "DP1312EA.h"
|
||
|
||
|
||
unsigned char nfc_i2c_no = 1; //CI2C match to twsi1
|
||
|
||
int8 output_uuid[64];
|
||
|
||
#define NRSTPD_PIN GPIO_PIN_NO_86
|
||
|
||
// NTAG213 内å˜å¸ƒå±€
|
||
#define NTAG213_PAGES 45 // 总页数 0-44
|
||
#define NTAG213_USER_START 4 // 用户数�起始页
|
||
#define NTAG213_USER_END 39 // 用户数æ�®ç»“æ�Ÿé¡µï¼ˆå…±36页,144å—节)
|
||
#define NTAG213_UID_PAGES 0 // UID 在第0-1页(7å—节UID + 1å—èŠ‚æ ¡éªŒï¼‰
|
||
|
||
extern int g_testmode;
|
||
extern int g_nfc_bind_status;
|
||
|
||
/***********************************************************************************************
|
||
*DP1312EA¼Ä´æÆ÷Ö¸¶¨Î»ÖÃλ
|
||
***********************************************************************************************/
|
||
void DP1312EA_SetBitMask(u8 reg,u8 mask)
|
||
{
|
||
u8 tmp = DP1312EA_ReadRawRC(reg);
|
||
DP1312EA_WriteRawRC(reg,tmp | mask);
|
||
}
|
||
|
||
/***********************************************************************************************
|
||
*DP1312EA¼Ä´æÆ÷Ö¸¶¨Î»¸´Î»
|
||
***********************************************************************************************/
|
||
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)
|
||
{
|
||
ql_i2c_write(nfc_i2c_no, 0x50>>1, Address, &value, 1);
|
||
}
|
||
|
||
u8 DP1312EA_ReadRawRC(uint8_t Address)
|
||
{
|
||
u8 ucResult=0;
|
||
|
||
ql_i2c_read(nfc_i2c_no, 0x50>>1, Address, &ucResult, 1);
|
||
|
||
return ucResult;
|
||
}
|
||
|
||
void DP1312EA_WriteFIFO(uint8_t *data, uint8_t len) {
|
||
|
||
for(uint8_t i = 0; i < len; i++) {
|
||
DP1312EA_WriteRawRC(FIFODataReg,data[i]);
|
||
}
|
||
}
|
||
|
||
void DP1312EA_ReadFIFO(uint8_t *buf, uint8_t len) {
|
||
|
||
for(uint8_t i = 0; i < len; i++) {
|
||
buf[i] = DP1312EA_ReadRawRC(FIFODataReg);
|
||
}
|
||
}
|
||
|
||
void Check_Chip(void)
|
||
{
|
||
u8 temp;;
|
||
temp=DP1312EA_ReadRawRC(VersionReg);
|
||
|
||
if(temp==0x82)
|
||
{
|
||
printf("\r\nDP1312EA is OK!");
|
||
}
|
||
else
|
||
{
|
||
printf("\r\nError!");
|
||
}
|
||
}
|
||
|
||
void DP1312EA_Enable(void)
|
||
{
|
||
ql_gpio_set_level(NRSTPD_PIN,PIN_LEVEL_LOW);
|
||
ql_rtos_task_sleep_ms(2);
|
||
}
|
||
|
||
void DP1312EA_Disable(void)
|
||
{
|
||
ql_gpio_set_level(NRSTPD_PIN,PIN_LEVEL_HIGH);
|
||
ql_rtos_task_sleep_ms(2);
|
||
}
|
||
|
||
|
||
void DP1312EA_Reset(void)
|
||
{
|
||
unsigned int iRet=0;
|
||
unsigned int fastmode = 0;
|
||
#if 1
|
||
ql_gpio_init(NRSTPD_PIN,PIN_DIRECTION_OUT,PIN_PULL_DISABLE,PIN_LEVEL_LOW);
|
||
|
||
ql_gpio_set_level(NRSTPD_PIN,PIN_LEVEL_LOW);
|
||
ql_rtos_task_sleep_ms(1);
|
||
ql_gpio_set_level(NRSTPD_PIN,PIN_LEVEL_HIGH);
|
||
ql_rtos_task_sleep_ms(2);
|
||
ql_gpio_set_level(NRSTPD_PIN,PIN_LEVEL_LOW);
|
||
ql_rtos_task_sleep_ms(1);
|
||
#endif
|
||
// //delay 500us Çë¿Í»§È·ÈÏdelay_usº¯ÊýÑÓʱ׼ȷ¡£
|
||
// DP1312EA_WriteRawRC(CommandReg,DP1312EA_RESETPHASE);//Èí¸´Î»
|
||
// delay_ms(5);
|
||
|
||
ql_i2c_init(nfc_i2c_no, fastmode);
|
||
}
|
||
|
||
void DP1312EA_FieldOn(void)
|
||
{
|
||
u8 n;
|
||
n = DP1312EA_ReadRawRC(TxControlReg);
|
||
if (!(n & 0x03))
|
||
DP1312EA_WriteRawRC(TxControlReg, n|0x03);
|
||
}
|
||
|
||
void DP1312EA_FieldOff(void)
|
||
{
|
||
DP1312EA_ClearBitMask(TxControlReg, 0x03);
|
||
}
|
||
|
||
|
||
|
||
/**********************************************************************************************************
|
||
*º¯ÊýÃû³Æ£ºs8 DP1312EA_PcdComTransceive(struct TranSciveBuffer *pi)
|
||
*¹¦ÄÜÃèÊö£º
|
||
ÃüÁî·¢Ëͺ¯Êý£¬¸÷ÖÖ¿¨Í¨Óá£
|
||
*ÊäÈë²ÎÊý£º
|
||
pi£ºÃüÁîºÍÊý¾ÝÖ¸Õ룻
|
||
|
||
*·µ»Ø²ÎÊý£º
|
||
MI_OK£º³É¹¦£»
|
||
other£ºÊ§°Ü£»
|
||
*ÆäËüÊä³ö£º
|
||
ÎÞ
|
||
**********************************************************************************************************/
|
||
s8 DP1312EA_PcdComTransceive(struct TranSciveBuffer *pi)
|
||
{
|
||
s8 status = MI_ERR;
|
||
u8 irqEn,waitFor,n,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); //01h
|
||
DP1312EA_SetBitMask(FIFOLevelReg,0x80); //0ah, //FlushFIFO
|
||
DP1312EA_WriteRawRC(ComIrqReg,0x7F); //04h
|
||
|
||
for (i=0; i<pi->MfLength; i++)
|
||
DP1312EA_WriteRawRC(FIFODataReg, pi->MfData [i]); //09h
|
||
|
||
DP1312EA_WriteRawRC(CommandReg, pi->MfCommand); //01h
|
||
|
||
if (pi->MfCommand == DP1312EA_TRANSCEIVE)
|
||
DP1312EA_SetBitMask(BitFramingReg,0x80); //StartSend
|
||
|
||
//
|
||
for(i = 500;i>0;i--)
|
||
{
|
||
n = DP1312EA_ReadRawRC(ComIrqReg); //04h
|
||
if((n&irqEn&0x01)||(n&waitFor))
|
||
break; //timerirq idleirq rxirq
|
||
}
|
||
DP1312EA_ClearBitMask(BitFramingReg,0x80); //0dh //StartSend
|
||
|
||
if (n&waitFor) //IdleIRq
|
||
{
|
||
if(DP1312EA_ReadRawRC(ErrorReg)&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; i<n; i++)
|
||
pi->MfData[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;
|
||
}
|
||
|
||
DP1312EA_SetBitMask(ControlReg,0x80); // stop timer now
|
||
DP1312EA_WriteRawRC(CommandReg,DP1312EA_IDLE); //01h
|
||
return status;
|
||
}
|
||
|
||
// å°†å��å…进制数组转æ�¢ä¸ºå��å…进制å—符串(如 0x48 -> "48")
|
||
void hex_array_to_hex_string(unsigned char *hex_array, int len, char *output) {
|
||
for (int i = 0; i < len; i++) {
|
||
// æ¯�个å—节转为2ä½�å��å…进制å—符
|
||
sprintf(output + i * 2, "%02X", hex_array[i]);
|
||
}
|
||
output[len * 2] = '\0'; // 结尾符
|
||
}
|
||
|
||
/**********************************************************************************************************
|
||
* 函数�称:s8 Read_NTAG213(u8 *uid_buf, u8 *data_buf, u16 *data_len)
|
||
* 功能æ��述:读å�– NTAG213 æ ‡ç¾çš„ UID 和所有用户数æ�®
|
||
* 输入å�‚数:æ—
|
||
* 输出�数:
|
||
* uid_buf - 返回7å—节UID
|
||
* data_buf - 返回用户数æ�®ï¼ˆ144å—节),调用者需分é…�足够空间
|
||
* data_len - 返回实际读�的数�长度
|
||
* 返回值:MI_OK - �功,其他 - 失败
|
||
**********************************************************************************************************/
|
||
s8 Read_NTAG213(u8 *uid_buf, u8 *data_buf, u16 *data_len)
|
||
{
|
||
s8 status;
|
||
u8 atqa[2];
|
||
u8 uid[12] = {0}; // 临时å˜å‚¨UID(å�¯èƒ½8å—节或4å—节)
|
||
u8 ulen;
|
||
u8 sak;
|
||
//u8 page_data[16]; // MfulRead一次读4页(16å—节)
|
||
//u8 read_page;
|
||
// u16 offset = 0;
|
||
|
||
*data_len = 0;
|
||
|
||
// 1. 激活�片(寻� + 防冲� + 选�)
|
||
DP1312EA_Reset();
|
||
ql_rtos_task_sleep_ms(1);
|
||
|
||
status = DP1312EA_PcdActivateA(atqa, uid, &ulen, &sak);
|
||
|
||
DP1312EA_Disable();
|
||
|
||
if(status != MI_OK)
|
||
{
|
||
// printf("Activate failed: %d\n", status);
|
||
return status;
|
||
}
|
||
|
||
// 2. åˆ¤æ–æ˜¯å�¦ä¸º NTAG213(或兼容的MIFARE Ultralight系列)
|
||
// NTAG213 特�:SAK = 0x00, ATQA = 0x0044 或 0x0004
|
||
// 且 UID 长度为 7 å—节(ulen å�¯èƒ½ä¸º 8,表示级è�”)
|
||
#if 0
|
||
if(sak != 0x00)
|
||
{
|
||
printf("Not a NTAG213/Ultralight card! SAK=0x%02X\n", sak);
|
||
return MI_ERR; // �是NTAG类型
|
||
}
|
||
#endif
|
||
|
||
// æ��å�–7å—节UID(NTAG213是7å—节UID)
|
||
if(ulen == 8)
|
||
{
|
||
// 两级è�”,跳过第一个å—节的级è�”æ ‡è®°0x88
|
||
memcpy(uid_buf, &uid[1], 7);
|
||
|
||
hex_array_to_hex_string(uid_buf, 7, output_uuid);
|
||
}
|
||
else if(ulen == 4)
|
||
{
|
||
// å�¯èƒ½æ˜¯Ultralight C(4å—节UID)或异常
|
||
memcpy(uid_buf, uid, 4);
|
||
printf("Warning: 4-byte UID, may be Ultralight C\n");
|
||
hex_array_to_hex_string(uid_buf, 4, output_uuid);
|
||
}
|
||
else
|
||
{
|
||
printf("Unknown UID length: %d\n", ulen);
|
||
return MI_ERR;
|
||
}
|
||
|
||
printf("uid_buf read:%s\r\n", output_uuid);
|
||
|
||
if(g_testmode==0){
|
||
if(g_nfc_bind_status==1){
|
||
handle_nfc_bind(output_uuid);
|
||
g_nfc_bind_status = 0;
|
||
}else{
|
||
//nfc 触å�‘æµ�程 ç„¶å�ŽéŸ³é¢‘æ’æ”¾å®Œæˆ� å†�去触å�‘录音 -> vad_leave_message
|
||
handle_nfc_trigger(output_uuid);
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
printf("NTAG213 detected, UID: ");
|
||
for(int i=0; i<7; i++) printf("%02X", uid_buf[i]);
|
||
printf("\n");
|
||
printf("ATQA: %02X%02X, SAK: %02X\n", atqa[1], atqa[0], sak);
|
||
|
||
// 3. 读�所有数�页(0-43,共44页,但通常我们读到39或43)
|
||
// 注æ„�:DP1312EA_PcdMfulRead 使用 PICC_READ(0x30),一次读4页(16å—节)
|
||
printf("Reading NTAG213 memory...\n");
|
||
|
||
for(read_page = 0; read_page < NTAG213_PAGES; read_page += 4)
|
||
{
|
||
status = DP1312EA_PcdMfulRead(read_page, page_data);
|
||
if(status != MI_OK)
|
||
{
|
||
printf("Read page %d failed: %d\n", read_page, status);
|
||
break; // 读�失败,�能是到了末尾或�片移开
|
||
}
|
||
|
||
// 将读å�–çš„16å—节(4页)å¤�制到用户缓冲区
|
||
// 注�:��超过缓冲区大�
|
||
if(offset + 16 <= 180) // NTAG213总容é‡�180å—节
|
||
{
|
||
memcpy(&data_buf[offset], page_data, 16);
|
||
offset += 16;
|
||
}
|
||
|
||
// 打�当�4页的数�
|
||
printf("Page %02d-%02d: ", read_page, read_page+3);
|
||
for(int i=0; i<16; i++)
|
||
{
|
||
printf("%02X ", page_data[i]);
|
||
if(i==3 || i==7 || i==11) printf("| ");
|
||
}
|
||
printf("\n");
|
||
}
|
||
|
||
*data_len = offset;
|
||
|
||
// 4. è§£æž� Capability Container(第3页,å��ç§»12-15å—节)
|
||
// CCæ ¼å¼�:E1 10 12 00( magic, version, size, read/write access)
|
||
if(*data_len >= 16)
|
||
{
|
||
u8 *cc = &data_buf[12]; // 第3页(�移12)
|
||
printf("Capability Container (Page 3): %02X %02X %02X %02X\n",
|
||
cc[0], cc[1], cc[2], cc[3]);
|
||
|
||
if(cc[0] == 0xE1)
|
||
{
|
||
printf(" Magic Number: 0xE1 (NFC Forum Tag)\n");
|
||
printf(" Version: %02X\n", cc[1]);
|
||
printf(" Size: %02X (%d bytes)\n", cc[2], cc[2]*8); // 0x12 = 144 bytes
|
||
}
|
||
}
|
||
#endif
|
||
return MI_OK;
|
||
}
|
||
|
||
/**********************************************************************************************************
|
||
* 函数�称:void Test_NTAG213(void)
|
||
* 功能�述:测试读�NTAG213并解�NDEF消�(如果有)
|
||
**********************************************************************************************************/
|
||
s8 Test_NTAG213(void)
|
||
{
|
||
u8 uid[7];
|
||
u8 ntag_data[180]; // NTAG213总容�
|
||
u16 data_len;
|
||
s8 status;
|
||
|
||
// printf("\n=== NTAG213 Read Test ===\n");
|
||
|
||
status = Read_NTAG213(uid, ntag_data, &data_len);
|
||
|
||
if(status == MI_OK)
|
||
{
|
||
printf("Read NTAG213 Success\n");
|
||
#if 0
|
||
printf("\nRead complete! Total %d bytes\n", data_len);
|
||
|
||
// 解�用户数�区(Page 4-39)
|
||
// 简�的NDEF检测:查找0x03(NDEF消�TLV起始)
|
||
printf("\nUser data area (Page 4-39):\n");
|
||
for(int i=16; i<data_len && i<160; i++) // 从第4页开始(�移16)
|
||
{
|
||
if((i-16)%16 == 0) printf("\n%03d: ", i);
|
||
printf("%02X ", ntag_data[i]);
|
||
}
|
||
printf("\n");
|
||
|
||
// 检查是å�¦æ˜¯NDEFæ ¼å¼�
|
||
if(ntag_data[16] == 0x03) // 第4页第0å—节是NDEF TLV
|
||
{
|
||
u8 ndef_len = ntag_data[17];
|
||
printf("\nNDEF message detected, length: %d bytes\n", ndef_len);
|
||
// 这里å�¯ä»¥æ·»åŠ NDEFè§£æž�逻辑...
|
||
}
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
// printf("Read NTAG213 failed: %d\n", status);
|
||
}
|
||
|
||
return status;
|
||
}
|
||
|
||
/***********************************************END*******************************************************/
|
||
|