AnsweredAssumed Answered

STM32F7 SPI5 simple config and test fail

Question asked by karpavicius.linas on Jul 24, 2015
Latest reply on Nov 20, 2015 by Phan.Le_Son
Hello, since i have lot of problems with HAL drivers, maybe some one could help me:

I need SPI5 in software CS mode and full duplex 2 lines. Here is my config:

SPI_HandleTypeDef hspi5;
 
void Piezo_SPI_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
   
  __GPIOA_CLK_ENABLE();
  __GPIOF_CLK_ENABLE();
  __SPI5_CLK_ENABLE();
   
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
  hspi5.Instance = SPI5;
  hspi5.Init.Mode = SPI_MODE_MASTER;
  hspi5.Init.Direction = SPI_DIRECTION_2LINES;
  hspi5.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi5.Init.NSS = SPI_NSS_SOFT;
  hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi5.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
  hspi5.Init.CRCPolynomial = 10;
  hspi5.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi5.Init.NSSPMode = SPI_NSS_PULSE_ENABLED;
  HAL_SPI_Init(&hspi5);
}

Now i want to write/read data to spy bus, with as simple code as possible

original F4 code for that is

uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx)
{
  /* Check the parameters */
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
   
  /* Return the data in the DR register */
  return SPIx->DR;
}
 
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_SPI_ALL_PERIPH_EXT(SPIx));
  /* Write in the DR register the data to be sent */
  SPIx->DR = Data;
}

But HAL libraries could make that better !

HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  __IO uint16_t tmpreg;
   
  if(hspi->State != HAL_SPI_STATE_READY)
  {
    return HAL_BUSY;
  }
   
  if((pData == NULL ) || (Size == 0))
  {
    return HAL_ERROR;
  }
 
  if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
  {
    /* the receive process is not supported in 2Lines direction master mode */
    /* in this case we call the transmitReceive process                     */
    return HAL_SPI_TransmitReceive(hspi,pData,pData,Size,Timeout);
  }
   
  /* Process Locked */
  __HAL_LOCK(hspi);
     
  hspi->State       = HAL_SPI_STATE_BUSY_RX;
  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
  hspi->pRxBuffPtr  = pData;
  hspi->RxXferSize  = Size;
  hspi->RxXferCount = Size;
  hspi->pTxBuffPtr  = (uint8_t *)NULL;
  hspi->TxXferSize  = 0;
  hspi->TxXferCount = 0;
 
  /* Reset CRC Calculation */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    SPI_RESET_CRC(hspi);
    /* this is done to handle the CRCNEXT before the latest data */
    hspi->RxXferCount--;
  }
 
  /* Set the Rx Fido threshold */
  if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
  {
    /* set fiforxthreshold according the reception data length: 16bit */
    CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
  }
  else
  {
    /* set fiforxthreshold according the reception data length: 8bit */
    SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
  }
 
  /* Configure communication direction 1Line and enabled SPI if needed */
  if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
  {
    SPI_1LINE_RX(hspi);
  }
 
  /* Check if the SPI is already enabled */
  if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
  {
    /* Enable SPI peripheral */
    __HAL_SPI_ENABLE(hspi);
  }
 
  /* Receive data in 8 Bit mode */
  if(hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
  {
    while(hspi->RxXferCount > 1)
    {
      /* Wait until the RXNE flag */
      if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      (*hspi->pRxBuffPtr++)= *(__IO uint8_t *)&hspi->Instance->DR;
      hspi->RxXferCount--; 
    }
  }
  else /* Receive data in 16 Bit mode */
  {  
    while(hspi->RxXferCount > 1 )
    {
      /* Wait until RXNE flag is reset to read data */
      if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
      hspi->pRxBuffPtr += sizeof(uint16_t);
      hspi->RxXferCount--;
    }
  }
   
  /* Enable CRC Transmission */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;
  
 
  /* Wait until RXNE flag is set */
  if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, Timeout) != HAL_OK)
  {
    return HAL_TIMEOUT;
  }
   
  /* Receive last data in 16 Bit mode */
  if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
  {       
    *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
    hspi->pRxBuffPtr += sizeof(uint16_t);
  }
  /* Receive last data in 8 Bit mode */
  else
  {
    (*hspi->pRxBuffPtr++) = *(__IO uint8_t *)&hspi->Instance->DR;
  }
  hspi->RxXferCount--;
   
  /* Read CRC from DR to close CRC calculation process */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    /* Wait until TXE flag */
    if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, Timeout) != HAL_OK)
    {
      /* Error on the CRC reception */
      hspi->ErrorCode|= HAL_SPI_ERROR_CRC;
    }
    if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
    {       
      tmpreg = hspi->Instance->DR;
      UNUSED(tmpreg); /* To avoid GCC warning */
    }
    else
    {
      tmpreg = *(__IO uint8_t *)&hspi->Instance->DR;
      UNUSED(tmpreg); /* To avoid GCC warning */
 
      if((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT))
      {
        if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, Timeout) != HAL_OK)
        {
          /* Error on the CRC reception */
          hspi->ErrorCode|= HAL_SPI_ERROR_FLAG;
        }
        tmpreg = *(__IO uint8_t *)&hspi->Instance->DR;
        UNUSED(tmpreg); /* To avoid GCC warning */
      }
    }
  }
   
  /* Check the end of the transaction */
  if(SPI_EndRxTransaction(hspi,Timeout) != HAL_OK)
  {
    return HAL_TIMEOUT;
  }
 
  hspi->State = HAL_SPI_STATE_READY;
     
  /* Check if CRC error occurred */
  if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
  {
    hspi->ErrorCode|= HAL_SPI_ERROR_CRC;
    __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
                   
    /* Process Unlocked */
    __HAL_UNLOCK(hspi);
    return HAL_ERROR;
  }
     
  /* Process Unlocked */
  __HAL_UNLOCK(hspi);
   
  if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
  {  
    return HAL_ERROR;
  }
  else
  {
    return HAL_OK;
  }
}


But i need to reduce this code to simple few lines of code

It should look like this, but it does not work, simply SPI is BUSSY, that's all i get !

while(((SPI5->SR & SPI_FLAG_TXE) == SPI_FLAG_TXE));
SPI5->DR = i;
while(((SPI5->SR & SPI_FLAG_RXNE) == SPI_FLAG_RXNE));
temp= SPI5->DR;

So does any one can tell me, why i can't send any data ? not even single packed was send, so i have no idea what's wrong here ( well, HAL libraries of course)

And for eagle thread readers, yes, i did disabled code, that use HAL gpio init funtion cal, since i already enabled right pin in AF mode prior SPI configuration, just like in good old SPL days

if(hspi->State == HAL_SPI_STATE_RESET)
{
  /* Allocate lock resource and initialize it */
  hspi->Lock = HAL_UNLOCKED;
 
  /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  //HAL_SPI_MspInit(hspi);
}



Outcomes