cancel
Showing results for 
Search instead for 
Did you mean: 

SPI transmition stop after first 4bits

andre239955_stm1_stmicro
Associate III

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

6 REPLIES 6
Chris21
Senior II

"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

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

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

Chris21
Senior II

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

That can interfere with SPI operation. 

andre239955_stm1_stmicro
Associate III

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

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