cancel
Showing results for 
Search instead for 
Did you mean: 

Using X-CUBE-NFC3 with STM32L475 custom board and SPI2 instead of SPI1

NFerr.1
Associate II

For my first foray into the STM32 world I've been trying to get to read nfc tags with a STM32L475 and ST25R95 custom board. It is taking me a while to get used to the CUBE IDE, since including libraries many times results in errors, specially since I'm coming from the Arduino IDE.

As the title says I'm trying to adapt the included polling example(for the L476 board) to work with a custom board based on the STM32L475. I'm using the SPI2 port which I have inited in the main code, (pins PB12-PB15). I have made the changes in platform.h and st25r95_com.h to change hspi1 to hspi2. But still I always get initialization failed... any more places I should be changing SPI1 to SPI2?

Thank you for your time.

1 ACCEPTED SOLUTION

Accepted Solutions

Hi,

Command >>>> 02*********** is a protocol Select. It used to configure ISO14443-A or B or Felica or ISO15693 protocols. it returns 0000 to inform that the command has been applied

Command >>>> 09******** is a write register. it returns 0000 to inform that the register value has been updated

Command >>>> 08******** is a read register. it returns 0001 + value of the register

st25r95ReadReg: retCode: 00 or st25r95WriteReg: retCode: 00 are log for read or write register API. Therefore "retCode: 00" for those API just informs that the communication between the MCU and the ST25R95 is ok.

The data exchanges with the tag are logged as:

DATA >>>> 260100

DATA <<<<(0x8700)  (retCode=4)

As long as the respCode for data exchanges is different from 0x80 or 0x90 (e.g. 0x87), nothing has been received properly from the tag. In that case, it is likely an antenna 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.

View solution in original post

20 REPLIES 20
Brian TIDAL
ST Employee

Hi,

to select SPI mode on ST25R95, make sure to have:

  • SSI_0 --> High
  • SSi_1--> Low

Also, make sure to have nIRQ_IN and nIRQ_OUT connected. On the Nucleo-L476RG

  • nIRQ_IN is connected to PA9 (GPIO mode: Output push pull, init output: low)
  • nIRQ_OUT is connected to PA10 (GPIO mode: Input mode)

Regarding the SPI2, make sure to have:

  • Mode: Full Duplex Master
  • HW NSS signal disable
  • Basic param: 8bits Moto MSB first
  • NSS Signal type: software
  • clock:
    • CPOL Low, CPHA 1Edge,
    • frequency must be below 2 MHz (set the prescaler accordingly)
  • NSS:
    • I guess NSS is connected on PB12: it must be configured in GPIO_Output (not in SPI2_NSS). GPIO Mode: Output push pull, Init output: High

In platform.h, make sure to have:

#define platformSpiTxRx(txBuf, rxBuf, len)      HAL_SPI_TransmitReceive((&hspi2), (txBuf), (rxBuf), (len), 1000)  /*!< SPI transceive               */

extern SPI_HandleTypeDef hspi2;

Also, check that the ST25R95 is properly powered.

If you still have some initialization issue,

  • can you probe SSI_0, SSI_1, IRQ_IN, IRQ_OUT, SPI2_CLK/MOSI/MISO, nSS_SPI with a logic analyzer and send me the trace

Thanks

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.
NFerr.1
Associate II

First of all I'd like to thank you very much for your time Brian.

The SPI mode is correctly picked, since we've hooked SSI_0 to VCC and SSI_1 to GND. SO that's a check.

About IRQ_IN and OUT, they are currently not connected to the MCU, so I guess that's where the problem arises, since they are needed for SPI communication?

Regarding the SPI2, this is how we are currently initializing it:

hspi2.Instance = SPI2;

hspi2.Init.Mode = SPI_MODE_MASTER;

hspi2.Init.Direction = SPI_DIRECTION_2LINES;

hspi2.Init.DataSize = SPI_DATASIZE_8BIT;

hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi2.Init.NSS = SPI_NSS_SOFT;

hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;

hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi2.Init.CRCPolynomial = 7;

hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

and

 __HAL_RCC_SPI2_CLK_ENABLE();

//INSIDE HAL_SPI_MspInit

GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

//NSS Declaration

GPIO_InitStruct.Pin = nSPI_SS_Pin; //PIN 12

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(nSPI_SS_GPIO_Port, &GPIO_InitStruct); //nSPI_SS_GPIO is declared to GPIOB

So I think that is correctly setup.

On platform.h

#define ST25R95_INTERFACE_SPI

and

#define platformSpiTxRx(txBuf, rxBuf, len)      HAL_SPI_TransmitReceive((&hspi2), (txBuf), (rxBuf), (len), 1000)  /*!< SPI transceive               */

and

#if !(ST25R95_INTERFACE_UART) /* ST25R95_INTERFACE_SPI */

extern SPI_HandleTypeDef hspi2;

#else /* !ST25R95_INTERFACE_SPI */

extern UART_HandleTypeDef huart1;

#endif /* ST25R95_INTERFACE_SPI */

Thank you once again for your time!

Brian TIDAL
ST Employee

Hi,

nIRQ_IN is needed for the startup sequence as described in ST25R95 Datasheet § 3.2 Startup sequence. nIRQ_OUT is needed to detect when the ST25R95 is ready to send an answer to any command.

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.
NFerr.1
Associate II

Hello,

I'll go see if that fixes the problem, I'll get back with more info soon.

