Showing results for 
Search instead for 
Did you mean: 

STM32G431 SPI MCU <--> MCU Communication


I have 2 PCBs, both with STM32G431 MCUs, and both MCUs should communicate with each other via SPI. Both PCBs are assembled in a chassis, the distance between the two PCBs is aprox. 10 cm. For max. Signal integrity I have chosen to use LVDS as a hardware Layer for the board to board connection. I use Texas Instruments SN65LVDS1 and SN65LVDT2 Drivers/Recievers. Some might consider this as complete overkill, but for me it’s worth the effort.

The LVDS itself works pretty well, as shown in the screenshot below: A signal delay of 8 ns from LVDS Driver IC input to LVDS Receiver Output is IMHO more than good enough for a reliable hardware layer, especially at that slow speed.


Screenshot. SPI Clock signal Master LVDS Driver Input (yellow), Slave LVDS Receiver Output (blue)

Both MCUs should exchange 20 Byte of data @5 KHz, but until now I could not convince the two STM32s to establish a reliable communication via SPI with each other. The setup for the master and the slave is: 1,2,4 or 8 MHz Clock, CPOL 0, CPHA 1, 8 Byte Motorola, MSB First, no CRC, Slave NSS Hardware Input, Master Software CSn. Both Instances use DMA, the Master in “Normal�? mode, the Slave in “Circular�? Mode. The main issue is: the received array on the Master is shifted by 3 or 4 bytes.

The Slave initiates the SPI communication via UART by sending an “I am ready�? signal to the master, the Master starts the communication with a delay of 25 ms. The Slave inits the SPI before sending the “ready signal�? and waits for incoming transmissions.

Both MCUs use >>HAL_SPI_TransmitReceive_DMA(…)<<, as said before the Master in normal Mode, the Slave in Circular mode. The data on the slave are in sync, but the data received by the master are shifted.

Under normal circumstances I’d say: ok, that’s a speed related issue, let’s slow down the clock. But: it does not matter how fast the SPI Clock is, the issue is the same at 1 Mbit, 2, Mbit or 8 Mbit.

I am pretty sure it’s not a hardware issue. Even at 8 MHz SPI Clock, the delay created by the LVDS ICs (8 ns, or 16 ns from Slave to Master) are negligible, if the SPI shifts the data on the rising edge and samples the data on the falling edge, as the duration of one clock cycle is 125 ns.

As posted here: I experienced the same issues with a Test-PCB with a STM32G070, which I created to test that Board to Board connection via LVDS. Which leads me to the conclusion, that this is not a hardware related issue, but must be an Issue of the HAL Drivers …

In difference to the post on stack overflow, the behavior on the STM32G431 is, that if I press the reset button on the Slave, the Communication is in Sync for a few cycles, but then the bytes are shifted pretty soon, where it remains stable.

/rant the HAL SPI DMA implantation is pretty disappointing for me so far. I simply don’t get it, why it’s not possible to sync the slave on the falling NSS signal? SPI works – for me – without issues as Master, but trying to use it as Slave turns out to be a nightmare so far …

My suspicion is, that something with the DMA is going wrong. It’s just a guess, but I’d say the DMA on the Master is “a bit sleepy�? – without being able to provide a proof for that claim, but because the received data on the slave are in sync.

How can I solve this? Any help would be highly appreciated, because this issue is driving me crazy! I have used SPI in several appications as Master e.g. to communicate with Flash Memory, DACs or a WIZnet Ethernet IC and all is working well. But Using an STM32 as SPI Slave seems to be a real issue …



> the HAL SPI DMA implantation is pretty disappointing for me so far.

Just don't use it. Write your own software and then, suddenly, you'll find yourself in control.



yes, I already though about that. But the effort is pretty high, and I'd prefer a working HAL-based solution. It can't be that difficult to get two STM32 MCUs connected via SPI as Master/Slave ...

Senior II

