Watchdog on BGM111 (and other Blue Gecko modules / boards)

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero Employee</font></font> </a> arkalvac on ‎02-23-2017 07:26 AM

 

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.

Comments
by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Genius</font></font> </a> goutamreddy
on ‎05-12-2017 05:58 PM

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 ...

 

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Genius</font></font> </a> goutamreddy
on ‎05-13-2017 11:07 AM

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...