Skip to main content
Philipp Caha
Associate
May 2, 2017
Question

Very slow HAL (SPI)

  • May 2, 2017
  • 4 replies
  • 3154 views
Posted on May 02, 2017 at 09:16

Hi,

I use the HAL Library for a STM32L4 MCU clocked at 80MHz. The time between two Bytes are 3us. This is to slow for my Application, but I can not transfer more bytes or use a DMA, because I must react on a Signal from a pin.

for (int i = 2; i < 8; i++)

{

        HAL_SPI_TransmitReceive(&hspi1, (uint8_t *)&awTxBuffer[i], (uint8_t *)&awRxBuffer[i], 1, 0x00);

        while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

//            while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5));

}

Is there a way to speed up my Application?

Thanks for hints,

Philipp

    This topic has been closed for replies.

    4 replies

    Philipp Caha
    Associate
    May 2, 2017
    Posted on May 02, 2017 at 10:35

    The last Parameter is a timeout, but it seems to be a frame timing parameter. So when I set the SPI clock from 8 to 4 MHz, the GAP between the bytes is 1.67us. At 8 MHz the bytes are faster on the bus, but the GAP is 3us.

    Tesla DeLorean
    Guru
    May 2, 2017
    Posted on May 02, 2017 at 17:48

    >>Is there a way to speed up my Application?

    Not use HAL, and review the use of the registers more directly.

    At the very least inspect the current library source code to understand what it is doing, and where the time might be going.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Chris1
    Associate II
    May 2, 2017
    Posted on May 02, 2017 at 18:11

    Consider use of Low Level functions, for example:

    static uint8_t SPI2_ReadByte (void)

    {

        uint32_t start_time_r;

        uint32_t this_time_r;

        while (LL_SPI_IsActiveFlag_RXNE(SPI2))

        {

            (void)LL_SPI_ReceiveData8(SPI2);      // flush any FIFO content

        }

        while (!LL_SPI_IsActiveFlag_TXE(SPI2))

        {

            ;

        }

        start_time_r = HAL_GetTick();

        LL_SPI_TransmitData8(SPI2, 0xFF);   // send dummy byte

        while (!LL_SPI_IsActiveFlag_RXNE(SPI2))

        {

            this_time_r = HAL_GetTick() - start_time_r;

            if (this_time_r > SPI2_READ_TIMEOUT)

            {

                // timeout error!

                break; 

            }

        }

        return(LL_SPI_ReceiveData8(SPI2));

    }
    Philipp Caha
    Associate
    May 9, 2017
    Posted on May 09, 2017 at 12:21

    Thank you, this was very helpful. It runs 5 times faster.

    S.Ma
    Principal
    July 28, 2017
    Posted on July 28, 2017 at 08:30

    When getting more familiar with the hw peripherals, max average speed can be further improved. Search for Interrupt based state machine, where pseudo program is clocked by interrupt events such as dma or exti.