This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem with implementation of the watchdog interrupt

I ran watchdog with this code:

void wdt_init(void)
{
	NRF_WDT->CONFIG = (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos) | ( WDT_CONFIG_SLEEP_Run << WDT_CONFIG_SLEEP_Pos);
	NRF_WDT->CRV = 1*32768;   //1 sec. timeout
	NRF_WDT->RREN |= WDT_RREN_RR0_Msk;  //Enable reload register 0
	NRF_WDT->TASKS_START = 1; //triggering of watchdog
}

Because I want to save some data to flash before the nrf51822 reset, I tried to use WDT_IRQn (generated on the TIMEOUT event). Unfortunately, my code doesn't work.

APP_TIMER_DEF(wdt_timer_id);

//some code

static void WDT_IRQHandler(void * p_context) 
{
	LEDS_OFF(BSP_LED_4_MASK);
	LEDS_OFF(BSP_LED_3_MASK);
	LEDS_OFF(BSP_LED_2_MASK);
	LEDS_OFF(BSP_LED_1_MASK);
	LEDS_OFF(BSP_LED_0_MASK);
	while(1)
	{
	}
}

void wdt_interrupt_init(void)
{
	uint32_t err_code;
	NRF_WDT->INTENSET = WDT_INTENSET_TIMEOUT_Msk;
	sd_nvic_SetPriority(WDT_IRQn, 1);
	sd_nvic_EnableIRQ(WDT_IRQn);
	err_code = app_timer_create(&wdt_timer_id,
										APP_TIMER_MODE_SINGLE_SHOT,
										WDT_IRQHandler);
	APP_ERROR_CHECK(err_code);
}

Adding WDT_IRQ doesn't change behavior of MCU, it restarts without executing of the WDT_IRQHandler.

I am not sure where I should place app_timer_start(wdt_timer_id, NRF_WDT->CRV, NULL) function. Up to now it is placed right beneath the place where the watchdog is being reloaded.

  • Hi

    There is some WDT with interrupt example code for SDK 11.0.0 available here, but without softdevice. There is also another branch there for nRF51 SDK 5.2.0 which has code for WDT with softdevice. Perhaps you can benefit looking at that as well.

    The watchdog reset is anyhow triggered when the watchdog timeout occurs, which delays the watchdog reset by 2x 32kHz clock cycles while executing the WDT interrupt handler, which is around 61 microsecond. You should be able to write one word to flash in that time, which takes maximum 46us according to the specification. Additionally it might take up to 10 microseconds to start execution of the interrupt handler after the WDT timeout interrupt is triggered.

    To prevent other interrupts from blocking the WDT interrupt, you might also want to set the WDT interrupt as high priority.

  • I'm a bit confused as to why you would want to call the WDT IRQ handler out of a timer. The system should invoke that function itself without it being in a timer. I'd suggest using Nordic's WDT driver as it already implements all of this for you. All you need to do is set up a configuration structure and call their init function. You can find it in SDK 11 components\drivers_nrf\wdt.

  • I just didn't understand how to implement event handler, after analyzing the code of the wdt example I did it in the right way. I didn't simply use the wdt example because I had problem with adding nrf_drv_wdt.c to my project. Besides, I wanted to learn how it works.

  • I thought that two clock cycles means 2x32768 ticks of the clock, that is about 2 seconds :D. Thanks for set this straight for me

Related