If you want to use watchdog timer on any Blue Gecko boards / modules, do the followings:

 

1) Create a new C project in Simplicity Studio

 

2) copy em_wdog.c into the project from:

C:\SiliconLabs\SimplicityStudio\v4\developer\stacks\ble\v2.x.x.x\platform\emlib\src

 

3) #include "em_wdog.h"

 

4) Configure the watchdog timer:

 

WDOG_Init_TypeDef init =
{
.enable = true, /* Start watchdog when init done */
.debugRun = false, /* WDOG not counting during debug halt */
.em2Run = true, /* WDOG counting when in EM2 */
.em3Run = true, /* WDOG counting when in EM3 */
.em4Block = false, /* EM4 can be entered */
.swoscBlock = false, /* Do not block disabling LFRCO/LFXO in CMU */
.lock = false, /* Do not lock WDOG configuration (if locked, reset needed to unlock) */
.clkSel = wdogClkSelULFRCO, /* Select 1kHZ WDOG oscillator */
.perSel = wdogPeriod_2k, /* Set the watchdog period to 2049 clock periods (ie ~2 seconds)*/
};

WDOG_Init(&init);.

 

5) Feed the watchdog before the counter overflows, e.g. using a soft timer:

 

while (1) {
struct gecko_cmd_packet* evt;
evt = gecko_wait_event();

switch (BGLIB_MSG_ID(evt->header)) {

case gecko_evt_system_boot_id:
/* Start soft timer to feed the watchdog every second.
* If the stack freezes, the soft timer will stop, and the watchdog will not be fed. */
gecko_cmd_hardware_set_soft_timer(32768,0,0);
break;

case gecko_evt_hardware_soft_timer_id:
/* Feed the watchdog every second while the stack is running */
WDOG_Feed();
break;

default: break;
}
}

 

6) Check at the beginning of main() if the reset was caused by watchdog

 

uint32_t resetCause = RMU_ResetCauseGet();
RMU_ResetCauseClear();

/* Check if the watchdog triggered the last reset */
if (resetCause & RMU_RSTCAUSE_WDOGRST)
{
/* watchdog reset occured */

You have to add em_rmu.c to the project and include "em_rmu.h" to implement this last step

 

Attached you can find an example project using wathchdog on BGM111 using Bluetooth SDK v2.1.1.

  • Knowledge Base Articles
  • Bluetooth Low Energy
  • Bluetooth Classic
  • I've got a watchdog timer running on a BGM121 under GCC successfully- if I comment out the WDOG_Feed() command, the watchdog causes a reset as expected.

     

     

    /* Defining the watchdog initialization data */
    WDOG_Init_TypeDef init =
    {
      .enable     = true,               /* Start watchdog when init done */
      .debugRun   = false,              /* WDOG not counting during debug halt */
      .em2Run     = true,               /* WDOG counting when in EM2 */
      .em3Run     = true,               /* WDOG counting when in EM3 */
      .em4Block   = false,              /* EM4 can be entered */
      .swoscBlock = false,              /* Do not block disabling LFRCO/LFXO in CMU */
      .lock       = false,              /* Do not lock WDOG configuration (if locked, reset needed to unlock) */
      .clkSel     = wdogClkSelULFRCO,   /* Select 1kHZ WDOG oscillator */
      .perSel     = wdogPeriod_8k,      /* Set the watchdog period to ~8 seconds)*/
    };
    
    uint32_t resetCause;
    
    void main(void)
    {
    	/* Move the interrupt vector table to RAM to safely handle interrupts
    	 * while performing write/erase operations on flash */
    	moveInterruptVectorToRam();
    	  /* Store the cause of the last reset, and clear the reset cause register */
    	  resetCause = RMU_ResetCauseGet();
    	  RMU_ResetCauseClear();
    
    #ifdef FEATURE_SPI_FLASH
      /* Put the SPI flash into Deep Power Down mode for those radio boards where it is available */
      MX25_init();
      MX25_DP();
      /* We must disable SPI communication */
      USART_Reset(USART1);
    
    #endif /* FEATURE_SPI_FLASH */
    
    	/* Initialize peripherals */
    	enter_DefaultMode_from_RESET();
    	/* Check if the watchdog triggered the last reset */
    	if (resetCause & RMU_RSTCAUSE_WDOGRST)
    	{
    		/* watchdog reset occurred */
    	}
    	/* Initializing watchdog with chosen settings */
    	WDOG_Init(&init);
    	/* Initialize stack */
    	gecko_init(&config);
    
    #ifdef FEATURE_IOEXPANDER
    if ( BSP_IOEXP_DEVICE_ID == BSP_IOExpGetDeviceId()) {
      BSP_PeripheralAccess(BSP_IOEXP_VCOM,   0); // Disable VCOM
      BSP_PeripheralAccess(BSP_IOEXP_DISPLAY,   1); // Enables the display by pulling DISP_ENABLE high.
      BSP_PeripheralAccess(BSP_IOEXP_SENSORS, 1); // Enables the Si7021 sensor on the Wireless STK by pulling SENSOR_ENABLE high
      BSP_PeripheralAccess(BSP_IOEXP_LEDS,    0); // The LEDs follow the bits LED0 and LED1 when this bit is set
    }
    #endif /* FEATURE_IOEXPANDER */
      
    	while (1) {
    		struct gecko_cmd_packet* evt;
    		evt = gecko_wait_event();   // check for stack event
    		appHandleEvents(evt);  		// run application and event handler
    
    //    	WDOG_Feed();
    		test_buttons_leds();
    	}
    }

     

    However, I am trying to use breakpoints to catch the reset, but they don't seem to trigger on any subsequent watchdog reset.

    The reason I know it IS working is that the LCD resets appropriately according to the timing of the watchdog period.

     

    I just wanted to be able to confirm/check the reset value on a watchdog reset ...

     

    0
  • It appears that a watchdog reset resets the debugger, so the debugger won't trigger on breakpoints after a watchdog reset.

     

    per this post: http://community.silabs.com/t5/32-bit-MCU/Watchdog-reset-confuses-debugger/m-p/108205/highlight/true#M3747

     

    0