Skip to main content
Visitor II
April 16, 2025
Question

SPI transmition stop after first 4bits

  • April 16, 2025
  • 5 replies
  • 503 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

    This topic has been closed for replies.

    5 replies

    Graduate
    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

    Visitor II
    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

    Graduate
    April 16, 2025

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

    Graduate
    April 16, 2025

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

    That can interfere with SPI operation. 

    Visitor II
    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
    Visitor II
    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