cancel
Showing results for 
Search instead for 
Did you mean: 

Nucleo NFC04 interrupt isn´t working

Kampi
Associate III

Hello,

I´m using an STM32 Nucleo G474RE and an X-NUCLEO-NFC04A1 and I want to use the interrupt function of the NFC board to detect a changing field, but the interrupt doesn´t get triggered by using this code (based on a example from ST):

#include "main.h"
#include "nfc04a1_nfctag.h"
 
const ST25DV_PASSWD st25dv_i2c_password = {.MsbPasswd = 0, .LsbPasswd = 0};
 
UART_HandleTypeDef hlpuart1;
ADC_HandleTypeDef hadc1;
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_LPUART1_UART_Init(void);
static void MX_ADC1_Init(void);
 
int main(void)
{
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();
 
	/* Configure the system clock */
	SystemClock_Config();
 
	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_LPUART1_UART_Init();
	MX_ADC1_Init();
	NFC04A1_LED_Init(GREEN_LED);
	NFC04A1_LED_Init(BLUE_LED);
	NFC04A1_LED_Init(YELLOW_LED);
	while(NFC04A1_NFCTAG_Init(NFC04A1_NFCTAG_INSTANCE) != NFCTAG_OK);
	NFC04A1_GPO_Init();
	NFC04A1_NFCTAG_PresentI2CPassword(NFC04A1_NFCTAG_INSTANCE, st25dv_i2c_password);
	NFC04A1_NFCTAG_ConfigIT(NFC04A1_NFCTAG_INSTANCE, ST25DV_GPO_ENABLE_MASK | ST25DV_GPO_FIELDCHANGE_MASK);
 
	while(1)
	{
	}
}
 
void BSP_GPO_Callback(void)
{
	NFC04A1_LED_On(GREEN_LED);
}
 
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};
	RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
	RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
	/** Configure the main internal regulator output voltage
	 */
	HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
 
	/** 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 = RCC_PLLM_DIV4;
	RCC_OscInitStruct.PLL.PLLN = 85;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
	RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
	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_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
	if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
	{
		Error_Handler();
	}
 
	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_I2C1;
	PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
	PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
	if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
	{
		Error_Handler();
	}
}
 
static void MX_ADC1_Init(void)
{
	ADC_MultiModeTypeDef multimode = {0};
	ADC_ChannelConfTypeDef sConfig = {0};
 
	hadc1.Instance = ADC1;
	hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
	hadc1.Init.Resolution = ADC_RESOLUTION_8B;
	hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	hadc1.Init.GainCompensation = 0;
	hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
	hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
	hadc1.Init.LowPowerAutoWait = DISABLE;
	hadc1.Init.ContinuousConvMode = DISABLE;
	hadc1.Init.NbrOfConversion = 1;
	hadc1.Init.DiscontinuousConvMode = DISABLE;
	hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
	hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
	hadc1.Init.DMAContinuousRequests = DISABLE;
	hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
	hadc1.Init.OversamplingMode = DISABLE;
 
	if(HAL_ADC_Init(&hadc1) != HAL_OK)
	{
		Error_Handler();
	}
 
	multimode.Mode = ADC_MODE_INDEPENDENT;
	if(HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
	{
		Error_Handler();
	}
 
	sConfig.Channel = ADC_CHANNEL_1;
	sConfig.Rank = ADC_REGULAR_RANK_1;
	sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
	sConfig.SingleDiff = ADC_SINGLE_ENDED;
	sConfig.OffsetNumber = ADC_OFFSET_NONE;
	sConfig.Offset = 0;
	if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
	{
		Error_Handler();
	}
}
 
static void MX_LPUART1_UART_Init(void)
{
	hlpuart1.Instance = LPUART1;
	hlpuart1.Init.BaudRate = 115200;
	hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
	hlpuart1.Init.StopBits = UART_STOPBITS_1;
	hlpuart1.Init.Parity = UART_PARITY_NONE;
	hlpuart1.Init.Mode = UART_MODE_TX_RX;
	hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
	hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 
	if(HAL_UART_Init(&hlpuart1) != HAL_OK)
	{
		Error_Handler();
	}
 
	if(HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
	{
		Error_Handler();
	}
 
	if(HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
	{
		Error_Handler();
	}
 
	if(HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
	{
		Error_Handler();
	}
}
 
static void MX_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
 
	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOF_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
 
	/* Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(GPIOA, LD2_Pin | GPIO_PIN_8 | GPIO_PIN_10, GPIO_PIN_RESET);
 
	/* Configure GPIO pin Output Level */
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_RESET);
 
	/* Configure GPIO pins : USART_TX_Pin USART_RX_Pin */
	GPIO_InitStruct.Pin = LPUART1_TX_Pin | LPUART1_RX_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	/* Configure GPIO pins : LD2_Pin PA8 PA10 */
	GPIO_InitStruct.Pin = LD2_Pin | GPIO_PIN_8 | GPIO_PIN_10;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	/* Configure GPIO pin : PA6 */
	GPIO_InitStruct.Pin = GPIO_PIN_6;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	/* Configure GPIO pins : PB4 PB5 */
	GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5;
	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);
 
	/* EXTI interrupt init */
	HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}
 
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 */
}

