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: Watchdog 0 cyclic writes

Guru 55913 points
Part Number: TM4C1294KCPDT

Cyclic writes to WDTLOAD REG-1 fail in a semaphore interrupt reload context of PWM0 zero interrupt for switch cases processed in 1 millisecond count downs of that semaphore. Otherwise the WDTLOAD succeeds in the same 1 millisecond semaphore interrupt without switch case calls being present.

The Watchdog WDTLOAD value (333ms) then incorrectly times out exceeding switch case 1 UserParameter.Count but only during semaphore interrupts of exact cyclic 1 millisecond periods. Setting the UseParameter.Count value above WDTLOAD value of 333ms and the dog times out when it should be reloading in cyclic 1ms periods of (case 1:) processed in the semaphore 1ms interrupt.

Other words the dog appears to be dead locked in this scenario and refuses to eat his food.

    switch(Newcase)
    {
           case 0;
            {

                /* Various C code processed in the millisecond context of
                   PWM0 GEN0 software interrupt */

                /* Load users milliseconds count value */
                Count = UserParameter.Count; 

                /* Unlock the Watchdodgs registers for write access */
                HWREG(WATCHDOG0_BASE + WDT_O_LOCK) = WDT_LOCK_UNLOCK;

            }

           case 1:
            {
            
                /* Wdog0 for 1ms intervals of user hold count x 120k. 
                 * Note: Count should default to milliseconds but does not */
                HWREG(WATCHDOG0_BASE + WDT_O_LOAD) = (Count * 120000);

                /* Various C code processed in the millisecond context of
                   PWM0 GEN1 software interrupt */

               /* Enable PWM selected (enabled) pin mux outputs for gating PWM. */
               HWREG(PWM0_BASE + PWM_O_ENABLE) |= (ulPWMOutBits & 0x3F);

                Count--;

                If (Count == 0)
                 {
                     Newcase = 2;

                     Count = UserParameter.Count; 

                     /* Lock the Watchdodg other registers blocking write access. */
                     HWREG(WATCHDOG0_BASE + WDT_O_LOCK) = WDT_LOCK_LOCKED;

                     break;
                 }
                 //break; doubles 1ms SW semaphore interrupt into case 1
            }
     }

  • Hi BP101,
    I'm not clear with your code. Where is the switch statement implemented? Is the switch part of the PWM0 ISR?

    Please be noted about the register access timing as described in the below excerpt when accessing the WD Timer1.

    Register Access Timing
    Because the Watchdog Timer 1 module has an independent clocking domain, its registers must be
    written with a timing gap between accesses. Software must guarantee that this delay is inserted
    between back-to-back writes to WDT1 registers or between a write followed by a read to the registers.
    The timing for back-to-back reads from the WDT1 module has no restrictions. The WRC bit in the
    Watchdog Control (WDTCTL) register for WDT1 indicates that the required timing gap has elapsed.
    This bit is cleared on a write operation and set once the write completes, indicating to software that
    another write or read may be started safely. Software should poll WDTCTL for WRC=1 prior to
    accessing another register. Note that WDT0 does not have this restriction as it runs off the system
    clock.
  • Hi Charles,

    Charles Tsai said:
    Is the switch part of the PWM0 ISR

    Not exactly - rather zero interrupt triggers a software interrupt in exact 1ms intervals relative to PWM frequency. That has been confirmed via GPIO port and the Switch case that loads in 1ms intervals from that semaphore context. That switch case fires the PWMENABLE register several time for user parameter count value in milliseconds. Scope captures the PWMENABLE output wave form a bit longer than user count parameter, roughly 50ms longer.

    Charles Tsai said:
    Please be noted about the register access timing as described in the below excerpt when accessing the WD Timer1.

    We are only loading WatchDog0.

    What seems to be happening is case 1 is not falling through the bottom, adding second break in case 1 makes no difference. When the user count is higher than the WDTLOAD value the Wdog0 interrupt triggers no matter that the WDTLOAD value should be when reloaded for 333ms counts every 1ms. That keeps the dog from timing out by feeding him in case 1 before firing PWMENABEL.

     

  • Hi BP101,

    What is the zero interrupt? Which module generates the zero interrupt?

    In your original post you said 'Cyclic writes to WDTLOAD REG-1 fail in a semaphore...' that is what I thought you were talking about WD timer 1, not WD timer 0.

  • PWM0 Gen0 produces load count zero INT, GEN1 INT is the SW semaphore INT triggered in the INT zero context every 1ms.

    WDTLOAD value seems to only load one time even when spoon fed via HWREG direct loads in case 1. That is unlock dog in case zero and lock dog again in case 1 break. Versus calling a stack function to reload WDog0 load value each 1ms period. It should take less than few 100us to output PWMENABLE register each 1ms interval of case 1, not 300ms.

    Oddly adding a second break (case 1) extends call to PWMENABLE function several 100ms longer than the user count parameter setting. That user entered count down should occur PWM0 GEN0 zero INT context of SW driven 1ms INT's within case1, looking back into NVIC priority chain from case 1 point of view.
  • Result of WDTLOAD being loaded for (1200000 * 8.3333 ns SYSCLK) or 10ms timeout; WDog0 times out in first 1ms interval.

    Should not have to multiply parameter user count by 120k (code above). Doing so makes the dogs timeout period hundreds of milliseconds rather than required 200us protection interval for PWNENABLE (case 1). The dog should only bark if the period extends past 200us in the 1ms intervals of case 1.
  • A datasheet contradiction exists to how/when the WDTLOAD register can be written thus restart the timers count leave out a crucial tidbit. Question then becomes how was Wdog0 even working once the INTEN bit was set as punching the dog did not first clear the INTEN bit. Seemingly that explains why the timers value required being set so high when the loop the dog was protecting is/was much shorter.  

    14.2 Functional description
    If WDTLOAD is written with a new value while the Watchdog Timer counter is counting, then the
    counter is loaded with the new value and continues counting.

    *********************************************************************************************************

    Watchdog Interrupt Enable
    The INTEN values are defined as follows:

    Value Description

    0 Interrupt event disabled. Once this bit is set, it can only be
     cleared by a hardware reset or a software reset initiated by
     setting the appropriate bit in the Watchdog Timer Software Reset (SRWD) register.  

    1 Interrupt event enabled.
     Once enabled, all writes are ignored.
     Setting this bit enables the Watchdog Timer.