cancel
Showing results for 
Search instead for 
Did you mean: 

How can I connect STM32G071 board with ST25R3911B chip (X-NUCLEO-NFC05A1)?

EElec.2
Associate II

Hello there, STM32 community!

I am new to the STM32 family and I am currently working on a project to read and write Mifare Classic and Desfire tags. For this, I am using an STM32G071-NUCLEO64 microcontroller and a X-NUCLEO-NFC05A1 (ST25R3911B) board connected via SPI. I have been trying to establish the SPI connection between the two devices and send/receive data, but so far, I have not been successful.

Initially, I tried to use the SPI example provided in STM32CubeIDE, but I was not able to receive data correctly.

Then, I followed a post on the ST community website to use the RFAL/NDEF libraries for my project. However, the post was for the 32f070RB board, and I had to make some modifications to make it work with my hardware.

Unfortunately, after copying the RFAL and NDEF libraries into my project, modifying the platform.h file, and adding the necessary modules, I am still unable to get it working.

The error I am receiving is:

#define ERR_HW_MISMATCH ((ReturnCode)36U) /*!< expected hw do not match */

after executing rfalNfcInitialize().

I am feeling lost and unable to find a suitable example for my specific case.

Can someone please guide me on how to initialize the connection between the STM32G071 and the ST25R3911B chip?

What is the best way to receive data and work with it?

Thank you very much for your time and help!

1 ACCEPTED SOLUTION

Accepted Solutions
Kamil Duljas
Senior III

Hahah, It was good journey :D I think that manual of NFC board is customized for few boards with the same pins .e.q F401, L476 etc. .... and You on other board must check and correct eventually differences. For example:


_legacyfs_online_stmicro_images_0693W00000biwh9QAA.pngMCU_LED3 on dedicated boards is PB0, look on F401:


_legacyfs_online_stmicro_images_0693W00000biwhEQAQ.pngbut on G0xx you have PB1:


_legacyfs_online_stmicro_images_0693W00000biwhTQAQ.png 

I'm happy that works. Mark some answer as best please 🙂

Dudo

View solution in original post

45 REPLIES 45
Kamil Duljas
Senior III

Coud you share your code or some links to ST example?

Dudo

Hello, yea!

My main function in main.c is like this:

int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
 
  spiInit(&hspi1);			// Initialize driver
  logUsartInit(&huart1);	// Initialize log module
 
  platformLog("Welcome to X-NUCLEO-NFC05A1\r\n");
 
 
  /* Initalize RFAL */
  if( !demoIni() )
  {
    /*
    * in case the rfal initalization failed signal it by flashing all LED
    * and stoping all operations
    */
    platformLog("Initialization failed..\r\n");
    while(1)
    {
      platformLedToogle(PLATFORM_LEDG_PORT, PLATFORM_LEDG_PIN);
      platformDelay(100);
    }
  }
 
	platformLog("Initialization succeeded..\r\n");
	for (int i = 0; i < 6; i++)
	{
		platformLedToogle(PLATFORM_LEDG_PORT, PLATFORM_LEDG_PIN);
		platformDelay(200);
	}
 
	platformLedOff(PLATFORM_LEDG_PORT, PLATFORM_LEDG_PIN);
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	/* Run Demo Application */
	demoCycle();
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

and the rest of project it's almost an exact copy of the the one you can donwload here: https://www.st.com/en/embedded-software/x-cube-nfc5.html#get-software

And in the first question, I add a link in the words "post on the ST community website" but in case it is not working, the link to the post I followed is: https://community.st.com/s/question/0D53W000006G1H9SAK/how-to-start-with-st25r3911b-and-is-it-really-necessary-to-use-rfal-and-st25r3911-libraries-for-simpel-project

Thanks!

Kamil Duljas
Senior III

Probably some wrong in your modified code (platform.h). coud you share file? What files did you change ?

Dudo

Of course.

This is my platform.h. And the only files that I changed are the platform.h and the main.c.

You will see that there are "UNKOWN_PIN and UNKOWN_PORT" that's because I don't need those PORT-PINS and I assigned a random one...

OK, so show also main.c 🙂

Dudo

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"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "demo.h"
#include "platform.h"
#include "spi.h"
#include "usart.h"
#include "logger.h"
#include "COMPONENTS/st_errno.h"
#include "MIDDLEWARES/RFAL/rfal_nfc.h"
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
 
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
 