1 ACCEPTED SOLUTION

Accepted Solutions
Kampi
Associate III

Okay, my own question gives me the solution. I don´t have activated the "EXTI line[9:5] interrupts in CubeMX:

0693W00000AMhMiQAL.png 

The code works as expected after adding this option =)

View solution in original post

10 REPLIES 10
Brian TIDAL
ST Employee

Hi,

when the interrupt is raised, EXTI9_5_IRQHandler is called.

do you have  HAL_EXTI_IRQHandler(&H_EXTI_6) function being called in EXTI9_5_IRQHandler?

void EXTI9_5_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI9_5_IRQn 0 */
 
  /* USER CODE END EXTI9_5_IRQn 0 */
  HAL_EXTI_IRQHandler(&H_EXTI_6);
  /* USER CODE BEGIN EXTI9_5_IRQn 1 */
 
  /* USER CODE END EXTI9_5_IRQn 1 */
}

HAL_EXTI_IRQHandler calls the BSP_GPO_Callback (This callback is registered with HAL_EXTI_RegisterCallback in NFC04A1_GPO_Init()

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.
Kampi
Associate III

Hi @Brian TIDAL_O​ ,

I have set a breakpoint in `HAL_EXTI_IRQHandler`, debug the application and put my smartphone on the NFC reader. It seems that the IRQHandler isn´t called.

Best wishes

Brian TIDAL
ST Employee

Hi,

Android smartphones have a particular behavior : when the screen is locked, NFC polling is disabled. Make sure to have the screen unlocked (try to first read a tag with ST25 NFC Tap application to make sure the NFC polling is running)

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.
Kampi
Associate III

Hi,

I have tried it by reading the memory of the device. The reading was successful, but again no interrupt.

Brian TIDAL
ST Employee

Hi,

Can you also the I2C connectivity on the NUCLEO-G474RE in particular Solder Bridges SB34/SB35 if using I2C1 PB8 and PB9 pins (see UM2505 for board configuration)?

Can you also try to use the original source code from STM32CubeExpansion_NFC4_V2.0.2\Projects\STM32L476RG-Nucleo\Examples\GPO?

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.
Kampi
Associate III

Hi,

the example is working. The green LED is enabled after I put my smartphone in the range of the antenna.

Brian TIDAL
ST Employee

Hi,

HW is OK and example code is working, so, you are very close now. Let us know the issue.

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.
Kampi
Associate III

Do I have to enable the interrupts over a function call or how do they get activated?

Brian TIDAL
ST Employee

Hi,

if using STM32CubeMX, go to NVIC tab and check the Enabled box for EXTI line 5-9:

0693W00000AMhHJQA1.png 

This should add HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); in the MX_GPIO_Init.

if you want to check, remove the shield and its initialisation code, set a breakpoint in the EXTI9_5_IRQHandler, set a wire between PA6 and GND, run and then connect PA6 to 3V3 this should force a rising interrupt and stop the debugger in the EXTI9_5_IRQHandler.

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.