cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L151CBT6 as SPI Slave: HAL_SPI_TransmitReceive sends Bytes of an 64 Array twice or more often but in correct order while HAL_SPI_TransmitReceive_DMA works just fine.

Chrizzly
Associate III

In my setup the STM32L151CBT6 is configured as slave of a PLD Master. To test the correct functionality I set up an 64 Byte Array ([0x00, 0x01, 0x02, ..., 0x64) which is transmitted by the slave during communication. The PLD "asks" for the readback parameters (the 64 Byte Array) in a cyclic manner. The PLD Master Clock is roughly 50/12= 4,16 MHz.

The Problem:

The HAL_SPI_TransmitReceive sends Bytes of an 64 Array twice or more often distributed over two 64 Byte Cycles. At the end of the 2nd cycle the value 0x64 is not reached. In the 3rd cycle it starts with 0x00 again and the pattern continues.

HAL_SPI_TransmitReceive_DMA shows correct behavior and sends every Byte of the 64 Byte Array in one cycle.

The Question:

Why do I see this behavior of the HAL_SPI_TransmitReceive Function? How can I fix it?

Appendix:

  • TransmitReceive Screenshots of PiceoScope
  • TransmitReceive_DMA Screenshots of PiceoScope
  • Clock Config Screenshot

I am really confused. Any help would be great.

5 REPLIES 5
TDK
Guru

You have set a 1ms timeout and the systick timer increments during the transfer. Set the timeout to HAL_MAX_DELAY. Not entirely convinced that's it, but certainly seems like it would cause the code to timeout and return HAL_TIMEOUT.

Monitor the return value.

If you feel a post has answered your question, please click "Accept as Solution".
Chrizzly
Associate III

Hello TDK, thank you for your answer.

I just tried it out and set the Timeout to HAL_MAX_DELAY. Unfortunately the problem remains unchanged.

Any other ideas?

TDK
Guru

Oh, probably the HAL code can't keep up with the fast clock rate. Slow the clock down by an order of magnitude and I bet the problem will disappear.

Some options to mitigate or solve would be to turn up optimization settings, turn up cpu clock speed, or use DMA, or write your own SPI code.

You only have 61 ticks to send out a new byte. Even if you can keep up, any interrupt that occurs in that time (e.g. SysTick) is very likely going to cause it to fail.

If you feel a post has answered your question, please click "Accept as Solution".
Chrizzly
Associate III

My PCLK's are configured to 32 MHz. In stm32l1xx_hal_spi.c is a table at the top of the file with following comment:

"Using the HAL it is not possible to reach all supported SPI frequency with the different SPI Modes,  the following table resume the max SPI frequency reached with data size 8bits/16bits, according to frequency of the APBx Peripheral Clock (fPCLK) used by the SPI instance."

In my case according to the table:

DataSize = SPI_DATASIZE_8BIT

Process: TX/RX

Transfer Mode: Polling

2Lines Fullduplex Slave

--> Fpclk/2

So if I read the table right the supported frequency should still be in range by a good margin, since my SPI operates on 4,16 MHz?

TDK
Guru

Regardless of what is written in the table, your results are consistent with the blocking HAL code being unable to shift data into the DR register fast enough to keep up.

One can't possibly know the max supported speed a priori given that the many variations of optimization settings, compilers, wait states, etc. will change it.

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