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.

TM4C1233H6PZ Clock Fault

Other Parts Discussed in Thread: TM4C1233H6PZ, TM4C123GH6PM

All, 

I am working with a custom board with a TM4C1233H6PZ with an external clock at 16MHz. I am using CCS v5.4 with the Stellaris ICDI.

The issue I have is that the chip hard faults as soon as I set the System Clock above 20MHz. If I run the exact same code minus a pinout change on the TM4C123GH6PM eval board, I can run the clock all the way up to 80MHz.

I believe this is the root of another issue I was seeing where I couldn't get the USB to work properly unless the system clock was below 20MHz. (Yes, I know the datasheet says the system clock must be at or above 20MHz.)

I wrote a simple test program for the clock issue I was seeing. And have attached it. Does anyone have any ideas?

Thanks,

Jed

/*
 * main.c
 */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "inc/hw_memmap.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"

int main(void)
{
	uint32_t g_SystemClockValue;

	SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
	g_SystemClockValue = SysCtlClockGet();


	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
	GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
	
	while(1)
	{
	    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0);
	    SysCtlDelay(g_SystemClockValue/4);
	    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0);
	    SysCtlDelay(g_SystemClockValue/4);
	}
	return 0;
}

  • Hi Jed,

    Jed Hobbs said:
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    I don't know if this is the cause of your problem. But, there is a 3 to 6 clock cycles before you use a peripheral  after enabling the clock for it. As a precaution there should be a delay of such equivalent, before using that peripheral.

    Do you have a hard fault with your simple code above.    

    -kel

  • Hello Jed,

    Agree with Kel. To double check you can read the register FAULTSTAT and FAULTADDR at location 0xE000ED28 and 0xE000ED38. The second register should have the base address of the GPIO-B.

    To make sure that this issue does not occur irrespective of the frequency a good idea is to put

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB));

    after the SysCtlPeripheralEnable function call. This ensures that the clock is working properly before accessing any peripheral.

    Regards

    Amit

  • Thanks for getting back to me so quickly.

    Yes, I am getting hard faults even after adding the code suggested by Amit.

    These faults vary a little bit. I seem to be getting two different varieties of faults.

    For the first set of faults I get either an 'Invalid State', an 'Instruction Bus Error', or an 'Instruction Bus Access Violation'. These faults all had  the same fault address of 0xE000.EDF8. None of these faults threw the Fault Address Register Valid Bit.

    The second set of faults threw the Fault Address Register Valid Bit and the Precise Data bus Error bit. However, the fault address changed. I got both 0x3000.3720 and 0x4C90.11D4.

    Out of approximately ten runs, eight of the faults were of the first set and two were of the second set.

    Just to rule out a few more things, I simplified the code even more.

    int main(void)
    {
    	SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN 
    			| SYSCTL_XTAL_16MHZ);
    	while(1)
    	{
    
    	}
    }

    Out of ten runs, six threw an Instruction Bus Error with a fault address of 0xE000.EDF8. The other four didn't fault.

    I'm currently digging through the SysCtlClockSet() function and it appears there are several hard coded delays. 

    Let me know if you have any ideas.

    Thanks,

    Jed

  • Hello Jed,

    Instead of using the MOSC, can you try the same using Internal Oscillator.

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_INT 
    			| SYSCTL_XTAL_16MHZ);

    That will help rule out any crystal problems

    Regards

    Amit

  • Amit,

    I've changed the code as follows. I'm getting Instruction Access Violation, Undefined Instruction Usage, and Instruction Bus faults. They all still have the same fault address 0xE000.EDF8. However, it appears these faults are occurring before main() is called. I set a break point at SysCtlClockSet() and out of ten runs, the program only reached it twice. The other eight times it faulted before hitting the break point.

    int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ); while(1) { } }


    The only other code in the program before this point that I can see is the standard ResetISR() function. Which calls a reset handler that I have not been able to find.

    Thanks,
    Jed

    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }

  • Hello jed,

    Cab you use the following startup_ccs.c? Looks like a lot is missing.

    Regards

    Amit

    //*****************************************************************************
    //
    // startup_ccs.c - Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 2.1.0.12573 of the DK-TM4C123G Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // Quadrature Encoder 1
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // Wide Timer 0 subtimer A
        IntDefaultHandler,                      // Wide Timer 0 subtimer B
        IntDefaultHandler,                      // Wide Timer 1 subtimer A
        IntDefaultHandler,                      // Wide Timer 1 subtimer B
        IntDefaultHandler,                      // Wide Timer 2 subtimer A
        IntDefaultHandler,                      // Wide Timer 2 subtimer B
        IntDefaultHandler,                      // Wide Timer 3 subtimer A
        IntDefaultHandler,                      // Wide Timer 3 subtimer B
        IntDefaultHandler,                      // Wide Timer 4 subtimer A
        IntDefaultHandler,                      // Wide Timer 4 subtimer B
        IntDefaultHandler,                      // Wide Timer 5 subtimer A
        IntDefaultHandler,                      // Wide Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        IntDefaultHandler,                      // Quadrature Encoder 2
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // PWM 1 Generator 0
        IntDefaultHandler,                      // PWM 1 Generator 1
        IntDefaultHandler,                      // PWM 1 Generator 2
        IntDefaultHandler,                      // PWM 1 Generator 3
        IntDefaultHandler                       // PWM 1 Fault
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    

  • Amit,

    I swapped out the startup_ccs.c that I was using with the one you supplied. I was using the one from the blinky example.

    I still get the same set of faults, however I just realized that they only occur when I use the reset function in the CCS debugger. If I reload the program with the debugger it runs properly the first time, then if I reset it, if faults.

    Thanks,

    Jed

  • Hello Jed

    Can you zip the project and send it across?

    Which reset are you performing: System Reset or Core Reset?

    Regards

    Amit

  • Hi Amit,

    I've attached the project. I was using the Core Reset.

    Jed

    8054.ClockTest.zip

  • Hello Jed

    I tried it on my LaunchPad for TM4C123 and it works every time. One thing I did change was use 2.1.0 of TIVAWare as I do not have 1.1 version on my PC. Can you check if the same issue occurs with the latest TIVAWare release?

    Regards

    Amit

  • Hi Amit,

    I've upgraded my TIVAWare release to 2.1.0.12573. Unfortunately it doesn't make any difference. The project does run on my TM4C123 Launchpad, but doesn't run on my custom board.

    Thanks,

    Jed

  • Hello Jed,

    What is the difference between the LaunchPad and the custom board? Is there a crystal on the LaunchPad and not on your custom board?

    Regards

    Amit

  • Jed,

        You should identify what is particularly different with your custom board compared to the Tiva Launchpad, that is possibly causing this problem. It is also possible that there are defective components at your custom board, and you would need to verify this using tools.

    -kel

  • Seems much to this reporter that your MCU may be incompletely Resetting.  Suggest that you check the pull-up R upon /Reset @ MCU and add a C to ground of at least 0.1uF.  Such has past presented to our clients very much as you describe, here.

    If the reset checks out - I'd move to an indepth exam of each/every power and ground pin.  You don't state the number of boards so inflicted - that would provide further guidance for your remote staff...

    Old standbys - proper 3V3 Regulator (adequately sized - we use 200mA as absolute minimum) and a good assortment of "close-in" bypass Cs - distributed evenly around each side of the MCU - and external pull-up Rs upon each/every JTAG line.  (yes - manual promises internal wpu, "adequate to task" - so too, "walking blindfolded in NYC rush traffic "may not" get you killed!")   

  • Amit, Kel, & CB1,

    Thanks for jumping on this. I really appreciate it. Other than layout differences and the difference in package sizes, my custom board has an external oscillator rather than a crystal. The oscillator is running at 16MHz. I am using a OCE716000XCCDRB oscillator by Precision Devices Inc. for my clock source.

    I have 7 of these custom boards and they all behave similarly. After further investigation it appears that anytime I am using the PLL the uController crashes after a very short period while if I use the external or internal clock directly it behaves appropriately.

    CB1,

    I added a 0.1uF cap and stiffened the pull up resistor I had on the reset line, 10kOhm to 1kOhm. These mods changed the rise time of the reset signal from 348nS to 112uS to rise from 160mV to 2.2V (Approximately 0.65* VDD). Rise time from 160mV to 3.160V changed from 1.2uS to 345uS. I didn’t see any oscillation in either signal. 

    All the power supplies appear to be running properly. The 3.3VDC is a 10Amp supply, no current issues here. The 3.3VDC Analog is run off the main 3.3VDC supply through a couple of blocking ferrite beads. There are plenty of bypass caps in various sizes both at the supply and at the uController.

    I also added 10kOhm pull up resistors to each JTAG line. They also don’t appear to have had any effect on this issue.

    Thanks,

    Jed

  • Hello Jed

    What is the API that the code is using for PLL?

    Also does it crash the same way when PLL is used with Internal Clock Source?

    Regards

    Amit

  • Hi Amit,

    I'm not sure I understand the question about the API. I'm using the SysCtlClockSet() function as defined in sysctl.c in the driverlib library. 

    Yes, it crashes the same if I use SYSCTL_OSC_MAIN, or SYSCTL_OSC_INT. 

    Thanks,

    Jed

  • Hello Jed,

    I was asking the same. So it crashes when PLL is used (irrespective of SYSCTL_OSC_MAIN or SYSCTL_OSC_INT being used for PLL). But it does not fail when the SYSCTL_OSC_MAIN or SYSCTL_OSC_INT is used as the System Clock Source.

    I would suggest monitoring the VDDC, VDDS and VDDA supplies when the PLL is locking as it could tell if there is an inrush current which causes a temp voltage dip.

    Regards

    Amit

  • Kel, Amit, & CB1.

    Thank you very much for your help. I found the issue late Friday afternoon. The capacitor connected to VDDC (pins 38 & 86) was not large enough. For some reason when I designed this implementation, I put in a 3.3 pF capacitor instead of a 2.5uF to 4.0uF capacitor. Woops.

    Thanks,

    Jed Hobbs