cancel
Showing results for 
Search instead for 
Did you mean: 

How to reduce STM32f303 SPI Overhead time and what is the min. running time?

QShi.1
Associate II

I want to get a two 16 bit values through two spi interface within 4µs . So I set the baudrate 18Mbits/s so that for 16bits it takes just < 1µs. Everything is working fine.

But the problem is the overhead time between twice HAL_SPI_RECEIVE is nealry 8µs by STM43F303 with 72MHz clock.

How could I reduce the overhead time?

Here are the code for the SPI Interface:

 hspi4.Instance = SPI4;

 hspi4.Init.Mode = SPI_MODE_MASTER;

 hspi4.Init.Direction = SPI_DIRECTION_2LINES;

 hspi4.Init.DataSize = SPI_DATASIZE_16BIT;

 hspi4.Init.CLKPolarity = SPI_POLARITY_HIGH;

 hspi4.Init.CLKPhase = SPI_PHASE_1EDGE;

 hspi4.Init.NSS = SPI_NSS_HARD_OUTPUT;

 hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;

 hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi4.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi4.Init.CRCPolynomial = 7;

 hspi4.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

 hspi4.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

 if (HAL_SPI_Init(&hspi4) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN SPI4_Init 2 */

 /* USER CODE END SPI4_Init 2 */

}

I test them in the main loop:

while(1)

{

uint16_t data_in;

HAL_SPI_Receive(&hsp4,(uint8_t *)&data_in,1,1);

}

And here you could see the SPI SCK, there are nearly 8µs overhead time between twice received data which is more than the transmit time 16/18MHz:

9 REPLIES 9
TDK
Guru

There's just overhead in HAL_SPI_Receive, and you're reading one byte at a time, which isn't going to be very efficient.

https://github.com/STMicroelectronics/STM32CubeF3/blob/8fa3aadf0255818f0ca72ba6a5a6731ef8c585fb/Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_spi.c#L1201

Using higher optimization levels could help, if you're not already there. Otherwise you can roll your own SPI interface to eliminate the delay. If you're only sending/receiving a byte at a time, it's fairly simple.

If you feel a post has answered your question, please click "Accept as Solution".
QShi.1
Associate II

Hi, thank you for the reply!

A16 bit (not one byte) is read at a time, you could also see the configuration and signal, there are 16 times clock at a time. There are just a long overhead between twice HAL_SPI_RECEIVE Block. For the Optimization of C Code I have used OP3, the maximum setting. It doesn't helps so much.

Generally I have to get two 12 Bit ADC value through two SPIs from external ADCs at every 5µs.

QShi.1
Associate II

Are there any low level examples for spi date receive of STM32f303?

gregstm
Senior III

How about DMAing the data to a buffer? You could make it 4 x 16-bit words long and interrupt using the Half transfer complete interrupt. I write direct to registers for efficiency and simplicity.

Why using any interrupt at all? Just use a circular DMA on both sides, and the receiver will see a "delayed copy" of transmitter's value at any time.

If atomicity is an issue, more care should be exercised, using multiple copies and some validity check.

JW

DMA is just suitable for a single SPI interface with multiple receiver or transmitter. It doesn't help two SPI Interfaces. The problem is always there. Even worse, because the two channel data couldn't be get at the same time.

The aim is I have to get two channel data at the same time and make signal processing. I couldn't wait a long time for multiple datas.

I misunderstood your post, sorry.

At this point, you should perhaps tell us more: what ADCs exactly, do you need some framing/sync signals, can you connect the two SPIs as master/slave and/or connect to them additional pins (in other words, are we talking about an already existing hardware, or is this design stage where hardware can change), do you want to proceed data on the fly or in batches?

You should start with dropping the idea of using Cube. Writing a simple basic polled SPI transfer is simple, based on reading the SPI chapter in RM alone. Look at the examples at the end of RM0091 (I know it's for different STM32 family, but SPI is similar).

JW

Hi Jan,

Thank you for the reply!

I have changed to STM32F4, It takes just 3µs time with the same code and is sufficient for my project. It depens on the System Clock.