Cannot read data on Block Mifare 1K card data using MFRC522 module and nRF52DK?

#include "mfrc522.h"

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>

#define PICC_TIMEOUT_5MS 0x09
#define PICC_TIMEOUT_10MS 0x13
#define PICC_TIMEOUT_15MS 0x1E

#define GPIO_CS 28

const struct device *gpio0_dev;
const struct device *spi_dev;

struct spi_config spi_cfg;
struct spi_cs_control chip;

struct spi_buf tx_buf;
struct spi_buf rx_buf;

void SPI_Init(void)
{
	spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi1));
	if (!spi_dev)
	{
		printk("Failed to get SPI device\n");
		return;
	}

	gpio0_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); // GPIO cihazını tanımla

	if (!gpio0_dev)
	{
		printk("Failed to get GPIO device\n");
		return;
	}

	// SPI yapılandırması
	spi_cfg.frequency = 10000000;
	spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
						SPI_MODE_CPOL | SPI_MODE_CPHA;
	spi_cfg.slave = 0;

	// CS pini için yapılandırma
	chip.gpio.port = gpio0_dev;
	chip.gpio.pin = GPIO_CS;
	chip.gpio.dt_flags = GPIO_ACTIVE_LOW;
	chip.delay = 2;

	// SPI yapılandırmasına CS pinini ekle
	spi_cfg.cs = chip;

	printk("\r\nSPI device is initialized and ready.\n");
}

uint8_t TM_MFRC522_RdReg(uint8_t ucAddress)
{
	uint8_t command = ((ucAddress << 1) & 0x7E) | 0x80; // MFRC522 adresi ile okuma komutunu oluştur
	uint8_t tx_data[2] = {command, 0x00};				// Okunan veriyi alacak buffer
	uint8_t rx_data[2] = {0};							// Okunan veriyi alacak buffer

	tx_buf.buf = tx_data;
	tx_buf.len = 2;

	rx_buf.buf = rx_data;
	rx_buf.len = 2;

	struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1};

	struct spi_buf_set rx = {
		.buffers = &rx_buf,
		.count = 1};

	if (spi_transceive(spi_dev, &spi_cfg, &tx, &rx) != 0)
	{
		printk("\r\nError reading MFRC522 register\r\n");
		return 0; // Hata durumunda 0 dön
	}
	printk("data responds <<<<: %02X-%02X\n", rx_data[0], rx_data[1]);
	return rx_data[1]; // Okunan veriyi dön
}

TM_MFRC522_STS_T MFRC522_Authenticate(uint8_t auth_mode, uint8_t block_addr, uint8_t *key, uint8_t *uid)
{

	TM_MFRC522_STS_T status;
	uint16_t recvBits;
	uint8_t i;
	uint8_t buff[12];

	//Verify the command block address + sector + password + card serial number
	buff[0] = auth_mode;
	buff[1] = block_addr;
	for (i = 0; i < 6; i++) {
		buff[i + 2] = *(key + i);
	}
	for (i = 0; i < 4; i++) {
		buff[i + 8] = *(uid + i);
	}
	status = TM_MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
	k_sleep(K_MSEC(100));
	printk("------------------Status: 0x%02X", status);
	TM_MFRC522_RdReg(MFRC522_REG_STATUS2);
	if ((status != MI_OK)
			|| (!(TM_MFRC522_RdReg(MFRC522_REG_STATUS2) & 0x08))) {
		status = MI_ERR;
	}

	return status;
}

void TM_MFRC522_WrReg(uint8_t ucAddress, uint8_t ucValue)
{
	uint8_t command = (ucAddress << 1) & 0x7E; // MFRC522 adresi ile yazma komutunu oluştur
	uint8_t value = ucValue;
	struct spi_buf_set tx_bufs;
	struct spi_buf txb[2];

	txb[0].buf = &command;
	txb[0].len = 1;
	txb[1].buf = &value;
	txb[1].len = 1;

	tx_bufs.buffers = txb;
	tx_bufs.count = 2;

	int ret = spi_write(spi_dev, &spi_cfg, &tx_bufs);
	if (ret != 0)
	{
		printk("\r\nSPI transfer failed with error: %d\r\n", ret);
		// Hata durumunda gerekli işlemler yapılabilir
	}
	else
	{
		// SPI iletişimi başarıyla gerçekleştirildi
	}
}

