Skip to main content
Graduate
April 23, 2024
Question

Delay in SPI Transfer with STM32H7

  • April 23, 2024
  • 11 replies
  • 3442 views

Dear Forum

Im using STM32 H755 ZI in the starter kit.

 

I set the Timer 4 for generate a Interrupt each 1ms.

At begin of INT:

     -I toggle a PIN,

      -and, send a SPI data (8 byte or 16..not important)

What I noted is a delay of almost 10uS beetwen pin toggle and begin of 1st bit TX from

SPI (begin of SPI transmission i means)

Some data:

FCPU=64M coming from internal 64M HSI

SPI1_CLK=4M coming from PER_CLK =64M  (with SPI prescaler=16  -->4M) 

FAPB=64M

Code inside INT Timer:

HAL_GPIO_TogglePin(PF10Test_GPIO_Port, PF10Test_Pin);

HAL_SPI_Transmit(&hspi1, p_Data16b, 1, 100);

__HAL_TIM_CLEAR_FLAG(htim4, TIM_FLAG_UPDATE);

 

Thanks for your help

Roberto

    This topic has been closed for replies.

    11 replies

    Graduate II
    April 23, 2024

    Probably __HAL_LOCK(hspi) inside HAL_SPI_Transmit() code takes some time...

    Graduate II
    April 23, 2024

    Are you sure about the core's clock rate?  How?

    Is the instruction cache enabled and the Flash configured for best performance?

    Super User
    April 23, 2024

    >What I noted is a delay of almost 10uS beetwen pin toggle and begin of 1st bit TX from

    And ...?  You want it faster or what ?  at 64 MHz (with a 500MHz capable cpu ) ?

     

    to see the speed of this cpu:

    - set cpu clock (pll) to 400MHz (or so)

    - set I-cache on/enable

    - set optimizer to -O2 (or -Ofast, try.)

     

    THEN check again. (and tell..) :)

    RoibertAuthor
    Graduate
    April 25, 2024

    Thanks to all for reply

    I removed the HAL, and write to the registers directly; now the dalay is 1us against 10us of before.

    Now i will try to set cache,and will report all.

    For now, my code is:

     

     SPI1->TXDR=(uint16_t)( 0x55AA);
     
    SPI1->CR1 |=SPI_CR1_CSTART;

    I dont need to test the .TXC because im transmitting in a INT timer of 1ms,( and sure, the transmission is already

    gone before next INT of 1ms)

    Thanks again

    Roberto

     

    RoibertAuthor
    Graduate
    April 27, 2024

    Some question again about SPI

    As specified before, I configured the SPI as Master. I configurated also

    the NSS as output driven by HW.

    I noted that this out seem very sensitive to noise: when touch the oscilloscope input, 

    the signal seem like it is float..Not very fix.   The same on MOSI out,and all this is tipical

    when a HI Impedence is out. 

    I think push pull is not hight impedence

     

    Thanks very much

    Roberto

    Super User
    April 27, 2024

    Are you sure about good GND connections ?

    Use a DMM and check ground from board to target - and to scope, if using it.

    RoibertAuthor
    Graduate
    April 28, 2024

    Thanks for reply.

    Im using the starter kit, NUCLEO-H755, and,as ground , I use the PIN5 of CN10.

    This is digital ground .

    Maybe the cable i connect to the pin are to long, but let me redo the connection

    and close some device near the kit (monitor and so...maybe some noise).

    I will tell you again

     

    I ask another question about SPI.. As before, I launch a SPI data inside a INT TIMER  of 1ms

    I set: 

    DSIZE=16 bit  // 1 Frame=16bit

    SPICLK=1US, so,  much more fast than 1ms of nexd data

    Then in timer i send data:

    INT_TIMER

    {

    //Load data

    SPI1->TXDR=(uint16_t)( 0x55AA); 
     
    //Start Tx
    SPI1->CR1 |=SPI_CR1_CSTART;

    ...

    }

     

    When i do this, the data is shift out OK, but CLK is 32 --bit--long..Not 16

    as i want.

    So, i can use the the TSIZE =1,reladed by TSER .

    So, in main:

    main

    {

    set TSIZE=1

     

    //Start SPI
    SPI1->CR1 |= SPI_CR1_SPE;

    }

    AND in Timer:

    {

        set TSER=1 ;

       //Load data

        SPI1->TXDR=(uint16_t)( 0x55AA);
     
       //Start Tx
        SPI1->CR1 |=SPI_CR1_CSTART;

    }

    In this way, I aspect that ,when FIFO empty , TSIZE will be reload with TSER=1

    and the process continue forever.

    What can i see is that data is ok, clk is long ok (16), CS also ok (H->L->H),but, this

    work only 1 times..Then stop.

    Look at register with IDE (after a breakpoint), i see TSIZE=1, TSER=1.

    Why.

    The HAL cen do this good because they START and STOP SPI via .SPE bit. But i think,

    this will cost a lot of time to schut on/off the controller.

    I would like reach is   : -Load FIFO with 16 bit, 

                                        -The SPI transmit this 16 bit delimitated by CS

                                        -..and so forever :)

    Thanks for hel, and excure for long text

      Roberto

      

     

     

     

    Graduate II
    April 28, 2024

    It would probably be very helpful to review some of the examples provided with the HAL package.  Maybe get one (or more) of them built and running on your Nucleo.  Understand the principles first and only then try to make it run faster.

    RoibertAuthor
    Graduate
    April 29, 2024

    Thanks Mr David for reply

    I create a code with Hal, and code is working as i aspect...all OK

    Because a big delay ,im triing to bypass HAL (hope is the correct solution.)

    So, I also read all the datasheet about SPI ,register and flags, tryng to bypass

    this problem. 

     

    Looking code of the SPI HAL ,HAL_TRANSMIT(...) I understand  they modify at every 

    call  the .TSIZE register,and this is possible, only if you disable SPI  (via   .SPE.)

    IF we -dont- want to disable  and renable  SPI  at each TX, we can use the TSER register

    that reload the TSIZE . This is what written in datasheet.

    So, just for riassume all , i have 2 case: (  i report the code for sintetize all , so , dont need to scroll

    previous post):

    1) dont touch TSIZE:  In this case, the transmission work continue, but i get 32 bit clk

    DSIZE=16 bit  // 1 Frame=16bit 

    INT_TIMER

    {

       //Load data

       SPI1->TXDR=(uint16_t)( 0x55AA); 
     
      //Start Tx
      SPI1->CR1 |=SPI_CR1_CSTART;
     
     .....

      }

    2) Setting TSIZE and TSER:  In this casa i get Correct number of clk, but only 1 time,

    then SPI stops.

    INT_TIMER

    {

         set TSER=1 ;

       //Load data

        SPI1->TXDR=(uint16_t)( 0x55AA);
     
       //Start Tx
        SPI1->CR1 |=SPI_CR1_CSTART;

    }

    What i would like to get, is that, i load FIFO with 1 or more frame, and SPI transmit each one,

    with correct CLK and each one with his own CS movement .

    Thanks for your time.

    Roberto

    RoibertAuthor
    Graduate
    May 7, 2024

    Dear Forum.

    About my last question, 

    I tried to use enable and disable SPI via .SPE, and so, able to reload TSIZE. This make the trasnfer

    correct, but i have not 10us as HAL produce, but 2-3 us .

    Question are:

    -Why so much delay, and, where i find in datasheet ?

    -Some explaination to my last question ? (The N2 in last my post). What im missing to read in datasheet ?

    Really thanks 

    Roberto

    Graduate II
    May 7, 2024

    Are you still running the core at 64 MHz with no instruction cache and no compiler optimizations?

    Why are you so fixated on 10 uSec to set up the SPI transaction?

    RoibertAuthor
    Graduate
    May 8, 2024

    Thanks Mr David for Reply

    I need to generate a SIN at 100KHZ, with a external DAC .  The 100K meand Period=10us.

    So, with the HAL delay of 8us circa, im at limit (without consider the SPI transfer time circa 0.5us).

    Because i send SPI data in a INT Timer of 10us, for 8us and more, i cant exit to INT...lot of time lost.

    Also using DMA (i did not try), i think the delay remain (the DMA will not solve the HAL delay ).

    Thanks again

    Roberto