Skip to main content
placidity.master_gmail.com
Associate III
January 13, 2021
Solved

NSS the output ignores the settings, and according to the waveform, the outputs are in the hiz state, because you can see the leads that are not damped by pressing to the ground. (STM32F303)

  • January 13, 2021
  • 4 replies
  • 2664 views

NSS the output ignores the settings, and according to the waveform, the outputs are in the hiz state, because you can see the leads that are not damped by pressing to the ground.

 (STM32F303)

   //   Bit 4 FRF: Frame format

   //   0: SPI Motorola mode

   //   1 SPI TI mode

   //   SPI2->CR2 |= 1<<4;

   //   Bit 3 NSSP : NSS pulse management

   //   This bit is used in master mode only. it allow the SPI to generate an NSS pulse between two

   //   consecutive data when doing continuous transfers. In the case of a single data transfer, it

   //   forces the NSS pin high level after the transfer.

   //   It has no meaning if CPHA = ’1’, or FRF = ’1’.

   //   0: No NSS pulse

   //   1: NSS pulse generated

   //   Note: 1. This bit must be written only when the SPI is disabled (SPE=0).

   //   2. This bit is not used in I2S mode and SPI TI mode.

   SPI2->CR2 |= 1<<3;

   //   Bit 2 SSOE: SS output enable

   //   0: SS output is disabled in master mode and the SPI interface can work in multimaster

   //   configuration

   //   1: SS output is enabled in master mode and when the SPI interface is enabled. The SPI

   //   interface cannot work in a multimaster environment.

   //   Note: This bit is not used in I 2 S mode and SPI TI mode.

   SPI2->CR2 |= 1<<2;

This topic has been closed for replies.
Best answer by waclawek.jan

I had a look at the LTC6804 and it appears to be a very complicated chip and I am not going to try to understand its working. However, this

CSB must remain low

for the entire duration of a command sequence, including

between a command byte and subsequent data.

indicates, that the STM32 SPI NSS pulsing mode is not usable for your case anyway.

So, the best thing to do is to set NSS to GPIO, and control it "manually", according to the required protocol.

JW

4 replies

waclawek.jan
Super User
January 13, 2021

Read out and check/post content of SPI and relevant GPIO registers.

Post relevant portions of the runtime code (best, a complete compilable but minimal program) and screenshot of waveform.

What exactly is your hardware and how exactly do you measure? Post photo.

JW

placidity.master_gmail.com
Associate III
January 14, 2021

data lines, through 1k resistors, are connected to the LTC6820 IC, and it in turn outputs normal isolatedSPI pulses, but the STM32F303 does not want to clock the NSS output normally 

------------------

   GPIOB->MODER |= ( 1 << 25 ); //10: Alternate function mode

   inner_sync();

   GPIOB->OSPEEDR |= (( 1 << 24 ) | ( 1 << 25 ));

   inner_sync();

   GPIOB->AFR[1] |= (( 1 << 16 ) | ( 1 << 18 )); 

   inner_sync();

------------------

uart_1_send_debug_var_1 ( (uint32_t) (GPIOB->MODER & ( 1 << 25 ) )) ;

sends : 

DEBG: var 1 : 0x02000000

------------------

uart_1_send_debug_var_1 ( (uint32_t) (GPIOB->OSPEEDR) & (( 1 << 24 ) | ( 1 << 25 )) );

sends :

DEBG: var 1 : 0x03000000

------------------

uart_1_send_debug_var_1 ( (uint32_t) (GPIOB->AFR[1]) & (( 1 << 16 ) | ( 1 << 18 )));

DEBG: var 1 : 0x00050000

------------------

SPI2->CR1 |= 1<<3 | 1<<4 | 1<<5 ;

uart_1_send_debug_var_1 ( (uint32_t) (SPI2->CR1) & (1<<3 | 1<<4 | 1<<5)) ;

DEBG: var 1 : 0x00000038

------------------

SPI2->CR1 |= 1<<2;

uart_1_send_debug_var_1 ( (uint32_t) (SPI2->CR1) & (1<<2)) ;

DEBG: var 1 : 0x00000004

------------------

SPI2->CR2 |= 1<<8 | 1<<9 | 1<<10;

uart_1_send_debug_var_1 ( (uint32_t) (SPI2->CR2) & (1<<8 | 1<<9 | 1<<10)) ;

DEBG: var 1 : 0x00000700

------------------

SPI2->CR2 |= 1<<3;   

uart_1_send_debug_var_1 ( (uint32_t) (SPI2->CR2) & (1<<3 )) ;

DEBG: var 1 : 0x00000008

------------------

SPI2->CR2 |= 1<<2;

uart_1_send_debug_var_1 ( (uint32_t) (SPI2->CR2) & (1<<2 )) ;

DEBG: var 1 : 0x00000004

------------------

in systick , on 2 Hz, send:

spi_2_put_string( "1" , 1 );      // tested. work.

spi_2_send_next_msg();

see pic

------------------

Clive1 (HNL)
Explorer
January 14, 2021

Overly selective masking, won't show what's in the actual registers

