cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 SPI5 simple config and test fail

megahercas6
Senior
Posted on July 24, 2015 at 13:45

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);
}

4 REPLIES 4
Amel NASRI
ST Employee
Posted on July 30, 2015 at 16:11

Hikarpavicius.linas,

I am not sure that you will get the SPI registers updated using ''

SPI5->DR = i;'' for example.

The SPI DR register is accessible with ''

hspi->Instance->DR''

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java/STM32F7Cube%20SPI%20with%20Circular%20DMA

to similar discussion.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on July 30, 2015 at 16:59

Want to wait while !=

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
megahercas6
Senior
Posted on August 02, 2015 at 21:45

My first program worked after i found that

HAL_SPI_Init(&hspi5);

simply reconfigured my pin's as called into gpio init function that was generated by CubeMx, so all i have to do is to modify stm32f7xx_hal_spi.c SPI_Init function so it will be more like SPL
son1
Associate II
Posted on November 20, 2015 at 06:39

Try to add below code in Init function of SPI:

''

 __HAL_SPI_ENABLE_IT(&hspi5, (SPI_IT_RXNE));

 __HAL_SPI_ENABLE(&hspi5);

''