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.

TM4C123GH6PM: Simple code snippet does not seem to work at 80 MHz

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Hi,

I am using the TM4C123G launch pad and the Keil development software.

At startup, just after setting the system clock  and initializing GPIO Port F, I execute the following loop:

//Wait on SW1 or SW2 to go low
do {
swData = GPIO_PORTF_DATA_R & 0x11;
}
while (swData == 0x11);

if ((swData & 0x01) == 0){

What I am observing is that with a 40 MHz clock, it works as expected. But with an 80MHz clock it eventually will exit the while loop and if I break on the if statement, swData  will be set to 0x11.  If I insert a short delay in the loop, it will also work fine at 80MHz. I tried it on two separate launchpads so it it not broken HW. Is there a known race condition on this chip that I am running into or am I making some noob mistake?

Thanks in advance

Joe Carbone

PS: Here is the assembly code Keil created

185: //Wait on SW1 or SW2 to go low
0x00000BD0 1D08 ADDS r0,r1,#4
0x00000BD2 6800 LDR r0,[r0,#0x00]
0x00000BD4 F4204070 BIC r0,r0,#0xF000
0x00000BD8 1D09 ADDS r1,r1,#4
0x00000BDA 6008 STR r0,[r1,#0x00]
186: do {
0x00000BDC BF00 NOP
187: swData = GPIO_PORTF_DATA_R & 0x11;
188: }
0x00000BDE 487E LDR r0,[pc,#504] ; @0x00000DD8
0x00000BE0 1F00 SUBS r0,r0,#4
0x00000BE2 6800 LDR r0,[r0,#0x00]
0x00000BE4 F0000011 AND r0,r0,#0x11
0x00000BE8 4984 LDR r1,[pc,#528] ; @0x00000DFC
0x00000BEA 6008 STR r0,[r1,#0x00]
189: while (swData == 0x11);
190:
191: //SW2 => Record
0x00000BEC 4608 MOV r0,r1
0x00000BEE 6800 LDR r0,[r0,#0x00]
0x00000BF0 2811 CMP r0,#0x11
0x00000BF2 D0F4 BEQ 0x00000BDE

  • Hi Joe,
    I just want to make sure if you ever press the SW2 button prior to seeing the code jump out of the while loop? Or you never press SW2 but the code will jump out of the while loop.

    What I think you need is the debouncing circuit. When a mechanical switch is pressed it will rebound a bit before settling, causing bounce. Debouncing is meant to removing the bounces. Debounce can be done in either hardware or software. For software solution, you can either Google around or find debounce example in <TivaWare_Installation>/examples/boards/ek-tm4c123gxl/drivers/buttons.c
  • I don't press either switch, and I've turned on the pullup resisters  (  GPIO_PORTF_PUR_R |= 0x11; )  long before I get to this loop. I just wait in Keil for a few seconds and the if statement is reached. The strange thing is I thought I was only doing one read of the port into a CPU register, but I see from the assembly code, it actually reads it twice even though it already has the value in R0 !. I guess the launchpad is noisy enough so that one of the PF pins drifts down toward ground? 

    Joe

  • Hi Joe,
    Can you repeat the same problem if you tie these two PF pins to 3.3V at 80MHz? Also instead of placing the breakpoint on the C code for line "if", can you place the breakpoint in the assembly code corresponding to the "if". Sometimes with the code optimization the breakpoint in the C code may not correspond with the assembly code.
  • Hi Charles,

    Thanks for your suggestions. When I tie 3.3 to both PF0 and PF4, the code ran for hours without the problem, so I'm sure it must be noise coupling onto one of those pins overpowering the weak internal pullup. At this point I'll live with the delay in the loop since it is not critical to what I'm trying to.

    Thanks again for your help
    Joe Carbone
  • May I note that it is suspected that vendor/friend Charles suggested tying those two pins to 3V3 via pull-up resistors. Direct connection of a GPIO to either power-rail - most always - is a "risky proposition" - and is outside of "best-practice." 4K7-10K should yield the same performance - yet proves far safer for your MCU...
  • Hi cb1,
    Thank you for suggestion to add the series resistor to limit the current drawn in the event the switch is indeed pressed. It was my ill suggestion to try connecting the pin directly to the power. I thought the poster already had a pull-up resistor but re-reading the post again it was instead an internal weak pullup.
  • You are most welcome, Charles. (we knew what you meant/intended)

    As MCU speeds increase - especially when (any) power control/fast switching circuits are nearby - the liabilities of the "so weak" internal pull-up/down resistors - become more & more apparent.

    May it be noted that this "internal resistor short-coming" - holds true across multiple ARM MCU vendors - not only those resident here...