uart_1_send_debug_var_1 ( (uint32_t) (GPIOB->MODER & ( 0x3 << 24)) ) ;

uart_1_send_debug_var_1 ( (uint32_t) (GPIOB->OSPEEDR & ( 0x3 << 24)) );

uart_1_send_debug_var_1 ( (uint32_t) (GPIOB->AFR[1] & ( 0xF << 16 )));

Same with OR'ing bits on, it won't clear other bits.

waclawek.jan
Super User
January 14, 2021

Make sure you have continuity from the NSS pin from the pin to the point of measurement, measuring at the point where the metal of the pin leaves the plastic of the case.

As an experiment, turn the given pin to GPIO Output and toggle it "manually" in the program and observe.

I'm interested also in the zeros in the registers, and also in the fields you don't set deliberately. Don't mask them when sending out. Perform the whole setup, and only just before attempting to send, transmit the *whole* registers, no masking.

This would be easier to do in debugger.

JW

placidity.master_gmail.com
Associate III
January 15, 2021

I made a measurement directly on the output of the IC,

and just in case, I measured the neighboring pins 5 steps

in each direction. I didn't see anything new. and just in case,

I took a reserve STM32F3DISCOVERY board, and its behavior is the same.

================================================================================

spi_2_put_string( "1", 1 );      // test. work.

spi_2_send_next_msg();

after send, debug the REG:

-------------------------------------------------------------------------------------------

uart_1_send_debug_var_1 ( (uint32_t) RCC->APB1ENR ) ;

DEBG: var 1 : 0x10024000

0001 0000  0000 0010  0100 0000  0000 0000

_________________________!

//RCC->APB1ENR |= ( 1 << 14 );

-------------------------------------------------------------------------------------------

uart_1_send_debug_var_1 ( (uint32_t) GPIOB->MODER ) ;

DEBG: var 1 : 0xAA000280

1010 1010  0000 0000  0000 0010  1000 0000

_______!

//GPIOB->MODER |= ( 1 << 25 );

-------------------------------------------------------------------------------------------

uart_1_send_debug_var_1 ( (uint32_t) GPIOB->OSPEEDR ) ;

DEBG: var 1 : 0xFF0000C0

1111 1111  0000 0000  0000 0000  1100 0000

_______!!

//GPIOB->OSPEEDR |= (( 1 << 24 ) | ( 1 << 25 ));

------------------------------------------------------------------------------------------

uart_1_send_debug_var_1 ( (uint32_t) GPIOB->AFR[1] ) ;

DEBG: var 1 : 0x55550000

0101 0101   0101 0101   0000 0000   0000 0000

___________________!_!

//GPIOB->AFR[1] |= (( 1 << 16 ) | ( 1 << 18 ));

-------------------------------------------------------------------------------------------

uart_1_send_debug_var_1 ( (uint32_t) SPI2->CR1 ) ;

DEBG: var 1 : 0x0000007F

0000 0000   0000 0000   0000 0000   0111 1111

_________________________________________!!_!

//SPI2->CR1 |= 1<<3 | 1<<4 | 1<<5 ;

   //   APB_1_FREQ

   //   Bits 5:3 BR[2:0]: Baud rate control

   //   000: f PCLK /2

   //   001: f PCLK /4

   //   010: f PCLK /8

   //   011: f PCLK /16

   //   100: f PCLK /32

   //   101: f PCLK /64

   //   110: f PCLK /128

   //   111: f PCLK /256

//SPI2->CR1 |= 1<<2;   

0000 0000   0000 0000   0000 0000   0111 1111

_____________________________________________!

//   Bit 2 MSTR: Master selection

//      0: Slave configuration

//      1: Master configuration

//   Note: This bit should not be changed when communication is ongoing.

//   This bit is not used in I 2 S mode.

//   SPI2->CR1 |= 1<<1;   

0000 0000   0000 0000   0000 0000   0111 1111

_____________________________________________!

   //   Bit1 CPOL: Clock polarity

   //   0: CK to 0 when idle

   //   1: CK to 1 when idle

   //   Note: This bit should not be changed when communication is ongoing.

   //   This bit is not used in I 2 S mode and SPI TI mode except the case when CRC is applied at TI mode.

   //

   //SPI2->CR1 |= 1;

   0111 1111

   ________!

   //   Bit 0 CPHA: Clock phase

   //      0: The first clock transition is the first data capture edge

   //      1: The second clock transition is the first data capture edge

   //   Note: This bit should not be changed when communication is ongoing.

   //   This bit is not used in I 2 S mode and SPI TI mode except the case when CRC is applied at TI mode.

placidity.master_gmail.com
Associate III
January 15, 2021

uart_1_send_debug_var_1 ( (uint32_t) SPI2->CR2 ) ;

DEBG: var 1 : 0x000017EC

