Author Topic: SPI Chip Select on STM32F7 MCUs  (Read 419 times)

0 Members and 1 Guest are viewing this topic.

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1129
  • Country: us
SPI Chip Select on STM32F7 MCUs
« on: August 05, 2020, 09:23:22 pm »
I'm working with an RTD temperature sensor chip that has an SPI interface connected to an STM32F767 MCU. I'm trying to find a way to make the STM32 SPI peripheral control the SPI CS output directly, but can't make it work.

There are bits in the SPI CR1 and CR2 registers, SSM and SSOE, that, according to the documentation, control "NSS" (this is what the STM32 documentation calls SPI chip select), but setting them according to the documentation doesn't seem to work as I expect. The NSS output from the MCU is always '0' (CS active) whenever the SPI peripheral is enabled.

What I'm expecting, and what I've seen on other MCUs, is the MCU drives CS high when idle, and then drives it low when it drives the clock and MOSI lines, and then drives it high again to complete the transfer.

Since I can't get the MCU to control CS, I've resorted to controlling it in software by directly driving the GPIO output port connected to the peripheral's CS input. Am I missing something here? Is there some secret sauce needed to get the SPI peripheral to control CS? BTW, I'm not using the ST HAL, or any other library code--I'm directly interfacing to the peripheral registers.
Complexity is the number-one enemy of high-quality code.
 

Offline newbrain

  • Frequent Contributor
  • **
  • Posts: 922
  • Country: se
Re: SPI Chip Select on STM32F7 MCUs
« Reply #1 on: August 05, 2020, 09:43:35 pm »
Nope, you are not missing anything: the HW implementation of NSS in STM32 SPI is, to be frank, pointless. :-//

From F7 RM:
Quote
NSS output enable (SSM=0,SSOE = 1): this configuration is only used when the MCU is set as master. The NSS pin is managed by the hardware.
The NSS signal is driven low as soon as the SPI is enabled in master mode (SPE=1), and is kept low until the SPI is disabled (SPE =0).
A pulse can be generated between continuous communications if NSS pulse mode is activated (NSSP=1).

So, the most you can obtain from it is a pulse between continuos communication, but it still stays low until you disable the SPI.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline dtodorov

  • Contributor
  • Posts: 12
  • Country: bg
Re: SPI Chip Select on STM32F7 MCUs
« Reply #2 on: August 05, 2020, 09:53:58 pm »
This sounds awfully familiar as with my experience with STM32F1xx series. Basically the hardware SS function is useless, as if nobody every thought a slave device could actually use the edges of CS input to trigger internal data latch or whatever.  :palm:
Anyway, what I ended up doing is rather nasty toggle of SPE bit before/after any SPI transfer while still using the NSS pin.

Code: [Select]
hspi1.Instance->CR1 |= SPI_CR1_SPE;
HAL_SPI_Receive( ... );
hspi1.Instance->CR1 &= ~(SPI_CR1_SPE);

 

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1129
  • Country: us
Re: SPI Chip Select on STM32F7 MCUs
« Reply #3 on: August 05, 2020, 10:48:04 pm »
Nope, you are not missing anything: the HW implementation of NSS in STM32 SPI is, to be frank, pointless. :-//

Bummer. That's what I thought.  :palm:

This isn't the first, and it won't be the last, time I've been bitten by poor decisions by the ST designers.

The most recent Cortex-M part I used previous to the STM32 was the Infineon XMC-4700, where not only does hardware control of CS work correctly, but it lets me set the frame size to anything between 1 and 63 bits, and set the bit rate to a much finer grained value than the STM32 (which only allows Fpclock divided by powers of two between 2 and 256).  |O
Complexity is the number-one enemy of high-quality code.
 
The following users thanked this post: thm_w

Offline Jope

  • Regular Contributor
  • *
  • Posts: 76
  • Country: de
Re: SPI Chip Select on STM32F7 MCUs
« Reply #4 on: August 05, 2020, 11:20:27 pm »
as if nobody every thought a slave device could actually use the edges of CS input to trigger internal data latch or whatever.