void TM_MFRC522_Init(void)
{

	TM_MFRC522_Reset();

	TM_MFRC522_WrReg(MFRC522_REG_T_MODE, 0x8D);
	TM_MFRC522_WrReg(MFRC522_REG_T_PRESCALER, 0x3E);

	TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_L, 5);
	TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_H, 0);

	TM_MFRC522_WrReg(MFRC522_REG_TX_AUTO, 0x40);
	TM_MFRC522_WrReg(MFRC522_REG_MODE, 0x3D);

	TM_MFRC522_WrReg(MFRC522_REG_RF_CFG, 0x70);

	TM_MFRC522_SetBitMask(MFRC522_REG_DIV1_EN, 0x80);

	TM_MFRC522_AntennaOn();


	// TM_MFRC522_WrReg(MFRC522_REG_T_MODE, 0x8D);
	// TM_MFRC522_WrReg(MFRC522_REG_T_PRESCALER, 0x3E);
	// TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_L, 30);
	// TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_H, 0);

	// /* 48dB gain */
	// //TM_MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70); 
	// TM_MFRC522_WrReg(MFRC522_REG_TX_AUTO, 0x40);
	// TM_MFRC522_WrReg(MFRC522_REG_MODE, 0x3D);
	// TM_MFRC522_AntennaOff();
	// TM_MFRC522_AntennaOn(); //Open the antenna
}

/* A function to initialize SPI Instance */

void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask)
{
	TM_MFRC522_WrReg(reg, TM_MFRC522_RdReg(reg) | mask);
}

void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask)
{
	TM_MFRC522_WrReg(reg, TM_MFRC522_RdReg(reg) & (~mask));
}

void TM_MFRC522_AntennaOn(void)
{
	uint8_t temp;

	temp = TM_MFRC522_RdReg(MFRC522_REG_TX_CONTROL);
	if (!(temp & 0x03))
		TM_MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}

void TM_MFRC522_AntennaOff(void)
{
	TM_MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}

void TM_MFRC522_Reset(void)
{
	uint8_t temp;

	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_RESETPHASE);

	do
	{
		temp = TM_MFRC522_RdReg(MFRC522_REG_COMMAND);
		temp &= 0x10;
	} while (temp);
}

uint8_t MFRC522_ToCard(uint8_t command, uint8_t *sendData, uint8_t sendLen, uint8_t *backData, unsigned *backLen)
{
	uint8_t _status = MI_ERR;
	uint8_t irqEn = 0x00;
	uint8_t waitIRq = 0x00;
	uint8_t lastBits;
	uint8_t n;
	unsigned i;

	switch (command)
	{
	case PCD_AUTHENT:
	{
		irqEn = 0x12;
		waitIRq = 0x10;
		break;
	}
	case PCD_TRANSCEIVE:
	{
		irqEn = 0x77;
		waitIRq = 0x30;
		break;
	}
	default:
		break;
	}

	TM_MFRC522_WrReg(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
	TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
	TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);

	for (i = 0; i < sendLen; i++)
	{
		TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, sendData[i]);
	}

	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, command);

	if (command == PCD_TRANSCEIVE)
	{
		TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
	}

	i = 0xFFFF;
	do
	{

		n = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
		i--;
	} while (i && !(n & 0x01) && !(n & waitIRq));

	TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);

	if (i != 0)
	{
		if (!(TM_MFRC522_RdReg(MFRC522_REG_ERROR) & 0x1B))
		{
			_status = MI_OK;
			if (n & irqEn & 0x01)
			{
				_status = MI_NOTAGERR;
			}

			if (command == PCD_TRANSCEIVE)
			{
				n = TM_MFRC522_RdReg(MFRC522_REG_FIFO_LEVEL);
				lastBits = TM_MFRC522_RdReg(MFRC522_REG_CONTROL) & 0x07;
				if (lastBits)
				{
					*backLen = (n - 1) * 8 + lastBits;
				}
				else
				{
					*backLen = n * 8;
				}

				if (n == 0)
				{
					n = 1;
				}

				if (n > 16)
				{
					n = 16;
				}

				for (i = 0; i < n; i++)
				{
					backData[i] = TM_MFRC522_RdReg(MFRC522_REG_FIFO_DATA);
				}

				backData[i] = 0;
			}
		}
		else
		{
			_status = MI_ERR;
		}
	}

	return _status;
}