0000 0000   0000 0000    0001 0111   1110 1100

                             12 bit ok

                                10

                                 9

                                  8 bit ok

                                       7 bit ok

                                        6 bit ok

                                         5 bit ok

                                          4 bit ok

                                            3 bit ok

                                             2 bit ok

                                              1;0; bit ok

   //   Bit 12 FRXTH: FIFO reception threshold

   //   This bit is used to set the threshold of the RXFIFO that triggers an RXNE event

   //   0: RXNE event is generated if the FIFO level is greater than or equal to 1/2 (16-bit)

   //   1: RXNE event is generated if the FIFO level is greater than or equal to 1/4 (8-bit)

   //   Note: This bit is not used in I2S mode.

SPI2->CR2 |= 1<<12;

   //   Bits 11:8 DS [3:0]: Data size

   //   These bits configure the data length for SPI transfers:

   //   0000: Not used

   //   0001: Not used

   //   0010: Not used

   //   0011: 4-bit

   //   0100: 5-bit

   //   0101: 6-bit

   //   0110: 7-bit

   //   0111: 8-bit

   //   1000: 9-bit

   //   1001: 10-bit

   //   1010: 11-bit

   //   1011: 12-bit

   //   1100: 13-bit

   //   1101: 14-bit

   //   1110: 15-bit

   //   1111: 16-bit

   //   If software attempts to write one of the “Not used�? values, they are forced to the value “0111�?(8-bit).

   //   Note: This bit is not used in I2S mode.

   // on reset is 8 bit;

   //SPI2->CR2 |= 1<<8 | 1<<9 | 1<<10 | 1<<11;

   SPI2->CR2 |= 1<<8 | 1<<9 | 1<<10;

   //   Bit 7 TXEIE: Tx buffer empty interrupt enable

   //   0: TXE interrupt masked

   //   1: TXE interrupt not masked. Used to generate an interrupt request when the TXE flag is set.

   SPI2->CR2 |= 1<<7 ;

   inner_sync();

   //   Bit 6 RXNEIE: RX buffer not empty interrupt enable

   //   0: RXNE interrupt masked

   //   1: RXNE interrupt not masked. Used to generate an interrupt request when the RXNE flag is set.

   SPI2->CR2 |= 1<<6;

   inner_sync();

   //   Bit 5 ERRIE: Error interrupt enable

   //   This bit controls the generation of an interrupt when an error condition occurs (CRCERR,

   //   OVR, MODF in SPI mode, FRE at TI mode and UDR, OVR, and FRE in I 2 S mode).

   //   0: Error interrupt is masked

   //   1: Error interrupt is enabled

   SPI2->CR2 |= 1<<5;

   inner_sync();

   //   Bit 4 FRF: Frame format

   //   0: SPI Motorola mode

   //   1 SPI TI mode

   //   SPI2->CR2 |= 1<<4;

   //   Bit 2 SSOE: SS output enable

   //   0: SS output is disabled in master mode and the SPI interface can work in multimaster

   //   configuration

   //   1: SS output is enabled in master mode and when the SPI interface is enabled. The SPI

   //   interface cannot work in a multimaster environment.

   //   Note: This bit is not used in I 2 S mode and SPI TI mode.

   SPI2->CR2 |= 1<<2;

-------------------------------------------------------------------------------------------

// try to heand directly drive

// gpio B reset val : 0x0000 0280

GPIOB->MODER |= ( 1 << 24 );

directly manual check pin :

#define SET_PORT_B_BIT(IN)      ( GPIOB->BSRR = 1 << IN )

#define RESET_PORT_B_BIT(IN)   ( GPIOB->BSRR = ( 1 << IN ) << 16 )

by systick: (2 Hz)

SET_PORT_B_BIT(12);

RESET_PORT_B_BIT(12);

it work fine.

waclawek.jan
Super User
January 15, 2021

According to RM, you are not supposed to set NSSP and CPHA simultaneously.

Try with CPHA=0.

JW

placidity.master_gmail.com
Associate III
January 16, 2021

thanks for the tip

yes, with CPHA=0, NSS works as it should, but there is another problem, in the documentation

for LTC6804, in the description of the 4-wire SPI interface, it is specified:

"the 4-wire serial port is configured to operate in a SPI

system using CPHA = 1 and CPOL = 1. Consequently, data

on SDI must be stable during the rising edge of SCK."

and in the description of isoSPI it is not specified about a phase and other,

but I so understand that isoSPI has to send signals according to logic of 4 wire SPI

"Standard SPI signals are encoded into differential pulses."

it turns out that STM will not be able to communicate with LTC6804 ?

waclawek.jan
waclawek.janBest answer
Super User
January 17, 2021

I had a look at the LTC6804 and it appears to be a very complicated chip and I am not going to try to understand its working. However, this

CSB must remain low

for the entire duration of a command sequence, including

between a command byte and subsequent data.

indicates, that the STM32 SPI NSS pulsing mode is not usable for your case anyway.

So, the best thing to do is to set NSS to GPIO, and control it "manually", according to the required protocol.

JW

placidity.master_gmail.com
Associate III
January 17, 2021

thank you for advice.

I suspected it, but I wasn't entirely sure.

due to little experience.

processing CSB manually is in theory a problem,

because the CPU can be distracted by interrupts,

and the time diagrams will float away,

and it is difficult to imagine what will happen in the end.