Skip to main content
Associate III
July 16, 2024
Question

SPI Loopback test on stm32h563zit6

  • July 16, 2024
  • 3 replies
  • 3281 views

HI, STM Experts,

                Using STM32CubeIDE, I configured a project with default settings for the STM32H563ZIT6 (8 MHz external clock), running at 250 MHz. Additionally, I've enabled SPI1 for full duplex communication (transmitting and receiving simultaneously), with a data size of 8 bits, clock polarity (clk pol) = 0, clock phase (clk ph) = 1, and set the prescaler to 2, resulting in a baud rate of 125.0 Mbits/s. It's usually possible to wire MOSI to MISO. However, when I try to receive data from SPI1, it doesn't work. I don't know where I made a mistake. Could anyone please support me?

uint8_t tx_buffer[] = { 'H', 'e', 'l', 'l', 'o', '\r', '\n' };
uint8_t rx_buffer[20];

while (1)
 {
	 //HAL_UART_Transmit(&huart7, tx_buffer, sizeof(tx_buffer), 100);
 HAL_Delay(1000);
 for (int i = 0; i < sizeof(tx_buffer); i++)
 {
 HAL_SPI_TransmitReceive(&hspi1, tx_buffer + i, rx_buffer, 1, 100);
 HAL_UART_Transmit(&huart7, rx_buffer, sizeof(rx_buffer), 100);
 HAL_Delay(200);
 }
 }
static void MX_SPI1_Init(void)
{
 /* 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_2;
 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();
 }
}

3 replies

Associate III
July 16, 2024

sorry for my post its working good but i have an doubt

i am testing loop back test on spi1 on stm32h563zit6 microcontroller

hardware connection:

spi1:

mosi---------->miso

 

uint8_t tx_buffer[] = { 'H', 'e', 'l', 'l', 'o', '\r', '\n' };
uint8_t rx_buffer[20];
while (1)
{
     HAL_Delay(1000);
       HAL_SPI_TransmitReceive(&hspi1, tx_buffer , rx_buffer, sizeof(tx_buffer), 100);
       HAL_UART_Transmit(&huart7, rx_buffer, sizeof(rx_buffer), 100);
       HAL_Delay(200);
     }
   }

Whenever I use the HAL_SPI_TransmitReceive function, it works well. However, when I try to use HAL_SPI_Transmit and HAL_SPI_Receive  functions instead of HAL_SPI_TransmitReceive , it doesn't work. What could be the problem? How can I make it work?

 

while (1)

{

HAL_Delay(1000);

HAL_SPI_Transmit(&hspi1, tx_buffer, sizeof(tx_buffer), 100);

HAL_SPI_Receive(&hspi1, rx_buffer, sizeof(rx_buffer), 100);

HAL_UART_Transmit(&huart7, rx_buffer, sizeof(rx_buffer), 100);

HAL_Delay(200);

}

}

Mike_ST
Technical Moderator
July 16, 2024

Hello,

When you're calling HAL_SPI_Transmit(), the chip is not ready to receive anything, so it is transmitting in the void.

and when you're calling HAL_SPI_Receive(), nobody is sending anything, so time out occurs.

So, maybe call  HAL_SPI_Receive_IT (and prepare the SPI ISR) before transmitting so the chip is ready to receive the data.

 

Associate III
July 16, 2024

thank you @Mike_ST  any reference?

TDK
Super User
July 16, 2024
"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate III
July 16, 2024

@Mike_ST any reference code?

Associate II
July 16, 2024

I mean... people already gave you almost everything above.
As discussed in the topic shared by @TDK, the solution is the same.
Modify your CubeMX project to enable SPI interrupts.
Then run something like this:

bool rx_compltet = false;

int main(void)
{
 uint8_t tx_buffer[] = { 'H', 'e', 'l', 'l', 'o', '\r', '\n' };
 uint8_t rx_buffer[20];
 while (1)
 {
 HAL_Delay(1000);

 HAL_SPI_Receive_IT(&hspi1, rx_buffer, sizeof(rx_buffer), 100);

 HAL_SPI_Transmit(&hspi1, tx_buffer, sizeof(tx_buffer), 100);

 HAL_Delay(200);
 if(rx_complete == true)
 {
 HAL_UART_Transmit(&huart7, rx_buffer, sizeof(rx_buffer), 100);
 }
 }
}

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
 if(hspi->Instance == SPI1)
 {
 rx_complete = true;
 }
}

 

Associate III
July 17, 2024

OK.. Thank you

Associate II
July 17, 2024

Did that helped?
Did you succeed with your loop back ?