STM32H7 SPI TXP flag not resetting
Hi Everyone
I have a very strange issue in the SPI of my STM32H745.
Consider following information
0) No Master present on the Bus
1) SPI5 is configured in slave.
2) No interrupts, no DMA just polling
3) Following is the initialization code (FIFO is set to One byte)
STATIC void MX_SPI5_Init(void)
{
/* USER CODE BEGIN SPI5_Init 0 */
/* USER CODE END SPI5_Init 0 */
/* USER CODE BEGIN SPI5_Init 1 */
/* USER CODE END SPI5_Init 1 */
/* SPI5 parameter configuration*/
hspi5.Instance = SPI5;
hspi5.Init.Mode = SPI_MODE_SLAVE;
hspi5.Init.Direction = SPI_DIRECTION_2LINES;
hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi5.Init.NSS = SPI_NSS_SOFT;
hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi5.Init.CRCPolynomial = 0x0;
hspi5.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
hspi5.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi5.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi5.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi5.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi5.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi5.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi5.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi5.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi5.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if (HAL_SPI_Init(&hspi5) != HAL_OK)
{
// Error_Handler(); //todo
}
/* USER CODE BEGIN SPI5_Init 2 */
/* USER CODE END SPI5_Init 2 */
}4) When i call the function HAL_SPI_TransmitReceive() i enter in following code section of the function
while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
{
/* check TXP flag */
if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL))
{
if ((initial_TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA))
{
*((__IO uint32_t *)&hspi->Instance->TXDR) = *((uint32_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint32_t);
hspi->TxXferCount -= (uint16_t)4UL;
initial_TxXferCount = hspi->TxXferCount;
}
else if ((initial_TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
{
#if defined (__GNUC__)
*ptxdr_16bits = *((uint16_t *)hspi->pTxBuffPtr);
#else
*((__IO uint16_t *)&hspi->Instance->TXDR) = *((uint16_t *)hspi->pTxBuffPtr);
#endif /* __GNUC__ */
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount -= (uint16_t)2UL;
initial_TxXferCount = hspi->TxXferCount;
}
else
{
*((__IO uint8_t *)&hspi->Instance->TXDR) = *((uint8_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint8_t);
hspi->TxXferCount--;
initial_TxXferCount = hspi->TxXferCount;
}
}
/* Wait until RXWNE/FRLVL flag is reset */
if (((hspi->Instance->SR & (SPI_FLAG_RXWNE | SPI_FLAG_FRLVL)) != 0UL) && (initial_RxXferCount > 0UL))
{
if ((hspi->Instance->SR & SPI_FLAG_RXWNE) != 0UL)
{
*((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
hspi->pRxBuffPtr += sizeof(uint32_t);
hspi->RxXferCount -= (uint16_t)4UL;
initial_RxXferCount = hspi->RxXferCount;
}
else if ((hspi->Instance->SR & SPI_FLAG_FRLVL) > SPI_RX_FIFO_1PACKET)
{
#if defined (__GNUC__)
*((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
#else
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
#endif /* __GNUC__ */
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount -= (uint16_t)2UL;
initial_RxXferCount = hspi->RxXferCount;
}
else
{
*((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
hspi->pRxBuffPtr += sizeof(uint8_t);
hspi->RxXferCount--;
initial_RxXferCount = hspi->RxXferCount;
}
}
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Process Unlocked */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_ERROR;
}
}Problem:
When following line of code is executed
*((__IO uint8_t *)&hspi->Instance->TXDR) = *((uint8_t *)hspi->pTxBuffPtr);i am expecting the TXP flag to get reset, but it get reset only when i execute above line of code 8 times, but my FIFO is set to one.
Following is the screenshot of debug window
What is missing, am i doing something wrong.
just for the information initial_RxXferCount is not decrementing that means indeed the master is not clocking. Also if i write manually some data in TXDR register through expression window during Debug then TXP flags get reset (as expected)
Please let me know if you need more information.