Thank you once again.

With the soldered IRQ_OUT and IRQ_IN the initialization succeeds! It cannot detect tags yet but I think it might be due an incorrect antenna design from our PCB makers. The Output stays in :

Intialization Succeeded

1. Tap a tag to read its contents

2. Present a tag to read its contents.

I think it is detecting the tags since the serial monitor indicator stops flashing when I scan a card and then it starts flashing again after some time.

Thank you very much!

Hi

you can turn #define ST25R95_DEBUG to true instead of false in .\Drivers\BSP\Components\ST25R95\st25r95_com.c and .\Drivers\BSP\Components\ST25R95\st25r95_com_spi.c

You will see the protocol commands sent over SPI, in particular the SendReceive command.

For example:

DATA >>>> 260100 //Example of Inventory command

DATA <<<<(0x8700)  (retCode=4) //ST25R95 return 0x8700 = Frame wait time out (no valid reception) 

DATA >>>> 260100 //Example of Inventory command

DATA <<<<(0x800D) 000064147D2D002302E0C2A8 00 (retCode=0) //ST25R95 returns the Inventory response received from the tag

If a 0x87 respCode is received, this means either no tag in the field or no answer properly received.

Feel free to share the log.

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,

Like you said, after turning on the DEBUG options, I have a mix of some retCode =4 and some retCode = 0.

Small sample below

[  261772] Set FWT=67800000 (protocol=1)

[  261778] DATA >>>> 260100

[  261802] DATA <<<<(0x8700)  (retCode=4)

[  261806] >>>> 0903680001

[  261809] <<<< 0000

[  261811] >>>> 0803690100

[  261814] <<<< 000153

st25r95ReadReg: retCode: 00

[  261819] >>>> 090468010133

[  261822] <<<< 0000

st25r95WriteReg: retCode: 00

[  261827] >>>> 0903680001

[  261830] <<<< 0000

[  261832] >>>> 0803690100

[  261835] <<<< 000133

st25r95ReadReg: retCode: 00

[  261840] >>>> 090468010130

[  261843] <<<< 0000

st25r95WriteReg: retCode: 00

[  261847] >>>> 02050301000070

[  261851] <<<< 0000

[  261853] >>>> 090468010130

[  261856] <<<< 0000

[  261858] Set FWT=4205 (protocol=3)

[  261862] >>>> 02050301000004

[  261865] <<<< 0000

[  261867] >>>> 090468010130

[  261870] <<<< 0000

[  261872] DATA >>>> 0600

[  261876] DATA <<<<(0x8700)  (retCode=4)

It seems the tag is not properly written from the amount of 0000 returned?

Thank you for the support once again.

Hi,

Command >>>> 02*********** is a protocol Select. It used to configure ISO14443-A or B or Felica or ISO15693 protocols. it returns 0000 to inform that the command has been applied

Command >>>> 09******** is a write register. it returns 0000 to inform that the register value has been updated

Command >>>> 08******** is a read register. it returns 0001 + value of the register

st25r95ReadReg: retCode: 00 or st25r95WriteReg: retCode: 00 are log for read or write register API. Therefore "retCode: 00" for those API just informs that the communication between the MCU and the ST25R95 is ok.

The data exchanges with the tag are logged as:

DATA >>>> 260100

DATA <<<<(0x8700)  (retCode=4)

As long as the respCode for data exchanges is different from 0x80 or 0x90 (e.g. 0x87), nothing has been received properly from the tag. In that case, it is likely an antenna 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.

Hello Brian,

Thank you for your time! I have got a X-NUCLEO-NFC03A1 expansion board now and I can sucessfully detect tags now! I'd like to use this board Wake Up from Event feature, so I would have my main STM32L475 chip sleeping (for low power consumption) and have the IRQ_OUT Pulse waking up my board.

My difficulty right now is to understand how I would set up the ST25R95HF in wake up MOde. I understand that the demoIni function puts the ST25R95HF in Ready Mode. Now I would have to put the NFC reader in Wait for Event with Tag Detector Mode. This would be done sending the command (>0x07 0E 02 21 00 38 01 18 00 20 60 60 64 74 3F 08) via SPI. But I see that there is some support for this in the rfal_nfc.c file .

I have also found something in the ndef demo which would be useful:

  err = rfalNfcInitialize();

  if( err == ERR_NONE )

  {

    discParam.compMode   = RFAL_COMPLIANCE_MODE_NFC;

    discParam.devLimit   = 1U;

    discParam.nfcfBR    = RFAL_BR_212;

    discParam.ap2pBR    = RFAL_BR_424;

    ST_MEMCPY( &discParam.nfcid3, NFCID3, sizeof(NFCID3) );

    ST_MEMCPY( &discParam.GB, GB, sizeof(GB) );

    discParam.GBLen     = sizeof(GB);

    discParam.notifyCb       = NULL;

    discParam.totalDuration    = 1000U;

    discParam.wakeupEnabled    = false;

    discParam.wakeupConfigDefault = true;

If I changed the wakeupEnabled to true, wakeupConfigDefault = false and provided a struct in the form of discParam.wakeupConfig = rfalWakeUpConfig(fill this struct in).

Would I have to change anything else?

MY main question is: would it be possible to adapt the X-Cube-NFC3 Demo to use the ST25R95HF in wakeup mode, or would I be better off doing a brand new code?

Thank you very much for your time,

Nuno