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.

RTOS/CC2640: Watchdog timer not working

Part Number: CC2640
Other Parts Discussed in Thread: , CC2650STK, , LAUNCHXL-CC2650, CC2650

Tool/software: TI-RTOS

Environment:

CC2640F128 (our custom board based on LSR SaBLE x R3)

ti\simplelink\ble_sdk_2_02_02_25

TI RTOS 2.21.1.08

Compiler TI v 16.9.11 LTS

CCS 8.2.0.00007

Added watchdog driver from the TI-RTOS to SimplePeripheral example. Also added the following piece of code.

in the Application

static Watchdog_Handle wdtHandle=NULL;

#define ENABLE_WDT      1
#define WDT_TICKS       (200)
// 1200000 ==> 1 min ??
// 15000 ==> 1sec (WDT runs always at 48MHz/32)
// 2000 ==>  timeout period to 100 ms ?

void watchdogTimerCallback(UArg handle)
{
    Watchdog_clear(wdtHandle);
    // Perform the equivalent of a PIN Reset (hard reset).
    // The cc26xx system has not been design to handle soft reset.
    // Making a soft reset can make the system unstable.
    // All soft reset needs to be replace by Hard reset.

    SysCtrlSystemReset();   // SysCtrlSystemReset() instead of HAL_SYSTEM_RESET()
}


void watchdogtimer_init()
{

    Watchdog_Params wdParams;
    uint32_t tickValue;

    // open watchdog
    Watchdog_init();
    Watchdog_Params_init(&wdParams);

    wdParams.resetMode = Watchdog_RESET_OFF; // or Watchdog_RESET_OFF ??
    wdParams.debugStallMode = Watchdog_DEBUG_STALL_ON;     // or Watchdog_DEBUG_STALL_ON ??
    wdParams.callbackFxn = watchdogTimerCallback;

    wdtHandle = Watchdog_open(Board_WATCHDOG, &wdParams);   // CC2650STK_WATCHDOG0

    tickValue = Watchdog_convertMsToTicks(wdtHandle, WDT_TICKS);

    Watchdog_setReload(wdtHandle, tickValue);

}

Board header file

/*!
 *  @def    CC2650STK_WatchdogName
 *  @brief  Enum of Watchdogs on the CC2650STK dev board
 */
typedef enum CC2650STK_WatchdogName {
    CC2650STK_WATCHDOG0 = 0,
    CC2650STK_WATCHDOGCOUNT
} CC2650STK_WatchdogName;

/* Generic Watchdog instance identifiers */
#define Board_WATCHDOG              CC2650STK_WATCHDOG0

Board c file

#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(Watchdog_config, ".const:Watchdog_config")
#pragma DATA_SECTION(watchdogCC26XXHWAttrs, ".const:watchdogCC26XXHWAttrs")
#endif

#include "WatchdogCC26XX.h"

WatchdogCC26XX_Object watchdogCC26XXObjects[CC2650STK_WATCHDOGCOUNT];

const WatchdogCC26XX_HWAttrs watchdogCC26XXHWAttrs[CC2650STK_WATCHDOGCOUNT] = {
    {
        .baseAddr    = WDT_BASE,
        .intNum = INT_WDT_IRQ,
        .reloadValue = 1000 /* Reload value in milliseconds */
    },
};

const Watchdog_Config Watchdog_config[CC2650STK_WATCHDOGCOUNT] = {
    {
        .fxnTablePtr = &WatchdogCC26XX_fxnTable,
        .object      = &watchdogCC26XXObjects[Board_WATCHDOG],  /* CC2650STK_WATCHDOG0 */
        .hwAttrs     = &watchdogCC26XXHWAttrs[Board_WATCHDOG]   /* CC2650STK_WATCHDOG0 */
    },
};

const uint_least8_t Watchdog_count = CC2650STK_WATCHDOGCOUNT;

This does not work. 

Same code, with small relevant modifications (like, board LAUNCHXL instead of CC2650STK) in the CC2640R2F , LAUNCHXL-CC2640R2 eval board environment - simplelink_cc2640r2_sdk_2_40_00_32, compiler TI v 18.1.5 LTS, SimpleLink R2 SDK 2.40.0.32 

is working. I am able to see oscilloscope probing the RED / GREEN LEDs .. that there are watchdog resets happening. 

