Skip to main content
Visitor II
April 22, 2024
Question

Minimizing SCLK pulse time on SPI with STM32H745

  • April 22, 2024
  • 7 replies
  • 3094 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.

    7 replies

    Super User
    April 22, 2024

    Use DMA.

    JW

    Graduate II
    April 22, 2024

    Start by using the FIFO.

    Graduate II
    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
    Visitor II
    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. 

    Graduate II
    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
    Visitor II
    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

     

    Graduate II
    April 23, 2024

    I do not use HAL

    dplogiicAuthor
    Visitor II
    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
    Visitor II
    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
    Visitor II
    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;

    }