cancel
Showing results for 
Search instead for 
Did you mean: 

ST25R3916 - SPI issue

StefanoSperandio_ST
Associate III

Hello everyone,

I'm working with the NFC08A1 (ST25R3916) reader, and I'm encountering an issue with SPI communication when trying to read the ST25R3916 registers.

I’ve written a simple function to read a register, as shown below:

 

 

 

uint8_t Read_A_RegSpace(uint8_t reg)
{
uint8_t tx_frame = 0;
uint8_t rxData = 0;
HAL_StatusTypeDef status;

tx_frame = reg | 0x40;

SPI_CS_Select();
status = HAL_SPI_Transmit(&hspi1, &tx_frame, 1, HAL_MAX_DELAY);

if (status != HAL_OK) {
   UART1_WriteString("Errore nel Transmit!\r\n");
   return 0xFF;
 }

status = HAL_SPI_Receive(&hspi1, &rxData, 1, HAL_MAX_DELAY);

if (status != HAL_OK) {
   UART1_WriteString("Errore nel Receive!\r\n");
   return 0xFF;
 }

SPI_CS_Deselect();
UART1_WriteString("Value: ");
UART1_WriteHex(rxData);

return rxData;
}

 

where:

 

void UART1_WriteHex(uint8_t number)
{
   char buffer[256] = {0};
   sprintf(buffer,"0x%x\r\n", number);
   UART1_WriteString(buffer);
}

void SPI_CS_Select(void)
{
   HAL_GPIO_WritePin(ST25R_NSS_GPIO_Port, ST25R_NSS_Pin, GPIO_PIN_RESET);
}

void SPI_CS_Deselect(void)
{
   HAL_GPIO_WritePin(ST25R_NSS_GPIO_Port, ST25R_NSS_Pin, GPIO_PIN_SET);
}

 

 

Whenever I attempt to read different registers using this function, I receive the same value for all registers (0x31 or 0x98). I'm confident that the SPI initialization is correct, and the chip select logic seems fine.

Does anyone know what could be causing this issue? Are there any specific steps or initialization procedures required to enable the correct use of SPI with the ST25R3916?

Any help or suggestions would be greatly appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions

Hi Stefano,

SPI is inherently full-duplex. The TransmitReceive will require all bytes to be sent and return all received bytes.

The Transmit or Receive only functions are a bit unexpected as they either drop incoming bytes or send some dummy bytes.

BR, Ulysses

View solution in original post

5 REPLIES 5
Ulysses HERNIOSUS
ST Employee

Hi StefanoSperandio_ST,

 

sounds like you might be using wrong SPI mode? 

Should be CLKPolarity = SPI_POLARITY_LOW; and CLKPhase = SPI_PHASE_1EDGE;.

Please check that with your code you actually see 16 pules on SCL, typically we are using HAL_SPI_TransmitReceive() because SPI is actually full-duplex on physical layer.

BR, Ulysses

StefanoSperandio_ST
Associate III

Hello!

Following the SPI configuration that i'm using:

void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  SPI_AutonomousModeConfTypeDef HAL_SPI_AutonomousMode_Cfg_Struct = {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_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 0x7;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
  hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY;
  hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_SPI_AutonomousMode_Cfg_Struct.TriggerState = SPI_AUTO_MODE_DISABLE;
  HAL_SPI_AutonomousMode_Cfg_Struct.TriggerSelection = SPI_GRP1_GPDMA_CH0_TCF_TRG;
  HAL_SPI_AutonomousMode_Cfg_Struct.TriggerPolarity = SPI_TRIG_POLARITY_RISING;
  if (HAL_SPIEx_SetConfigAutonomousMode(&hspi1, &HAL_SPI_AutonomousMode_Cfg_Struct) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

The configuration appears to be as you suggested in your previous response.

However, I was thinking of trying the SPI_TransmitReceive() function instead of the separate Transmit and Receive calls that I'm currently using. Could you explain the differences between these two methods?

Additionally, what potential issues could arise from using Transmit()  followed by Receive() in my current code? Would it be better to use SPI_TransmitReceive() in this case?

Thanks in advance for your help!

 

Hi, 

sorry, my bad, should have been: CLKPhase = SPI_PHASE_2EDGE; and NSSPMode = SPI_NSS_PULSE_DISABLE

Please give it a try. If it does not help, then please look at the signals!

 

Ulysses

Hi!!

thank you for your reply. I've setted the SPI as you said in this reply but it doesn't work again...

Can you explain me how the TransmitReceive function works??

 

Thank you in advance.

Stefano

Hi Stefano,

SPI is inherently full-duplex. The TransmitReceive will require all bytes to be sent and return all received bytes.

The Transmit or Receive only functions are a bit unexpected as they either drop incoming bytes or send some dummy bytes.

BR, Ulysses