Which is stupid. A chip select should not be abused for that.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 2007
  • Country: dk
Re: SPI Chip Select on STM32F7 MCUs
« Reply #5 on: August 05, 2020, 11:23:34 pm »
as if nobody every thought a slave device could actually use the edges of CS input to trigger internal data latch or whatever.

Which is stupid. A chip select should not be abused for that.

so most spi devices are stupid?
 

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1129
  • Country: us
Re: SPI Chip Select on STM32F7 MCUs
« Reply #6 on: August 06, 2020, 03:07:18 am »
as if nobody every thought a slave device could actually use the edges of CS input to trigger internal data latch or whatever.

Which is stupid. A chip select should not be abused for that.

so most spi devices are stupid?

IMO, yes.  Most of them have stupid limitations on frame size, bit rate, and handling of CS.
Complexity is the number-one enemy of high-quality code.
 

Offline newbrain

  • Frequent Contributor
  • **
  • Posts: 922
  • Country: se
Re: SPI Chip Select on STM32F7 MCUs
« Reply #7 on: August 06, 2020, 09:54:02 pm »
This sounds awfully familiar as with my experience with STM32F1xx series. Basically the hardware SS function is useless, as if nobody every thought a slave device could actually use the edges of CS input to trigger internal data latch or whatever.  :palm:
Anyway, what I ended up doing is rather nasty toggle of SPE bit before/after any SPI transfer while still using the NSS pin.

Code: [Select]
hspi1.Instance->CR1 |= SPI_CR1_SPE;
HAL_SPI_Receive( ... );
hspi1.Instance->CR1 &= ~(SPI_CR1_SPE);
And even this won't work (on the F7 in master mode at least):
I'm looking at the scope, and NSS goes tri-state as soon as one disables the SPI. It's only driven (low) when the SPI is enabled.
I'm checking, because I remembered trying something similar and not succeeding.

OTOH, in pulse mode, NSS will go high for every transmitted byte (if in 8 bit mode) or half word (in 16 bit mode) or whatever bit size has been programmed.

It does not care at all if the FIFO still has data, you'll get all your pulses - so it's only good for slaves that work on a 4 to 16 bit base.
EtA: Worse, if the pulse flag is enabled, even selecting SW NSS will interrupt the the clock every time a 'byte' is out.  |O

This is next to useless. :rant:

Other vendors do that correctly:
  • NXP's iMX.RT SPI will accept a CS indication in the initial command written on the FIFO to begin the transaction (the FIFO contains both data and commands).
  • Even the lowly Kinetis KE04 gets it right!
  • LPC176x: This one is fun, if CPHA = 0, SSEL wil pulse between bytes, if CPHA = 1, it will will stay low until the end of the full transaction!
    Since many peripherals work for CPHA=x, CPOL=y and for CPHA=!x, CPOL=!y, this is actually quite good.
  • Cypress PSoC5 SPI component will keep SS low until the FIFO is empty and the last bit is out.
  • Texas' MSP432: Who knows, the Technical Reference Manual is (as for any other topic) clear as mud in moonless night while blindfolded.
« Last Edit: August 06, 2020, 10:04:23 pm by newbrain »
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: thm_w, Siwastaja

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 2270
  • Country: ca
Re: SPI Chip Select on STM32F7 MCUs
« Reply #8 on: August 06, 2020, 10:37:47 pm »
It looks like SAMD21/51 behave the same way (pulsed):

[attachimg=1]
 
The following users thanked this post: newbrain

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 2853
  • Country: fi
Re: SPI Chip Select on STM32F7 MCUs
« Reply #9 on: August 07, 2020, 12:44:14 pm »
Wow, I'm surprised to hear some manufacturers have got this trivial thing right!

I think that one source of confusion for the designers is they were never told what the nSS signal actually is, and they have never used existing SPI devices to see how they communicate in the real world.

So not understanding what the nSS is supposed to do, they throw dice and implement something.