uint8_t MFRC522_Request(uint8_t reqMode, uint8_t *TagType)
{
	uint8_t _status = MI_ERR; // Mặc định là lỗi, chỉ đổi thành MI_OK khi thành công
	uint8_t backBits = 0;	  // Số bit phản hồi từ thẻ

	printk("MFRC522_Request: Sending reqMode = 0x%02X\n", reqMode);

	// Đặt BitFramingReg thành 0x07 (chỉ cần nếu có vấn đề giao tiếp)
	TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x07);

	// Chuẩn bị dữ liệu gửi đi
	TagType[0] = reqMode;

	// Gửi lệnh và nhận phản hồi từ thẻ
	_status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

	printk("MFRC522_Request: Status = %d, backBits = 0x%02X\n", _status, backBits);

	// Kiểm tra xem phản hồi có hợp lệ không
	if ((_status == MI_OK) && (backBits == 0x10))
	{
		printk("MFRC522_Request: Card detected successfully!\n");
	}
	else
	{
		printk("MFRC522_Request: Failed! _status = %d, backBits = 0x%02X\n", _status, backBits);
		_status = MI_ERR;
	}

	return _status;
}

uint8_t MFRC522_isCard(uint8_t *TagType)
{
	if (MFRC522_Request(PICC_REQA, TagType) == MI_OK)

		return 1;
	else
		return 0;
}

TM_MFRC522_STS_T TM_MFRC522_Anticoll(uint8_t *serNum)
{
	TM_MFRC522_STS_T status;
	uint8_t i;
	uint8_t serNumCheck = 0;
	uint16_t unLen;

	TM_MFRC522_ClearBitMask(MFRC522_REG_STATUS2, 0x08);
	TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x00); // TxLastBists = BitFramingReg[2..0]
	TM_MFRC522_SetBitMask(MFRC522_REG_COLL, 0x80);

	/* ANTICOLLISION command with NVB does not specify 40 valid bits (NVB not to 0x70) */
	/* Note: "NVB=0x20" defines that the PCD will transmit no part of UID CLn, and it forces all
			 PICCs in the field to respond with their complete UID CLn. */
	serNum[0] = PICC_ANTICOLL;
	serNum[1] = 0x20; // NVB
	status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

	if (status == MI_OK)
	{
		/* Check card serial number */
		for (i = 0; i < 4; i++)
		{
			serNumCheck ^= serNum[i];
		}

		/* BCC: UID CLn checkbyte and is calculated
		   as exclusive-or over the 4 previous bytes */
		if (serNumCheck != serNum[i])
		{
			status = MI_ERR;
		}
	}
	TM_MFRC522_SetBitMask(MFRC522_REG_COLL, 0x80);

	return status;
}

