I use the nfc chip of clrc66303 through spi communication, direct register operation, Error loading

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I use the nfc chip of clrc66303 through spi communication, direct register operation, Error loading

Jump to solution
3,262 Views
a751116023
Contributor I

STM32F103C8T6+CLRC66303HN chip is used, spi1 is used for communication. The source code is attached, using the Anticollision register layer for CLRC663.zip library.

a751116023_0-1744099937362.png

 

0 Kudos
Reply
1 Solution
3,208 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @a751116023 

报错协议没加载成功,这个时候RF就被关掉了,所以您看不到13.56MHz的RF信号。建议您先排查下SPI通讯,确保MCU和CLRC663之间的通讯是正确的,通常情况下,SPI驱动没问题,当前的代码是完全可以工作的。

View solution in original post

0 Kudos
Reply
8 Replies
3,235 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @a751116023 

不同协议的卡应答有所不同,NXP原有的例程是基于 Tpye 2标签写的。您的工程读的是什么类型的卡?又出现了什么错误呢?或者是在哪一步报错的呢?

0 Kudos
Reply
3,224 Views
a751116023
Contributor I

非debug模式,是在这里报错的,Error loading Protocol ErrorCode: 0x15

	/*-------------------------------------------- SET UP RC663	-----------------------------------------------------------------*/

	/* writeRegister(Address, Value)
	 * writeRegister writes a value into a Register.
	 *
	 * The CommandReg (0x00) is used to control the state machine in the RC663, which is able to execute certain commands.
	 * Command 0x00 cancels previous execution and the state machine returns into Idle mode. */
	writeRegister(0x00, 0x00);
	/* The FIFOControlReg (0x02) defines the characteristics of the FIFO. Depending on, whether bits are set or not, the FIFO
	 * characteristics can be changed.
	 * The value 0xB0 (1011 0000) translates to: FIFO size is 255 bytes
	 * 											 High Alert deactivated
	 * 											 Low Alert activated (LoAlert =1 if FIFOLength <= WaterLevel)
	 * 											 Flush the FIFO*/
	writeRegister(0x02, 0xB0);

	/* Command 0xF1 is performing a soft Reset. Triggered by this command all the default values for the register setting
	 * will be read from the EEPROM and copied into the register set.*/
	writeRegister(0x00, 0xF1);

	/*--------------------------------------------------------------------------------------------------------------------------*/



	/*-------------------------------------------- LOAD PROTOCOL - ISO/IEC14443 A - 106	----------------------------------------*/

	/* Command 0x00 cancels previous execution and the state machine returns into Idle mode.*/
	writeRegister(0x00, 0x00);

	/* Flushes the FIFO and maintains old FIFO characteristics (detailed description at line 64)*/
	writeRegister(0x02, 0xB0);

	/* Register 0x05 is the FIFO and used to write into and read from FIFO.
	 * To load the Protocol ISO/IEC14443 A - 106 the FIFO has to be filled with 0x00 and 0x00 and then
	 * the Command 0x0D LoadProtocol has to be performed
	 *
	 * The RC663 has an EEPROM, where different Register Presets for different Protocols are saved.
	 * With the LoadProtocol command (0x0D) these presets can be load into the registers.
	 * */
	writeRegister(0x05, 0x00);
	writeRegister(0x05, 0x00);
	writeRegister(0x00, 0x0D);

	/* readRegister(Address, Buffer)
	 * ReadRegister reads a Register and writes its value into the Buffer.
	 *
	 * Register 0x0A is the ErrorRegister.
	 * The Value of the ErrorRegister should be 0x00 otherwise an Error occurred during the LoadProtocol command.*/
	readRegister(0x0A, &errorRegister);

	/* Checks if an Error has occurred*/
	if(errorRegister != 0) {
		/* turns on red status LED to notify the user that an Error has occurred*/
		HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_SET);
		DEBUG_PRINTF("Error loading Protocol \t ErrorCode: 0x%02X\n", errorRegister);
		/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
		 * Value 0x8E switches the RF field OFF */
		writeRegister(0x28, 0x86);
		HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_RESET);
		return 1;
	}

, 

0 Kudos
Reply
3,209 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @a751116023 

报错协议没加载成功,这个时候RF就被关掉了,所以您看不到13.56MHz的RF信号。建议您先排查下SPI通讯,确保MCU和CLRC663之间的通讯是正确的,通常情况下,SPI驱动没问题,当前的代码是完全可以工作的。

0 Kudos
Reply
3,173 Views
a751116023
Contributor I

修改CLRC663的供电系统后,目前协议不报错了,也正常输出13.56MHz的RF信号了。

