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.

TM4C1232H6PM: Watchdog 1 Write Complete Bit not set

Part Number: TM4C1232H6PM
Other Parts Discussed in Thread: TM4C1232D5PM

Hello,

I have the problem that the Write Complete Bit in Watchdog 1 will not always be set. As per datasheet prior every write to the WD1 register it need to be checked if writing is allowed.

The Test code enables the WD1 and should feed WD1 while counting up ui32cnt. But ui32cnt is only incremented to 1 and then we are hanging in

while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0)
{}

 

#include <stdbool.h>
#include <stdint.h>

#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_gpio.h"
#include "inc/hw_watchdog.h"

#include "driverlib/sysctl.h"
#include "driverlib/watchdog.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"


//		Frequenzy in Hz of Watchdog 1 clock source
#define WATCHDOG1_CLK				16000000

//		 Timeout of Watchdog 1 in seconds
#define WATCHDOG1_TIMEOUT			10

//*****************************************************************************
static void WaitForWD1ReadyToWrite(void)
{
	while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0)
	{}
}

int32_t ui32cnt;

int32_t main(void)
{	
	//
	// Fix Errata WDT#01: Watchdog Timer 1 Module Cannot be Used Without Enabling Other Peripherals First
	//
	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
	
	//
    // Enable the Watchdog
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG1);
	
	while (SysCtlPeripheralReady(SYSCTL_PERIPH_WDOG1) ==0)
	{}
	
	//
	// Unock the watchdog registers the can be changed.
	//
	WaitForWD1ReadyToWrite();
	WatchdogUnlock(WATCHDOG1_BASE);

    //
    // Enables stalling of the watchdog timer during debug events.
    //
	WaitForWD1ReadyToWrite();
	WatchdogStallEnable(WATCHDOG1_BASE);
	
	
	WaitForWD1ReadyToWrite();
    WatchdogReloadSet(WATCHDOG1_BASE, WATCHDOG1_CLK * WATCHDOG1_TIMEOUT);
	
    //
    // Enable the watchdog timer.
    //
	WaitForWD1ReadyToWrite();
    WatchdogEnable(WATCHDOG1_BASE);

	//
	// Lock the watchdog registers for writing.
	//
	WaitForWD1ReadyToWrite();
	WatchdogLock(WATCHDOG1_BASE);
	
	
	while(1)
	{
		ui32cnt++;
		
		SysCtlDelay(10000);

		//
		// Unlock the Watchdog registers for writing
		//
		WaitForWD1ReadyToWrite();
		WatchdogUnlock(WATCHDOG1_BASE);
		
		//
		// Feed the Watchdog by writing the load value
		//
		WaitForWD1ReadyToWrite();
		HWREG(WATCHDOG1_BASE + WDT_O_LOAD) = WATCHDOG1_CLK * WATCHDOG1_TIMEOUT;

		//
		// Lock the Watchdog registers
		//
		WaitForWD1ReadyToWrite();
		WatchdogLock(WATCHDOG1_BASE);
	}
}

Thanks

