cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U5xx: SPI3 slave fails at 80 MHz

tjaekel
Lead

I use OCTOSPI as SPI master and listen via SPI3 as Slave (in SW NCS mode) what was sent from master.

SPI3 Slave fails for clock speed 80 MHz (larger as 54 MHz:(

Symptoms:

  • the data bytes on SPI3 slave are wrong (they look like shifted by one bit)
  • running my command again results in a hang (polling status seems to fail)
  • with OCTALSPI DIV = 3 (53.333 MHz) - all looks fine still
  • so, SPI3 can keep up with 54 MHz as a SPI slave

Also realized:

with debug options (-g3, -Og) it fails earlier, already 40 MHz is the fastest I can get. But OK (obvious: with better optimization a faster speed for polling).

I use these conditions:

  • QSPI (OCTOSPI in QSPI mode) is the master
  • SPI3 is a slave, just using SCK and MOSI (NCS is in SW mode)
  • QSPI sends in indirect mode, via "polling" (checking FIFO threshold before to send a new byte)
  • SPI3 polls also, its SPI_FLAG_RXP
  • both are combined in one SW loop (with polling status)

 

	      do
	      {
	    	*((__IO uint8_t *)data_reg) = *hospi->pBuffPtr;

	        /* Wait till fifo threshold or transfer complete flags are set to read received data */
	        status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout);

	        if (status != HAL_OK)
	        {
	          break;
	        }

	        if (i == 0)
	        {
	        	/* on first iteration we get CMD and one byte! */
	        	while ( ! __HAL_SPI_GET_FLAG(&hspi3, SPI_FLAG_RXP)) {;}
	        	*(hospi->pBuffPtr - 1) = SPI3->RXDR;
	        	while ( ! __HAL_SPI_GET_FLAG(&hspi3, SPI_FLAG_RXP)) {;}
	        	*hospi->pBuffPtr = SPI3->RXDR;
	        	i = 1;
	        }
	        else
	        {
	        	while ( ! __HAL_SPI_GET_FLAG(&hspi3, SPI_FLAG_RXP)) {;}
	        	*hospi->pBuffPtr = SPI3->RXDR;			//XXXX
	        }

	        hospi->pBuffPtr++;
	        hospi->XferCount--;
	      } while (hospi->XferCount > 0U);

 

I was expecting to see SPI3 as slave receiver working up to the same speed as OCTOSPI (80 MHz).

But it works only up to 53.333 MHz (but still OK for my purpose, 40 MHz as "regular SPI via OCTOSPI as QSPI).

 

1 ACCEPTED SOLUTION

Accepted Solutions

OK, the same statements found in U5A5 datasheet (not using U575):

100 MHz as SPI Slave, VDD=1V8 should be possible.
(1.71 V ≤ VDDIOX ≤ 3.6 V, voltage range 1)
I run voltage range 1.

It is just a SPI Slave:

  /* SPI3 parameter configuration*/
  hspi3.Instance = SPI3;
  hspi3.Init.Mode = SPI_MODE_SLAVE;
  hspi3.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;	//SPI_DIRECTION_2LINES;
  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;				//SPI3 only 8 or 16bit !!

Not very important as long as 40 MHz works (for me).

The duty cycle maybe matters (50%, as mentioned in note 3):
3. The maximum frequency in slave transmitter mode is determined by the sum of tv(SO) and tsu(MI) that has to fit into SCK low
or high phase preceding the SCK sampling edge. This value can be achieved when the SPI communicates with a master
having tsu(MI) = 0 while Duty(SCK) = 50%.

This one I cannot influence: it is generated by the OCTOSPI.

 

I close the ticket, never mind (don't waste your time with it. Just to have it reported as "unexpected" result.

 

 

View solution in original post

3 REPLIES 3
STOne-32
ST Employee

Dear @tjaekel ,

thank you for the question . It may happen a timing issue either by definition of some specific I/Os and voltage range / VOS or also by loading capacitors ( matching Master Output valid and setup time ) to meet within the half cycle sampling . 

IMG_6452.jpeg


We need to investigate it closely in your setup and used I/Os then have the corrective plan .

Hope it helps you.

Cheers,

STOne-32

I run MCU VDD = 1V8.

There is no load (just a scope connected, no device).

Let's see (the SPI3 in STM32U5A5 is anyway a bit "strange", e.g. this limitation mentioned for 1024 bytes max., assuming via DMA)

OK, the same statements found in U5A5 datasheet (not using U575):

100 MHz as SPI Slave, VDD=1V8 should be possible.
(1.71 V ≤ VDDIOX ≤ 3.6 V, voltage range 1)
I run voltage range 1.

It is just a SPI Slave:

  /* SPI3 parameter configuration*/
  hspi3.Instance = SPI3;
  hspi3.Init.Mode = SPI_MODE_SLAVE;
  hspi3.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;	//SPI_DIRECTION_2LINES;
  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;				//SPI3 only 8 or 16bit !!

Not very important as long as 40 MHz works (for me).

The duty cycle maybe matters (50%, as mentioned in note 3):
3. The maximum frequency in slave transmitter mode is determined by the sum of tv(SO) and tsu(MI) that has to fit into SCK low
or high phase preceding the SCK sampling edge. This value can be achieved when the SPI communicates with a master
having tsu(MI) = 0 while Duty(SCK) = 50%.

This one I cannot influence: it is generated by the OCTOSPI.

 

I close the ticket, never mind (don't waste your time with it. Just to have it reported as "unexpected" result.