我目前改为15693协议读取 I CODE SLIX2的卡,一直读取不到卡,IRQ0的值一直是0x28  是什么原因?

uint8_t waitForCardResponse() {
	uint8_t IRQ0[2] = {0x06,0x00};
	uint16_t counter = 0x00;

	/* Continuous Loop, which exits if the IRQ0 == 0x3c or IRQ0 == 0x03e or the counter is bigger than 1000
	 *
	 * Register 0x06 is the IRQ0 (Interrupt Register 0)
	 *
	 * When the Card has responded following bits will be set in IRQ0.
	 * The value 0x3c (0011 1100) translates to: FIFO data number has reached the bottom level as configured by the register WaterLevel
	 * 											 Command terminated by itself
	 * 											 Data transmission is completed
	 * 											 Receiver detects end of data stream
	 *
	 * The value 0x3e (0011 1110) translates to: same as 0x3c + An Error has occurred
	 *
	 * If the Card hasn't responded after 10000 loop cycles then exit the loop to prevent getting stuck in an infinite loop.
	 */
	while( IRQ0[1] != 0x3c && IRQ0[1] != 0x3e && counter < 10000) {
		IRQ0[0] = 0x06;
		IRQ0[1] = 0x00;
		readRegister(IRQ0,2);
		counter++;
	}
	return IRQ0[1]==0x3c;
}

 

0 Kudos
Reply
3,160 Views
KaiLi
NXP TechSupport
NXP TechSupport

Hello @a751116023 

标签应答的数据不在0x28,建议您检查

15: if(CardResponded())
{
16: readRegister(0x05, UID);
}

 

0 Kudos
Reply
3,175 Views
a751116023
Contributor I

之前芯片供电电压有问题,改正确之后。目前芯片正常工作,也能出信号了。但是IRQ0寄存器一直是0x28,读不到卡。会是什么原因?

/*
*         Copyright (c), NXP Semiconductors Gratkorn / Austria
*
*                     (C)NXP Semiconductors
*       All rights are reserved. Reproduction in whole or in part is
*      prohibited without the written consent of the copyright owner.
*  NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
* particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
*                          arising from its use.
*/

/** \file
* $Author: Vogtberg S $
* $Date: 25.09.2019$
*
*
*
* This Example shows how to communicate between LPC1769 and RC663 via SPI and
* which Register have to be set to send a Select Command and fetch a UID (Works with NTAG216)
*
*/

#include "typeDefs.h"
#include "main.h"

volatile uint16_t delay;
/*******************************************************************************
**   Function Declarations
*******************************************************************************/
uint8_t waitForCardResponse(void);
void writeRegister(uint8_t * txData,uint8_t len);
void readRegister(uint8_t * rxData,uint8_t len);

extern SPI_HandleTypeDef hspi1;
/*******************************************************************************
**   Main Function
*******************************************************************************/

void RC663_Init(void) {
	// 硬件复位
	HAL_GPIO_WritePin(CLRC663_RST_GPIO_Port, CLRC663_RST_Pin, GPIO_PIN_RESET);
	HAL_Delay(10);
	HAL_GPIO_WritePin(CLRC663_RST_GPIO_Port, CLRC663_RST_Pin, GPIO_PIN_SET);
	HAL_Delay(10);
	HAL_GPIO_WritePin(CLRC663_RST_GPIO_Port, CLRC663_RST_Pin, GPIO_PIN_RESET);
	HAL_Delay(10);
}