TM_MFRC522_STS_T TM_MFRC522_ToCard(uint8_t command, uint8_t *sendData,
									  uint8_t sendLen, uint8_t *backData, uint16_t *backLen)
{
	TM_MFRC522_STS_T status = MI_ERR;
	uint8_t irqEn = 0x00;
	uint8_t waitIRq = 0x00;
	uint8_t lastBits;
	uint8_t n;
	uint16_t i;

	switch (command)
	{
	case PCD_AUTHENT:
	{
		irqEn = 0x12;
		waitIRq = 0x10;
		break;
	}
	case PCD_TRANSCEIVE:
	{
		irqEn = 0x77;
		waitIRq = 0x30;
		break;
	}
	default:
		break;
	}

	TM_MFRC522_WrReg(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
	TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
	TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);

	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);

	// Writing data to the FIFO
	for (i = 0; i < sendLen; i++)
	{
		TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, sendData[i]);
	}

	// Execute the command
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, command);
	if (command == PCD_TRANSCEIVE)
	{
		TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80); // StartSend=1,transmission of data starts
	}

	// Waiting to receive data to complete
	i = 2000; // i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
	do
	{
		// CommIrqReg[7..0]
		// Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
		n = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
		i--;
	} while ((i != 0) && !(n & 0x01) && !(n & waitIRq));

	TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80); // StartSend=0

	if (i != 0)
	{
		if (!(TM_MFRC522_RdReg(MFRC522_REG_ERROR) & 0x1B))
		{
			status = MI_OK;
			if (n & irqEn & 0x01)
			{
				status = MI_NOTAGERR;
			}

			if (command == PCD_TRANSCEIVE)
			{
				n = TM_MFRC522_RdReg(MFRC522_REG_FIFO_LEVEL);
				lastBits = TM_MFRC522_RdReg(MFRC522_REG_CONTROL) & 0x07;
				if (lastBits)
				{
					*backLen = (n - 1) * 8 + lastBits;
				}
				else
				{
					*backLen = n * 8;
				}

				if (n == 0)
				{
					n = 1;
				}
				if (n > MFRC522_MAX_LEN)
				{
					n = MFRC522_MAX_LEN;
				}

				// Reading the received data in FIFO
				for (i = 0; i < n; i++)
				{
					backData[i] = TM_MFRC522_RdReg(
						MFRC522_REG_FIFO_DATA);
				}
			}
		}
		else
		{
			status = MI_ERR;
		}
	}
	// TM_MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x80);
	// TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);
	return status;
}

void TM_MFRC522_CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
	uint8_t i, n;

	TM_MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04);

	TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);

	for (i = 0; i < len; i++)
	{
		TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, *(pIndata + i));
	}
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_CALCCRC);

	i = 0xFF;
	do
	{
		n = TM_MFRC522_RdReg(MFRC522_REG_DIV_IRQ);
		i--;
	} while ((i != 0) && !(n & 0x04));

	pOutData[0] = TM_MFRC522_RdReg(MFRC522_REG_CRC_RESULT_L);
	pOutData[1] = TM_MFRC522_RdReg(MFRC522_REG_CRC_RESULT_M);
}

void TM_MFRC522_Halt(void)
{

	uint8_t buff[4];

	buff[0] = PICC_HALT; // 0x50: Lệnh HALT
	buff[1] = 0x00;
	TM_MFRC522_CalculateCRC(buff, 2, &buff[2]); // Tính CRC

	// Ghi dữ liệu vào FIFO
	TM_MFRC522_ClearBitMask(MFRC522_REG_COLL, 0x80); // Clear lỗi
	for (int i = 0; i < 4; i++)
	{
		TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, buff[i]);
	}

	// Kích hoạt lệnh HALT nhưng không chờ phản hồi
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);

	printk("TM_MFRC522_Halt: Card halted successfully.\n");
}

uint8_t TM_MFRC522_Check(uint8_t *id)
{
	uint8_t status;
	uint8_t cardtype[3];

	status = MFRC522_Request(PICC_REQA, cardtype);
	if (status == MI_OK)
		status = TM_MFRC522_Anticoll(id);
	else
		status = MI_ERR;

	return status;
}

