2024-10-21 06:19 AM
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!
Solved! Go to Solution.
2024-11-12 07:48 AM
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
2024-10-21 07:53 AM
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
2024-10-21 07:59 AM
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!
2024-10-21 08:14 AM
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
2024-10-25 07:56 AM
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
2024-11-12 07:48 AM
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