int runApp (void) {
	uint8_t counter;
	uint8_t txData[10]= {0};
	uint8_t errorRegister[2]= {0x0A,0x00};
	uint8_t UID[9] = {0x05};

	/* Initializes the LPC1769*/

	//DEBUG_PRINTF("Start \n");
	/*-------------------------------------------- SET UP RC663	-----------------------------------------------------------------*/

	/* writeRegister(Address, Value)
	 * writeRegister writes a value into a Register.
	 *
	 * The CommandReg (0x00) is used to control the state machine in the RC663, which is able to execute certain commands.
	 * Command 0x00 cancels previous execution and the state machine returns into Idle mode. */
	writeRegister(txData,2);
	/* The FIFOControlReg (0x02) defines the characteristics of the FIFO. Depending on, whether bits are set or not, the FIFO
	 * characteristics can be changed.
	 * The value 0xB0 (1011 0000) translates to: FIFO size is 255 bytes
	 * 											 High Alert deactivated
	 * 											 Low Alert activated (LoAlert =1 if FIFOLength <= WaterLevel)
	 * 											 Flush the FIFO*/
	txData[0]=0x02;
	txData[1]=0xB0;
	writeRegister(txData,2);

	/* Command 0xF1 is performing a soft Reset. Triggered by this command all the default values for the register setting
	 * will be read from the EEPROM and copied into the register set.*/
	txData[0]=0x00;
	txData[1]=0xF1;
	writeRegister(txData,2);

	/*--------------------------------------------------------------------------------------------------------------------------*/



	/*-------------------------------------------- LOAD PROTOCOL - ISO/IEC15693 - 106	----------------------------------------*/

	/* Command 0x00 cancels previous execution and the state machine returns into Idle mode.*/
	txData[0]=0x00;
	txData[1]=0x00;
	writeRegister(txData,2);

	/* Flushes the FIFO and maintains old FIFO characteristics (detailed description at line 64)*/
	txData[0]=0x02;
	txData[1]=0xB0;
	writeRegister(txData,2);

	/* Register 0x05 is the FIFO and used to write into and read from FIFO.
	 * To load the Protocol ISO/IEC14443 A - 106 the FIFO has to be filled with 0x00 and 0x00 and then
	 * the Command 0x0D LoadProtocol has to be performed
	 *
	 * The RC663 has an EEPROM, where different Register Presets for different Protocols are saved.
	 * With the LoadProtocol command (0x0D) these presets can be load into the registers.
	 * */
	txData[0]=0x05;
	txData[1]=0x0A;
	txData[2]=0x0A;
	writeRegister(txData,3);

	txData[0]=0x00;
	txData[1]=0x0D;
	writeRegister(txData,2);

	/* readRegister(Address, Buffer)
	 * ReadRegister reads a Register and writes its value into the Buffer.
	 *
	 * Register 0x0A is the ErrorRegister.
	 * The Value of the ErrorRegister should be 0x00 otherwise an Error occurred during the LoadProtocol command.*/
	readRegister(errorRegister,2);

	/* Checks if an Error has occurred*/
	if(errorRegister[1] != 0) {
		/* turns on red status LED to notify the user that an Error has occurred*/
		HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_SET);
		DEBUG_PRINTF("Error loading Protocol \t ErrorCode: 0x%02X\n", errorRegister[1]);
		/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
		 * Value 0x8E switches the RF field OFF */
		txData[0]=0x28;
		txData[1]=0x86;
		writeRegister(txData,2);
		HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_RESET);
		return 1;
	}

	/*--------------------------------------------------------------------------------------------------------------------------*/



	/*-------------------------------------------- Send REQA -------------------------------------------------------------------*/

	/* Flushes the FIFO and maintains old FIFO characteristics (detailed description at line 62)*/
	txData[0]=0x02;
	txData[1]=0xB0;
	writeRegister(txData,2);

	/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
	 * Value 0x8E switches the RF field ON */
	txData[0]=0x28;
	txData[1]=0x8E;
	writeRegister(txData,2);

	HAL_GPIO_WritePin(LED_15693_GPIO_Port, LED_15693_Pin, GPIO_PIN_SET);

	txData[0]=0x05;
	txData[1]=0x01;
	txData[2]=0x94;
	txData[3]=0x28;
	txData[4]=0x12;
	writeRegister(txData,5);

	txData[0]=0x00;
	txData[1]=0x0C;
	writeRegister(txData,2);

	txData[0]=0x00;
	txData[1]=0x00;
	writeRegister(txData,2);

	txData[0]=0x02;
	txData[1]=0xB0;
	writeRegister(txData,2);

	txData[0]=0x06;
	txData[1]=0x7F;
	writeRegister(txData,2);

	txData[0]=0x05;
	txData[1]=0x06;
	txData[2]=0x01;
	txData[3]=0x00;
	writeRegister(txData,4);

	/* The value 0x07 written into the Command Register triggers the Transceive command
	 * This command transmits data from FIFO buffer and automatically activates the receiver after a transmission is finished.*/
	txData[0]=0x00;
	txData[1]=0x07;
	writeRegister(txData,2);

	/* Register 0x0A is the ErrorRegister.
	 * The Value of the ErrorRegister should be 0x00 otherwise an Error occurred during the LoadProtocol command.*/
	readRegister(errorRegister,2);

	/* Checks if an Error has occurred*/
	if(errorRegister[1] != 0) {
		/* turns on red status LED to notify the user that an Error has occurred*/
		HAL_GPIO_WritePin(LED_SYS_GPIO_Port,LED_SYS_Pin, GPIO_PIN_SET);
		DEBUG_PRINTF("Error transmitting REQA\t ErrorCode: 0x%02X\n", errorRegister[1]);
		/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
		 * Value 0x8E switches the RF field OFF */
		txData[0]=0x28;
		txData[1]=0x86;
		writeRegister(txData,2);
		HAL_GPIO_WritePin(LED_15693_GPIO_Port,LED_15693_Pin, GPIO_PIN_RESET);
	}

	/*--------------------------------------------------------------------------------------------------------------------------*/

	/*-------------------------------------------- Fetch ATQA -------------------------------------------------------------------*/

	/* Wait until the Card has responded*/
	for(counter=0; counter<16; counter++) {
		if(waitForCardResponse()) {
			readRegister(UID,9);

			/*Print the UID*/
			DEBUG_PRINTF("UID: ");

			for(int i = 0; i < 8; i++) {
				DEBUG_PRINTF("%02x ", UID[i+1]);
			}
			DEBUG_PRINTF("\n");
			txData[0]=0x33;
			txData[1]=0x0C;
			writeRegister(txData,2);
			txData[0]=0x2E;
			txData[1]=0x00;
			writeRegister(txData,2);
			txData[0]=0x02;
			txData[1]=0xB0;
			writeRegister(txData,2);
			txData[0]=0x00;
			txData[1]=0x07;
			writeRegister(txData,2);
		}
	}

	DEBUG_PRINTF("\nEND\n");
	txData[0]=0x28;
	txData[1]=0x86;
	writeRegister(txData,2);

	return 0;
}

