AnsweredAssumed Answered

STM32L0 SPI CRC Error

Question asked by Tansem on Apr 25, 2015
Hi,

I modify the spi sample code but enable CRC function, however I always get CRCERR. I dont know the reason.

Here is the initialization of SPI:

     SPI2->CR1 |= SPI_BAUDRATEPRESCALER_256;     
     SPI2->CR1 &= ~SPI_CR1_CPOL;
     SPI2->CR1 &= ~SPI_CR1_CPHA;
     SPI2->CR1 &= ~SPI_CR1_BIDIMODE;
     SPI2->CR1 |= SPI_CR1_CRCEN;     
     SPI2->CR1 &= ~SPI_CR1_RXONLY;
     SPI2->CR1 |= SPI_CR1_SSM;
     SPI2->CR1 |= SPI_CR1_SSI;     
     SPI2->CR1 &= ~SPI_CR1_LSBFIRST;
     SPI2->CR1 |= SPI_CR1_MSTR;
     SPI2->CR1 &= ~SPI_CR1_DFF;
  /* Configure : NSS management */
     SPI2->CR2 |= SPI_CR2_SSOE;

  /* Configure : CRC Polynomial */
  SPI2->CRCPR = 0x07;  //reset value

Here is the Transmit function:
uint8_t SPI_Transmit(uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
     __IO uint16_t tmpreg;
     uint8_t* pTxBuffPtr = pData;
     uint16_t TxCount = Size;

  if(SPI_State == SPI_STATE_READY)
  {     
    if((pTxBuffPtr == NULL ) || (TxCount == 0)) 
    {
      return  STATUS_ERROR;
    }
          
     SPI_State = SPI_STATE_BUSY_TX;
          
    /* Reset CRC Calculation */
          if(SPI2->CR1 & SPI_CR1_CRCEN)
          {
               SPI2->CR1 &= ~SPI_CR1_CRCEN;
               SPI2->CR1 |= SPI_CR1_CRCEN;
          }
    /* Check if the SPI is already enabled */ 
    if((SPI2->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
    {
      /* Enable SPI peripheral */
      SPI2->CR1 |=  SPI_CR1_SPE;
    }


          if(TxCount == 0x01)
          {
               SPI2->DR = *pTxBuffPtr++;
               TxCount--;
          }
          
          while(TxCount > 0)
          {
               /* Wait until TXE flag is set to send data */
               if(SPI_WaitOnFlagUntilTimeout(SPI_SR_TXE, RESET, Timeout) != STATUS_OK)
               
                    return STATUS_TIMEOUT;
               }
               SPI2->DR = *pTxBuffPtr++;
               TxCount--;
          }
          
          /* Enable CRC Transmission */
          if(SPI2->CR1 & SPI_CR1_CRCEN) 
          {
               SPI2->CR1 |= SPI_CR1_CRCNEXT;
          }


    /* Wait until TXE flag is set to send data */
    if(SPI_WaitOnFlagUntilTimeout(SPI_SR_TXE, RESET, Timeout) != STATUS_OK)
    {
      return STATUS_TIMEOUT;
    }


    /* Wait until Busy flag is reset before disabling SPI */
    if(SPI_WaitOnFlagUntilTimeout(SPI_SR_BSY, SET, Timeout) != STATUS_OK)
    { 
      return STATUS_TIMEOUT;
    }
 
    /* Clear OVERUN flag in 2 Lines communication mode because received is not read */
    if((SPI2->CR1 & SPI_CR1_BIDIMODE) == 0)
    {
      tmpreg = SPI2->DR;
      tmpreg = SPI2->SR;
    }


     SPI_State = SPI_STATE_READY;
    return STATUS_OK;
     }
  else
  {
    return STATUS_BUSY;
  }
}


After call this function, CRCERR bit will be set.
I enable CRCNEXT bit after last data is written to the SPI_DR register.
It should be ok right?
What is the problem? Please help me.
Thank you.

Outcomes