2015-07-24 04:45 AM
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);
}
2015-07-30 07:11 AM
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''
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.
2015-07-30 07:59 AM
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;
2015-08-02 12:45 PM
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
2015-11-19 09:39 PM