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.

TM4C1294 Hard Fault Upon Device Reconnect when in USB OTG Host Mode

Other Parts Discussed in Thread: TM4C1294KCPDT, SYSBIOS

My custom board has a TM4C1294KCPDT processor operating in OTG mode.  Because the attached device's cable has ID grounded, the TIVA chip is used in host mode with an external device.  The processor generates a Hard Fault; Bus Fault; Imprecise when the device is reconnected following a disconnect. 

Environment is CCS 6.1.0.00104.  TI-RTOS version 2.14.00.10.  TIVAWARE version TivaWare_C_Series-2.1.1.71b.  Device is proprietary "handpad" that is similar to a gamepad; it has VBUS-Powered and has a Microchip PIC18F8J50 processor with the MICROCHIP USB device stack.  Emulator is Blackhawk XDS100v2 ARM.

Sequence:

1.  Power up TIVAWARE with the handpad attached.  Device and TIVA chip talk fine.

2.  Physically disconnect the device's cable from the TIVAWARE board.  Wait several seconds until TIVA device goes back into unconnected state.

3.  Reconnect the device's cable.

4.  The TIVA device recognizes the reconnect and sets itself up as a host.

5.  Less than a second later, the TIVA chip throws a Hard Fault:Forced exception.  The Bus Fault: Imprecise is also asserted.  The fault is occurring in the usbhostenum.c file, but the exact location seems to move around.

I went into my main.c module and added code to change the ARM ACTRL register (address = 0xe000,e008) from 0x0 to 0x7.  (This disables IT folding, write buffering, and multicycle instruction interrupts.  Now, what is reported is Hard Fault: Forced Exception; Bus Fault Precise that always occurs at the same place.

The line of source code where the fault occurs is the inner statement of the if located at source code line 4417 of usbhostenum.c:

            if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].psDevice)
            {
                g_sUSBHCD.psUSBINPipes[ui32Idx].psDevice->ui32Flags |=       <- Fault occurs here
                                                    USBHDEV_FLAG_NOTIFYINT;
            }

For reference, ui32Idx is equal to 1 when the fault occurs.

Disassembling this instruction,

ldr

ldr

movs

muls

ldr

ldr

orr

