2024-04-22 06:37 AM
Hello STM community,
I'm working on optimizing SPI communication on an STM device, and I'm encountering an issue with the timing of SCLK pulses. After transmitting 16 SCLK pulses, there's a delay of 3μs before the next set of 16 pulses can be generated.
I need to reduce this delay to ensure that SCLK can be immediately generated after CS goes low. Can anyone suggest methods or configurations to minimize this delay and maintain a continuous SCLK stream after CS is pulled low?
I'm trying to achieve sampling rate for ADC ADS7046 interfacing.
sclk take same time even not used CS.
I want to sclk immediately on after cs low.
Below I attach some snap of spi cycle.
2024-04-23 03:43 AM
Probably HAL_Lock on H7 needs some communication between the multiple cores. It seems. HAL does not provide a block transfer mode. So for every transfer, the lock must be taken and release. A better way would be an extra call to lock the SPI, then do several plain transfers and after that unlock the device.
2024-04-23 04:00 AM
No, it is not __HAL_LOCK. It is more probable the receive callback. Try the blocking mode calls so no callback is involved.
2024-05-06 03:09 AM - edited 2024-05-06 03:14 AM
Hello team,
i'm trying with polling, interrupt, DMA and NSS metho also but I'm not get desire solution.
please anyone suggest another way to minimize sclk pulse regenerate/ off time... without delay it getting same time with sclk....
2024-05-06 11:29 PM
Hello team,
Any possibilities minimize timing in hal_spi.c file
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint32_t tickstart;
HAL_StatusTypeDef errorcode = HAL_OK;
#if defined (__GNUC__)
__IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
#endif /* __GNUC__ */
/* Check Direction parameter */
assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
/* Lock the process */
__HAL_LOCK(hspi);
/* Init tickstart for timeout management*/
tickstart = HAL_GetTick();
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
__HAL_UNLOCK(hspi);
return errorcode;
}
if ((pData == NULL) || (Size == 0UL))
{
errorcode = HAL_ERROR;
__HAL_UNLOCK(hspi);
return errorcode;
}
/* Set the transaction information */
hspi->State = HAL_SPI_STATE_BUSY_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pRxBuffPtr = (uint8_t *)pData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;
/*Init field not used in handle to zero */
hspi->pTxBuffPtr = NULL;
hspi->TxXferSize = (uint16_t) 0UL;
hspi->TxXferCount = (uint16_t) 0UL;
hspi->RxISR = NULL;
hspi->TxISR = NULL;
/* Configure communication direction: 1Line */
if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
{
SPI_1LINE_RX(hspi);
}
else
{
SPI_2LINES_RX(hspi);
}
/* Set the number of data at current transfer */
MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
if (hspi->Init.Mode == SPI_MODE_MASTER)
{
/* Master transfer start */
SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
}
/* Receive data in 32 Bit mode */
if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
{
/* Transfer loop */
while (hspi->RxXferCount > 0UL)
{
/* Check the RXWNE/EOT flag */
if ((hspi->Instance->SR & (SPI_FLAG_RXWNE | SPI_FLAG_EOT)) != 0UL)
{
*((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
hspi->pRxBuffPtr += sizeof(uint32_t);
hspi->RxXferCount--;
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_TIMEOUT;
}
}
}
}
/* Receive data in 16 Bit mode */
else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
{
/* Transfer loop */
while (hspi->RxXferCount > 0UL)
{
/* Check the RXP flag */
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
{
#if defined (__GNUC__)
*((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
#else
*((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
#endif /* __GNUC__ */
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_TIMEOUT;
}
}
}
}
/* Receive data in 8 Bit mode */
else
{
/* Transfer loop */
while (hspi->RxXferCount > 0UL)
{
/* Check the RXP flag */
if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
{
*((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
hspi->pRxBuffPtr += sizeof(uint8_t);
hspi->RxXferCount--;
}
else
{
/* Timeout management */
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
hspi->State = HAL_SPI_STATE_READY;
return HAL_TIMEOUT;
}
}
}
}
#if (USE_SPI_CRC != 0UL)
if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* Wait for crc data to be received */
if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
}
#endif /* USE_SPI_CRC */
/* Call standard close procedure with error check */
SPI_CloseTransfer(hspi);
/* Unlock the process */
__HAL_UNLOCK(hspi);
hspi->State = HAL_SPI_STATE_READY;
if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
{
return HAL_ERROR;
}
return errorcode;
}