cancel
Showing results for 
Search instead for 
Did you mean: 

HAL SPI function writes wrong values into reciver Buffer

RCsak.1
Associate II

0693W00000JMWfQQAX.pngHello, I am not an embedded systems guy, so please bear with me.

I have an issue reading data to my STM32G071 nucleo board from an external device via SPI using DMA.

To do this I used code from an ST example project.

I suspect the issue lies within the HAL_SPI_TransmitReceive_DMA function.

I would appreciate any suggestions on how to fix it / things I could try.

I can send commands etc. to the external device, interrupts are triggered as expected etc.

Dozens of shorter reads / writes are sent to the device without any issue beforehand. The device actually reacats accordingly to commands sent.

But for a longer readout sequence I oberserve very weird behaviour:

- I send 26 16bit words to the device

- On my osciloscope I can see everything behaves as expected

- in particular the 26 responses observed on the osciloscope are also as expected

But wrong values get written into the reciever buffer

I have attached 2 images.

image1 shows the final words on my osciloscope.

image2 is the reciever buffer memory after the the dma finishes.

- For the last 3 response Bytes I expect 2CFF , 3500 , 0000

- The osiciloscope shows that they are indeed 2CFF , 3500 , 0000 (attached image 1)

- But where I would expect 3500 I get (seemingly out of nowhere) 2C00 in the response buffer

- 3500 and all following answers are shifted 2 Byte "downward" (attached image 2)

additional information

- the issue is consistently reproducable after restarts,..

- before the HAL function is called, the reciever buffer is infact empty (memory set to 00 00)

- the reciever buffer is not manipulated any more before looking into it and taking attached image 2

- the last response does actually get cut off. If I send a different sequence (where the final reply is not 0000), the final reply does not get written into memory.

- the error allways seems to be on the 25th 16bit word, when i lengthen the transmission the same issue happens on the 25th response, 2C00 appears seemingly out of nowhere, the consecutive responses are shifted 16bit backwards and the last one is cut off

- all 26 16 bit words are sent with a single call of HAL_SPI_TransmitReceive_DMA, and for the first 24 responses everything seems fine,

 e.g. you can see the 2C52 response on the images matches what I observe on the osciloscope.

- the HAL_SPI_TransmitReceive_DMA function function is called with the buffer adresses and length 52 (26*16bit = 52Byte)

I am happy to provide further information & would appreciate any suggestions on solutions / what to try etc.

kind regards

Roger

0693W00000JMWf6QAH.png

1 ACCEPTED SOLUTION

Accepted Solutions
Passing 52 would do 52 transactions. If you want only 26, pass 26. The parameter is in SPI words, not bytes. You appear to have an SPI word size of 16 bits based on the CS behavior.
Could be many (other) things that are wrong. If you can provide more code, it would help to debug the issue.
Monitoring HAL return status would also help.
If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

11 REPLIES 11
RCsak.1
Associate II

Sorry the images are both meant to be attached below the post..

How exactly are the Rx and Tx buffers defined?

How do you call HAL_SPI_TransmitReceive_DMA()?

Does your program wait until the transaction finishes?

JW

RCsak.1
Associate II

Hello, thanks for the response.

The exact line is

HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)ptr_tx_buffer, (uint8_t *)ptr_rx_buffer, (len<<1));

ptr_tx_buffer points to one of many standard commands

ptr_rx_buffer points to a large raw data buffer, and is continously increased over a measurment cycle.

They are managed in a seperate file, wich is quite complex, but tested in practice over many years.

From my understanding it should not have an effect on the function as long as i guarantee that I hand over empty buffers and I dont manipulate them before I read the memory and notice the mistake..?

RCsak.1
Associate II

The programm does wait for DMA complete interrupt (DMA1_Channel2_3_IRQHandler)

This interrupt triggers as expected, and the programm continues as usual afterwards.

But the measured data is obviously wrong.

TDK
Guru

> HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)ptr_tx_buffer, (uint8_t *)ptr_rx_buffer, (len<<1));

What is len? Boil the problem down to the bare minimum which shows the problem and present that code. Initialize the receive buffer with 0xFF or something so you know when it's been overwritten.

The DMA controller doesn't have the ability to modify bytes mid-stream, so the problem is likely elsewhere, perhaps in program logic somewhere.

Note that DMA1_Channel2_3_IRQHandler gets called on more than just the transfer complete flag.

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

len is 26 , the shift by 1 is to convert from 16bit words to byte

the problem boiled down as much as i can:

I see on the osciloscope what the spi answer is.

I see that whats written to the reciever buffer is not identical.

It matches most of the time, but in one very specific case it does not.

>The DMA controller doesn't have the ability to modify bytes mid-stream, so the problem is likely >elsewhere, perhaps in program logic somewhere.

This is my understanding as well. What could go wrong? Do I exceed the max. buffer size? Could an issue with my initialisation cause this issue? Is the HAL

I will do a run with the buffer initialised to FFFF instead of 0000, but it should not matter, I am sure that the 2C is wrongly written, it should a 35 instead.

Passing 52 would do 52 transactions. If you want only 26, pass 26. The parameter is in SPI words, not bytes. You appear to have an SPI word size of 16 bits based on the CS behavior.
Could be many (other) things that are wrong. If you can provide more code, it would help to debug the issue.
Monitoring HAL return status would also help.
If you feel a post has answered your question, please click "Accept as Solution".

¨Thanks for the helpful response. At the moment I pass 52 to the HAL function to trigger a 26 word transmission. My SPI configuration might be the problem.

HAL_SPI_TransmitReceive_DMA does return 0, i.e. no error.

Could you point me towards documentation that specifies that the length is the number of words, not the length in Bytes?