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.

TM4C1294KCPDT: Reset following external clock failure

Part Number: TM4C1294KCPDT
Other Parts Discussed in Thread: EK-TM4C1294XL

I ran into some issues with the watchdog timer reset not working following loss of clock. I've got everything working now, but that behavior was quite unexpected and I've got some questions about reset.

I'm using the PLL is used to derive SYSCLK from the MOSC, which is provided by an external single-ended source that may stop.

I found that watchdog module 1 (the one clocked off PIOSC) and the RST pin where both unable to reset the device after the external clock stopped. I was able to make them work by changing the reset types in RESBEHAVCTL from the default simulated POR to a system reset. Is this the expected behavior? If so, it would be nice if the workaround for errata SYSCTL#03 mentioned the need to change the reset type. What is the difference between the simulated POR sequence and a system reset?

  • HI,

     Can you elaborate what do you mean the watchdog is unable to perform a simulated POR? They simulated POR will reset the entire device as if a cold reset from power up. The system reset is more like a warm reset which also reset the pretty much the entire device but no full device initialization.

     If you read the datasheet the subtle difference between the two is that :

    The watchdog timer Power-On Reset sequence is as follows:
    1. The watchdog timer times out for the second time without being serviced.
    2. An internal POR reset is asserted.
    3. The internal reset is released and the core executes a full initialization of the device. Upon
    completion, the core loads from memory the initial stack pointer, the initial program counter,
    and the first instruction designated by the program counter, and then begins execution. Refer
    to “Reset” on page 1983 for watchdog timeout internal reset deassertion timing.


    The watch dog timer system reset sequence is as follows:
    1. The watchdog timer times out for the second time without being serviced.
    2. An internal reset is asserted.
    3. The internal reset is released and the microcontroller loads from memory the initial stack pointer,
    the initial program counter, and the first instruction designated by the program counter, and
    then begins execution.

  • I have the watchdog configured with reset generation enabled and interrupt generation disabled. I tested it by increasing the timeout to a couple seconds and halting the processor using the emulator. The various blinking LEDs all freeze in their current state. After twice the timeout period, they all go out as the device resets (there are pull ups/downs to turn them off when not driven). When I try to trigger the watchdog in the same configuration by stopping the clock, the LEDs freeze indefinitely and it never resets. While in this state the RST pin does nothing. When the clock later resumes, the device resets if the watchdog had timed out during the period when the clock was stopped.

    If I add the following to my initialization, the LEDs freeze when the clock stops and after twice the watchdog period, they go out as the device resets.

    SysCtlResetBehaviorSet(SYSCTL_RESBEHAVCTL_WDOG1_SYSRST | SYSCTL_RESBEHAVCTL_WDOG0_SYSRST |
                           SYSCTL_RESBEHAVCTL_BOR_SYSRST   | SYSCTL_RESBEHAVCTL_EXTRES_SYSRST);

  • Hi,
    I think there is a difference between the two different scenarios. In the first case, when the WD times out due to the fact that the CPU didn't reset the WD counter in time, the clock is still running. Note that the rest of devices such as CPU and GPIO modules are still receiving the clock. In the second case, there is no clock to the device. Many of the digital logic requires clock to sample the reset. What I think might have happened is that without the clock, even if the presence of the reset, the digital logic are not reset. This is why when you provide the clock again, circuitry relying on the clock in the device will resume. Note without the clock the CPU is like stopped indefinitely.
  • From the third case it's clear that the digital logic an be reset without a clock. I just surprised that the the simulated POR can't do it but the system reset can. I guess the simulated POR does something that requires a clock before it actually issues the internal reset.

  • I agree with you and I'm under the same impression that the simulated POR should reset without clock. I will check with my colleague tomorrow for more ideas.
  • Hi,
    I've discussed with my colleague and we can't understand why the simulated POR would not be generated while a system reset would otherwise.
    The only I can think of is that some circuitry (i.e. synchronization of signals) responsible for generating the simulated POR requires the clock while circuitry responsible for generating system reset does not need the clock. This would not be the ideal outcome if the circuitry behaves as such unexpectedly. I will suggest you continue with the system reset and in the reset handler reads the RESC register to find out the cause of the reset and handle the WD reset accordingly.
  • Hi BB_,

     I modified the existing TivaWware watchdog example to use the WD1 instead of WD0. The WD1 runs off of the PIOSC. I actually cannot reproduce your finding. I only have the launchpad with me. Once the example is running, I force the OSC0 to ground. I can see the reset -- the simulated POR reset actually happened.  If you have a chance please also try it. You can refer to the original watchdog example under <TivaWare_Installation>/examples/boards/ek-tm4c1294xl/watchdog. Below code is what I modified to use WD1.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/watchdog.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "drivers/buttons.h"
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>Watchdog (watchdog)</h1>
    //!
    //! This example application demonstrates the use of the watchdog as a simple
    //! heartbeat for the system.  If the watchdog is not periodically fed, it will
    //! reset the system.  Each time the watchdog is fed, the LED is inverted so
    //! that it is easy to see that it is being fed, which occurs once every
    //! second.  To stop the watchdog being fed and, hence, cause a system reset,
    //! press the SW1 button.
    //
    //*****************************************************************************
    
    //****************************************************************************
    //
    // System clock rate in Hz.
    //
    //****************************************************************************
    uint32_t g_ui32SysClock;
    
    //*****************************************************************************
    //
    // Flag to tell the watchdog interrupt handler whether or not to clear the
    // interrupt (feed the watchdog).
    //
    //*****************************************************************************
    volatile bool g_bFeedWatchdog = true;
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    //
    // The interrupt handler for the watchdog.  This feeds the dog (so that the
    // processor does not get reset) and winks the LED connected to GPIO B3.
    //
    //*****************************************************************************
    void
    WatchdogIntHandler(void)
    {
        //
        // If we have been told to stop feeding the watchdog, return immediately
        // without clearing the interrupt.  This will cause the system to reset
        // next time the watchdog interrupt fires.
        //
        if(!g_bFeedWatchdog)
        {
            return;
        }
    
        //
        // Clear the watchdog interrupt.
        //
        ROM_WatchdogIntClear(WATCHDOG1_BASE);
    
        //
        // Invert the GPIO PN0 value.
        //
        ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0,
                         (ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_0) ^
                                         GPIO_PIN_0));
    }
    
    //*****************************************************************************
    //
    // This function is called when the SW1 button is pressed.
    //
    //*****************************************************************************
    static int32_t
    SW1ButtonPressed(void)
    {
        //
        // Set the flag that tells the interrupt handler not to clear the
        // watchdog interrupt.
        //
        g_bFeedWatchdog = false;
    
        return(0);
    }
    
    //*****************************************************************************
    //
    // This example demonstrates the use of the watchdog timer.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Set the clocking to run directly from the crystal at 120MHz.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_480), 16000000);
        //
        // Initialize the buttons driver.
        //
        ButtonsInit();
    
        //
        // Enable the peripherals used by this example.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG1);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    
        //
        // Enable processor interrupts.
        //
        ROM_IntMasterEnable();
    
        //
        // Set GPIO PN0 as an output.  This drives an LED on the board that will
        // toggle when a watchdog interrupt is processed.
        //
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0);
        ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_0, 0);
    
        //
        // Enable the watchdog interrupt.
        //
        ROM_IntEnable(INT_WATCHDOG);
    
        //
        // Set the period of the watchdog timer to 1 second.
        //
        ROM_WatchdogReloadSet(WATCHDOG1_BASE, g_ui32SysClock);
    
        //
        // Enable reset generation from the watchdog timer.
        //
        ROM_WatchdogResetEnable(WATCHDOG1_BASE);
    
        // Enable stall during debug mode
        WatchdogStallEnable(WATCHDOG1_BASE);
    
        //
        // Enable the watchdog timer.
        //
        ROM_WatchdogEnable(WATCHDOG1_BASE);
    
        //
        // Loop forever while the LED winks as watchdog interrupts are handled.
        //
        while(1)
        {
            //
            // Poll for the select button pressed
            //
            uint8_t ui8Buttons = ButtonsPoll(0, 0);
            if(ui8Buttons & USR_SW1)
            {
                SW1ButtonPressed();
                while(1)
                {
                }
            }
        }
    }

    I grounded the OSC0 by connecting the C44 terminal to ground. The example is supposed to toggle a LED. If reset happened, the LED will stop.