UART_HandleTypeDef huart1;
 
/* USER CODE BEGIN PV */
uint8_t globalCommProtectCnt = 0;
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
 
  spiInit(&hspi1);			// Initialize driver
  logUsartInit(&huart1);	// Initialize log module
 
  platformLog("Welcome to X-NUCLEO-NFC05A1\r\n");
 
 
  /* Initalize RFAL */
  if( !demoIni() )
  {
    /*
    * in case the rfal initalization failed signal it by flashing all LED
    * and stoping all operations
    */
    platformLog("Initialization failed..\r\n");
    while(1)
    {
      platformLedToogle(PLATFORM_LEDG_PORT, PLATFORM_LEDG_PIN);
      platformDelay(100);
    }
  }
 
	platformLog("Initialization succeeded..\r\n");
	for (int i = 0; i < 6; i++)
	{
		platformLedToogle(PLATFORM_LEDG_PORT, PLATFORM_LEDG_PIN);
		platformDelay(200);
	}
 
	platformLedOff(PLATFORM_LEDG_PORT, PLATFORM_LEDG_PIN);
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	/* Run Demo Application */
	demoCycle();
 
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  /** 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.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief SPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI1_Init(void)
{
 
  /* USER CODE BEGIN SPI1_Init 0 */
 
  /* USER CODE END SPI1_Init 0 */
 
  /* USER CODE BEGIN SPI1_Init 1 */
 
  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
 
  /* USER CODE END SPI1_Init 2 */
 
}
 
/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{
 
  /* USER CODE BEGIN USART1_Init 0 */
 
  /* USER CODE END USART1_Init 0 */
 
  /* USER CODE BEGIN USART1_Init 1 */
 
  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
 
  /* USER CODE END USART1_Init 2 */
 
}
 
/**
  * @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();
 
  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI4_15_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 .ioc file for port-pin info!

So if you modified only these two files, where is the initalization GPIO for SPI? B0 and B4?

Perhaps instead of changing platform.h you should changing main.h? I think main.h is more board specific than platform.h

Dudo

It makes sense...

So, I init them like this:

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_GPIOB_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_4, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : PC13 */
  GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  /*Configure GPIO pin : PB0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /*Configure GPIO pin : PB4 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
 
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

configured using the visual interface of STM32CubeIDE so I can't mess it up hahaha

But anyways, the error code is still the 36 (ERR_HW_MISMATCH) mentioned earlier...

Kamil Duljas
Senior III

Yours PB4 that repleace IRQ_3911_Pin is wrong:

/*Configure GPIO pin : PB4 */

GPIO_InitStruct.Pin = GPIO_PIN_4;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLDOWN;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pin : IRQ_3911_Pin */

 GPIO_InitStruct.Pin = IRQ_3911_Pin;

 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 HAL_GPIO_Init(IRQ_3911_GPIO_Port, &GPIO_InitStruct);

My advice. Undo all changes. Start from beginning and change only main.h:

```

/* Private define ------------------------------------------------------------*/

#define B1_Pin GPIO_PIN_13

#define B1_GPIO_Port GPIOC

#define IRQ_3911_Pin GPIO_PIN_0

#define IRQ_3911_GPIO_Port GPIOA

#define IRQ_3911_EXTI_IRQn EXTI0_IRQn

#define LED_F_Pin GPIO_PIN_1

#define LED_F_GPIO_Port GPIOA

#define LED_B_Pin GPIO_PIN_4

#define LED_B_GPIO_Port GPIOA

#define LED_A_Pin GPIO_PIN_0

#define LED_A_GPIO_Port GPIOB

#define LED_FIELD_Pin GPIO_PIN_8

#define LED_FIELD_GPIO_Port GPIOA

#define TMS_Pin GPIO_PIN_13

#define TMS_GPIO_Port GPIOA

#define TCK_Pin GPIO_PIN_14

#define TCK_GPIO_Port GPIOA

#define SWO_Pin GPIO_PIN_3

#define SWO_GPIO_Port GPIOB

#define LED_V_Pin GPIO_PIN_4

#define LED_V_GPIO_Port GPIOB

#define LED_AP2P_Pin GPIO_PIN_5

#define LED_AP2P_GPIO_Port GPIOB

#define SPI1_CS_Pin GPIO_PIN_6

#define SPI1_CS_GPIO_Port GPIOB

Dudo