What's the solution? (for our custom board - having already designed on CC2640F128 )

  • How do you judge it doesn’t work on your CC2640 custom board?

  • There is no reset happening when I probe a GPIO (IOID_8 0x00000008 // IO Id 8) signal in oscilloscope. which is toggled in init.
    This is similar test code I added in the eval kit board LAUNCHXL (in which reset is happening.)
  • Try to set a breakpoint inside your watchdogTimerCallback and trace/debug to see if it hits.
  • Unfortunately, it does not hit the Callback function !
  • Try to check if you get correct wdtHandle after you do Watchdog_open.
  • Yes. Please see attached below.

  • I made couple of changes as well.

    " ... .resetMode = Watchdog_RESET_ON" .. 

        wdParams.resetMode = Watchdog_RESET_ON; // or Watchdog_RESET_OFF ??
        wdParams.debugStallMode = Watchdog_DEBUG_STALL_ON;     // or Watchdog_DEBUG_STALL_ON ??
    

    and "INT_NMI_FAULT" .. 

    const WatchdogCC26XX_HWAttrs watchdogCC26XXHWAttrs[CC2650STK_WATCHDOGCOUNT] = {
        {
            .baseAddr    = WDT_BASE,
            .intNum = INT_NMI_FAULT,    /* INT_WDT_IRQ or INT_NMI_FAULT ?? */
            .reloadValue = 150 /* Reload value in milliseconds */
        },
    };
    

    But, there is no interrupt generated !

    Registers ... 

    As well, added 

    GRP( WDT ).REG( RIS ).BFLD( WDTRIS )

    to Watch Expression, with continuously refresh setting for 200 ms .

    Does not seem to have interrupts !

  • Do you have any "working" Watchdog sample code for CC2640F128 !? (not any other CC26 / 5 xx)
  • 1. Try to set wdParams.resetMode = Watchdog_RESET_OFF
    2. Change the following code
    const WatchdogCC26XX_HWAttrs watchdogCC26XXHWAttrs[CC2650STK_WATCHDOGCOUNT] = {
    {
    .baseAddr = WDT_BASE,
    .intNum = INT_NMI_FAULT, /* INT_WDT_IRQ or INT_NMI_FAULT ?? */
    .reloadValue = 150 /* Reload value in milliseconds */
    },
    };

    to

    const WatchdogCC26XX_HWAttrs watchdogCC26XXHWAttrs[CC2650STK_WATCHDOGCOUNT] = {
    {
    .baseAddr = WDT_BASE,
    .reloadValue = 150, /* Reload value in milliseconds */
    .intNum = INT_NMI_FAULT /* INT_WDT_IRQ or INT_NMI_FAULT ?? */
    },
    };

    Rebuild your code to test again.
  • Thanks for your support.

    Though, there is no INT received yet !

    Before the suggested change,

    Watchdog_config	struct Watchdog_Config[2]	[{fxnTablePtr=0x00008F60 {watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=...,object=...,...	0x00008F7C	
    	[0]	struct Watchdog_Config	{fxnTablePtr=0x00008F60 {watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=...,object=...	0x00008F7C	
    		fxnTablePtr	struct Watchdog_FxnTable *	0x00008F60 {watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=0x00008B03,watchdogInit=...	0x00008F7C	
    			*(fxnTablePtr)	struct Watchdog_FxnTable	{watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=0x00008B03,watchdogInit=...	0x00008F60	
    				watchdogClear	void (*)(Watchdog_Config**)	0x00008A5D	0x00008F60	
    				watchdogClose	void (*)(Watchdog_Config**)	0x00001933	0x00008F64	
    				watchdogControl	int (*)(Watchdog_Config**,unsigned int,unknown*)	0x00008B03	0x00008F68	
    				watchdogInit	void (*)(Watchdog_Config**)	0x00008AF5	0x00008F6C	
    				watchdogOpen	Watchdog_Config** (*)(Watchdog_Config**,Watchdog_Params*)	0x00005239	0x00008F70	
    				watchdogSetReload	void (*)(Watchdog_Config**,unsigned int)	0x00007865	0x00008F74	
    				watchdogConvertMsToTicks	unsigned int (*)(unsigned int)	0x00007AB1	0x00008F78	
    		object	void *	0x20001FA0	0x00008F80	
    		hwAttrs	void *	0x0000900C	0x00008F84	
    	[1]	struct Watchdog_Config	{fxnTablePtr=0x00000000 {watchdogClear=0x20003F20,watchdogClose=0x000072D1,watchdogControl=...,object=...	0x00008F88	
    		fxnTablePtr	struct Watchdog_FxnTable *	0x00000000 {watchdogClear=0x20003F20,watchdogClose=0x000072D1,watchdogControl=0x1001CA01,watchdogInit=...	0x00008F88	
    		object	void *	0x00000000	0x00008F8C	
    		hwAttrs	void *	0x00000000	0x00008F90	
    
    0x0000900C	watchdogCC26XXHWAttrs
    0x0000900C	00	00	08	40	02	00	00	00	96	00	00	00
    
    0x20001FA0	watchdogCC26XXObjects
    0x20001FA0	01	00	00	00	00	00	00	00	01	00	00	00	00	00	00	00	7C	8F	00	00	11	88	00	00	00	00	00	00	FF	00	02	00	00	00	00	00	00	00	00	00
    
    0x00008F60	WatchdogCC26XX_fxnTable
    0x00008F60	5D	8A	00	00	33	19	00	00	03	8B	00	00	F5	8A	00	00	39	52	00	00	65	78	00	00	B1	7A	00	00
    
    

    And after the change

    Watchdog_config	struct Watchdog_Config[2]	[{fxnTablePtr=0x00008F60 {watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=...,object=...,...	0x00008F7C	
    	[0]	struct Watchdog_Config	{fxnTablePtr=0x00008F60 {watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=...,object=...	0x00008F7C	
    		fxnTablePtr	struct Watchdog_FxnTable *	0x00008F60 {watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=0x00008B03,watchdogInit=...	0x00008F7C	
    			*(fxnTablePtr)	struct Watchdog_FxnTable	{watchdogClear=0x00008A5D,watchdogClose=0x00001933,watchdogControl=0x00008B03,watchdogInit=...	0x00008F60	
    				watchdogClear	void (*)(Watchdog_Config**)	0x00008A5D	0x00008F60	
    				watchdogClose	void (*)(Watchdog_Config**)	0x00001933	0x00008F64	
    				watchdogControl	int (*)(Watchdog_Config**,unsigned int,unknown*)	0x00008B03	0x00008F68	
    				watchdogInit	void (*)(Watchdog_Config**)	0x00008AF5	0x00008F6C	
    				watchdogOpen	Watchdog_Config** (*)(Watchdog_Config**,Watchdog_Params*)	0x00005239	0x00008F70	
    				watchdogSetReload	void (*)(Watchdog_Config**,unsigned int)	0x00007865	0x00008F74	
    				watchdogConvertMsToTicks	unsigned int (*)(unsigned int)	0x00007AB1	0x00008F78	
    		object	void *	0x20001FA0	0x00008F80	
    		hwAttrs	void *	0x0000900C	0x00008F84	
    	[1]	struct Watchdog_Config	{fxnTablePtr=0x00000000 {watchdogClear=0x20003F20,watchdogClose=0x000072D1,watchdogControl=...,object=...	0x00008F88	
    		fxnTablePtr	struct Watchdog_FxnTable *	0x00000000 {watchdogClear=0x20003F20,watchdogClose=0x000072D1,watchdogControl=0x1001CA01,watchdogInit=...	0x00008F88	
    		object	void *	0x00000000	0x00008F8C	
    		hwAttrs	void *	0x00000000	0x00008F90	
    
    0x0000900C	watchdogCC26XXHWAttrs
    0x0000900C	00	00	08	40	02	00	00	00	96	00	00	00
    
    0x20001FA0	watchdogCC26XXObjects
    0x20001FA0	01	00	00	00	00	00	00	00	00	00	00	00	00	00	00	00	7C	8F	00	00	11	88	00	00	00	00	00	00	FF	00	02	00	00	00	00	00	00	00	00	00
    
    0x00008F60	WatchdogCC26XX_fxnTable
    0x00008F60	5D	8A	00	00	33	19	00	00	03	8B	00	00	F5	8A	00	00	39	52	00	00	65	78	00	00	B1	7A	00	00
    
    

    where both cases watchdogCC26XXHWAttrs[] seemed to be same effect.

    This should be correct, I suppose. Because struct members are 

    /*!
     *  @brief  Watchdog hardware attributes for CC26XX
     */
    typedef struct WatchdogCC26XX_HWAttrs {
        unsigned int baseAddr;       /*!< Base adddress for Watchdog */
        unsigned int intNum;         /*!< Watchdog interrupt number */
        unsigned long reloadValue;   /*!< Reload value in milliseconds for Watchdog */
    } WatchdogCC26XX_HWAttrs;

  • Which BLE STACK do you test this? I just test this with BLE stack 2.2.2 simple_peripheral example on my LAUNCHXL-CC2650, and it works fine.
  • My environment is
    ble_sdk_2_02_02_25
    tirtos_cc13xx_cc26xx_2_21_01_08
    cc2650stk (not CC2650_LAUNCHXL)
  • Don't you use CC2640F128 custom board. Why does it become CC2650STK now? Anyway, I see no problem to make watchdog work on cc2650stk. I can test this when I can access to my CC2650STK.
  • It is custom board, but mostly similar to STK. So, we are using board files with small modifications.

    Do you suspect any changes that may effect ?? Any pointers please !? 

  • Since you are using cc2650stk example, I suppose you should to set wdParams.resetMode = Watchdog_RESET_OFF
    and use the following code
    const WatchdogCC26XX_HWAttrs watchdogCC26XXHWAttrs[CC2650STK_WATCHDOGCOUNT] = {
    {
    .baseAddr = WDT_BASE,
    .intNum = INT_NMI_FAULT, /* INT_WDT_IRQ or INT_NMI_FAULT ?? */
    .reloadValue = 150 /* Reload value in milliseconds */
    },
    };
  • Thanks for your support.

    After commenting out the code ... 

    //#if defined(__TI_COMPILER_VERSION__)
    //#pragma DATA_SECTION(Watchdog_config, ".const:Watchdog_config")
    //#pragma DATA_SECTION(watchdogCC26XXHWAttrs, ".const:watchdogCC26XXHWAttrs")
    //#endif

    it worked. Now, I am getting in to the callback function.

    Separate section couldn't be reached !? Address not reachable !!?? 

    I don't know.

    But the same code worked in CC2640R2F platform. (With pragma to DATA Section !) 

    Wondering ! 

    Do you get why ??