I think you have to slice your problem to pieces and solve it piece by piece.

  1. you need to check your cable is right. you can check it by set SPI pin to GPIO and try to drive it from one to one and check the mcu in end of cable can get a correct signal.
  2. you can check spi communication by set one to be master and another one to be slave and send data from master to slave on interrupt mode which it's easiest way to debug.
  3. please remind that the slave can send data to master when the master is on read mode because SPI clock is handled by master only.

Lucky be with you.


Thanks @Tinnagit for your inputs.

The cables are fine, i can communicate via SPI (at 8 MHz Clock rate), when I call the TxRxDMA not to often. My workaround atm is, that is send large chunks of data every 5 ms. That is working in full duplex mode. I can live with that solution, alas it's not what I wanted. When I try to send smaller chunks of data, but faster (e.g. one Block every Millisecond), it starts getting out of sync again.

For me this looks like: HAL is not capable of handling such "fast" repetitive Transmissions. Maybe e.g. the DMA is not yet ready when the clock starts. There is to much overhead ST added for our convenience (ease of use), but this convenience seems to be a show stopper in this situation. I had to implement that SPI communication on my own, using LL Drivers, but this would take to much time in this project. So i stick with the block transfer method, which is pretty stable, learned my lesson and remember that for the next project.

I played around with the LL drivers, I also got SPI running with LL drivers in a test project, but I found it to difficult to integrate that into the current project, where I exclusively use HAL. By the way: if anyone asks her/himself why that NSS Pin is not working, when using LL drivers and Bare Metal Programming: it's because it acts as "Open Drain" Output and you need external 3V3 and a pull-up resistor.

> this would take to much time in this project

Is this a hobby project, or a professional one?

The difference being, that the "much time" a) pays dividend in the long term b) pays dividend in the deeper understanding of the topic.

(The question above was incorrect, but the proper question - "do you intend to work with STM32 systematically?" - makes sense only in context of the explanation above. The quiet albeit not always correct implication in the original question was, that professionals have to stand behind their product, i.e. understand their decisions deeply, and that they usually work longer, often during whole carrier and beyond, within one particular field).

> I had to implement that SPI communication on my own, using LL Drivers

Why? What do you expect from LL? It's mostly just renaming registers, so if you want to check something in the RM, you need to translate the LL names to those used in RM (and the CMSIS-mandated device header).

I know that ST knowingly, willingly and deliberately pushes "libraries" insted of proper support of rudimentary microcontroller programming, and I see the lure of being able to "generate code" by clicking in CubeMX, but IMO it's not worth it, and is mostly waste of that "much time".



with all given respect @waclawek.jan

your view is the view of a person, who is only responsible for the implementation of the software and does not see the bigger picture.

The dividend you are talking about will only pay of, if you make it to the market before your competitors do so. If you are 1 year late, because your highest directive is to implement that with CMSIS and your own self coded hardware abstraction layer, you will sell nothing and without sales there is no dividend.

ST pushes the HAL drivers, because it dramatically improves the time to market and therefore dramatically improves the value of their product.

Okay, so you have a workaround, without gaining insight into the problem, and it was quick. It may or may not bite you in the future. Some people are happy with risks, some seek them actively.

> self coded hardware abstraction layer

Of course I wouldn't (unless specifically paid to do that, as they are genuine albeit extremely rare reasons for things like that), that would be a genuine waste of time.


After re-reading your initial post: you appear to utilize NSS to sync master/slave. How exactly do you handle that in slave? Observe MISO/MOSI/SCK/NSS using LA and check/post/describe what's wrong. An interesting insight to problem might result from outputting the received/transmitted data independently e.g. through UART and comparing. SPI in newer STM32 are overtly complex and contain a small FIFO which may cause confusion - read the SPI chapter.



it will most probably not bite, because this project is just an intermediate solution - to give the customer something to work with, which will be replaced by a more sophisticated solution in the next 6-12 month.

I get your point, what you are trying to say. And we learned our lesson stumbling uppon this issue. But that does not necessarily mean that we have to investigate that down to the root cause (which we asume is in the overhead of the HAL), because it's not worth the effort and nobody will pay us for this in the current situation.