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.

CC2538: CC2538 Watchdog won't stop under PM2

Part Number: CC2538

Hello All,

I am desperate with the last problem with our CC2538 board.

It is supposed to be simple. I just wanted to enable watchdog on a low-power board that constantly stays in PM2.

The code is exactly like below:

// Some code to set sleep timer

REG(SCB_SYSCTRL) |= SCB_SYSCTRL_SLEEPDEEP;

REG(SYS_CTRL_PMCTL) = 2;

__asm volatile( "dsb" );
__asm volatile( "wfi" );
__asm volatile( "isb" );

PRINTF("WAKEUP\n");

When watchdog is enabled the  board is always reset by watchdog. without reaching printing "WAKEUP".

When watchdog is not enabled. code "wfi" will ake up by sleep timer after a few seconds and everything is running nicely!

It is driving me crazy! I can't imagine anything could possibly go wrong!

BTW, I am using external 32K crystal. And PD6 and PD7 are correctly set as analog input!

Any help is appreciated!

  • The watchdog will always reset the device unless you 'pet' the dog before the WDT expires. The default setting is 32768 or 1 second.

    Regards,
    Chris
  • Hi Chris,
    Thanks for your reply. But it is not what TI claims. TI claims that CC2538 watchdog will stop counting under all power mode and only resume counting when back to active mode.

    From TI document:

    The contents of the 15-bit counter are retained during all power modes, and the WDT continues counting when entering active mode again.

    I realized that my watchdog are counting in all power mode, from pm0 to pm2. It didn't reset under pm0 because pm0 always wakes up in less than 1 second.

  • Thank you. I currently do not have an answer but I am looking into the discussion regarding the transition from 16Mhz from 32Mhz found in the TRM.

    "Any event on enabled interrupts in the transition period between 32 MHz and
    16 MHz clock source will stop the chip from entering the selected power mode
    unless WFI is asserted again or not deasserted by the interrupt handler. The
    clock source will be reverted to the setting it had before, i.e. the chip will have
    the same status as before the WFI was asserted."

    Regards,
    Chris
  • Hi Chris,

    Thank you! I finally found out the problem. It was caused by Emulator override control.

    I found this in the startup code:

    HWREG(SYS_CTRL_EMUOVR) = 0xFF;

    Commenting out the code solved the problem

    I would recommend adding this to the watchdog section of the document. It might help other people.

    Again. Appreciate your effort very much!

  • Hi Chris,

    I have to re-open this issue. I was wrong, SYS_CTRL_EMUOVR does NOT solve the issue.

    Watchdog still resets the board.

    BTW, in my code, I manually switch to 16mhz rcosc before asseting wfi. Still the watch dog resets.

  • When the sleep timer interrupt wakes up the device, how is the device returned to sleep so that the WDT will not continue to count?   Do you clear the wdt during the sleep timer interrupt?  

    /******************************************************************************
    *  Filename:       watchdog_simple.c
    *  Revised:        $Date: 2013-04-10 10:58:59 +0200 (Wed, 10 Apr 2013) $
    *  Revision:       $Revision: 9697 $
    *
    *  Description:    Example demonstrating how to configure the watchdog timer.
    *
    *  Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
    *
    *
    *  Redistribution and use in source and binary forms, with or without
    *  modification, are permitted provided that the following conditions
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    ******************************************************************************/
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "hw_memmap.h"
    #include "gpio.h"
    #include "hw_ioc.h"
    #include "ioc.h"
    #include "interrupt.h"
    #include "sys_ctrl.h"
    #include "systick.h"
    #include "uartstdio.h"
    #include "watchdog.h"
    
    #include "hw_ints.h"
    #include "sleepmode.h"
    #include "uart.h"
    
    //
    //*****************************************************************************
    //
    //! \addtogroup watchdog_examples_list
    //! <h1>Watch dog (watchdog_simple)</h1>
    //!
    //! This example shows how to configure and clear the watchdog timer.
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - NONE
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you can add these interrupt handlers to your
    //! vector table.
    //! - None
    //!
    //*****************************************************************************
    #define EXAMPLE_PIN_LED_1            GPIO_PIN_0   //PC0
    #define EXAMPLE_PIN_LED_2            GPIO_PIN_1   //PC1
    #define EXAMPLE_GPIO_LED_BASE        GPIO_C_BASE
    
    
    //*****************************************************************************
    //
    // Sleep mode timer ISR
    //
    //*****************************************************************************
    void SleepModeIntHandler(void)
    {
        GPIOPinWrite(EXAMPLE_GPIO_LED_BASE, 
                     EXAMPLE_PIN_LED_1,
                     0);
                     
        return;
    }
    
    //*****************************************************************************
    //
    //
    //*****************************************************************************
    int main(void)
    {
        uint32_t ui32Val;
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // (no ext 32k osc, no internal osc)
        //
        //SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);
        SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_16MHZ);
    
        //
        // Set IO clock to the same as system clock
        //
        //SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
        SysCtrlIOClockSet(SYS_CTRL_SYSDIV_16MHZ);
        
        GPIOPinTypeGPIOOutput(EXAMPLE_GPIO_LED_BASE,
                              (EXAMPLE_PIN_LED_1 | EXAMPLE_PIN_LED_2));
        
        GPIOPinWrite(EXAMPLE_GPIO_LED_BASE, 
                     EXAMPLE_PIN_LED_1,
                     1);
        GPIOPinWrite(EXAMPLE_GPIO_LED_BASE, 
                     EXAMPLE_PIN_LED_2,
                     1);
        
        //
        // Let system enter powermode 2 when going to deep sleep
        //
        SysCtrlPowerModeSet(SYS_CTRL_PM_2);
    
        //
        // Enable the Sleep Timer wakeup
        //
        GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER); 
    
        //
        // Enable sleep mode interrupt
        //
        IntEnable(INT_SMTIM);
        
        //
        // Set timer to 10000
        //
        ui32Val = SleepModeTimerCountGet();
        SleepModeTimerCompareSet(ui32Val + 10000);
        GPIOPinWrite(EXAMPLE_GPIO_LED_BASE, 
                 EXAMPLE_PIN_LED_1,
                 1);
    
        //
        // Enable watchdog
        //
        //WatchdogEnable(WATCHDOG_INTERVAL_32768);  
        WatchdogEnable(WATCHDOG_INTERVAL_8192);
        
        while(1)
        {
            //
            // Go to sleep
            //
            SysCtrlDeepSleep();
        }
        
    }
    

    Please see the attached and confirn that the WDT is still running.

    Regards,
    Chris