cancel
Showing results for 
Search instead for 
Did you mean: 

R/W a Tag using ST25R3916

CT-55555
Senior

Hello everyone, 

I want to Read / Write a Tag using the X-Nucleo - NFC08A1. The demo project(polling) runs perfectly. I also installed X-Cube-NFC6. Which rfal libary is the best and how do I implement the function in the main.c.

 

Tnak you for helping

1 ACCEPTED SOLUTION

Accepted Solutions
Brian TIDAL
ST Employee

Hi,

basically, the demo provides an almost turnkey solution: after some initialization, the main() loops on MX_X_CUBE_NFC6_Process() that does the job to detect a tag and reads its unique ID. Then, when a type V tag has been discovered, the demoCycle calls demoNfcv where the user can add its own code  for his application.

demoNfcv provides a example of reading the block #1 of a type 5 tag with the function rfalNfcvPollerReadSingleBlock. You just need to modify the code in demoNfcv to read the various blocks required by your application with rfalNfcvPollerReadSingleBlock

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

15 REPLIES 15
Brian TIDAL
ST Employee

Hi,

I would suggest to reuse the demo project you have built and to base your application on top of it.

Rgds

BT

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello Brian, 

I tried you'r suggestion, but I'am not sure how to built the application on top of the base. 

I have a NFC-Tag type V and I want to use the function: static void demoNfcv(rfalNfcvListenDevice *nfcvDev). Which steps are needed to use this function ?

Rgds

 

Brian TIDAL
ST Employee

Simple: include your code in this function 🙂

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Sorry but I don't really get it. I'am new to STMCubeIde. Can you explain ist a little more specific. I got my main.c and the demo_polling.c. Which steps are needed to get this function running.

Thank you for you're help. 

Brian TIDAL
ST Employee

Hi,

When reading back https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/problem-to-connect-nucleo-nfc08a1-with-stm32f205vet6-via-spi/td-p/598247 and "The demo project(polling) runs perfectly." my understanding is that you've been able to generate the polling application from STM32CubeMX and been able to run it on your custom board.

Did I miss something?

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi, 

that is correct. I'm able to detect different types of NFC-Tag's with the demo polling.

Rgds

So if I put a Tag next to the reader the LED's show me which type of Tag is used. But now I want to read and write a Tag. 

Rgds

 

Hi,

 

demoNfcv() includes a example of how to read a given block. It also provide sample code to write a given block.

You just need to put your code (i.e. reading several blocks or writing a block) instead of the demo code inside demoNfcv.

Rgds

BT

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi, 

this is my main.c: 

/* USER CODE BEGIN Header */

/**

******************************************************************************

* @file : main.c

* @brief : Main program body

******************************************************************************

* @attention

*

* Copyright (c) 2023 STMicroelectronics.

* All rights reserved.

*

* This software is licensed under terms that can be found in the LICENSE file

* in the root directory of this software component.

* If no LICENSE file comes with this software, it is provided AS-IS.

*

******************************************************************************

*/

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "main.h"

#include "app_x-cube-nfcx.h"

 

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

 

int main(void)

{

 

HAL_Init();

 

SystemClock_Config();

 

 

MX_GPIO_Init();

MX_X_CUBE_NFC6_Init();

 

while (1)

{

/* USER CODE END WHILE */

 

MX_X_CUBE_NFC6_Process();

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

 

 

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 

/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

RCC_OscInitStruct.PLL.PLLM = 10;

RCC_OscInitStruct.PLL.PLLN = 200;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;

RCC_OscInitStruct.PLL.PLLQ = 4;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

{

Error_Handler();

}

}

 

/**

* @brief GPIO Initialization Function

* @param None

* @retval None

*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

 

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4

|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);

 

/*Configure GPIO pin : PA4 */

GPIO_InitStruct.Pin = GPIO_PIN_4;

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

/*Configure GPIO pins : PD0 PD2 PD3 PD4

PD5 PD6 PD7 */

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4

|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

 

/* EXTI interrupt init*/

HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI4_IRQn);

 

HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

 

/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}

 

/* USER CODE BEGIN 4 */

 

/* USER CODE END 4 */

 

/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

}

/* USER CODE END Error_Handler_Debug */

}

 

#ifdef USE_FULL_ASSERT

/**

* @brief Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* @param file: pointer to the source file name

* @param line: assert_param error line source number

* @retval None

*/

void assert_failed(uint8_t *file, uint32_t line)

{

/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* USER CODE END 6 */

}

#endif /* USE_FULL_ASSERT */

 

 

 

And the function I want to use is located in demo_polling.c.The function in demo_polling.c look like that:

 

 

 

 

 

static void demoNfcv( rfalNfcvListenDevice *nfcvDev )

{

#if RFAL_FEATURE_NFCV

 

ReturnCode err;

uint16_t rcvLen;

uint8_t blockNum = 1;

uint8_t rxBuf[ 1 + DEMO_NFCV_BLOCK_LEN + RFAL_CRC_LEN ]; /* Flags + Block Data + CRC */

uint8_t *uid;

uint8_t reqFlag;

#if DEMO_NFCV_WRITE_TAG

uint8_t wrData[DEMO_NFCV_BLOCK_LEN] = { 0x11, 0x22, 0x33, 0x99 }; /* Write block example */

#endif /* DEMO_NFCV_WRITE_TAG */

 

uid = nfcvDev->InvRes.UID;

reqFlag = RFAL_NFCV_REQ_FLAG_DEFAULT;

 

#if DEMO_NFCV_USE_SELECT_MODE

/*

* Activate selected state

*/

err = rfalNfcvPollerSelect( reqFlag, nfcvDev->InvRes.UID );

platformLog(" Select %s \r\n", (err != RFAL_ERR_NONE) ? "FAIL (revert to addressed mode)": "OK" );

if( err == RFAL_ERR_NONE )

{

reqFlag = (RFAL_NFCV_REQ_FLAG_DEFAULT | RFAL_NFCV_REQ_FLAG_SELECT);

uid = NULL;

}

#endif /* DEMO_NFCV_USE_SELECT_MODE */

 

/*

* Read block using Read Single Block command

* with addressed mode (uid != NULL) or selected mode (uid == NULL)

*/

err = rfalNfcvPollerReadSingleBlock(reqFlag, uid, blockNum, rxBuf, sizeof(rxBuf), &rcvLen);

platformLog(" Read Block: %s %s\r\n", (err != RFAL_ERR_NONE) ? "FAIL": "OK Data:", (err != RFAL_ERR_NONE) ? "" : hex2Str( &rxBuf[1], DEMO_NFCV_BLOCK_LEN));

 

#if DEMO_NFCV_WRITE_TAG /* Writing example */

err = rfalNfcvPollerWriteSingleBlock(reqFlag, uid, blockNum, wrData, sizeof(wrData));

platformLog(" Write Block: %s Data: %s\r\n", (err != RFAL_ERR_NONE) ? "FAIL": "OK", hex2Str( wrData, DEMO_NFCV_BLOCK_LEN) );

err = rfalNfcvPollerReadSingleBlock(reqFlag, uid, blockNum, rxBuf, sizeof(rxBuf), &rcvLen);

platformLog(" Read Block: %s %s\r\n", (err != RFAL_ERR_NONE) ? "FAIL": "OK Data:", (err != RFAL_ERR_NONE) ? "" : hex2Str( &rxBuf[1], DEMO_NFCV_BLOCK_LEN));

#endif /* DEMO_NFCV_WRITE_TAG */

 

#endif /* RFAL_FEATURE_NFCV */

}

 

 Sorry for the hard time but can you show me hw to do that.