Newsflash: nSS is a hardware packet delimiter signal. Compare to UART where you don't have the concept of "packets", this is a massive improvement. Now you can have an arbitrary length of a data block and know exactly where it starts and where it ends, so you also know when the next one starts. Fancy! Someone should have told this to the ST engineers.

Falling edge of nSS signifies the start of a new data packet. A properly implemented SPI slave flushes any incomplete job when it sees nSS going high (end of packet; end of asserting the slave). When it sees nSS going low, the slave has a fresh start in its state machine. Then any number of words of communication ensues; even non-predetermined number! After the command is finished, master sets nSS high again, deactivating the slave.

Some slaves add extra requirements such as keeping nSS active (low) for a certain time before the first word, or after the last word (or worse, between the words). This is understandable so the slaves have time to do internal processing. I would perfectly understand if the MCU SPI peripheral implementation couldn't support these special requirements in hardware.

But just delimiting the packet is absolutely trivial once you understand that this is what the nSS signal is! You just need this concept; it can be signified by writing/reading start-of-packet, end-of-packet commands/status bits to a peripheral control register, it can be stored alongside data in the FIFO, or you can use a word counter which is programmed to its own peripheral register.

Do note that, depending on what you are doing, with STM32, you may end up having to not only disable and re-enable the SPI peripheral, but also reset it through the RCC reset registers; which obviously only exist to circumvent completely broken-by-design peripherals, but thank God/whatever these control registers are there!

One such example is slave mode operation with variable-length messages (or even with fixed length, you would likely want to add robustness to the system by utilizing nSS as a real packet delimiter signal so that you don't go out of sync forever if you miss a single clock). At least with F765, you have to use a GPIO interrupt on the nSS pin and use an interrupt handler to reset the SPI peripheral through the RCC registers, after every transfer. This is just nuts. Luckily, it's surprisingly fast, just a few clock cycles. I might suggest them to have the SPI peripheral internally run linux to make booting it slower.

The funny thing is, they are trying to get it right, and they still get it wrong each new revision.

For example, when I migrated code from said F765 to the new H743, I noticed they had added a lot more complexity with the concept of "transfer" (which is finally correct). They added a transfer size counter that can be programmed beforehand. Wow! But then, instead of using this counter to drive nSS; or in slave mode, reset the counter with nSS going low, the only thing it can do is to generate an interrupt in master mode. Oh and they fixed the peripheral enough so you can reset it with writing SPE 0 and back 1 again, no need to use RCC registers anymore. (EDIT: looking back at my code, I had to reset it through RCC in the end, because I used the hardware CRC mode, and it's still broken. Their HDL clearly has so many edge cases and they don't use behavioral testbenches to test all operating modes; after receiving bug reports for years, they fix one case, and leave all other cases unfixed.)

So, analogous to a car, they have a car the can't steer left at all, but can steer right, as long as you alternatively press brake and gas pedals 5 times while trying to steer, simply because they don't know what "steering" means. After 10 years of development and 5 new models, they finally have arrived to a point where you still can't steer left at all, but now you can steer right by just turning the radio volume knob at the same time, which is a lot more convenient than it was before. And, you can always steer left by attaching a rope to the steering rack and pulling that.
« Last Edit: August 07, 2020, 01:45:47 pm by Siwastaja »
 
The following users thanked this post: thm_w, newbrain, dtodorov

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1129
  • Country: us
Re: SPI Chip Select on STM32F7 MCUs
« Reply #10 on: August 07, 2020, 03:12:59 pm »
The funny thing is, they are trying to get it right, and they still get it wrong each new revision.

This is the thing that bothers me the most about how some vendors implement peripherals--they get it wrong time after time. You'd think that after getting it wrong once and listening to user feedback they'd realize the error in their ways and fix it in later revisions and in later models, but for some reason ST can't grasp that and continues to get basic things wrong.

Come on ST, SPI is not rocket science--it's one of the simplest protocols there is--and continually getting it wrong is just inexcusable.  :palm:
Complexity is the number-one enemy of high-quality code.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf