This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Strange timing behavior in my code

I write two codes for generating greq at PA0-Pa7: Diff in code 1 & code 2 is that only BSSR register is moved to define macro.

code1

#define WRITE_TFT_DATA_PINS(VALUE)                     {                                                                 \ 
                                                            GPIOA->BSRRL = (uint16_t)( VALUE & 0x000000ff);              \ 
                                                            GPIOA->BSRRH = (uint16_t)(~VALUE & 0x000000ff);              \ 
                                                       }

void main()
{
  for( i = 8; i < 255; i++ )
  {
    WRITE_TFT_DATA_PINS(i);
  }
}

code2

void main()
{
  for( i = 8; i < 255; i++ )
  {
    GPIOA->BSRRL = (uint16_t)( VALUE & 0x000000ff);
    GPIOA->BSRRH = (uint16_t)(~VALUE & 0x000000ff);
  }
}

Now on checking freq on PA7 pin for code 1 = 55Khz & for code 2 = 65Khz (approx.)

I checked the preprocessor file of both code, both are almost same
code1

    while(1)
    {
        uint32_t i;
        for( i = 8; i < 255; i++ )
        {
            { ((GPIO_TypeDef *) ((((uint32_t)0x40000000) + 0x00020000) + 0x0000))->BSRRL = (uint16_t)( i & 0x000000ff); (GPIO_TypeDef *) ((((uint32_t)0x40000000) + 0x00020000) + 0x0000))->BSRRH = (uint16_t)(~i & 0x000000ff); };


        }
    }

code2

    while(1)
    {
        uint32_t i;
        for( i = 8; i < 255; i++ )
        {

             ((GPIO_TypeDef *) ((((uint32_t)0x40000000) + 0x00020000) + 0x0000))->BSRRL = (uint16_t)( i & 0x000000ff);
             ((GPIO_TypeDef *) ((((uint32_t)0x40000000) + 0x00020000) + 0x0000))->BSRRH = (uint16_t)(~i & 0x000000ff);
        }
    }

Then i checked its disassembly , after for loop:

code1

0x0800020E 2008      MOVS     r0,#0x08
0x08000210 B2C2      UXTB     r2,r0
0x08000212 830A      STRH     r2,[r1,#0x18]
0x08000214 43C2      MVNS     r2,r0
0x08000216 B2D2      UXTB     r2,r2
0x08000218 834A      STRH     r2,[r1,#0x1A]
0x0800021A 1C40      ADDS     r0,r0,#1
0x0800021C 28FF      CMP      r0,#0xFF
0x0800021E D3F7      BCC      0x08000210
0x08000220 E7F5      B        0x0800020E

code2


0x0800021A 2109      MOVS     r1,#0x09
0x0800021C B2CA      UXTB     r2,r1
0x0800021E 8302      STRH     r2,[r0,#0x18]
0x08000220 43CA      MVNS     r2,r1
0x08000222 B2D2      UXTB     r2,r2
0x08000224 8342      STRH     r2,[r0,#0x1A]
0x08000226 1C4A      ADDS     r2,r1,#1
0x08000228 B2D4      UXTB     r4,r2
0x0800022A 8304      STRH     r4,[r0,#0x18]
0x0800022C 43D2      MVNS     r2,r2
0x0800022E B2D2      UXTB     r2,r2
0x08000230 8342      STRH     r2,[r0,#0x1A]
0x08000232 1C89      ADDS     r1,r1,#2
0x08000234 29FF      CMP      r1,#0xFF
0x08000236 D3F1      BCC      0x0800021C
0x08000238 E7EC      B        0x08000214

My question is when both coeds are same except define which I don't think should change the code assembly.
Also optimzation and other parameter are same for both

  • My question is when both coeds are same except define which I don't think should change the code assembly.

    To find out, you would have to compare the behaviour of two code sequences that actually are equivalent after preprocessing. Yours aren't.

    Nor will your "code2" actually preprocess to what you say it did.

  • It's curious. It seems that the empty statement formed by using the the macro is preventing loop unrolling (for no good reason).

    Try changing your macro to

    #define WRITE_TFT_DATA_PINS(VALUE) do { ... } while (0)
    

    instead of

    #define WRITE_TFT_DATA_PINS(VALUE) { ... }
    

    Using do/while(0) is a common thing to do with multi-statement macros and will save you some confusion if you ever use any constructs that won't accept an empty statement like:

        ...
        if (b)
            WRITE_TFT_DATA_PINS(i);
        else
            bar();
        ...