CH584NFC读Ultrlight卡代码
前言:
针对CH584读Ultrlight卡做讲解。
Ultrlight卡的ATQA=0x0044,SAK=00。
#define SECTOR_1 4
/*********************************************************************
* @fn parse_ndef_text_record
*
* @brief 解析NDEF Text Record TLV数据
*
* @param data - 包含NDEF数据的缓冲区
* @param length - 数据的长度
*
* @return none
*/
void parse_ndef_text_record(uint8_t *data, uint16_t length)
{
uint8_t *p = data;
uint16_t index = 0;
// 寻找 NDEF Message TLV (Type 0x03)
while (index < length)
{
uint8_t t = p[index];
uint8_t l = 0;
uint16_t v_index = 0;
if (t == 0x03) // NDEF Message TLV
{
index++;
l = p[index];
index++;
v_index = index;
PRINTF("Found NDEF Message TLV, Length: %d\n", l);
// 解析 NDEF 记录
if (l > 0)
{
uint8_t header = p[v_index];
uint8_t type_len = p[v_index + 1];
uint8_t payload_len = p[v_index + 2];
uint8_t type_offset = 3;
// 检查是否是 Text Record (Type 'T')
if (type_len == 1 && p[v_index + type_offset] == 'T')
{
PRINTF("Found NDEF Text Record\n");
uint8_t payload_offset = v_index + type_offset + type_len;
uint8_t status_byte = p[payload_offset];
uint8_t lang_code_len = status_byte & 0x3F;
uint8_t text_offset = payload_offset + 1 + lang_code_len;
uint8_t text_len = payload_len - 1 - lang_code_len;
// 打印文本内容
PRINTF("Text: ");
for (int i = 0; i < text_len; i++)
{
PRINTF("%c ", p[text_offset + i]);
}
PRINTF("\n");
}
}
index += l;
}
else if (t == 0x00) // Null TLV
{
index++;
}
else if (t == 0xFE) // Terminator TLV
{
PRINTF("Found Terminator TLV\n");
break;
}
else // 其他类型的 TLV
{
index++;
l = p[index];
index += (1 + l);
}
}
}
#define PCD_READ_OVER_TIME 5
uint16_t PcdNTAG21xRead(uint8_t addr, uint8_t *pData)
{
uint16_t res = PCD_COMMUNICATE_ERROR;
nfca_pcd_controller_state_t status;
nfca_pcd_set_wait_ms(PCD_READ_OVER_TIME);
g_nfca_pcd_send_buf[0] = PICC_READ;
g_nfca_pcd_send_buf[1] = addr;
ISO14443AAppendCRCA((uint8_t *)g_nfca_pcd_send_buf, 2);
ISO14443ACalOddParityBit((uint8_t *)g_nfca_pcd_send_buf, (uint8_t *)g_nfca_pcd_parity_buf, 4);
if (nfca_pcd_communicate((4 * 8), NFCA_PCD_REC_MODE_NORMAL, 0) == 0)
{
status = nfca_pcd_wait_communicate_end();
if(status == NFCA_PCD_CONTROLLER_STATE_DONE)
{
if (g_nfca_pcd_recv_bits == (18 * 9))
{
if (ISO14443ACheckOddParityBit(g_nfca_pcd_recv_buf, g_nfca_pcd_parity_buf, 18))
{
if(ISO14443_CRCA(g_nfca_pcd_recv_buf, 18) == 0)
{
__MCPY(pData, g_nfca_pcd_recv_buf, g_nfca_pcd_recv_buf + 16);
res = PCD_NO_ERROR;
}
else
{
res = PCD_CRC_ERROR;
}
}
else
{
res = PCD_ODD_PARITY_ERROR;
}
}
else if (g_nfca_pcd_recv_bits == ACK_NAK_FRAME_SIZE)
{
res = PICC_NAK_HEAD | g_nfca_pcd_recv_buf[0];
}
else
{
res = PCD_UNKNOWN_ERROR;
}
}
}
end:
return res;
}
if(res == 0x0044) /* Mifare Ultrlight卡片 */
{
res = PcdAnticoll(PICC_ANTICOLL1);
if (res == PCD_NO_ERROR)
{
if(g_nfca_pcd_recv_buf[0] == 0x88)
{
picc_uid[0] = g_nfca_pcd_recv_buf[1];
picc_uid[1] = g_nfca_pcd_recv_buf[2];
picc_uid[2] = g_nfca_pcd_recv_buf[3];
res = PcdSelect(PICC_ANTICOLL1, g_nfca_pcd_recv_buf);
if (res == PCD_NO_ERROR)
{
res = PcdAnticoll(PICC_ANTICOLL2);
if (res == PCD_NO_ERROR)
{
picc_uid[3] = g_nfca_pcd_recv_buf[0];
picc_uid[4] = g_nfca_pcd_recv_buf[1];
picc_uid[5] = g_nfca_pcd_recv_buf[2];
picc_uid[6] = g_nfca_pcd_recv_buf[3];
PRINTF("Ultrlight uid: %02x %02x %02x %02x %02x %02x %02x\n", picc_uid[0], picc_uid[1],
picc_uid[2], picc_uid[3], picc_uid[4], picc_uid[5], picc_uid[6]);
res = PcdSelect(PICC_ANTICOLL2, g_nfca_pcd_recv_buf);
if (res == PCD_NO_ERROR)
{
/* 防冲突第二层选中成功 */
PRINTF("SELECT OK, SAK: %02x\n", g_nfca_pcd_recv_buf[0]);
mDelaymS(10);
uint8_t sector_data[64];
uint8_t block_count = 0;
for (uint8_t i = SECTOR_1; i < SECTOR_1 + 8; i++)
{
// res = PcdRead(i);
PcdNTAG21xRead(i, g_nfca_pcd_test_buf);
if (res != PCD_NO_ERROR)
{
PRINTF("Read block %d ERR: 0x%x\n", i, res);
goto nfc_halt_ul;
}
memcpy(§or_data[block_count * 4], g_nfca_pcd_test_buf, 4);
block_count++;
}
// 打印整个扇区的数据
PRINTF("Sector %d Data:\n", SECTOR_1 / 4);
for (uint8_t i = 0; i < sizeof(sector_data); i++)
{
PRINTF("%02x ", sector_data[i]);
if ((i + 1) % 4 == 0)
{
PRINTF("\n");
}
}
// 解析NDEF数据
parse_ndef_text_record(sector_data, sizeof(sector_data));
nfc_halt_ul:
PcdHalt();
}
}
else
{
PRINTF("ERROR ANTICOLL2\n");
}
}
else
{
PRINTF("CARD PcdSelect error: %d\n", res);
}
}
else
{
PRINTF("ERROR UID0\n");
}
}
}
读取数据内容和NDEF解析日志:

浙公网安备 33010602011771号