Skip to main content
Associate III
April 22, 2024
Question

Minimizing SCLK pulse time on SPI with STM32H745

  • April 22, 2024
  • 13 replies
  • 4743 views

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.

dplogiic_0-1713792741909.png

dplogiic_1-1713792774343.pngdplogiic_2-1713792788831.pngdplogiic_3-1713792800189.png

 

dplogiic_4-1713792925306.png

 

This topic has been closed for replies.

13 replies

waclawek.jan
Super User
April 22, 2024

Use DMA.

JW

Uwe Bonnes
Chief
April 22, 2024

Start by using the FIFO.

Uwe Bonnes
Chief
April 22, 2024

If you need the framing with CS, read the reference and understand how NSS can  be used to automaitcally generate the frame around a packet.

dplogiicAuthor
Associate III
April 23, 2024

Hello Uwe Bonnes,

Thanks for reply. I also used DMA with normal mode then frame also same as above with additional delay. So then I am trying with circular DMA that time data not read as given. and SCLK generated continuous and cs not toggle. please can you provide one example code with stm32h745 SPI DMA. I want to achieve 3msps sampling rate for ADC ads7046. 

Uwe Bonnes
Chief
April 23, 2024

The timing above does not look like hardware NSS. When using hardware NSS the timing between NSS and clock and between transfers is set by SPI_CFG2_MIDI and MSSI. HAL will probably have a way to set hardware NSS and those values, adding however a level of obfuscation between the reference manual and theseetings needed by HAL

dplogiicAuthor
Associate III
April 23, 2024

yes Uwe Bonnes, can you please provide example code and setting what to do. and which mode i need to select normal or circular dma?

dplogiic_0-1713863114800.pngdplogiic_1-1713863277077.png

 

Uwe Bonnes
Chief
April 23, 2024

I do not use HAL

dplogiicAuthor
Associate III
April 23, 2024

it's ok. can you share it. any type of example you can share. 

now i used with hardware nss 

blue= sclk, red= nss

dplogiic_0-1713867972243.png

dplogiic_1-1713868013743.png

how can i minimize sclk time 

dplogiic_2-1713868120739.png

dplogiic_3-1713868160985.png

without buffer print it also take same time.

 

dplogiicAuthor
Associate III
May 6, 2024

Hello team, 

i'm trying with polling, interrupt, DMA and NSS metho also but I'm not get desire solution. 

dplogiic_0-1714990103891.pngdplogiic_1-1714990123773.png

please anyone suggest another way to minimize sclk pulse regenerate/ off time...   without delay it getting same time with sclk.... 

 

dplogiicAuthor
Associate III
May 7, 2024

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;

}