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
- NSS high input means the bus is free, and you are allowed to transmit
- NSS low input means someone else is transmitting, and you become a slave.
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.