cancel
Showing results for 
Search instead for 
Did you mean: 

Get hardware NSS mode for SPI with DMA in STM32 (F0/F4) working? Or alternatively manually start the according DMA channel (Low Level functions)

Christian Wächter
Associate III

Hello,

I'm trying to get a SPI communication in between two STM32 running with DMA. One is the STM32F051R8T7 (slave), the other ist the STM32F412ZET7 (master). There is nothing else on this SPI-bus. The best would be, if it runs with hardware controlled NSS. I'm facing various problems here and already tried a lot.

The basic problem I'm facing is, that I want to send multiple "messages" via SPI. A message should be any amount of bytes that are filled into one tx-Buffer and then send via SPI by the DMA. After one message, the data in the tx buffer will get modified and send again and so on.

My code is based on the examples of CubeMX, e.g. STM32F072RB-Nucleo\Examples_LL\SPI\SPI_TwoBoards_FullDuplex_DMA. It is working somehow, but I have some independend issues, depending on which way I go from here:

  • When I want to use the hardware NSS, I have to disable the SPI-periphery by LL_SPI_Disable(SPIx) after one message has been send, so that the NSS-signal will be set to high again. but it seems that the NSS-pin is not active pushed to the high-level after sending the LL_SPI_Disable() command, which results in a very slow rising voltage. I assume that the SPI-pins are just set into tristate mode in this case. Pull-Up resistors decrease the time of the rising edges, but are still not perfect. (Yellow = NSS, Cyan = CLK, Purple = MOSI). This is a very crappy behaviour, which means the hardware-NSS function cannot be used this way! Or is there a way to control the NSS-pin when it is in hardware-mode, so that it is pushed to the high-level as it should?0690X00000DYnRuQAL.png

  • An other option would be to always let the SPI-periphery enabled and therefore the NSS-signal set to the low-level. This is fine in this case, because there is nothing else on this SPI-bus execpt the master and slave STM32. But in this case, I'm missing a way to manually initiate the sending of the next message for the DMA. Usually, the tx data is changed after the SPI has been disabled. When enabling the SPI-periphery again, the tx buffer is send imediatelly with DMA, which is fine. But how could I send the data without disabling and again enabling the SPI-periphery? When I would do this, the NSS-level is changed as described above. The functions LL_DMA_EnableStream() or LL_SPI_EnableDMAReq_TX() do not seem to initiate a new transfer for the DMA controller.

Best regards,

Christian

13 REPLIES 13

This all is a recurring theme here. My November 8, 2018 at 7:19 PM post in https://community.st.com/s/question/0D50X00009XkYEnSAN/spi-master-nss-always-low-in-stm32f4 shows that I already have this misconception rooted deeply in my mind... sorry again.

JW

Well, I would totally agree if hardware NSS would only work in a specific use case like descibed by you. But is the rising edge of the NSS-signal in this case a "good" edge, or the same slow charging curve like shown above?

Yes. As with any wired-OR system, the value of pullup is crucial here, together with any parasitic capacitance.

JW

PS. There's also no provision to prevent collisions. Take it as it is, or leave it.

> Yes. As with any wired-OR system, the value of pullup is crucial here, together with any parasitic capacitance.

Well, but that's again my point from the first post: You cannot have a really fast rising edge with a pullup. That's why, the NSS pin is usually configured as Push-Pull