This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TM4C123GH6PM: GPIO response time seems too long...

Part Number: TM4C123GH6PM

Tool/software: Code Composer Studio

I need a sanity check here.  I'm using the TM4C123G Launchpad.  I have the clock set at 80Mhz.

SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);


If I understand correctly, the PLL runs at 200MHz, so 200/2.5 = 80MHz clock

I have a GPIO connected to the o-scope.  I'm turning it on and off immediately.

 

GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);

GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, 0);

 

The time from the rising edge of the GPIO to the falling edge of the GPIO is measured at about 148 ns.  With an 80Mhz clock, this seems a little on the slow side to me.  Am I screwing up the math or something?

  • Brian,
    At 80MHz, one clock cycle is 12.5ns. It seems that there are 12 cycles between each of the instructions above.
    That sounds reasonable.
    Using the ROM_ TivaWare function should gain you one or two cycles.
    Of course, fast switching of GPIO's shall not be chased by software - if that's what you need, use other tools such as the PWM or Timer hardware peripherals.
    Regards
    Bruno
  • Hi Brian,

    Actually the PLL is running at 400MHz, but /5 gives the 80MHz system clock.

    The use of C functions to set and clear the pin clearly adds some overhead. If you look at the assembly language created, you will see something like this:

     98               GPIOPinWrite(GPIO_PORTG_BASE, USER_LED, USER_LED);
              $C$L2:
    00000720:   2104                movs       r1, #4
    00000722:   4620                mov        r0, r4
    00000724:   460A                mov        r2, r1
    00000726:   F000F882            bl         #0x82e
     99               GPIOPinWrite(GPIO_PORTG_BASE, USER_LED, ~(USER_LED));
    0000072a:   4620                mov        r0, r4
    0000072c:   2104                movs       r1, #4
    0000072e:   22FB                movs       r2, #0xfb
    00000730:   F000F87D            bl         #0x82e
     93           while(1)
    00000734:   E7F4                b          $C$L2

    The subroutine is short and will look like this:

              GPIOPinWrite():
    0000082e:   F8402021            str.w      r2, [r0, r1, lsl #2]
    00000832:   4770                bx         lr

    So if you follow the flow, there are 6 assembly instructions between the first write to the pin and the second write to the pin. Two of those instructions are branches. There are ways to toggle a pin more efficiently, but often at the cost of readability or portability.

  • I'm trying to understand. So, the following on the Tm4C123 will give me an 80Mhz clock?

    SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    I changed it to SYSCTL_SYSDIV_2_5, expecting to see a change in the GPIO timing on the scope and saw none?
  • Sorry, I had a mistake. So with SYSCTL_SYS_DIV_2_5, one GPIO pulse is 140ns. With SYSCTL_SYSDIV_5 one GPIO pulse is 240ns.
    Now I'm confused. I would have expected it to be the other way around.
  • There is an inherent divide by 2 which means the 400MHz PLL outputs 200MHz. Divide by "2.5" gives you an 80MHz system clock. This gave you a 140nS pulse width. Divide by "5" gives you a 40MHz system clock, which gave you a 240nS pulse width. The reason why it is not 280nS is that at 40MHz the flash operates without a wait state and does not need the prefetch buffer. In this case it saved you one cycle.
  • Back to my original problem. I'm controlling the conversion input on an ADC. The conversion needs to go high for a min of 10ns. Then high again for the duration of the conversion, which means the falling edge needs to occur less than 320ns after the initial pulse. I'm thinking that my idea of controlling this with a GPIO is not feasible.
  • Brian,
    These things typically require a MINIMUM pulse width. It does not mean it has to be 10ns, they will work fine with 50ns, 100ns...
    As for the 320ns event, there is probably something else that can indicate to your code that the conversion is finished, and you can shift your GPIO after that event triggers. Otherwise, just use a timer hooked to the GPIO.
    Bruno