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.

CC26XX Watchdog Examples and Documentation Clarification

I am looking to implement a watchdog reset for a device which will use a cc26xx chip. The documentation in the RTOS User Guide lists out the process to init the module and setup the resetMode and callbackFxn. These seem straightforward. However, when looking at the documentation generated in doxygen - I see a note that claims that:

"Note that the watchdog driver has not been fully validated, and thus should be considered experimental."

Moreover, right below it states something about the SPI API - is this a copy paste error in your documentation? 

For reference, I am using the Ti-RTOS SimpleLink v2.13.00.06.

I would also appreciate pointers to a couple of examples which implement and use this functionality. Additionally, I would also like to understand what remains to be validated with the watchdog driver?

  • Hello,

    As you've likely seen from searching E2E, there is no watchdog driver available in the TI-RTOS driver package.

    Best wishes
  • JXS, 

    I don't think this is true. My version of the RTOS includes a WatchdogCC26XX file. Are you telling me that a Watchdog timer cannot be implemented in the CC26XX package(s)?

  • Shaba,

    The watchdog driver is for now not included in our nightly automated regression tests, therefore it is marked as experimental and not included in the Board file.

    Below is an example showing how to set it up.

    To ensure the full program is running fine you should to implement a more advanced way of clearing the WDT interrupt. You can for example do the following:

    • Have a periodic TI RTOS clock set an event and post a semaphore for your main application loop. The clock should expire more often than the WDT.
    • In the event handler, unlock, reload and lock the watchdog again (driverlib/watchdog.h /WatchdogUnlock / WatchdogLock / WatchdogReloadSet)
    • In the WDT callback simply do a hard reset of the device (driverlib/sys_ctrl.h / SysCtrlSystemReset)

    Note that the WDT is not running in Standby mode as it is running of the high-speed 48MHz clock which is then stopped. 

    Regards,
    Svend

    //Board.h or application
    typedef enum CC2650_WatchdogName {
        CC2650_WATCHDOG0 = 0,
        CC2650_WATCHDOGCOUNT,
    } CC2650_WatchdogName;
    
    //Board.c or application
    WatchdogCC26XX_Object watchdogCC26XXObjects[CC2650_WATCHDOGCOUNT];
    
    const WatchdogCC26XX_HWAttrs watchdogCC26XXHwAttrs[] =  {
      {
        .baseAddr = WDT_BASE,
        .intNum   = INT_WATCHDOG,
      }
    };
    
    const Watchdog_Config Watchdog_config[] = {
      { &WatchdogCC26XX_fxnTable, &watchdogCC26XXObjects[0], &watchdogCC26XXHwAttrs[0] },
      { NULL, NULL, NULL },
    };
    
    //Application:
    
    #include <ti/sysbios/family/arm/cc26xx/Power.h>
    #include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
    #include <ti/drivers/Watchdog.h>
    #include <ti/drivers/watchdog/WatchdogCC26XX.h>
    
    Watchdog_Handle hWDT;
    
    void wdtCallback(UArg a0) {
      Watchdog_clear(hWDT);
    }
    
    void someInitFxn() {
      Watchdog_Params wp;
      Watchdog_Params_init(&wp);
      wp.callbackFxn    = wdtCallback;
      wp.debugStallMode = Watchdog_DEBUG_STALL_ON;
      wp.resetMode      = Watchdog_RESET_ON;
    
      hWDT = Watchdog_open(Board_WATCHDOG, &wp);
      Watchdog_setReload(hWDT, 1500000); // 1sec (WDT runs always at 48MHz/32)
    }

  • Thank you Svend for the very detailed explanation and examples. I really appreciate the help! I was able to get something almost like this working last week, but like you pointed out - it only works when the system is not idle.

    A couple of follow up questions if you will:

    1. When is this expected to be part of the official release? I am using a version with the UART HW Flow Control enabled which I think is a more recent version of the RTOS

    2. So it is not possible for the WDT to operate when the main MCU is on idle? Does this mean if I have a sensor controller task running in the Background - it will not impact the WD register and decrement it? 

    3. My application tries to minimize the on-time for the M3 - in my case I would only manage and clear the WDT when in my application main loop which involves the M3, correct?

    4. Where is the DEBUG_STALL documented? What exactly does this allow? I assume in a broad sense it allows for us to debug the application without the WDT causing a reset?

    5. I also assume that if my M3 was running at a lower speed of 1MHz then the WDT will decrement proportionally to that clock, correct?

    Thanks again for all the help!

  • svendbt said:

    Note that the WDT is not running in Standby mode as it is running of the high-speed 48MHz clock which is then stopped. 

    I had noticed this, with the Reload time set to 10 seconds it actually takes about 666 seconds for the interrupt to fire because the chip is in standby mode most of the time. So doesn't this raise a question, if the chip gets stuck in standby mode then the Watchdog will never reset it. Is this a situation that could happen?

  • Hello svendbt:

    just a problem , when I add

    const Watchdog_Config Watchdog_config[] = {

     { &WatchdogCC26XX_fxnTable, &watchdogCC26XXObjects[0], &watchdogCC26XXHwAttrs[0] },

     { NULL, NULL, NULL },

    };

    into Board.c

    I get error messages:

  • You need to include the driver file
    /* Include drivers */
    #include <ti/drivers/watchdog/WatchdogCC26XX.h>
  • Hello Christin :
    I also add #include <ti/drivers/watchdog/WatchdogCC26XX.h> in Board.c
    Board.c path :
    C:\ti\tirtos_simplelink_2_13_00_06\packages\ti\boards\SRF06EB\CC2650EM_7ID\Board.c
  • Hi all,

    The wdt is very easy to enable via settings values to the registers. I haven't figured out timing or callback events. But this code should work as a functional WDT.

    In initialisation phase. (Tested before BIOS_start())
    *(uint32_t*) 0x40080C00 = 0x1ACCE551; // Open Lock
    *(uint32_t*) 0x40080000 = 24000000; // Load to the timer (not sure about relation to seconds)
    *(uint32_t*) 0x40080008 = 0x00000007; // Settings for wdt - Non-Maskable & Reset Enable & Interrupt Enable
    *(uint32_t*) 0x40080C00 = 0x00000000; // Close Lock

    And to clear the timer.
    *(uint32_t*) 0x4008000C = 0x00000001;