Skip to main content
andre239955_stm1_stmicro
Associate III
April 16, 2025
Question

SPI transmition stop after first 4bits

  • April 16, 2025
  • 5 replies
  • 2036 views

Hello 
I'm using trying to access to an external flash through the SPI
I try to send 5 bytes, my SPI transmit function work well if I put some delay (1us) between each byte, if I don't put this delay transmission start and stop just after 4bits.

andre239955_stm1_stmicro_0-1744810925721.png

green -> clk
yellow -> cs
blue Mosi
same code with delay activated

andre239955_stm1_stmicro_1-1744811271887.png

Here below the code

__attribute__((optimize("O0"),long_call, section (".code_in_ram")))
int SPI4_Transmit(const uint8_t *pdata,uint16_t Size, uint32_t Timeout)
{
	//SPI_2LINES_RX(SPI4);
	MODIFY_REG(SPI4->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_0);
	/* Set the number of data at current transfer */
	MODIFY_REG(SPI4->CR2, SPI_CR2_TSIZE, Size);
	/* Enable SPI peripheral */
	IS25_SPI_ENABLE
 /* Master transfer start */
	IS25_SPI_START
 /* Transmit data in 8 Bit mode, see SPI init */
 uint16_t TxCount = Size;
 /* Transfer loop */
 uint32_t au32_microsec = 8*( HAL_RCC_GetHCLKFreq() / 1000000 );
 uint32_t au32_millisec = au32_microsec * 1000;
 uint32_t au32_initial_ticks = DWT->CYCCNT;
 int ret = 0;

 const uint8_t * pTxBuffPtr = (const uint8_t *)pdata;

 while (TxCount > 0UL)
 {
 /* Check the TXP flag */
 if ((SPI4->SR & SPI_FLAG_TXP) == SPI_FLAG_TXP)
 	{
 *((__IO uint8_t *)&SPI4->TXDR) = *((const uint8_t *)pTxBuffPtr);
 pTxBuffPtr += sizeof(uint8_t);
 		TxCount--;
 	}
 else /* Timeout management */
 {
 		if ((DWT->CYCCNT - au32_initial_ticks) > (Timeout*au32_millisec))
 		{
				ret = -1;
				break;
 		}
 }
 // Wait some time before continuing why???? without that is not working, normally SPI_FLAG_TXP should take care of availablity of space
 uint32_t au32_ticks = DWT->CYCCNT + 500;
 		while (DWT->CYCCNT < au32_ticks);
 }

 	// Done, wait end of transmission
 	if (0 == ret)
 	{
 		while ((SPI4->SR & SPI_FLAG_EOT) != 0)
		{
			if ((DWT->CYCCNT - au32_initial_ticks) > (Timeout*au32_millisec))
			{
				ret = -1;
				break;
			}
		}
 	}
 	IS25_SPI_CLEAR_EOTFLAG
 IS25_SPI_CLEAR_TXTFFLAG
	IS25_SPI_DISABLE
	IS25_CLEAR_OVR
 return ret;
}

 

And register content before transmission loop

andre239955_stm1_stmicro_2-1744811441425.png

When delay is not there, I have the impress that uploading second byte interfere and cancel the transmission that is on going.  Adding the delay fix this but I don't understand where is the mistake, for me no delay is needed SPI_FLAG_TXP is there for that.
If you have any idea that you can share with me it coule be very nice
Thank-you

5 replies

Chris21
Associate II
April 16, 2025

"TXP flag is cleared when the TxFIFO contains less than FTHLV empty locations", as mentioned by TDK.  

https://community.st.com/t5/stm32-mcus-products/stm32h7-spi-txp-flag-not-resetting/td-p/186826

andre239955_stm1_stmicro
Associate III
April 16, 2025

thanks, but what will be the solution?  Don't use this test based on TXP_FLAG? but what else

My code is largely inspired from the HAL_SPI_Transmit(). If I replace my function by a call to HAL_SPI_Transmit() I don't have the problem, it's also based on the TXP_FLAG.
I compared registry content for both function before starting transmission and they are stricly the same, (FTHLV set to 1data)
Thank-you

Chris21
Associate II
April 16, 2025

I suggest review of how HAL_SPI_Transmit() operates for the 8-bit data case.

Chris21
Associate II
April 16, 2025

Are you observing SPI register contents with the debugger, while transmit occurs?

That can interfere with SPI operation. 

andre239955_stm1_stmicro
Associate III
April 17, 2025

Hello Chris21,

Thank-you to take time to trying to help me.
I effectively follow the 8bit transfer from the HAL function to create this one.
To test, I break before and after the function to avoid any interference during the transfer.
I did the same test with both function my and HAL, content of SPI register just before the transfer loop are equals.
Two difference that I can see:

  • My code is executed from Ram (I will move it and test from flash to see if it's impacting)

  • My code is a bit faster
andre239955_stm1_stmicro
Associate III
April 17, 2025

Executing code from flash, send 8bits in place of 4, pushing the second byte into the TXDR seems to cancel the ongoing transmission