2023-12-05 12:22 AM - edited 2023-12-05 12:23 AM
Hello,
I am working with a STM32F446ZET6 and using it as an SPI slave.
I use the function HAL_SPI_Transmit_Receive_IT function to receive 4 bytes of data.
It used to work properly in our conception, for example when the master sends 0x12, 0x34, 0x56, 0x78, in my reception buffer on the slave side i receive correctly the data in this order.
Recently, we received 10 new boards: on one of them the SPI is behaving strangely when the sending frequency is above 1000Hz. When the master send the same data as above, sometimes the STM32 receive them in disorder :
meaning that in the reception buffer we may have 0x34, 0x56, 0x78, 0x12.
When troubleshooting it appears the problem comes from the STM32 because when we replace it, the problem disappeared.
But I don't understand this problem that appear with some chips.
Is there a way to fix that with code?
2023-12-05 06:03 AM
Looks like the master and slave may not by synchronized. IF your slave comes up mid-transfer, it's going to miss out on some bytes.
Typically synchronization is handed by looking at the CS pin. When it goes high (or low if you're quick), reset the transfer.
This is a code bug not a hardware bug.
2023-12-05 06:10 AM
But this only appens on 1 of my board, out of 10 having the same programm.
I only read the content of the SPI buffer after the interruption of the function HAL_SPI_TxRxCpltCallback().
After reading the content of the buffer, I restart the same pattern using the same HAL_SPI_TransmitReceive_IT() function.
Is it not the right way to receive the same data size periodocally?
2023-12-05 06:15 AM
If they're not synchronized from the start, restarting it in such a manner will not fix the issue.
2023-12-05 06:21 AM
Yes, i understand that. But the thing is that at the beginning the devices are synchronized.
If fact the behaviour is strange: like 80% of the time the reception will be ok (0x12, 0x34, 0x56, 0x78), but then during 2 receptions some data will be flipped (egz. 0x34, 0x56, 0x78, 0x12).
This only happen when I increase the sending frequency on the master side.
And again it only happen with 1 STM32 chip, the others do not have this behaviour (with the same code).
2023-12-05 06:33 AM
> And again it only happen with 1 STM32 chip, the others do not have this behaviour (with the same code).
This stalls the conversation. There is an issue somewhere, but if we always fall back to "well it works on an identical configuration" we don't advance the ball.
There aren't glaring hardware flaws in the STM32F4. It doesn't have the capability to flip the order of received bytes within the DMA peripheral.
Instead of sending 0x01234567, advance the numbers on each transaction. Then you will know if the last byte is from the previous transaction or not.
2023-12-06 06:00 AM
I understand what you are telling me and I'm trying to debug it.
But I want to know if it means then that the behaviour of a code can be different depending on the chip (still in the STM32F446ZET6 series)? Does it mean that I will have to write another code for some of my STM32F446ZET6 with this desynchronization problem? Or will the new code work also for the STM32F446ZET6 that I have and do not have this problem yet.
2023-12-06 06:32 AM
Barring exotic things like overclocking, chips will all behave the same.
There is a nonzero chance that a particular chip is damaged, but the vastly more common scenario is that the difference is explained by something else, typically code, sometimes hardware.
2024-01-08 05:39 AM
After more debugging, we have found that when using the function HAL_SPI_TransmitReceive_IT we sometimes miss a byte:
As slave we are receiving 4 bytes every cycle (100us), between each byte the CS is toggled by the master.
At the beginning the SPI communication is synchronized. After approximately 5-7 seconds, the first byte received in the cycle may be lost, thus desynchronizing our process.
This only happen when the transmission frequency is above 1kHz and on 1 component out of 10.
Example : the master sends in a loop {0x01, 0x02, 0x03, 0x04} then {0x0A, 0x0B, 0x0C, 0x0D}.
The slave might receive in a cycle {0x0B, 0x0C, 0x0D, 0x01}. --> the byte 0x0A is lost.
Hoping that I have provided enough elements, to identify the source of this.
2024-01-08 07:03 AM
Have the SPI Slave toggle a GPIO when it detects the problem. Use that GPIO to trigger a logic analyzer displaying the SPI signals.