AnsweredAssumed Answered

SPI Timeout problem

Question asked by Vigdor.Ari on Feb 28, 2016
Latest reply on Aug 19, 2016 by kircicek.yilmaz
Hi,
I'm using ST's driver for SPI in full -duplex, 8 bit, master mode. The function HAL_SPI_TransmitReceive() returns sometimes HAL_TIMEOUT. After inspecting code I don't understand the following:
The code below at line marked A===>: Waits for RXNE to get set. Then DR is read. this should clear the RXNE flag.
When this is last read operation in loop, we continue to B===>.
In B===> we again wait for RXNE to get set.
My questions are:
     1. How can RXNE be set if data was not sent on TX?
     2. Sometimes the check of RXNE in B===> passes. I can't understand how RXNE was set if prior to B we read DR (and therefore I would expect the flag to be cleared)?
     Thanks,
     Ari
     
===========================================
     
     /* Transmit and Receive data in 8 Bit mode */
    else
    {
      hspi->Instance->DR = (*hspi->pTxBuffPtr++);
      hspi->TxXferCount--;


      if(hspi->TxXferCount == 0)
      {


        /* Enable CRC Transmission */
        if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)
        {
          hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;
        }


        /* Wait until RXNE flag is set */
        if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
        {
          return HAL_TIMEOUT;
        }


        (*hspi->pRxBuffPtr) = hspi->Instance->DR;
        hspi->RxXferCount--;
      }
      else
      {
        while(hspi->TxXferCount > 0)
        {
          /* Wait until TXE flag is set to send data */
          if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)
          {
            return HAL_TIMEOUT;
          }


          hspi->Instance->DR = (*hspi->pTxBuffPtr++);
          hspi->TxXferCount--;


          /* Enable CRC Transmission */
          if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED))
          {
            hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;
          }


A===>     /* Wait until RXNE flag is set */
          if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
          {
            return HAL_TIMEOUT;
          }


          (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
          hspi->RxXferCount--;
        }


B===>  /* Wait until RXNE flag is set */
       if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)
        {
          return HAL_TIMEOUT;
        }


        (*hspi->pRxBuffPtr++) = hspi->Instance->DR;
        hspi->RxXferCount--;
      }
    }

Outcomes