cancel
Showing results for 
Search instead for 
Did you mean: 

[STM32L0:SPI] Hard output NSS

Joris COLLOMB
Associate II
Posted on June 08, 2018 at 17:31

Hi,

I'm trying to use the hardware controled NSS pin, but I'm getting some trouble.

According to the Reference Manual:

'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).'

-The HAL enable the SPI at transmission, but never disable it. (I'm in 2 line full duplex mode) So, if I want a correct behavior of the NSS pin (return to high after the end of a transaction), I must disable the SPI after call of HAL function? That's how I made it in my code:

HAL_SPI_Transmit(&

hspi

,dataTx,4,HAL_MAX_DELAY);

HAL_SPI_Receive(&

hspi

,dataRx,5,HAL_MAX_DELAY);

__HAL_SPI_DISABLE(hspi);

This code work correctly.

-But I've notice a issue if I use this code:

status  = HAL_SPI_Transmit (

hspi

, &opcode, 1,

HAL_MAX_DELAY

);

status

|

= HAL_SPI_Receive (

hspi

, &response, 1,

HAL_MAX_DELAY

);

__HAL_SPI_DISABLE

(

hspi

);

opcode = PROGRAM_ERASE_BUFF1_OPCODE;

status 

|

= HAL_SPI_Transmit(

hspi

, &opcode, 1,

HAL_MAX_DELAY

);

status |= HAL_SPI_Transmit_IT(

hspi

, data, size);

__HAL_SPI_DISABLE

(

hspi

);

I want NSS to go low, send 1 byte, receive 1 byte, NSS to go high, go low again, send 1 bytes, receive x bytes in non-blocking mode (I add a '__HAL_SPI_DISABLE(hspi)' in the RxCallback).

But the behavior is unexpected: NSS don't go high after first Receive/Transmit, and stay low until the end of x bytes reception.

If I put a breakpoint between the two transaction, the behavior of NSS is as expected.

So the SPI module have a issue with the hardware control of NSS pin if we enable/disable it to fast.

Am I correct?

Thx

#stm32 #nss #spi
6 REPLIES 6
Posted on June 10, 2018 at 00:28

This is how NSS works in STM32, accept it as a fact. It is not meant to frame transmissions, it is meant to signal a master

being present in multimaster environment. This is not incorrect - there is no SPI standard thus there is no 'correct' behaviour.

In some STM32 model lines (but not in 'L0) SPI has a mode where it toggles NSS between each consecutive frame (byte, halfword, whatever bitlength is set), but again you may not be comfortable with this. Note, that the SPI module does not know of your data length (i.e. how many bytes does a 'transaction' consist of) so it simply can't generate what you deem as 'correct'.

If this behaviour does not suit your purpose, you have to generate a signal according to your needs by other means, e.g. using a GPIO output and toggling it 'manually' whenever needed.

In your code snippet above, NSS probably went inactive between the two transactions for a very short time; you could prolong that by inserting some sort of a delay.

JW

Posted on June 11, 2018 at 10:32

Hi JW,

thanks for your reply and your explanation, but for me there is still an issue.

The problem may not be the hardware, but at least the documentation of it:

 30.3.5 Slave select (NSS) pin management

In slave mode, the NSS works as a standard “chip select� input and lets the slave

communicate with the master. In master mode, NSS can be used either as output or input.

As an input it can prevent multimaster bus collision,

and as an output it can drive a slave

select signal of a single slave.

So the documentation (here: RM0376 for STM32L072x8) is not agree with you, NSS is meant to be used as a CS if there is only one slave.

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

And this sentence is still incorrect, as I achieve a SPE = 0 and NSS low condition. 

If NSS should not be used as CS, the documentation must say it clearly IMHO.

Although,

NSS probably went inactive between 

the two transactions

This is electrically untrue, I can add oscilloscope snippet to show you. 

Thx,

Have a good day.

JC

stm322399
Senior
Posted on June 12, 2018 at 11:15

It sounds to me that disabling SPI using that HAL macro might not be enough to make sure that SPI is really disabled and then release the NSS line.

The RM376 clearly explain how to disable, and this involves waiting that BSY bit becomes cleared by hardware. Did you pay attention to that.

In my understanding Rx completed callback is used to notice for data availability, which is likely to coincide with end of transfer, but what if the hardware requires a few extra cycles to terminate properly the transfer ? The presence of the BSY tells you that there is something else to care, and you definitively must check it.

Posted on June 12, 2018 at 09:31

So the documentation (here: RM0376 for STM32L072x8) is not agree with you, NSS is meant to be used as a CS if there is only one slave.

Okay and then what? As I've said, there's no standard for SPI, so there's no fixed understanding of what CS could mean. For slaves, usually, NSS is a signal, which, when set inactive, sets MISO to threestate and resets the internal bit counter; and that's all. So, for single slave, it's enough that the master sets NSS to inactive briefly before the first transaction, to reset the slave's bit counter to achieve synchronicity, and then set it active before the first clock. The present implementation fulfills this requirement. Sure there are slaves which require NSS to go inactive to 'finish' a transaction (e.g. to transfer data from shift to holding/working registers) but that's not that usual. As I've said, the STM32 SPI module does not have a byte/frame counter to support this behaviour.

NSS probably went inactive between 

the two transactions

This is electrically untrue, I can add oscilloscope snippet to show you. 

Is the NSS pin's OSPEEDR set to fast enough, and the oscilloscope and its probe fast enough too, to show a pulse lasting one processor cycle?

JW

Posted on June 12, 2018 at 10:36

Hi,

As I'm saying, I'm not discuss the way of work of SPI, just point a misleading sentence in a documentation.. this one:

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

This sentence is not accurate enough, and it should specify that the SPI module need to be disabled for a certain  time before NSS goes High again. Just that.

Is the NSS pin's OSPEEDR set to fast enough, and the oscilloscope and its probe fast enough too, to show a pulse lasting one processor cycle?

Yes, 

OSPEEDR

 at full speed, SPI clock @ 32MHz.

Oscilloscpoe 2GS/s 200MHz, probe 200MHz.

Thanks for your time.

J

Posted on June 12, 2018 at 18:31

Incidentally, a

https://community.st.com/0D50X00009XkYEnSAN

reappeared, and that might contain the thruth: that NSS goes threestate when SPI is disabled.

JW