//----------------------------------------------------------------------------------
// <copyright file="wdtrog/c" company="LiquidRobotics">
//	Copyright (c) Liquid Robotics Corporation.  All rights reserved.
// </copyright>
//
// <summary>
// 	General purpose interface to watchdog timer, allows for requiring a configurable
//  set of trigger events to be set before actually retriggering the watchdog
// </summary>
//
// <owner>Mike Cookson</owner>
//---------------------------------------------------------------------------------

#include "includes.h"
#include <avr/wdt.h>
#include "wdtrig.h"

#if WDTRIG_ENABLED != 0
static volatile uint32_t watchdogTriggerMask;		// all of these bits must be set to trigger watchdog
static volatile uint32_t watchdogCurrentMask;		// these are the current watchdog bits
#endif

/*PAGE*/
/*
 *******************************************************************************
 *             INITIALIZE THE WATCHDOG AND CONFIGURES TRIGGER MASK
 *
 * Description :	Enables the watchdog for the timeout value in the header file
 *					(8 seconds typically) and saves the trigger mask that will
 *					be required in order to cause a real watchdog trigger.
 *
 * Arguments : 		trigMask is the mask of bits that must be set before the
 *					watchdog will really be triggered (0=always trigger)
 *
 * Returns:			n/a
 *
 * Notes:			Using this mask, the client application can determine which
 *					events will cause the watchdog to retrigger for maximum
 *					flexibility.  In some applications, a simple context switch
 *					may be enough to cause a watchdog trigger, while others may
 *					need to verify that application-specific actions are working.
 *******************************************************************************
 */
#if WDTRIG_ENABLED != 0
void OSwatchdogInit(uint32_t trigMask)
{
	WDTRIG_CONFIG_WATCHDOG();			// enables and configures the watchdog

	watchdogCurrentMask = 0;			// clear the current bits
	watchdogTriggerMask = trigMask;		// save the trigger mask
}
#endif

/*PAGE*/
/*
 *******************************************************************************
 *             RETRIGGER THE WATCHDOG IF ALL REQUIREMENTS ARE MET
 *
 * Description :	Sets the flags indicated by "mask" in the current bit mask
 *					and then checks if all required bits are set, triggering
 *					the watchdog timer if so.
 *
 * Arguments : 		mask indicates which event that has occurred that might
 *					require a watchdog timer reset; typically this is a mask
 *					with only one bit set
 *
 * Returns:			n/a
 *
 * Notes:			
 *******************************************************************************
 */
#if WDTRIG_ENABLED != 0
void OSwatchdogTrigger(uint32_t mask)
{
	// if adding the "mask" bits results in the watchdog trigger mask
	// bits being set, then retrigger the watchdog
	OS_CPU_SR cpu_sr;
	OS_ENTER_CRITICAL();

	long temp = watchdogCurrentMask |= mask;

	OS_EXIT_CRITICAL();

	if ((temp & watchdogTriggerMask) == watchdogTriggerMask)
	{
		OS_ENTER_CRITICAL();
		watchdogCurrentMask = 0;
		OS_EXIT_CRITICAL();

		wdt_reset();
	}
}
#endif
