SAM4S watch dog timer and simulating lockup

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi - I am following this example to enable a WDT and simulate a deadlock on my SAM4S xplained pro. In the below example, the WDT_Handler(void) is never called. When an interrupt is detected on PA14, I start a while loop to simulated the lockup. The interrupt is firing but never calls WDT_Handler(). Either I am not setting up the WDT correctly or I am not simulating the deadlock correctly. Any help is appreciated.

#include <asf.h>
#include "conf_usart.h"

// interrupt
void setup_interupts(void);
void pin_edge_handler(const uint32_t id, const uint32_t index);

volatile bool g_b_button_event = false;
/** System Tick event flag */
volatile bool g_b_systick_event = false;
/** System tick increased by 1 every millisecond */
volatile uint32_t g_ul_ms_ticks = 0;
/** Watchdog period 3000ms */
#define WDT_PERIOD                        3000
#define WDT_RESTART_PERIOD                2000

#define SW1 PIO_PA14

void configure_wdt(void);
int main (void)
{
	board_init();
	sysclk_init();	// don't for get this!
	SysTick_Config(sysclk_get_cpu_hz() / 1000); // for system tick

	delay_init();
	configure_uart(115200);
	printf("SAM4S WDT\n");
	setup_interupts();
	configure_wdt();

	while (1) {

		if(g_b_button_event){
			printf("Simulate deadlock\n");
			while (1) {
			}
		}
	}
}
void configure_wdt(void){

	uint32_t wdt_mode, timeout_value;
	/* Get timeout value. */
	timeout_value = wdt_get_timeout_value(WDT_PERIOD * 1000, BOARD_FREQ_SLCK_XTAL);
	if (timeout_value == WDT_INVALID_ARGUMENT) {
		while (1) {
			/* Invalid timeout value, error. */
		}
	}
	/* Configure WDT to trigger an interrupt (or reset). */
	wdt_mode = WDT_MR_WDFIEN |  /* Enable WDT fault interrupt. */
            WDT_MR_WDRPROC   |  /* WDT fault resets processor only. */
            WDT_MR_WDDBGHLT  |  /* WDT stops in debug state. */
            WDT_MR_WDIDLEHLT; /* WDT stops in idle state. */

	/* Initialize WDT with the given parameters. */
	wdt_init(WDT, wdt_mode, timeout_value, timeout_value);

	/* Configure and enable WDT interrupt. */
	NVIC_DisableIRQ(WDT_IRQn);
	NVIC_ClearPendingIRQ(WDT_IRQn);
	NVIC_SetPriority(WDT_IRQn, 0);
	NVIC_EnableIRQ(WDT_IRQn);
}

void WDT_Handler(void)
{
	printf("Enter watchdog interrupt.\r");

	/* Clear status bit to acknowledge interrupt by dummy read. */
	wdt_get_status(WDT);
	/* Restart the WDT counter. */
	wdt_restart(WDT);
	printf("The watchdog timer was restarted.\r");
	g_b_button_event = false;
}

void setup_interupts(void){

	pmc_enable_periph_clk(ID_PIOA);
	pio_set_input(PIOA, SW1, PIO_PULLUP);
	pio_set_debounce_filter(PIOA,  SW1, 20);
	pio_handler_set(PIOA, ID_PIOA, SW1, PIO_IT_EDGE, pin_edge_handler);
	pio_enable_interrupt(PIOA, SW1);
	NVIC_EnableIRQ(PIOA_IRQn);
}

void pin_edge_handler(const uint32_t id, const uint32_t index)
{
	if ((id == ID_PIOA) && (index == SW1)){
		if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, SW1) ){
			printf("Button Presses to trigger deadlock\n\r");
			g_b_button_event = true;
		}
	}

}

void SysTick_Handler(void)
{
	/* Set systick event flag (g_b_systick_event) and add 1 to systick. */
	g_b_systick_event = true;
	g_ul_ms_ticks++;
}

 

This topic has a solution.

"When all else fails, read the directions"

Last Edited: Sun. May 28, 2017 - 01:38 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Solved - When creating a project for the SAM4S xplained pro board, by default the following is burried in the board_init()

#ifndef CONF_BOARD_KEEP_WATCHDOG_AT_INIT
	wdt_disable(WDT);
#endif

wdt_disables the watch dog timer.

 

p_wdt->WDT_MR = WDT_MR_WDDIS;

The problem is the WDT_MR register can only be written to once. Nice little boobie trap!

 

"When all else fails, read the directions"