Initial import of NFC GNSS SDK project

This commit is contained in:
chenjintao
2026-09-15 16:10:12 +08:00
commit 2746cc3d4e
3070 changed files with 892062 additions and 0 deletions
@@ -0,0 +1,431 @@
/***********************************************************************************************
*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*******************************************************/