TM_MFRC522_STS_T TM_MFRC522_Auth(uint8_t auth_mode, uint8_t block_addr, uint8_t *key, uint8_t *uid)
{
	uint8_t auth_cmd[12];

	auth_cmd[0] = auth_mode;	  // 0x60 = KeyA, 0x61 = KeyB
	auth_cmd[1] = block_addr;	  // Địa chỉ block cần xác thực
	memcpy(&auth_cmd[2], key, 6); // Copy key vào mảng
	memcpy(&auth_cmd[8], uid, 4); // Copy UID vào mảng

	// 🔹 Reset trạng thái trước khi gửi authentication
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, 0x00);
	TM_MFRC522_WrReg(MFRC522_REG_COMM_IRQ, 0x7F);
	TM_MFRC522_WrReg(MFRC522_REG_FIFO_LEVEL, 0x80);
	TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, 0x0A);
	TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, 0x04);
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, 0x0C);

	k_sleep(K_MSEC(10)); // Thêm delay nhỏ để chip xử lý

	// 🔹 Reset lại FIFO trước khi gửi authentication
	TM_MFRC522_WrReg(MFRC522_REG_FIFO_LEVEL, 0x80);
	// 🔹 Gửi 12 byte auth command vào FIFO
	TM_MFRC522_WrRegMulti(MFRC522_REG_FIFO_DATA, auth_cmd, 12);

	// 🔹 Cấu hình truyền dữ liệu
	TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x00);

	// 🔹 Kích hoạt authentication
	TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_AUTHENT);

	// 🔹 Chờ hoàn thành auth bằng polling thay vì delay cố định
	uint8_t wait = 1000;
	while (!(TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ) & 0x10) && wait--)
	{
		k_sleep(K_MSEC(1));
	}

	// 🔹 Kiểm tra authentication thành công hay không
	for (int i = 0; i < 5; i++)
	{
		int a = TM_MFRC522_RdReg(MFRC522_REG_STATUS2);
		k_sleep(K_MSEC(100));
		if (a & 0x08)
		{				  // Kiểm tra CRYPTO1_ON
			return MI_OK; // ✅ Thành công
		}
		printk("========================%02X\n", a);
	}

	// 🔹 Nếu thất bại, đọc ErrorReg để debug
	uint8_t error = TM_MFRC522_RdReg(MFRC522_REG_ERROR);
	printk("Authentication failed! ErrorReg: 0x%02X\n", error);

	return MI_ERR; // ❌ Authentication thất bại
}

TM_MFRC522_STS_T MFRC522_ReadBlock(uint8_t block, uint8_t *buffer, uint16_t *back_len)
{
	// TM_MFRC522_STS_T status;
	// uint8_t sendData[4];
	// uint16_t length = 0;
	// // Chuẩn bị lệnh đọc
	// sendData[0] = PICC_READ; // Lệnh MIFARE_READ
	// sendData[1] = block;	 // Địa chỉ block cần đọc
	// // TM_MFRC522_CalculateCRC(sendData, 2, &sendData[2]);
	// // printf("send data: %X %X %X %X\n", sendData[0], sendData[1], sendData[2], sendData[3]);
	// // Gọi hàm MFRC522_ToCard
	// status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, sendData, 2, buffer, &length);
	// printk("lendata: %d\n", length);
	// printf("status: %d\n", status);
	// // Kiểm tra kết quả
	// if (status != MI_OK)
	// {
	// 	return MI_ERR; // Đọc thất bại hoặc dữ liệu trả về không đúng kích thước
	// }
	// TM_MFRC522_SetBitMask(MFRC522_REG_CONTROL, 0x80);
	// TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);
	// return MI_OK; // Đọc thành công
	// uint8_t keyA[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Key mặc định
	// uint8_t blockAddr = 8;									// Đọc block 8
	// uint8_t authData[12];
	// uint8_t backData[18];
	// uint16_t backLen;
	// TM_MFRC522_STS_T status;

	// // Ghép dữ liệu xác thực
	// authData[0] = PICC_AUTHENT_A; // Hoặc PICC_AUTHENT_B nếu dùng Key B
	// authData[1] = blockAddr;
	// memcpy(&authData[2], keyA, 6);
	// memcpy(&authData[8], ID + 0, 4); // UID từ 4 byte cuối

	// // Thực hiện xác thực
	// status = TM_MFRC522_ToCard(PCD_AUTHENT, authData, 12, NULL, 0);
	// if (status != MI_OK)
	// {
	// 	printk("Authen failed\n");
	// 	return status;
	// }

	// // Đọc dữ liệu từ block
	// uint8_t readCmd[2] = {PICC_READ, blockAddr};
	// status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, readCmd, 2, backData, &backLen);
	// if (status == MI_OK && backLen == 16 * 8)
	// {
	// 	printk("Data read from block %d: ", blockAddr);
	// 	for (int i = 0; i < 16; i++)
	// 	{
	// 		printk("%02X ", backData[i]);
	// 	}
	// 	printk("\n");
	// }
	// else
	// {
	// 	printk("Read failed\n");
	// }
}

