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?
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.