Files
banban/ql-application/threadx/interface/custom_app/DP1312EA.c
T

432 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/***********************************************************************************************
*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*******************************************************/