armstm32spimaster-slavestm32f1

Setting nss_soft in Master (SPI)


I want to set the NSS pin to software mode in master using Nucleo STM32F103RB.

In the reference manual, they say,

In NSS Software mode, set the SSM and SSI bits in the SPI_CR1 register. If the NSS pin is required in output mode, the SSOE bit only should be set.

Why do we need to set the SSI bit with SSM?

What is the purpose of the SSOE bit?


Solution

  • It's related to the rarely used multi-master communication.

    In a multi-master setup, the NSS signal controls access to the SPI bus. The ST documentation is unfortunately a bit vague there, but my understanding is that

    Why do we need to set SSI bit with SSM?

    If the SSM (Software Slave Management) bit is set in master mode, then the SSI (Slave Select Internal) bit becomes the source of the NSS signal instead of the pin. Setting SSI to 1 allows the master to transmit, setting it to 0 makes it a slave (clears the MSTR bit in CR1).

    If you have a single master, just set

    SPI->CR1 = SPI_CR1_MSTR | SPI_CR1_SPE | SPI_CR1_SSM | SPI_CR1_SSI
    

    and don't worry about the rest. It's the most flexible way, and you can control as many slaves as you like with GPIO outputs connected to the CS lines separately. You can use the NSS pin as GPIO as well.

    What is the purpose of SSOE bit?

    It changes the NSS pin to an output. Initially set to high, it becomes low when the controller starts transmitting (when the DR register is written to). Note that it won't automatically become high again when the transfer is finished, but by setting SPI_CR1_SPE to 0.

    Using SSOE can be useful when a single master is talking to a single slave, because CS is controlled by the SPI registers. Not having to talk to a GPIO peripheral at all, there isn't any need to load its base address to a register and holding it there, saving some cycles and a couple of bytes in flash, making it possible to use a register for something else by an optimizing compiler.