Kilian

  • Hello Kilian,

    Did you check the errata for TM4C123 device? Watchdog Timer 1 has some entries.

    Regards,
    Sai
  • Hi, Sai

    Stellaris Sai said:
    Did you check the errata for TM4C123 device? Watchdog Timer 1 has some entries.

    Yes, I have checked the Errata. This is the reason for. Line 36 in the Code.

    Additionally, I have tried to add this code in line 92 but also without success.

    //
    // Fix Errata WDT#02: Watchdog Clear Mechanism Described in the Data Sheet Does not Work for the
    // Watchdog Timer 1 Module
    //
    while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0) {}
    HWREG(WATCHDOG0_BASE + WDT_O_ICR) = 1;

  • Does anyone have an Idea? I could still not solve this…
  • Hello Kilian

    Any specific access after which the WRC fails to clear? I remember a similar issue reported, but I haven't been able to find the same yet.
  • Hi Amit,

    Amit Ashara said:

    Any specific access after which the WRC fails to clear?

    It Fails in Line 96 of the code, after feeding the WD by thi

    //
    // Feed the Watchdog by writing the load value
    //
    while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0)	{}
    WatchdogReloadSet(WATCHDOG1_BASE, WATCHDOG1_CLK * WATCHDOG1_TIMEOUT);


    Or by the alternative:

    //
    // Fix Errata WDT#02: Watchdog Clear Mechanism Described in the Data Sheet Does not Work for the
    // Watchdog Timer 1 Module
    //
    while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0)	{}
    HWREG(WATCHDOG0_BASE + WDT_O_ICR) = 1;
    

  • Hello Kilian,

    Thanks. I will look into the issue.
  • Feel your pain - hate to see one "suffer."

    Would it not serve you to (temporarily) redirect your code towards Watchdog_0 - and note the results?    Recall that the vendor admits (some) issue w/WDog_1 - perhaps the issue is broader than they admit.

    If you can succeed w/WDog_0 then the issue is most certainly WDog_1 related - and your presentation of your findings may enable the vendor to suggest some work-around...

  • The Problem is because of the different clock domain of WD1 and the need to wait until data was written. This cannot accrue in WD0 but I could verify that the code works fine with WD1 on an TM4C1232D5PM.

    I think there must be a way to get WD1 to work I assume TI have tested WD1 and there is no use of a WD which cannot be feed.
  • Hello Kilian

    Surprisingly, I have been able to reproduce the problem and always occurring after the LOAD operation in the while loop. It is indeed the WDT#02 and that it was not made clear in the errata sheet. Instead of using Reload, use the interrupt clear mechanism.
  • Amit Ashara said:
    It is indeed the WDT#02

    D'oh stupid me of cause is has to be WATCHDOG1_BASE. Thank you Amit!

    Just for someone looking for code working with WD1 here is the fixed code:

    #include <stdbool.h>
    #include <stdint.h>
    
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_watchdog.h"
    
    #include "driverlib/sysctl.h"
    #include "driverlib/watchdog.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/rom.h"
    
    
    //      Frequenzy in Hz of Watchdog 1 clock source
    #define WATCHDOG1_CLK               16000000
    
    //       Timeout of Watchdog 1 in seconds
    #define WATCHDOG1_TIMEOUT           10
    
    //*****************************************************************************
    static void WaitForWD1ReadyToWrite(void)
    {
        while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0)
        {}
    }
    
    int32_t ui32cnt;
    
    int32_t main(void)
    {   
        //
        // Fix Errata WDT#01: Watchdog Timer 1 Module Cannot be Used Without Enabling Other Peripherals First
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        
        //
        // Enable the Watchdog
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG1);
        
        while (SysCtlPeripheralReady(SYSCTL_PERIPH_WDOG1) ==0)
        {}
        
        //
        // Unock the watchdog registers the can be changed.
        //
        WaitForWD1ReadyToWrite();
        WatchdogUnlock(WATCHDOG1_BASE);
    
        //
        // Enables stalling of the watchdog timer during debug events.
        //
        WaitForWD1ReadyToWrite();
        WatchdogStallEnable(WATCHDOG1_BASE);
        
        
        WaitForWD1ReadyToWrite();
        WatchdogReloadSet(WATCHDOG1_BASE, WATCHDOG1_CLK * WATCHDOG1_TIMEOUT);
        
        //
        // Enable the watchdog timer.
        //
        WaitForWD1ReadyToWrite();
        WatchdogEnable(WATCHDOG1_BASE);
    
        //
        // Lock the watchdog registers for writing.
        //
        WaitForWD1ReadyToWrite();
        WatchdogLock(WATCHDOG1_BASE);
        
        
        while(1)
        {
            ui32cnt++;
            
            SysCtlDelay(10000);
    
            //
            // Unlock the Watchdog registers for writing
            //
            WaitForWD1ReadyToWrite();
            WatchdogUnlock(WATCHDOG1_BASE);
            
            //
            // Feed the Watchdog
            // Fix Errata WDT#02: Watchdog Clear Mechanism Described in the Data Sheet Does not Work for the
            // Watchdog Timer 1 Module
            //
            while((HWREG(WATCHDOG1_BASE + WDT_O_CTL) & WDT_CTL_WRC) == 0) {}
            HWREG(WATCHDOG1_BASE + WDT_O_ICR) = 1;
    
            //
            // Lock the Watchdog registers
            //
            WaitForWD1ReadyToWrite();
            WatchdogLock(WATCHDOG1_BASE);
        }
    }