2025-04-16 6:56 AM
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.
green -> clk
yellow -> cs
blue Mosi
same code with delay activated
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
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
2025-04-16 7:39 AM
"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
2025-04-16 8:08 AM
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
2025-04-16 8:22 AM
I suggest review of how HAL_SPI_Transmit() operates for the 8-bit data case.
2025-04-16 8:58 AM
Are you observing SPI register contents with the debugger, while transmit occurs?
That can interfere with SPI operation.
2025-04-16 10:45 PM
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:
2025-04-17 2:25 AM
Executing code from flash, send 8bits in place of 4, pushing the second byte into the TXDR seems to cancel the ongoing transmission