TM_MFRC522_STS_T TM_MFRC522_WriteData(uint8_t cmd, uint8_t *data, uint8_t length)
{
	uint8_t command = (cmd << 1) & 0x7E; // Lệnh ghi (bit 0 = 0)

	struct spi_buf txb[2];
	struct spi_buf_set tx_bufs;

	txb[0].buf = &command;
	txb[0].len = 1;
	txb[1].buf = data;
	txb[1].len = length;

	tx_bufs.buffers = txb;
	tx_bufs.count = 2;

	int ret = spi_write(spi_dev, &spi_cfg, &tx_bufs);
	if (ret != 0)
	{
		printk("SPI transfer failed with error: %d\n", ret);
	}

	uint8_t irq = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
	if (irq & 0x10) // Kiểm tra bit IdleIRq (0x10)
	{
		return MI_OK; // Authentication thành công
	}
	return MI_ERR; // Authentication thất bại
}

void TM_MFRC522_WrRegMulti(uint8_t reg, uint8_t *data, uint8_t len)
{
	uint8_t command = ((reg << 1) & 0x7E); // Lệnh ghi
	struct spi_buf_set tx_bufs;
	struct spi_buf txb[2];

	txb[0].buf = &command;
	txb[0].len = 1;
	txb[1].buf = data;
	txb[1].len = len;

	tx_bufs.buffers = txb;
	tx_bufs.count = 2;
	printf("==========>: ");
	for (int i = 0; i < len; i++)
	{
		printk("0x%02X ", data[i]);
	}
	printf("\n");
	int ret = spi_write(spi_dev, &spi_cfg, &tx_bufs);
	if (ret != 0)
	{
		printk("SPI write failed! Error: %d\n", ret);
	}
}

TM_MFRC522_STS_T TM_MFRC522_Read(uint8_t blockAddr, uint8_t *recvData)
{
	uint8_t cmd[2];
	uint16_t recvLen;
	TM_MFRC522_STS_T status;

	cmd[0] = 0x30;
	cmd[1] = blockAddr;

	status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, cmd, 2, recvData, &recvLen);

	if (status == MI_OK && recvLen == 16)
	{
		return MI_OK;
	}

	return MI_ERR; 
}
mfrc522.h
#include <zephyr/drivers/gpio.h>

#include <zephyr/drivers/SPi.h>
#include "mfrc522.h"

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led1)
uint8_t ID[5];
/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

TM_MFRC522_STS_T TM_MFRC522_ReadBlock(uint8_t blockAddr, uint8_t *buffer, uint16_t *bufferLen)
{
        TM_MFRC522_STS_T status;
        uint8_t cmd[2];

        cmd[0] = PICC_READ; // Lệnh đọc block (0x30)
        cmd[1] = 0;         // Địa chỉ block muốn đọc

        // Gửi lệnh đọc
        status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, cmd, 2, buffer, bufferLen);

        // Kiểm tra kết quả
        if (status != MI_OK)
        {
                printk("=========================Reading block %d failed!status %d \n", blockAddr, status);
                return MI_ERR;
        }

        printk("Read Block %d: ", blockAddr);
        for (int i = 0; i < 16; i++)
        {
                printk("%02X ", buffer[i]);
        }
        printk("\n");

        return MI_OK;
}

TM_MFRC522_STS_T TM_MFRC522_ReadUID(uint8_t *uid)
{
        uint8_t tagType[2];
        TM_MFRC522_STS_T status;

        // 🔹 Gửi yêu cầu kiểm tra thẻ
        status = MFRC522_Request(0x26, tagType); // 0x26 = REQA (0x52 nếu dùng WUPA)
        if (status != MI_OK)
        {
                return status;
        }

        // 🔹 Gửi lệnh Anti-Collision để lấy UID
        status = TM_MFRC522_Anticoll(uid);
        if (status != MI_OK)
        {
                return status;
        }

        // 🔹 Gửi lệnh Select thẻ
        // status = MFRC522_Authenticate(0x93, 0x00, NULL, uid); // Chỉ cần xác nhận UID
        // if (status != MI_OK)
        // {
        //         return status;
        // }

        return MI_OK;
}