str     r0, [r1, #0x30]            <- fault occurs on this instruction. 

Prior to fault, r0 is 0x0001,C1D5, r1 is 0, r2 is 1, sp is 0x2001,02b0 which is within my defined .data area of memory

At entry to the ti_sysbios_family_arm_m3_Hwi_excHandlerAsm__I, r0-r2 are the same, sp is 0x2001,0290

Suggestions on how to diagnose this?

Tom

  • Hello Tom

    The CPU is trying to write to a flash location 0x1 (R1) which will generate a bus fault. Can you check what the value is at the first connect?

    Regards
    Amit
  • Hi Amit,

    At bootup (actually a few seconds execution starts) r0=1; r1=0x2001,50D8; R2=0; SP = 0x2001,02b0. {Just before executing the STR instruction associated with line 4419}

    Although I don't think I changed anything, I did have to rebuild and the exception sometimes seems to get thrown at a different point. In both cases, it is at STR function. In both cases it is Hard Fault:Forced with Bus Fault:Precise.

    With no breakpoints set, the exception still throws at line 4419 with the values I previously reported being shown by the exception handler.

    If I put a breakpoint at usbhostenum.c line 4419, the exception is thrown (according the the exception handler report) at the STR instruction at the end of usbhostenum.c line 4311:

    // Remember that we need to notify this device's class
    // driver that an interrupt occurred.
    //
    g_sUSBHCD.psUSBINPipes[ui32Idx].psDevice->ui32Flags |= <--- Throws on STR at end of this instruction
    USBHDEV_FLAG_NOTIFYINT;

    The exception handler reports R0 = 0x0001c1d5; R1 = 0; R2 = 0; SP = 0x200101B0

    After boot with breakpoints at both 4311 and 4419, the breakpoint at 4419 trips first and then the one at 4311. The first time 4311 trips, R0= 0x200150D8; R1 = 0x20014bb0; R2 = 0; SP = 0x20010188. If I let it run (actually keep hitting the run button) disconnect the device and the reconnect the device, then the 4419 breakpoint trips with R0= 0x200150D8; R1 = 0x210014bb0; R2 = 0; SP=0x20010188. Assembly language single stepping on the STR after 4419 immediately throws the exception.

    Tom
  • Hello Tom,

    You mentioned in the second connect the value of R1 = 0x210014bb0; Is the 0x21 a typo and you meant R1 = 0x20014bb0?

    Since it is a specific STR option we need to see what the value of CPU registers are that cause the STR to incorrectly access an address location in Flash.

    Or could there be a stack corruption (try to increase the Stack Size)

    Regards
    Amit
  • Hi Amit,

    Sorry for the typo, you are correct -- the value was 0x20014bb0.

    I doubled the stack size for all tasks. I did have to increase the heap size as well to avoid a warning during build (I always clean before building).

    At this time roughly the same thing is happening. Upon reconnect I still get the hardfault:forced; busfault:PRECISERR: address 30 with exception occurred in ISR thread at PC = 0x0000ab58 which is the STR at usbhostenum.c line 4419. R0=0x0001c47d; R1 = 0; R2 = 1; SP=0x200102b0.

    One other interesting thing I noticed that may, or may not, be relevant: Our handpad has some LEDs on it and two 8-segment LED displays. Upon power up, the 8-segment displays normally show "- -"; once the TIVA board is up it begins continually sending commands to the handpad to display "<blank> 1" (left display blank and right one has the number '1'). As for the problem we are chasing right now, the "standard" behavior is what I observe upon the initial connect; the handpad displays '1' prior to the first time I hit the breakpoint at 4419. I then repeatedly hit run everytime I hit a breakpoint. After I disconnect, the breakpoints stop firing. I then reconnect the handpad and observe the same standard behavior ('- -' followed by ' 1') and then the breakpoint at 4419 fires. Assembly stepping results in the exception being thrown on the STR instruction. In other words, the connection is partially coming up before the exception is thrown. Don't know if this is relevant, but...

    What should I try next?
    Tom
  • Hello Tom

    Based on the description of the issue, we do know that the Bus Fault is due to a STR operation to Flash. However we need to trace back what causes the address of the flash to be loaded instead of the SRAM variable. This would require back tracing the Breakpoint which changes the R1 value. When I say back trace, I mean the function calls before the issue which should have the correct value of R1 as SRAM and not Flash.

    Regards
    Amit
  • Hi Amit,

    (All comments related to usbhostenum.c unless otherwise indicated)

    I have traced things a bit and determined that the fault occurs when line 4419 is executed with *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0.

    Here is the sequence of events I have been able to identify using a few breakpoints, not all of which were active at the same time.

    1. Boot TIVA. It will run until line 1130. At this point ui32EndpointType = 0x00220000 and *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0. Resume running.

    2. Hit breakpoint at 1265. This code sets *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0x200190d8 and g_sUSBHCD.psUSBINPipes[0].ui32Type to 0x00220000. Resume running.

    3. Hit breakpoint at 1130. At this point ui32EndpointType=0x00210000 and *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0x200190d8. Resume running. (Does not hit breakpoint at 1265.)

    4. Hit breakpoint at 4419. At this point g_sUSBHCD.psUSBINPipes[0] = 0x00220000 and *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0x200190d8. Resume running.

    5. Disconnect handpad. Hit breakpoint at 2346. This code sets *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0 and g_sUSBHCD.psUSBINPipes[0].ui32Type to 0. Resume running.

    6. Connect handpad. Hits breakpoint at 4419 without hitting 1130 or 1265. At this point g_sUSBHCD.psUSBINPipes[0].ui32Type = 0 and *(&g_sUSBHCD.psUSBINPipes[0].psDevice) = 0.

    Note that I have written the array index as 0 to show what is actually happening even though the actual code sometimes is i32Idx (which happens to be zero at the times noted above).


    What should I try next?
    Tom