void writeRegister(uint8_t * txData,uint8_t len) {
	/* 地址构造:左移1位 + 写操作位(0) */
	txData[0] = (txData[0] << 1) & 0xFE; // 写操作必须保证LSB=0
	SPI1_NSS_LOW();
	CHECK_SPI1_READY
	HAL_StatusTypeDef res=HAL_SPI_Transmit(&hspi1, txData,len, HAL_MAX_DELAY);
	//DEBUG_PRINTF("writeRegister \t address:0x%02X \t val:0x%02X \t res:0x%02X\n",txData[0],txData[1],res);
	CHECK_SPI1_READY
	SPI1_NSS_HIGH();
	//HAL_Delay(len); // 至少维持1us(根据CLRC663手册要求)
}

void readRegister(uint8_t * rxData,uint8_t len) {
	/* 地址构造:左移1位 + 读操作位(1) */
	uint8_t address=rxData[0];
	rxData[0] = ((address & 0x7F) << 1) | 0x01; // 确保地址不超7bit
	SPI1_NSS_LOW();
	CHECK_SPI1_READY
	HAL_StatusTypeDef res=HAL_SPI_TransmitReceive(&hspi1, rxData, rxData, len, HAL_MAX_DELAY);
	//DEBUG_PRINTF("readRegister \t address:0x%02X \t val:0x%02X \t res:0x%02X\n",rxData[0],rxData[1],res);
	CHECK_SPI1_READY
	SPI1_NSS_HIGH();
	//HAL_Delay(len); // 至少维持1us(根据CLRC663手册要求)
}

uint8_t waitForCardResponse() {
	uint8_t IRQ0[2] = {0x06,0x00};
	uint16_t counter = 0x00;

	/* Continuous Loop, which exits if the IRQ0 == 0x3c or IRQ0 == 0x03e or the counter is bigger than 1000
	 *
	 * Register 0x06 is the IRQ0 (Interrupt Register 0)
	 *
	 * When the Card has responded following bits will be set in IRQ0.
	 * The value 0x3c (0011 1100) translates to: FIFO data number has reached the bottom level as configured by the register WaterLevel
	 * 											 Command terminated by itself
	 * 											 Data transmission is completed
	 * 											 Receiver detects end of data stream
	 *
	 * The value 0x3e (0011 1110) translates to: same as 0x3c + An Error has occurred
	 *
	 * If the Card hasn't responded after 10000 loop cycles then exit the loop to prevent getting stuck in an infinite loop.
	 */
	while( IRQ0[1] != 0x3c && IRQ0[1] != 0x3e && counter < 10000) {
		IRQ0[0] = 0x06;
		IRQ0[1] = 0x00;
		readRegister(IRQ0,2);
		counter++;
	}
	return IRQ0[1]==0x3c;
}
/******************************************************************************
**                            End Of File
******************************************************************************/

 

0 Kudos
Reply
3,230 Views
a751116023
Contributor I

用的m1卡,debug时候,CLRC66303HN的错误寄存器不再报错,但是用频谱仪看不到13.56MHz的信号,但是27.12MHz的晶振正常起振

Tags (1)
0 Kudos
Reply
3,250 Views
a751116023
Contributor I

I use the nfc chip of clrc66303 through spi communication, direct register operation, Error loading Protocol ErrorCode: 0xFF has been reported

STM32F103C8T6+CLRC66303HN chip is used, spi1 is used for communication. The source code is attached, using the Anticollision register layer for CLRC663.zip library

0 Kudos
Reply