#include "MFRC522.h"

uint8_t MFRC522_SelectTag(uint8_t *uid)
{
        uint8_t buffer[9]; // Buffer dữ liệu gửi đi
        uint16_t recvBits; // Số bit nhận được
        uint8_t status;
        uint8_t i;
        uint8_t sak; // Select Acknowledge (SAK)

        // Gửi lệnh SELECT với mã thẻ (0x93 cho MIFARE 1K)
        buffer[0] = PICC_SElECTTAG;
        buffer[1] = 0x70; // Byte chỉ định mức SELECT
        for (i = 0; i < 5; i++)
        {
                buffer[i + 2] = uid[i]; // Copy UID vào buffer
        }

        // Tính CRC-A (bắt buộc để xác thực)
        TM_MFRC522_CalculateCRC(buffer, 7, &buffer[7]);

        // Gửi lệnh SELECT qua giao tiếp với thẻ
        status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);

        // Kiểm tra phản hồi từ thẻ
        if ((status == MI_OK) && (recvBits == 24))
        {
                sak = buffer[0]; // Lưu Select Acknowledge (SAK)
                return sak;
        }

        return 0; // Lỗi hoặc thẻ không phản hồi đúng
}

int main(void)
{
        int ret;
        SPI_Init();
        TM_MFRC522_Init();
        if (!gpio_is_ready_dt(&led))
        {
                return 0;
        }

        ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
        if (ret < 0)
        {
                return 0;
        }
        uint8_t version = TM_MFRC522_RdReg(MFRC522_REG_VERSION);
        printk("MFRC522 Version: 0x%X\n", version);
        // uint8_t buffer[16];
        // uint8_t len;
        // uint8_t status = TM_MFRC522_ReadBlock(7, buffer, &len);

        // if (status == MI_OK)
        // {
        //         printk("Sector Trailer (Block 7): ");
        //         for (int i = 0; i < 16; i++)
        //         {
        //                 printk("%02X ", buffer[i]);
        //         }
        //         printk("\n");
        // }
        // while (1)
        // {
        //         uint8_t keyA[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Key A mặc định
        //         uint8_t keyB[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Key B mặc định

        //         // Xác thực với Key A
        //         printk("Authentication Start\n");
        //         TM_MFRC522_STS_T status = TM_MFRC522_Auth(PICC_AUTHENT1A, 4, keyA, ID);
        //         if (status != MI_OK)
        //         {
        //                 printk("Authentication failed with Key A!\n");
        //                 // return MI_ERR;
        //         }
        //         printk("Authentication successful with Key A!\n");

        //         // Sau khi xác thực thành công, bạn có thể tiếp tục đọc Block 7
        //         uint8_t buffer[16];
        //         uint16_t len;
        //         printk("Read data on block Start\n");
        //         status = TM_MFRC522_ReadBlock(0, buffer, &len);
        //         if (status == MI_OK)
        //         {
        //                 printk("Block 0 data: ");
        //                 for (int i = 0; i < 16; i++)
        //                 {
        //                         printk("%02X ", buffer[i]);
        //                 }
        //                 printk("\n");
        //         }
        //         printk("End Read\n");
        //         k_sleep(K_MSEC(1000));
        // }
        if (TM_MFRC522_ReadUID(ID) == MI_ERR)
                printk("UID-1: %02X-%02X-%02X-%02X-%02X\r\n", ID[0], ID[1], ID[2], ID[3], ID[4]);
        if (TM_MFRC522_ReadUID(ID) == MI_ERR)
                printk("UID-2: %02X-%02X-%02X-%02X-%02X\r\n", ID[0], ID[1], ID[2], ID[3], ID[4]);
        if (TM_MFRC522_ReadUID(ID) == MI_ERR)
                printk("UID-3: %02X-%02X-%02X-%02X-%02X\r\n", ID[0], ID[1], ID[2], ID[3], ID[4]);
        uint8_t key[4][6] = {
            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // Key 0: FF FF FF FF FF FF (Mặc định)
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Key 1: 00 00 00 00 00 00
            {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7}, // Key 2: D3 F7 D3 F7 D3 F7
            {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}  // Key 3: A0 A1 A2 A3 A4 A5
        };

        // uint8_t uid[4] = {0xF3, 0x50, 0xBA, 0x02}; // UID của thẻ (cần lấy từ bước đọc UID)
        uint8_t block_addr = 4;                   // Block cần xác thực
        uint8_t type_tag[2] = {0};
        while (1)
        {
                k_sleep(K_MSEC(1000));
                TM_MFRC522_Halt();
                printk("=================================== MFRC522_Request\n");
                if (MFRC522_Request(0x26, type_tag) != MI_OK)
                {
                        printk("ERROR: MFRC522_Request failed! No card detected.\n");
                        continue;
                }
                printk("Card detected! Type: 0x%X 0x%X\n", type_tag[0], type_tag[1]);

                printk("=================================== TM_MFRC522_Anticoll\n");
                if (TM_MFRC522_Anticoll(ID) != MI_OK)
                {
                        printk("ERROR: TM_MFRC522_Anticoll failed! Unable to get UID.\n");
                        continue;
                }
                printk("Card UID: %02X %02X %02X %02X\n", ID[0], ID[1], ID[2], ID[3]);
                TM_MFRC522_Halt();

                k_sleep(K_MSEC(500));
                printk("=================================== MFRC522_SelectTag\n");
                uint8_t sak = MFRC522_SelectTag(ID);
                if (sak == 0)
                {
                        printk("ERROR: MFRC522_SelectTag failed! No response from card.\n");
                        continue;
                }
                printk("Card SAK: 0x%X\n", sak);
                TM_MFRC522_Halt();
                k_sleep(K_MSEC(500));
                int auth_status = MFRC522_Authenticate(PICC_AUTHENT1A, block_addr, key[0], ID);
                while (auth_status != MI_OK)
                {
                        if (TM_MFRC522_ReadUID(ID) == MI_ERR)
                                printk("UID-3: %02X-%02X-%02X-%02X-%02X\r\n", ID[0], ID[1], ID[2], ID[3], ID[4]);
                        printk("Retrying Authentication...\n");
                        TM_MFRC522_AntennaOn();
                        k_sleep(K_MSEC(1000));
                        printk("=================================== MFRC522_Authenticate\n");
                        auth_status = MFRC522_Authenticate(PICC_AUTHENT1A, block_addr, key[0], ID);
                        if(auth_status == MI_OK)
                        {
                                printk("========================== MFRC522_Authenticate Fail\n");
                        }
                        TM_MFRC522_AntennaOff();
                        k_sleep(K_MSEC(1000));
                        TM_MFRC522_AntennaOn();
                        uint8_t buffer[16];
                        uint16_t len;
                        printk("Read data onblock\n");
                        uint8_t status = TM_MFRC522_ReadBlock(block_addr, buffer, &len);
                }
                return 0;
        }
}

Hello everyone,

I am currently facing an issue when trying to read data from a block of a Mifare 1K card. After debugging, I found that my program fails to authenticate the sector of the block. Has anyone encountered this issue before?
Enviroment: nrf connect Desktop, nRF Connect SDK Toolchain v2.9.0
Lib MFRC522: mfrc5222_lib

TM_MFRC522_STS_T TM_MFRC522_Read(uint8_t blockAddr, uint8_t *recvData)
{
	uint8_t cmd[2];
	uint16_t recvLen;
	TM_MFRC522_STS_T status;

	cmd[0] = 0x30;
	cmd[1] = blockAddr;

	status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, cmd, 2, recvData, &recvLen);

	if (status == MI_OK && recvLen == 16)
	{
		return MI_OK;
	}

	return MI_ERR; 
}

Parents Reply Children
No Data
Related